/// <summary> /// Gets all events for a tracking number. /// </summary> /// <param name="trackingNumber">The tracking number to track</param> /// <returns>List of Shipment Events.</returns> public virtual IList <ShipmentStatusEvent> GetShipmentEvents(string trackingNumber) { string errors; var trackingDetails = CanadaPostHelper.GetTrackingDetails(trackingNumber, _canadaPostSettings.ApiKey, _canadaPostSettings.UseSandbox, out errors); if (trackingDetails == null) { _logger.Error(errors); return(new List <ShipmentStatusEvent>()); } var events = new List <ShipmentStatusEvent>(); foreach (var eventItem in trackingDetails.significantevents) { events.Add(new ShipmentStatusEvent { EventName = eventItem.eventdescription, Location = eventItem.eventsite, Date = DateTime.Parse(eventItem.eventdate) }); } return(events); }
/// <summary> /// Gets available shipping options /// </summary> /// <param name="getShippingOptionRequest">A request for getting shipping options</param> /// <returns>Represents a response of getting shipping rate options</returns> public GetShippingOptionResponse GetShippingOptions(GetShippingOptionRequest getShippingOptionRequest) { if (getShippingOptionRequest == null) { throw new ArgumentNullException("getShippingOptionRequest"); } if (getShippingOptionRequest.Items == null) { return new GetShippingOptionResponse { Errors = new List <string> { "No shipment items" } } } ; if (getShippingOptionRequest.ShippingAddress == null) { return new GetShippingOptionResponse { Errors = new List <string> { "Shipping address is not set" } } } ; if (getShippingOptionRequest.ShippingAddress.Country == null) { return new GetShippingOptionResponse { Errors = new List <string> { "Shipping country is not set" } } } ; if (string.IsNullOrEmpty(getShippingOptionRequest.ZipPostalCodeFrom)) { return new GetShippingOptionResponse { Errors = new List <string> { "Origin postal code is not set" } } } ; //get available services string errors; var availableServices = CanadaPostHelper.GetServices(getShippingOptionRequest.ShippingAddress.Country.TwoLetterIsoCode, _canadaPostSettings.ApiKey, _canadaPostSettings.UseSandbox, out errors); if (availableServices == null) { return new GetShippingOptionResponse { Errors = new List <string> { errors } } } ; //create object for the get rates requests var result = new GetShippingOptionResponse(); object destinationCountry; switch (getShippingOptionRequest.ShippingAddress.Country.TwoLetterIsoCode.ToLowerInvariant()) { case "us": destinationCountry = new mailingscenarioDestinationUnitedstates { zipcode = getShippingOptionRequest.ShippingAddress.ZipPostalCode }; break; case "ca": destinationCountry = new mailingscenarioDestinationDomestic { postalcode = getShippingOptionRequest.ShippingAddress.ZipPostalCode }; break; default: destinationCountry = new mailingscenarioDestinationInternational { countrycode = getShippingOptionRequest.ShippingAddress.Country.TwoLetterIsoCode }; break; } var mailingScenario = new mailingscenario { customernumber = _canadaPostSettings.CustomerNumber, originpostalcode = getShippingOptionRequest.ZipPostalCodeFrom, destination = new mailingscenarioDestination { Item = destinationCountry } }; //get original parcel characteristics decimal originalLength; decimal originalWidth; decimal originalHeight; decimal originalWeight; GetWeight(getShippingOptionRequest, out originalWeight); GetDimensions(getShippingOptionRequest, out originalLength, out originalWidth, out originalHeight); //get rate for all available services var errorSummary = new StringBuilder(); foreach (var service in availableServices.service) { var currentService = CanadaPostHelper.GetServiceDetails(_canadaPostSettings.ApiKey, service.link.href, service.link.mediatype, out errors); if (currentService != null) { #region parcels count calculation var totalParcels = 1; //parcels count by weight var maxWeight = currentService.restrictions != null && currentService.restrictions.weightrestriction != null && currentService.restrictions.weightrestriction.maxSpecified ? currentService.restrictions.weightrestriction.max : int.MaxValue; if (originalWeight * 1000 > maxWeight) { var parcelsOnWeight = Convert.ToInt32(Math.Ceiling(originalWeight * 1000 / maxWeight)); if (parcelsOnWeight > totalParcels) { totalParcels = parcelsOnWeight; } } //parcels count by length var maxLength = currentService.restrictions != null && currentService.restrictions.dimensionalrestrictions != null && currentService.restrictions.dimensionalrestrictions.length != null && currentService.restrictions.dimensionalrestrictions.length.maxSpecified ? currentService.restrictions.dimensionalrestrictions.length.max : int.MaxValue; if (originalLength > maxLength) { var parcelsOnLength = Convert.ToInt32(Math.Ceiling(originalLength / maxLength)); if (parcelsOnLength > totalParcels) { totalParcels = parcelsOnLength; } } //parcels count by width var maxWidth = currentService.restrictions != null && currentService.restrictions.dimensionalrestrictions != null && currentService.restrictions.dimensionalrestrictions.width != null && currentService.restrictions.dimensionalrestrictions.width.maxSpecified ? currentService.restrictions.dimensionalrestrictions.width.max : int.MaxValue; if (originalWidth > maxWidth) { var parcelsOnWidth = Convert.ToInt32(Math.Ceiling(originalWidth / maxWidth)); if (parcelsOnWidth > totalParcels) { totalParcels = parcelsOnWidth; } } //parcels count by height var maxHeight = currentService.restrictions != null && currentService.restrictions.dimensionalrestrictions != null && currentService.restrictions.dimensionalrestrictions.height != null && currentService.restrictions.dimensionalrestrictions.height.maxSpecified ? currentService.restrictions.dimensionalrestrictions.height.max : int.MaxValue; if (originalHeight > maxHeight) { var parcelsOnHeight = Convert.ToInt32(Math.Ceiling(originalHeight / maxHeight)); if (parcelsOnHeight > totalParcels) { totalParcels = parcelsOnHeight; } } //parcel count by girth var lengthPlusGirthMax = currentService.restrictions != null && currentService.restrictions.dimensionalrestrictions != null && currentService.restrictions.dimensionalrestrictions.lengthplusgirthmaxSpecified ? currentService.restrictions.dimensionalrestrictions.lengthplusgirthmax : int.MaxValue; var lengthPlusGirth = 2 * (originalWidth + originalHeight) + originalLength; if (lengthPlusGirth > lengthPlusGirthMax) { var parcelsOnHeight = Convert.ToInt32(Math.Ceiling(lengthPlusGirth / lengthPlusGirthMax)); if (parcelsOnHeight > totalParcels) { totalParcels = parcelsOnHeight; } } //parcel count by sum of length, width and height var lengthWidthHeightMax = currentService.restrictions != null && currentService.restrictions.dimensionalrestrictions != null && currentService.restrictions.dimensionalrestrictions.lengthheightwidthsummaxSpecified ? currentService.restrictions.dimensionalrestrictions.lengthheightwidthsummax : int.MaxValue; var lengthWidthHeight = originalLength + originalWidth + originalHeight; if (lengthWidthHeight > lengthWidthHeightMax) { var parcelsOnHeight = Convert.ToInt32(Math.Ceiling(lengthWidthHeight / lengthWidthHeightMax)); if (parcelsOnHeight > totalParcels) { totalParcels = parcelsOnHeight; } } #endregion //set parcel characteristics mailingScenario.services = new[] { currentService.servicecode }; mailingScenario.parcelcharacteristics = new mailingscenarioParcelcharacteristics { weight = Math.Round(originalWeight / totalParcels, 3), dimensions = new mailingscenarioParcelcharacteristicsDimensions { length = Math.Round(originalLength / totalParcels, 1), width = Math.Round(originalWidth / totalParcels, 1), height = Math.Round(originalHeight / totalParcels, 1) } }; //get rate var priceQuotes = CanadaPostHelper.GetShippingRates(mailingScenario, _canadaPostSettings.ApiKey, _canadaPostSettings.UseSandbox, out errors); if (priceQuotes != null) { foreach (var option in priceQuotes.pricequote) { result.ShippingOptions.Add(new ShippingOption { Name = option.servicename, Rate = PriceToPrimaryStoreCurrency(option.pricedetails.due * totalParcels), Description = string.Format("Delivery {0}into {1} parcels", option.servicestandard != null && !string.IsNullOrEmpty(option.servicestandard.expectedtransittime) ? string.Format("in {0} days ", option.servicestandard.expectedtransittime) : string.Empty, totalParcels), }); } } else { errorSummary.AppendLine(errors); } } else { errorSummary.AppendLine(errors); } } //write errors var errorString = errorSummary.ToString(); if (!string.IsNullOrEmpty(errorString)) { _logger.Error(errorString); } if (!result.ShippingOptions.Any()) { result.AddError(errorString); } return(result); }