public void can_calculate_with_multple_items_1() { var request = new GetShippingOptionRequest(); request.Items.Add(new ShoppingCartItem() { Quantity = 3, ProductVariant = new ProductVariant() { Length = 2, Width = 2, Height = 2 } }); request.Items.Add(new ShoppingCartItem() { Quantity = 1, ProductVariant = new ProductVariant() { Length = 3, Width = 5, Height = 2 } }); decimal length, width, height = 0; request.GetDimensions(out width, out length, out height); Math.Round(length, 2).ShouldEqual(3.78); Math.Round(width, 2).ShouldEqual(5); //preserve max width Math.Round(height, 2).ShouldEqual(3.78); }
/// <summary> /// Gets fixed shipping rate (if shipping rate computation method allows it and the rate can be calculated before checkout). /// </summary> /// <param name="getShippingOptionRequest">A request for getting shipping options</param> /// <returns>Fixed shipping rate; or null in case there's no fixed shipping rate</returns> public decimal? GetFixedRate(GetShippingOptionRequest getShippingOptionRequest) { if (getShippingOptionRequest == null) throw new ArgumentNullException("getShippingOptionRequest"); return GetRate(); }
public void can_calculate_with_cubic_item_and_multiple_qty() { var request = new GetShippingOptionRequest(); request.Items.Add(new ShoppingCartItem() { Quantity = 3, ProductVariant = new ProductVariant() { Length = 2, Width = 2, Height = 2 } }); decimal length, width, height = 0; request.GetDimensions(out width, out length, out height); Math.Round(length, 2).ShouldEqual(2.88); Math.Round(width, 2).ShouldEqual(2.88); Math.Round(height, 2).ShouldEqual(2.88); }
/// <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"); var response = new GetShippingOptionResponse(); response.ShippingOptions.Add(new ShippingOption() { Name = "Shipping option 1", Description = "", Rate = GetRate() }); response.ShippingOptions.Add(new ShippingOption() { Name = "Shipping option 2", Description = "", Rate = GetRate() }); return response; }
public void can_calculate_with_multple_items_2() { //take 8 cubes of 1x1x1 which is "packed" as 2x2x2 var request = new GetShippingOptionRequest(); for (int i = 0; i < 8;i++) request.Items.Add(new ShoppingCartItem() { Quantity = 1, ProductVariant = new ProductVariant() { Length = 1, Width = 1, Height = 1 } }); decimal length, width, height = 0; request.GetDimensions(out width, out length, out height); Math.Round(length, 2).ShouldEqual(2); Math.Round(width, 2).ShouldEqual(2); Math.Round(height, 2).ShouldEqual(2); }
/// <summary> /// Gets fixed shipping rate (if shipping rate computation method allows it and the rate can be calculated before checkout). /// </summary> /// <param name="getShippingOptionRequest">A request for getting shipping options</param> /// <returns>Fixed shipping rate; or null in case there's no fixed shipping rate</returns> public decimal? GetFixedRate(GetShippingOptionRequest getShippingOptionRequest) { if (getShippingOptionRequest == null) throw new ArgumentNullException("getShippingOptionRequest"); int? restrictByCountryId = (getShippingOptionRequest.ShippingAddress != null && getShippingOptionRequest.ShippingAddress.Country != null) ? (int?)getShippingOptionRequest.ShippingAddress.Country.Id : null; var shippingMethods = this._shippingService.GetAllShippingMethods(restrictByCountryId); var rates = new List<decimal>(); foreach (var shippingMethod in shippingMethods) { decimal rate = GetRate(shippingMethod.Id); if (!rates.Contains(rate)) rates.Add(rate); } //return default rate if all of them equal if (rates.Count == 1) return rates[0]; return null; }
private void SetShipmentDetails(RateRequest request, GetShippingOptionRequest getShippingOptionRequest, decimal orderSubTotal, string currencyCode) { //set drop off type switch (_fedexSettings.DropoffType) { case Nas.Plugin.Shipping.Fedex.DropoffType.BusinessServiceCenter: request.RequestedShipment.DropoffType = RateServiceWebReference.DropoffType.BUSINESS_SERVICE_CENTER; break; case Nas.Plugin.Shipping.Fedex.DropoffType.DropBox: request.RequestedShipment.DropoffType = RateServiceWebReference.DropoffType.DROP_BOX; break; case Nas.Plugin.Shipping.Fedex.DropoffType.RegularPickup: request.RequestedShipment.DropoffType = RateServiceWebReference.DropoffType.REGULAR_PICKUP; break; case Nas.Plugin.Shipping.Fedex.DropoffType.RequestCourier: request.RequestedShipment.DropoffType = RateServiceWebReference.DropoffType.REQUEST_COURIER; break; case Nas.Plugin.Shipping.Fedex.DropoffType.Station: request.RequestedShipment.DropoffType = RateServiceWebReference.DropoffType.STATION; break; default: request.RequestedShipment.DropoffType = RateServiceWebReference.DropoffType.BUSINESS_SERVICE_CENTER; break; } request.RequestedShipment.TotalInsuredValue = new Money(); request.RequestedShipment.TotalInsuredValue.Amount = orderSubTotal; request.RequestedShipment.TotalInsuredValue.Currency = currencyCode; request.RequestedShipment.ShipTimestamp = DateTime.Now; // Shipping date and time request.RequestedShipment.ShipTimestampSpecified = true; request.RequestedShipment.RateRequestTypes = new RateRequestType[2]; request.RequestedShipment.RateRequestTypes[0] = RateRequestType.ACCOUNT; request.RequestedShipment.RateRequestTypes[1] = RateRequestType.LIST; request.RequestedShipment.PackageDetail = RequestedPackageDetailType.INDIVIDUAL_PACKAGES; request.RequestedShipment.PackageDetailSpecified = true; }
public void should_return_zero_with_all_zero_dimensions() { var request = new GetShippingOptionRequest(); request.Items.Add(new ShoppingCartItem() { Quantity = 1, ProductVariant = new ProductVariant() { Length = 0, Width = 0, Height = 0 } }); decimal length, width, height = 0; request.GetDimensions(out width, out length, out height); length.ShouldEqual(0); width.ShouldEqual(0); height.ShouldEqual(0); }
private List<Item> CreateItems(GetShippingOptionRequest getShippingOptionRequest) { var result = new List<Item>(); var usedMeasureWeight = _measureService.GetMeasureWeightBySystemKeyword("kg"); if (usedMeasureWeight == null) throw new NasException("CanadaPost shipping service. Could not load \"kg\" measure weight"); var usedMeasureDimension = _measureService.GetMeasureDimensionBySystemKeyword("meters"); if (usedMeasureDimension == null) throw new NasException("CanadaPost shipping service. Could not load \"meter(s)\" measure dimension"); foreach (var sci in getShippingOptionRequest.Items) { var pv = sci.ProductVariant; var item = new Item(); item.Quantity = sci.Quantity; //Canada Post uses kg(s) decimal unitWeight = _shippingService.GetShoppingCartItemTotalWeight(sci) / sci.Quantity; item.Weight = _measureService.ConvertFromPrimaryMeasureWeight(unitWeight, usedMeasureWeight); item.Weight = Math.Round(item.Weight, 2); if (item.Weight == decimal.Zero) item.Weight = 0.01M; //Canada Post uses centimeters item.Length = Convert.ToInt32(Math.Ceiling(_measureService.ConvertFromPrimaryMeasureDimension(pv.Length, usedMeasureDimension) * 100)); if (item.Length == decimal.Zero) item.Length = 1; item.Width = Convert.ToInt32(Math.Ceiling(_measureService.ConvertFromPrimaryMeasureDimension(pv.Width, usedMeasureDimension) * 100)); if (item.Width == decimal.Zero) item.Width = 1; item.Height = Convert.ToInt32(Math.Ceiling(_measureService.ConvertFromPrimaryMeasureDimension(pv.Height, usedMeasureDimension) * 100)); if (item.Height == decimal.Zero) item.Height = 1; result.Add(item); } return result; }
private void SetPayment(RateRequest request, GetShippingOptionRequest getShippingOptionRequest) { request.RequestedShipment.ShippingChargesPayment = new Payment(); // Payment Information request.RequestedShipment.ShippingChargesPayment.PaymentType = PaymentType.SENDER; // Payment options are RECIPIENT, SENDER, THIRD_PARTY request.RequestedShipment.ShippingChargesPayment.PaymentTypeSpecified = true; request.RequestedShipment.ShippingChargesPayment.Payor = new Payor(); request.RequestedShipment.ShippingChargesPayment.Payor.AccountNumber = _fedexSettings.AccountNumber; }
/// <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"); var response = new GetShippingOptionResponse(); if (getShippingOptionRequest.Items == null) { response.AddError("No shipment items"); return response; } if (getShippingOptionRequest.ShippingAddress == null) { response.AddError("Shipping address is not set"); return response; } string zipPostalCodeFrom = _australiaPostSettings.ShippedFromZipPostalCode; string zipPostalCodeTo = getShippingOptionRequest.ShippingAddress.ZipPostalCode; int weight = GetWeight(getShippingOptionRequest); int length = GetLength(getShippingOptionRequest); int width = GetWidth(getShippingOptionRequest); int height = GetHeight(getShippingOptionRequest); var country = getShippingOptionRequest.ShippingAddress.Country; //estimate packaging int totalPackages = 1; int totalPackagesDims = 1; int totalPackagesWeights = 1; if (length > MAX_LENGTH || width > MAX_LENGTH || height > MAX_LENGTH) { totalPackagesDims = Convert.ToInt32(Math.Ceiling((decimal)Math.Max(Math.Max(length, width), height) / MAX_LENGTH)); } if (weight > MAX_WEIGHT) { totalPackagesWeights = Convert.ToInt32(Math.Ceiling((decimal)weight / (decimal)MAX_WEIGHT)); } totalPackages = totalPackagesDims > totalPackagesWeights ? totalPackagesDims : totalPackagesWeights; if (totalPackages == 0) totalPackages = 1; if (totalPackages > 1) { //recalculate dims, weight weight = weight / totalPackages; height = height / totalPackages; width = width / totalPackages; length = length / totalPackages; if (weight < MIN_WEIGHT) weight = MIN_WEIGHT; if (height < MIN_LENGTH) height = MIN_LENGTH; if (width < MIN_LENGTH) width = MIN_LENGTH; if (length < MIN_LENGTH) length = MIN_LENGTH; } int girth = height + height + width + width; if (girth < MIN_GIRTH) { height = MIN_LENGTH; width = MIN_LENGTH; } if (girth > MAX_GIRTH) { height = MAX_LENGTH / 4; width = MAX_LENGTH / 4; } try { switch (country.ThreeLetterIsoCode) { case "AUS": //domestic services response.ShippingOptions.Add(RequestShippingOption(zipPostalCodeFrom, zipPostalCodeTo, country.TwoLetterIsoCode, "Standard", weight, length, width, height, totalPackages)); response.ShippingOptions.Add(RequestShippingOption(zipPostalCodeFrom, zipPostalCodeTo, country.TwoLetterIsoCode, "Express", weight, length, width, height, totalPackages)); response.ShippingOptions.Add(RequestShippingOption(zipPostalCodeFrom, zipPostalCodeTo, country.TwoLetterIsoCode, "EXP_PLT", weight, length, width, height, totalPackages)); break; default: //international services response.ShippingOptions.Add(RequestShippingOption(zipPostalCodeFrom, zipPostalCodeTo, country.TwoLetterIsoCode, "Air", weight, length, width, height, totalPackages)); response.ShippingOptions.Add(RequestShippingOption(zipPostalCodeFrom, zipPostalCodeTo, country.TwoLetterIsoCode, "Sea", weight, length, width, height, totalPackages)); response.ShippingOptions.Add(RequestShippingOption(zipPostalCodeFrom, zipPostalCodeTo, country.TwoLetterIsoCode, "ECI_D", weight, length, width, height, totalPackages)); response.ShippingOptions.Add(RequestShippingOption(zipPostalCodeFrom, zipPostalCodeTo, country.TwoLetterIsoCode, "ECI_M", weight, length, width, height, totalPackages)); response.ShippingOptions.Add(RequestShippingOption(zipPostalCodeFrom, zipPostalCodeTo, country.TwoLetterIsoCode, "EPI", weight, length, width, height, totalPackages)); break; } foreach (var shippingOption in response.ShippingOptions) { shippingOption.Rate += _australiaPostSettings.AdditionalHandlingCharge; } } catch (Exception ex) { response.AddError(ex.Message); } return response; }
private int GetWidth(GetShippingOptionRequest getShippingOptionRequest) { int value = Convert.ToInt32(Math.Ceiling(this._measureService.ConvertFromPrimaryMeasureDimension(getShippingOptionRequest.GetTotalWidth(), this.GatewayMeasureDimension))); return (value < MIN_LENGTH ? MIN_LENGTH : value); }
/// <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"); var response = new GetShippingOptionResponse(); if (getShippingOptionRequest.Items == null) { response.AddError("No shipment items"); return response; } if (getShippingOptionRequest.ShippingAddress == null) { response.AddError("Shipping address is not set"); return response; } if (getShippingOptionRequest.ShippingAddress.Country == null) { response.AddError("Shipping country is not set"); return response; } if (getShippingOptionRequest.ShippingAddress.StateProvince == null) { response.AddError("Shipping state is not set"); return response; } try { var profile = new Profile(); profile.MerchantId = _canadaPostSettings.CustomerId; var destination = new Destination(); destination.City = getShippingOptionRequest.ShippingAddress.City; destination.StateOrProvince = getShippingOptionRequest.ShippingAddress.StateProvince.Abbreviation; destination.Country = getShippingOptionRequest.ShippingAddress.Country.TwoLetterIsoCode; destination.PostalCode = getShippingOptionRequest.ShippingAddress.ZipPostalCode; var items = CreateItems(getShippingOptionRequest); var lang = CanadaPostLanguageEnum.English; if (_workContext.WorkingLanguage.LanguageCulture.StartsWith("fr", StringComparison.InvariantCultureIgnoreCase)) lang = CanadaPostLanguageEnum.French; var requestResult = GetShippingOptionsInternal(profile, destination, items, lang); if (requestResult.IsError) { response.AddError(requestResult.StatusMessage); } else { foreach (var dr in requestResult.AvailableRates) { var so = new ShippingOption(); so.Name = dr.Name; if (!string.IsNullOrEmpty(dr.DeliveryDate)) so.Name += string.Format(" - {0}", dr.DeliveryDate); so.Rate = dr.Amount; response.ShippingOptions.Add(so); } } foreach (var shippingOption in response.ShippingOptions) { if (!shippingOption.Name.StartsWith("canada post", StringComparison.InvariantCultureIgnoreCase)) shippingOption.Name = string.Format("Canada Post {0}", shippingOption.Name); } } catch (Exception e) { response.AddError(e.Message); } return response; }
private string CreateRequest(string username, string password, GetShippingOptionRequest getShippingOptionRequest) { var usedMeasureWeight = _measureService.GetMeasureWeightBySystemKeyword(MEASUREWEIGHTSYSTEMKEYWORD); if (usedMeasureWeight == null) throw new NasException(string.Format("USPS shipping service. Could not load \"{0}\" measure weight", MEASUREWEIGHTSYSTEMKEYWORD)); var baseusedMeasureWeight = _measureService.GetMeasureWeightById(_measureSettings.BaseWeightId); if (baseusedMeasureWeight == null) throw new NasException("Primary weight can't be loaded"); var usedMeasureDimension = _measureService.GetMeasureDimensionBySystemKeyword(MEASUREDIMENSIONSYSTEMKEYWORD); if (usedMeasureDimension == null) throw new NasException(string.Format("USPS shipping service. Could not load \"{0}\" measure dimension", MEASUREDIMENSIONSYSTEMKEYWORD)); var baseusedMeasureDimension = _measureService.GetMeasureDimensionById(_measureSettings.BaseDimensionId); if (usedMeasureDimension == null) throw new NasException("Primary dimension can't be loaded"); int length = Convert.ToInt32(Math.Ceiling(getShippingOptionRequest.GetTotalLength() / baseusedMeasureDimension.Ratio * usedMeasureDimension.Ratio)); int height = Convert.ToInt32(Math.Ceiling(getShippingOptionRequest.GetTotalHeight() / baseusedMeasureDimension.Ratio * usedMeasureDimension.Ratio)); int width = Convert.ToInt32(Math.Ceiling(getShippingOptionRequest.GetTotalWidth() / baseusedMeasureDimension.Ratio * usedMeasureDimension.Ratio)); int weight = Convert.ToInt32(Math.Ceiling(_shippingService.GetShoppingCartTotalWeight(getShippingOptionRequest.Items) / baseusedMeasureWeight.Ratio * usedMeasureWeight.Ratio)); if (length < 1) length = 1; if (height < 1) height = 1; if (width < 1) width = 1; if (weight < 1) weight = 1; string zipPostalCodeFrom = getShippingOptionRequest.ZipPostalCodeFrom; string zipPostalCodeTo = getShippingOptionRequest.ShippingAddress.ZipPostalCode; //valid values for testing. http://testing.shippingapis.com/ShippingAPITest.dll //Zip to = "20008"; Zip from ="10022"; weight = 2; int pounds = Convert.ToInt32(weight / 16); int ounces = Convert.ToInt32(weight - (pounds * 16.0M)); int girth = height + height + width + width; //Get shopping cart sub-total. V2 International rates require the package value to be declared. decimal subTotal = decimal.Zero; foreach (var shoppingCartItem in getShippingOptionRequest.Items) { if (!shoppingCartItem.IsShipEnabled) continue; subTotal += _priceCalculationService.GetSubTotal(shoppingCartItem, true); } string requestString = string.Empty; bool isDomestic = IsDomesticRequest(getShippingOptionRequest); if (isDomestic) { #region domestic request zipPostalCodeFrom = CommonHelper.EnsureMaximumLength(CommonHelper.EnsureNumericOnly(zipPostalCodeFrom), 5); zipPostalCodeTo = CommonHelper.EnsureMaximumLength(CommonHelper.EnsureNumericOnly(zipPostalCodeTo), 5); var sb = new StringBuilder(); sb.AppendFormat("<RateV4Request USERID=\"{0}\" PASSWORD=\"{1}\">", username, password); sb.Append("<Revision>2</Revision>"); var xmlStrings = new USPSStrings(); // Create new instance with string array if ((!IsPackageTooHeavy(pounds)) && (!IsPackageTooLarge(length, height, width))) { var packageSize = GetPackageSize(length, height, width); // RJH get all XML strings not commented out for USPSStrings. // RJH V3 USPS Service must be Express, Express SH, Express Commercial, Express SH Commercial, First Class, Priority, Priority Commercial, Parcel, Library, BPM, Media, ALL or ONLINE; // AC - Updated to V4 API and made minor improvements to allow First Class Packages (package only - not envelopes). foreach (string element in xmlStrings.Elements) // Loop over elements with property { if ((element == "First Class") && (weight >= 14)) { // AC - At the time of coding there aren't any First Class shipping options for packages over 13 ounces. } else { sb.Append("<Package ID=\"0\">"); sb.AppendFormat("<Service>{0}</Service>", element); if (element == "First Class") sb.Append("<FirstClassMailType>PARCEL</FirstClassMailType>"); sb.AppendFormat("<ZipOrigination>{0}</ZipOrigination>", zipPostalCodeFrom); sb.AppendFormat("<ZipDestination>{0}</ZipDestination>", zipPostalCodeTo); sb.AppendFormat("<Pounds>{0}</Pounds>", pounds); sb.AppendFormat("<Ounces>{0}</Ounces>", ounces); sb.Append("<Container/>"); sb.AppendFormat("<Size>{0}</Size>", packageSize); sb.AppendFormat("<Width>{0}</Width>", width); sb.AppendFormat("<Length>{0}</Length>", length); sb.AppendFormat("<Height>{0}</Height>", height); sb.AppendFormat("<Girth>{0}</Girth>", girth); sb.Append("<Machinable>FALSE</Machinable>"); sb.Append("</Package>"); } } } else { int totalPackages = 1; int totalPackagesDims = 1; int totalPackagesWeights = 1; if (IsPackageTooHeavy(pounds)) { totalPackagesWeights = Convert.ToInt32(Math.Ceiling((decimal)pounds / (decimal)MAXPACKAGEWEIGHT)); } if (IsPackageTooLarge(length, height, width)) { totalPackagesDims = Convert.ToInt32(Math.Ceiling((decimal)TotalPackageSize(length, height, width) / (decimal)108)); } totalPackages = totalPackagesDims > totalPackagesWeights ? totalPackagesDims : totalPackagesWeights; if (totalPackages == 0) totalPackages = 1; int pounds2 = pounds / totalPackages; //we don't use ounces int ounces2 = ounces / totalPackages; int height2 = height / totalPackages; int width2 = width / totalPackages; int length2 = length / totalPackages; if (pounds2 < 1) pounds2 = 1; if (height2 < 1) height2 = 1; if (width2 < 1) width2 = 1; if (length2 < 1) length2 = 1; var packageSize = GetPackageSize(length2, height2, width2); int girth2 = height2 + height2 + width2 + width2; for (int i = 0; i < totalPackages; i++) { foreach (string element in xmlStrings.Elements) { if ((element == "First Class") && (weight >= 14)) { // AC - At the time of coding there aren't any First Class shipping options for packages over 13 ounces. } else { sb.AppendFormat("<Package ID=\"{0}\">", i.ToString()); sb.AppendFormat("<Service>{0}</Service>", element); if (element == "First Class") sb.Append("<FirstClassMailType>PARCEL</FirstClassMailType>"); sb.AppendFormat("<ZipOrigination>{0}</ZipOrigination>", zipPostalCodeFrom); sb.AppendFormat("<ZipDestination>{0}</ZipDestination>", zipPostalCodeTo); sb.AppendFormat("<Pounds>{0}</Pounds>", pounds2); sb.AppendFormat("<Ounces>{0}</Ounces>", ounces2); sb.Append("<Container/>"); sb.AppendFormat("<Size>{0}</Size>", packageSize); sb.AppendFormat("<Width>{0}</Width>", width2); sb.AppendFormat("<Length>{0}</Length>", length2); sb.AppendFormat("<Height>{0}</Height>", height2); sb.AppendFormat("<Girth>{0}</Girth>", girth2); sb.Append("<Machinable>FALSE</Machinable>"); sb.Append("</Package>"); } } } } sb.Append("</RateV4Request>"); requestString = "API=RateV4&XML=" + sb.ToString(); #endregion } else { #region international request var sb = new StringBuilder(); // sb.AppendFormat("<IntlRateRequest USERID=\"{0}\" PASSWORD=\"{1}\">", username, password); sb.AppendFormat("<IntlRateV2Request USERID=\"{0}\" PASSWORD=\"{1}\">", username, password); //V2 International rates require the package value to be declared. Max content value for most shipping options is $400 so it is limited here. decimal intlSubTotal = decimal.Zero; if (subTotal > 400) { intlSubTotal = 400; } else { intlSubTotal = subTotal; } //little hack here for international requests length = 12; width = 12; height = 12; girth = height + height + width + width; string mailType = "Package"; //Package, Envelope var packageSize = GetPackageSize(length, height, width); if ((!IsPackageTooHeavy(pounds)) && (!IsPackageTooLarge(length, height, width))) { sb.Append("<Package ID=\"0\">"); sb.AppendFormat("<Pounds>{0}</Pounds>", pounds); sb.AppendFormat("<Ounces>{0}</Ounces>", ounces); sb.Append("<Machinable>FALSE</Machinable>"); sb.AppendFormat("<MailType>{0}</MailType>", mailType); sb.Append("<GXG>"); sb.Append("<POBoxFlag>N</POBoxFlag>"); sb.Append("<GiftFlag>N</GiftFlag>"); sb.Append("</GXG>"); sb.AppendFormat("<ValueOfContents>{0}</ValueOfContents>", intlSubTotal); sb.AppendFormat("<Country>{0}</Country>", getShippingOptionRequest.ShippingAddress.Country.Name); sb.Append("<Container>RECTANGULAR</Container>"); sb.AppendFormat("<Size>{0}</Size>", packageSize); sb.AppendFormat("<Width>{0}</Width>", width); sb.AppendFormat("<Length>{0}</Length>", length); sb.AppendFormat("<Height>{0}</Height>", height); sb.AppendFormat("<Girth>{0}</Girth>", girth); sb.Append("<CommercialFlag>N</CommercialFlag>"); sb.Append("</Package>"); } else { int totalPackages = 1; int totalPackagesDims = 1; int totalPackagesWeights = 1; if (IsPackageTooHeavy(pounds)) { totalPackagesWeights = Convert.ToInt32(Math.Ceiling((decimal)pounds / (decimal)MAXPACKAGEWEIGHT)); } if (IsPackageTooLarge(length, height, width)) { totalPackagesDims = Convert.ToInt32(Math.Ceiling((decimal)TotalPackageSize(length, height, width) / (decimal)108)); } totalPackages = totalPackagesDims > totalPackagesWeights ? totalPackagesDims : totalPackagesWeights; if (totalPackages == 0) totalPackages = 1; int pounds2 = pounds / totalPackages; //we don't use ounces int ounces2 = ounces / totalPackages; int height2 = height / totalPackages; int width2 = width / totalPackages; int length2 = length / totalPackages; if (pounds2 < 1) pounds2 = 1; if (height2 < 1) height2 = 1; if (width2 < 1) width2 = 1; if (length2 < 1) length2 = 1; //little hack here for international requests length2 = 12; width2 = 12; height2 = 12; var packageSize2 = GetPackageSize(length2, height2, width2); int girth2 = height2 + height2 + width2 + width2; for (int i = 0; i < totalPackages; i++) { sb.AppendFormat("<Package ID=\"{0}\">", i.ToString()); sb.AppendFormat("<Pounds>{0}</Pounds>", pounds2); sb.AppendFormat("<Ounces>{0}</Ounces>", ounces2); sb.Append("<Machinable>FALSE</Machinable>"); sb.AppendFormat("<MailType>{0}</MailType>", mailType); sb.Append("<GXG>"); sb.Append("<POBoxFlag>N</POBoxFlag>"); sb.Append("<GiftFlag>N</GiftFlag>"); sb.Append("</GXG>"); sb.AppendFormat("<ValueOfContents>{0}</ValueOfContents>", intlSubTotal); sb.AppendFormat("<Country>{0}</Country>", getShippingOptionRequest.ShippingAddress.Country.Name); sb.Append("<Container>RECTANGULAR</Container>"); sb.AppendFormat("<Size>{0}</Size>", packageSize2); sb.AppendFormat("<Width>{0}</Width>", width2); sb.AppendFormat("<Length>{0}</Length>", length2); sb.AppendFormat("<Height>{0}</Height>", height2); sb.AppendFormat("<Girth>{0}</Girth>", girth2); sb.Append("<CommercialFlag>N</CommercialFlag>"); sb.Append("</Package>"); } } sb.Append("</IntlRateV2Request>"); requestString = "API=IntlRateV2&XML=" + sb.ToString(); #endregion } return requestString; }
/// <summary> /// Get dimensions /// </summary> /// <param name="request">Request to get shipping options</param> /// <param name="width">Width</param> /// <param name="length">Length</param> /// <param name="height">Height</param> /// <param name="useCubeRootMethod">A value indicating whether dimensions are calculated based on cube root of volume</param> public static void GetDimensions(this GetShippingOptionRequest request, out decimal width, out decimal length, out decimal height, bool useCubeRootMethod = true) { if (useCubeRootMethod) { //cube root of volume decimal totalVolume = 0; decimal maxProductWidth = 0; decimal maxProductLength = 0; decimal maxProductHeight = 0; foreach (var shoppingCartItem in request.Items) { var productVariant = shoppingCartItem.ProductVariant; if (productVariant != null) { totalVolume += shoppingCartItem.Quantity * productVariant.Height * productVariant.Width * productVariant.Length; if (productVariant.Width > maxProductWidth) { maxProductWidth = productVariant.Width; } if (productVariant.Length > maxProductLength) { maxProductLength = productVariant.Length; } if (productVariant.Height > maxProductHeight) { maxProductHeight = productVariant.Height; } } } decimal dimension = Convert.ToDecimal(Math.Pow(Convert.ToDouble(totalVolume), (double)(1.0 / 3.0))); length = width = height = dimension; //sometimes we have products with sizes like 1x1x20 //that's why let's ensure that a maximum dimension is always preserved //otherwise, shipping rate computation methods can return low rates if (width < maxProductWidth) { width = maxProductWidth; } if (length < maxProductLength) { length = maxProductLength; } if (height < maxProductHeight) { height = maxProductHeight; } } else { //summarize all values (very inaccurate with multiple items) width = length = height = decimal.Zero; foreach (var shoppingCartItem in request.Items) { var productVariant = shoppingCartItem.ProductVariant; if (productVariant != null) { width += productVariant.Width * shoppingCartItem.Quantity; length += productVariant.Length * shoppingCartItem.Quantity; height += productVariant.Height * shoppingCartItem.Quantity; } } } }
/// <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"); var response = new GetShippingOptionResponse(); if (getShippingOptionRequest.Items == null) { response.AddError("No shipment items"); return response; } if (getShippingOptionRequest.ShippingAddress == null) { response.AddError("Shipping address is not set"); return response; } if (getShippingOptionRequest.ShippingAddress.Country == null) { response.AddError("Shipping country is not set"); return response; } Currency requestedShipmentCurrency; var request = CreateRateRequest(getShippingOptionRequest, out requestedShipmentCurrency); var service = new RateService(); // Initialize the service service.Url = _fedexSettings.Url; try { // This is the call to the web service passing in a RateRequest and returning a RateReply var reply = service.getRates(request); // Service call if (reply.HighestSeverity == RateServiceWebReference.NotificationSeverityType.SUCCESS || reply.HighestSeverity == RateServiceWebReference.NotificationSeverityType.NOTE || reply.HighestSeverity == RateServiceWebReference.NotificationSeverityType.WARNING) // check if the call was successful { if (reply != null && reply.RateReplyDetails != null) { var shippingOptions = ParseResponse(reply, requestedShipmentCurrency); foreach (var shippingOption in shippingOptions) response.ShippingOptions.Add(shippingOption); } else { if (reply != null && reply.Notifications != null && reply.Notifications.Length > 0 && !String.IsNullOrEmpty(reply.Notifications[0].Message)) { response.AddError(string.Format("{0} (code: {1})", reply.Notifications[0].Message, reply.Notifications[0].Code)); return response; } else { response.AddError("Could not get reply from shipping server"); return response; } } } else { Debug.WriteLine(reply.Notifications[0].Message); response.AddError(reply.Notifications[0].Message); return response; } } catch (SoapException e) { Debug.WriteLine(e.Detail.InnerText); response.AddError(e.Detail.InnerText); return response; } catch (Exception e) { Debug.WriteLine(e.Message); response.AddError(e.Message); return response; } return response; }
/// <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"); var response = new GetShippingOptionResponse(); if (getShippingOptionRequest.Items == null || getShippingOptionRequest.Items.Count == 0) { response.AddError("No shipment items"); return response; } if (getShippingOptionRequest.ShippingAddress == null) { response.AddError("Shipping address is not set"); return response; } int countryId = getShippingOptionRequest.ShippingAddress.CountryId.HasValue ? getShippingOptionRequest.ShippingAddress.CountryId.Value : 0; int stateProvinceId = getShippingOptionRequest.ShippingAddress.StateProvinceId.HasValue ? getShippingOptionRequest.ShippingAddress.StateProvinceId.Value : 0; string zip = getShippingOptionRequest.ShippingAddress.ZipPostalCode; decimal subTotal = decimal.Zero; foreach (var shoppingCartItem in getShippingOptionRequest.Items) { if (shoppingCartItem.IsFreeShipping || !shoppingCartItem.IsShipEnabled) continue; subTotal += _priceCalculationService.GetSubTotal(shoppingCartItem, true); } decimal weight = _shippingService.GetShoppingCartTotalWeight(getShippingOptionRequest.Items); var shippingMethods = _shippingService.GetAllShippingMethods(countryId); foreach (var shippingMethod in shippingMethods) { decimal? rate = GetRate(subTotal, weight, shippingMethod.Id, countryId, stateProvinceId, zip); if (rate.HasValue) { var shippingOption = new ShippingOption(); shippingOption.Name = shippingMethod.GetLocalized(x => x.Name); shippingOption.Description = shippingMethod.GetLocalized(x => x.Description); shippingOption.Rate = rate.Value; response.ShippingOptions.Add(shippingOption); } } return response; }
private string CreateRequest(string accessKey, string username, string password, GetShippingOptionRequest getShippingOptionRequest, UPSCustomerClassification customerClassification, UPSPickupType pickupType, UPSPackagingType packagingType) { var usedMeasureWeight = _measureService.GetMeasureWeightBySystemKeyword(MEASUREWEIGHTSYSTEMKEYWORD); if (usedMeasureWeight == null) throw new NasException(string.Format("UPS shipping service. Could not load \"{0}\" measure weight", MEASUREWEIGHTSYSTEMKEYWORD)); var usedMeasureDimension = _measureService.GetMeasureDimensionBySystemKeyword(MEASUREDIMENSIONSYSTEMKEYWORD); if (usedMeasureDimension == null) throw new NasException(string.Format("UPS shipping service. Could not load \"{0}\" measure dimension", MEASUREDIMENSIONSYSTEMKEYWORD)); int length = Convert.ToInt32(Math.Ceiling(_measureService.ConvertFromPrimaryMeasureDimension(getShippingOptionRequest.GetTotalLength(), usedMeasureDimension))); int height = Convert.ToInt32(Math.Ceiling(_measureService.ConvertFromPrimaryMeasureDimension(getShippingOptionRequest.GetTotalHeight(), usedMeasureDimension))); int width = Convert.ToInt32(Math.Ceiling(_measureService.ConvertFromPrimaryMeasureDimension(getShippingOptionRequest.GetTotalWidth(), usedMeasureDimension))); int weight = Convert.ToInt32(Math.Ceiling(_measureService.ConvertFromPrimaryMeasureWeight(_shippingService.GetShoppingCartTotalWeight(getShippingOptionRequest.Items), usedMeasureWeight))); if (length < 1) length = 1; if (height < 1) height = 1; if (width < 1) width = 1; if (weight < 1) weight = 1; string zipPostalCodeFrom = getShippingOptionRequest.ZipPostalCodeFrom; string zipPostalCodeTo = getShippingOptionRequest.ShippingAddress.ZipPostalCode; string countryCodeFrom = getShippingOptionRequest.CountryFrom.TwoLetterIsoCode; string countryCodeTo = getShippingOptionRequest.ShippingAddress.Country.TwoLetterIsoCode; decimal orderSubTotalDiscountAmount = decimal.Zero; Discount orderSubTotalAppliedDiscount = null; decimal subTotalWithoutDiscountBase = decimal.Zero; decimal subTotalWithDiscountBase = decimal.Zero; _orderTotalCalculationService.GetShoppingCartSubTotal(getShippingOptionRequest.Items, out orderSubTotalDiscountAmount, out orderSubTotalAppliedDiscount, out subTotalWithoutDiscountBase, out subTotalWithDiscountBase); var sb = new StringBuilder(); sb.Append("<?xml version='1.0'?>"); sb.Append("<AccessRequest xml:lang='en-US'>"); sb.AppendFormat("<AccessLicenseNumber>{0}</AccessLicenseNumber>", accessKey); sb.AppendFormat("<UserId>{0}</UserId>", username); sb.AppendFormat("<Password>{0}</Password>", password); sb.Append("</AccessRequest>"); sb.Append("<?xml version='1.0'?>"); sb.Append("<RatingServiceSelectionRequest xml:lang='en-US'>"); sb.Append("<Request>"); sb.Append("<TransactionReference>"); sb.Append("<CustomerContext>Bare Bones Rate Request</CustomerContext>"); sb.Append("<XpciVersion>1.0001</XpciVersion>"); sb.Append("</TransactionReference>"); sb.Append("<RequestAction>Rate</RequestAction>"); sb.Append("<RequestOption>Shop</RequestOption>"); sb.Append("</Request>"); if (String.Equals(countryCodeFrom, "US", StringComparison.InvariantCultureIgnoreCase) == true) { sb.Append("<PickupType>"); sb.AppendFormat("<Code>{0}</Code>", GetPickupTypeCode(pickupType)); sb.Append("</PickupType>"); sb.Append("<CustomerClassification>"); sb.AppendFormat("<Code>{0}</Code>", GetCustomerClassificationCode(customerClassification)); sb.Append("</CustomerClassification>"); } sb.Append("<Shipment>"); sb.Append("<Shipper>"); sb.Append("<Address>"); sb.AppendFormat("<PostalCode>{0}</PostalCode>", zipPostalCodeFrom); sb.AppendFormat("<CountryCode>{0}</CountryCode>", countryCodeFrom); sb.Append("</Address>"); sb.Append("</Shipper>"); sb.Append("<ShipTo>"); sb.Append("<Address>"); sb.Append("<ResidentialAddressIndicator/>"); sb.AppendFormat("<PostalCode>{0}</PostalCode>", zipPostalCodeTo); sb.AppendFormat("<CountryCode>{0}</CountryCode>", countryCodeTo); sb.Append("</Address>"); sb.Append("</ShipTo>"); sb.Append("<ShipFrom>"); sb.Append("<Address>"); sb.AppendFormat("<PostalCode>{0}</PostalCode>", zipPostalCodeFrom); sb.AppendFormat("<CountryCode>{0}</CountryCode>", countryCodeFrom); sb.Append("</Address>"); sb.Append("</ShipFrom>"); sb.Append("<Service>"); sb.Append("<Code>03</Code>"); sb.Append("</Service>"); if ((!IsPackageTooHeavy(weight)) && (!IsPackageTooLarge(length, height, width))) { sb.Append("<Package>"); sb.Append("<PackagingType>"); sb.AppendFormat("<Code>{0}</Code>", GetPackagingTypeCode(packagingType)); sb.Append("</PackagingType>"); sb.Append("<Dimensions>"); sb.AppendFormat("<Length>{0}</Length>", length); sb.AppendFormat("<Width>{0}</Width>", width); sb.AppendFormat("<Height>{0}</Height>", height); sb.Append("</Dimensions>"); sb.Append("<PackageWeight>"); sb.AppendFormat("<Weight>{0}</Weight>", weight); sb.Append("</PackageWeight>"); if (_upsSettings.InsurePackage) { //The maximum declared amount per package: 50000 USD. int packageInsurancePrice = Convert.ToInt32(subTotalWithDiscountBase); sb.Append("<PackageServiceOptions>"); sb.Append("<InsuredValue>"); sb.AppendFormat("<CurrencyCode>{0}</CurrencyCode>", _currencyService.GetCurrencyById(_currencySettings.PrimaryStoreCurrencyId).CurrencyCode); sb.AppendFormat("<MonetaryValue>{0}</MonetaryValue>", packageInsurancePrice); sb.Append("</InsuredValue>"); sb.Append("</PackageServiceOptions>"); } sb.Append("</Package>"); } else { int totalPackages = 1; int totalPackagesDims = 1; int totalPackagesWeights = 1; if (IsPackageTooHeavy(weight)) { totalPackagesWeights = Convert.ToInt32(Math.Ceiling((decimal)weight / (decimal)MAXPACKAGEWEIGHT)); } if (IsPackageTooLarge(length, height, width)) { totalPackagesDims = Convert.ToInt32(Math.Ceiling((decimal)TotalPackageSize(length, height, width) / (decimal)108)); } totalPackages = totalPackagesDims > totalPackagesWeights ? totalPackagesDims : totalPackagesWeights; if (totalPackages == 0) totalPackages = 1; int weight2 = weight / totalPackages; int height2 = height / totalPackages; int width2 = width / totalPackages; int length2 = length / totalPackages; if (weight2 < 1) weight2 = 1; if (height2 < 1) height2 = 1; if (width2 < 1) width2 = 1; if (length2 < 1) length2 = 1; //The maximum declared amount per package: 50000 USD. int packageInsurancePrice = Convert.ToInt32(subTotalWithDiscountBase / totalPackages); for (int i = 0; i < totalPackages; i++) { sb.Append("<Package>"); sb.Append("<PackagingType>"); sb.AppendFormat("<Code>{0}</Code>", GetPackagingTypeCode(packagingType)); sb.Append("</PackagingType>"); sb.Append("<Dimensions>"); sb.AppendFormat("<Length>{0}</Length>", length2); sb.AppendFormat("<Width>{0}</Width>", width2); sb.AppendFormat("<Height>{0}</Height>", height2); sb.Append("</Dimensions>"); sb.Append("<PackageWeight>"); sb.AppendFormat("<Weight>{0}</Weight>", weight2); sb.Append("</PackageWeight>"); if (_upsSettings.InsurePackage) { sb.Append("<PackageServiceOptions>"); sb.Append("<InsuredValue>"); sb.AppendFormat("<CurrencyCode>{0}</CurrencyCode>", _currencyService.GetCurrencyById(_currencySettings.PrimaryStoreCurrencyId).CurrencyCode); sb.AppendFormat("<MonetaryValue>{0}</MonetaryValue>", packageInsurancePrice); sb.Append("</InsuredValue>"); sb.Append("</PackageServiceOptions>"); } sb.Append("</Package>"); } } sb.Append("</Shipment>"); sb.Append("</RatingServiceSelectionRequest>"); string requestString = sb.ToString(); return requestString; }
/// <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"); var response = new GetShippingOptionResponse(); if (getShippingOptionRequest.Items == null) { response.AddError("No shipment items"); return response; } if (getShippingOptionRequest.ShippingAddress == null) { response.AddError("Shipping address is not set"); return response; } if (getShippingOptionRequest.ShippingAddress.Country == null) { response.AddError("Shipping country is not set"); return response; } if (getShippingOptionRequest.CountryFrom == null) { getShippingOptionRequest.CountryFrom = _countryService.GetCountryById(_upsSettings.DefaultShippedFromCountryId); if (getShippingOptionRequest.CountryFrom == null) getShippingOptionRequest.CountryFrom = _countryService.GetAllCountries(true).FirstOrDefault(); } if (String.IsNullOrEmpty(getShippingOptionRequest.ZipPostalCodeFrom)) getShippingOptionRequest.ZipPostalCodeFrom = _upsSettings.DefaultShippedFromZipPostalCode; string requestString = CreateRequest(_upsSettings.AccessKey, _upsSettings.Username, _upsSettings.Password, getShippingOptionRequest, _upsSettings.CustomerClassification, _upsSettings.PickupType, _upsSettings.PackagingType); string responseXml = DoRequest(_upsSettings.Url, requestString); string error = ""; var shippingOptions = ParseResponse(responseXml, ref error); if (String.IsNullOrEmpty(error)) { foreach (var shippingOption in shippingOptions) { if (!shippingOption.Name.ToLower().StartsWith("ups")) shippingOption.Name = string.Format("UPS {0}", shippingOption.Name); shippingOption.Rate += _upsSettings.AdditionalHandlingCharge; response.ShippingOptions.Add(shippingOption); } } else { response.AddError(error); } return response; }
private RateRequest CreateRateRequest(GetShippingOptionRequest getShippingOptionRequest, out Currency requestedShipmentCurrency) { // Build the RateRequest var request = new RateRequest(); request.WebAuthenticationDetail = new RateServiceWebReference.WebAuthenticationDetail(); request.WebAuthenticationDetail.UserCredential = new RateServiceWebReference.WebAuthenticationCredential(); request.WebAuthenticationDetail.UserCredential.Key = _fedexSettings.Key; request.WebAuthenticationDetail.UserCredential.Password = _fedexSettings.Password; request.ClientDetail = new RateServiceWebReference.ClientDetail(); request.ClientDetail.AccountNumber = _fedexSettings.AccountNumber; request.ClientDetail.MeterNumber = _fedexSettings.MeterNumber; request.TransactionDetail = new RateServiceWebReference.TransactionDetail(); request.TransactionDetail.CustomerTransactionId = "***Rate Available Services v7 Request - NasCommerce***"; // This is a reference field for the customer. Any value can be used and will be provided in the response. request.Version = new RateServiceWebReference.VersionId(); // WSDL version information, value is automatically set from wsdl request.ReturnTransitAndCommit = true; request.ReturnTransitAndCommitSpecified = true; request.CarrierCodes = new RateServiceWebReference.CarrierCodeType[2]; // Insert the Carriers you would like to see the rates for request.CarrierCodes[0] = RateServiceWebReference.CarrierCodeType.FDXE; request.CarrierCodes[1] = RateServiceWebReference.CarrierCodeType.FDXG; decimal subTotalBase = decimal.Zero; decimal orderSubTotalDiscountAmount = decimal.Zero; Discount orderSubTotalAppliedDiscount = null; decimal subTotalWithoutDiscountBase = decimal.Zero; decimal subTotalWithDiscountBase = decimal.Zero; _orderTotalCalculationService.GetShoppingCartSubTotal(getShippingOptionRequest.Items, out orderSubTotalDiscountAmount, out orderSubTotalAppliedDiscount, out subTotalWithoutDiscountBase, out subTotalWithDiscountBase); subTotalBase = subTotalWithDiscountBase; request.RequestedShipment = new RequestedShipment(); SetOrigin(request, getShippingOptionRequest); SetDestination(request, getShippingOptionRequest); requestedShipmentCurrency = GetRequestedShipmentCurrency( request.RequestedShipment.Shipper.Address.CountryCode, // origin request.RequestedShipment.Recipient.Address.CountryCode); // destination decimal subTotalShipmentCurrency; var primaryStoreCurrency = _currencyService.GetCurrencyById(_currencySettings.PrimaryStoreCurrencyId); if (requestedShipmentCurrency.CurrencyCode == primaryStoreCurrency.CurrencyCode) subTotalShipmentCurrency = subTotalBase; else subTotalShipmentCurrency = _currencyService.ConvertFromPrimaryStoreCurrency(subTotalBase, requestedShipmentCurrency); Debug.WriteLine(String.Format("SubTotal (Primary Currency) : {0} ({1})", subTotalBase, primaryStoreCurrency.CurrencyCode)); Debug.WriteLine(String.Format("SubTotal (Shipment Currency): {0} ({1})", subTotalShipmentCurrency, requestedShipmentCurrency.CurrencyCode)); SetShipmentDetails(request, getShippingOptionRequest, subTotalShipmentCurrency, requestedShipmentCurrency.CurrencyCode); SetPayment(request, getShippingOptionRequest); switch (_fedexSettings.PackingType) { case PackingType.PackByOneItemPerPackage: SetIndividualPackageLineItemsOneItemPerPackage(request, getShippingOptionRequest, subTotalShipmentCurrency, requestedShipmentCurrency.CurrencyCode); break; case PackingType.PackByVolume: SetIndividualPackageLineItemsCubicRootDimensions(request, getShippingOptionRequest, subTotalShipmentCurrency, requestedShipmentCurrency.CurrencyCode); break; case PackingType.PackByDimensions: default: SetIndividualPackageLineItems(request, getShippingOptionRequest, subTotalShipmentCurrency, requestedShipmentCurrency.CurrencyCode); break; } return request; }
/// <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"); var response = new GetShippingOptionResponse(); if (getShippingOptionRequest.Items == null) { response.AddError("No shipment items"); return response; } if (getShippingOptionRequest.ShippingAddress == null) { response.AddError("Shipping address is not set"); return response; } if (String.IsNullOrEmpty(getShippingOptionRequest.ZipPostalCodeFrom)) getShippingOptionRequest.ZipPostalCodeFrom = _uspsSettings.ZipPostalCodeFrom; bool isDomestic = IsDomesticRequest(getShippingOptionRequest); string requestString = CreateRequest(_uspsSettings.Username, _uspsSettings.Password, getShippingOptionRequest); string responseXml = DoRequest(_uspsSettings.Url, requestString); string error = ""; var shippingOptions = ParseResponse(responseXml, isDomestic, ref error); if (String.IsNullOrEmpty(error)) { foreach (var shippingOption in shippingOptions) { if (!shippingOption.Name.ToLower().StartsWith("usps")) shippingOption.Name = string.Format("USPS {0}", shippingOption.Name); shippingOption.Rate += _uspsSettings.AdditionalHandlingCharge; response.ShippingOptions.Add(shippingOption); } } else { response.AddError(error); } return response; }
public void can_calculate_with_single_item_and_qty_1() { var request = new GetShippingOptionRequest(); request.Items.Add(new ShoppingCartItem() { Quantity = 1, ProductVariant = new ProductVariant() { Length = 2, Width = 2, Height = 2 } }); decimal length, width, height = 0; request.GetDimensions(out width, out length, out height); length.ShouldEqual(2); width.ShouldEqual(2); height.ShouldEqual(2); }
private void SetDestination(RateRequest request, GetShippingOptionRequest getShippingOptionRequest) { request.RequestedShipment.Recipient = new Party(); request.RequestedShipment.Recipient.Address = new RateServiceWebReference.Address(); if (_fedexSettings.UseResidentialRates) { request.RequestedShipment.Recipient.Address.Residential = true; request.RequestedShipment.Recipient.Address.ResidentialSpecified = true; } request.RequestedShipment.Recipient.Address.StreetLines = new string[1] { "Recipient Address Line 1" }; request.RequestedShipment.Recipient.Address.City = getShippingOptionRequest.ShippingAddress.City; if (getShippingOptionRequest.ShippingAddress.StateProvince != null && IncludeStateProvinceCode(getShippingOptionRequest.ShippingAddress.Country.TwoLetterIsoCode)) { request.RequestedShipment.Recipient.Address.StateOrProvinceCode = getShippingOptionRequest.ShippingAddress.StateProvince.Abbreviation; } else { request.RequestedShipment.Recipient.Address.StateOrProvinceCode = string.Empty; } request.RequestedShipment.Recipient.Address.PostalCode = getShippingOptionRequest.ShippingAddress.ZipPostalCode; request.RequestedShipment.Recipient.Address.CountryCode = getShippingOptionRequest.ShippingAddress.Country.TwoLetterIsoCode; Debug.WriteLine(String.Format("Destination: {0}, {1} {2}", request.RequestedShipment.Recipient.Address.StateOrProvinceCode, request.RequestedShipment.Recipient.Address.PostalCode, request.RequestedShipment.Recipient.Address.CountryCode)); }
/// <summary> /// Is a request domestic /// </summary> /// <param name="getShippingOptionRequest">Request</param> /// <returns>Rsult</returns> protected bool IsDomesticRequest(GetShippingOptionRequest getShippingOptionRequest) { //Origin Country must be USA, Collect USA from list of countries bool result = true; if (getShippingOptionRequest != null && getShippingOptionRequest.ShippingAddress != null && getShippingOptionRequest.ShippingAddress.Country != null) { switch (getShippingOptionRequest.ShippingAddress.Country.ThreeLetterIsoCode) { case "USA": // United States case "PRI": // Puerto Rico case "UMI": // United States minor outlying islands case "ASM": // American Samoa case "GUM": // Guam case "MHL": // Marshall Islands case "FSM": // Micronesia case "MNP": // Northern Mariana Islands case "PLW": // Palau case "VIR": // Virgin Islands (U.S.) result = true; break; default: result = false; break; } } return result; }
private void SetIndividualPackageLineItems(RateRequest request, GetShippingOptionRequest getShippingOptionRequest, decimal orderSubTotal, string currencyCode) { // Rate request setup - Total Dimensions of Shopping Cart Items determines number of packages var usedMeasureWeight = GetUsedMeasureWeight(); var usedMeasureDimension = GetUsedMeasureDimension(); int length = ConvertFromPrimaryMeasureDimension(getShippingOptionRequest.GetTotalLength(), usedMeasureDimension); int height = ConvertFromPrimaryMeasureDimension(getShippingOptionRequest.GetTotalHeight(), usedMeasureDimension); int width = ConvertFromPrimaryMeasureDimension(getShippingOptionRequest.GetTotalWidth(), usedMeasureDimension); int weight = ConvertFromPrimaryMeasureWeight(_shippingService.GetShoppingCartTotalWeight(getShippingOptionRequest.Items), usedMeasureWeight); if (length < 1) length = 1; if (height < 1) height = 1; if (width < 1) width = 1; if (weight < 1) weight = 1; if ((!IsPackageTooHeavy(weight)) && (!IsPackageTooLarge(length, height, width))) { request.RequestedShipment.PackageCount = "1"; request.RequestedShipment.RequestedPackageLineItems = new RequestedPackageLineItem[1]; request.RequestedShipment.RequestedPackageLineItems[0] = new RequestedPackageLineItem(); request.RequestedShipment.RequestedPackageLineItems[0].SequenceNumber = "1"; // package sequence number request.RequestedShipment.RequestedPackageLineItems[0].Weight = new RateServiceWebReference.Weight(); // package weight request.RequestedShipment.RequestedPackageLineItems[0].Weight.Units = RateServiceWebReference.WeightUnits.LB; request.RequestedShipment.RequestedPackageLineItems[0].Weight.Value = weight; request.RequestedShipment.RequestedPackageLineItems[0].Dimensions = new RateServiceWebReference.Dimensions(); // package dimensions request.RequestedShipment.RequestedPackageLineItems[0].Dimensions.Length = _fedexSettings.PassDimensions ? length.ToString() : "0"; request.RequestedShipment.RequestedPackageLineItems[0].Dimensions.Width = _fedexSettings.PassDimensions ? width.ToString() : "0"; request.RequestedShipment.RequestedPackageLineItems[0].Dimensions.Height = _fedexSettings.PassDimensions ? height.ToString() : "0"; request.RequestedShipment.RequestedPackageLineItems[0].Dimensions.Units = RateServiceWebReference.LinearUnits.IN; request.RequestedShipment.RequestedPackageLineItems[0].InsuredValue = new Money(); // insured value request.RequestedShipment.RequestedPackageLineItems[0].InsuredValue.Amount = orderSubTotal; request.RequestedShipment.RequestedPackageLineItems[0].InsuredValue.Currency = currencyCode; } else { int totalPackages = 1; int totalPackagesDims = 1; int totalPackagesWeights = 1; if (IsPackageTooHeavy(weight)) { totalPackagesWeights = Convert.ToInt32(Math.Ceiling((decimal)weight / (decimal)MAXPACKAGEWEIGHT)); } if (IsPackageTooLarge(length, height, width)) { totalPackagesDims = Convert.ToInt32(Math.Ceiling((decimal)TotalPackageSize(length, height, width) / (decimal)108)); } totalPackages = totalPackagesDims > totalPackagesWeights ? totalPackagesDims : totalPackagesWeights; if (totalPackages == 0) totalPackages = 1; int weight2 = weight / totalPackages; int height2 = height / totalPackages; int width2 = width / totalPackages; int length2 = length / totalPackages; if (weight2 < 1) weight2 = 1; if (height2 < 1) height2 = 1; if (width2 < 1) width2 = 1; if (length2 < 1) length2 = 1; decimal orderSubTotal2 = orderSubTotal / totalPackages; request.RequestedShipment.PackageCount = totalPackages.ToString(); request.RequestedShipment.RequestedPackageLineItems = new RequestedPackageLineItem[totalPackages]; for (int i = 0; i < totalPackages; i++) { request.RequestedShipment.RequestedPackageLineItems[i] = new RequestedPackageLineItem(); request.RequestedShipment.RequestedPackageLineItems[i].SequenceNumber = (i + 1).ToString(); // package sequence number request.RequestedShipment.RequestedPackageLineItems[i].Weight = new RateServiceWebReference.Weight(); // package weight request.RequestedShipment.RequestedPackageLineItems[i].Weight.Units = RateServiceWebReference.WeightUnits.LB; request.RequestedShipment.RequestedPackageLineItems[i].Weight.Value = (decimal)weight2; request.RequestedShipment.RequestedPackageLineItems[i].Dimensions = new RateServiceWebReference.Dimensions(); // package dimensions request.RequestedShipment.RequestedPackageLineItems[i].Dimensions.Length = _fedexSettings.PassDimensions ? length2.ToString() : "0"; request.RequestedShipment.RequestedPackageLineItems[i].Dimensions.Width = _fedexSettings.PassDimensions ? width2.ToString() : "0"; request.RequestedShipment.RequestedPackageLineItems[i].Dimensions.Height = _fedexSettings.PassDimensions ? height2.ToString() : "0"; request.RequestedShipment.RequestedPackageLineItems[i].Dimensions.Units = RateServiceWebReference.LinearUnits.IN; request.RequestedShipment.RequestedPackageLineItems[i].InsuredValue = new Money(); // insured value request.RequestedShipment.RequestedPackageLineItems[i].InsuredValue.Amount = orderSubTotal2; request.RequestedShipment.RequestedPackageLineItems[i].InsuredValue.Currency = currencyCode; } } }
/// <summary> /// Gets fixed shipping rate (if shipping rate computation method allows it and the rate can be calculated before checkout). /// </summary> /// <param name="getShippingOptionRequest">A request for getting shipping options</param> /// <returns>Fixed shipping rate; or null in case there's no fixed shipping rate</returns> public decimal? GetFixedRate(GetShippingOptionRequest getShippingOptionRequest) { return null; }
private void SetIndividualPackageLineItemsCubicRootDimensions(RateRequest request, GetShippingOptionRequest getShippingOptionRequest, decimal orderSubTotal, string currencyCode) { // Rate request setup - Total Volume of Shopping Cart Items determines number of packages //From FedEx Guide (Ground): //Dimensional weight is based on volume (the amount of space a package //occupies in relation to its actual weight). If the cubic size of your FedEx //Ground package measures three cubic feet (5,184 cubic inches or 84,951 //cubic centimetres) or greater, you will be charged the greater of the //dimensional weight or the actual weight. //A package weighing 150 lbs. (68 kg) or less and measuring greater than //130 inches (330 cm) in combined length and girth will be classified by //FedEx Ground as an “Oversize” package. All packages must have a //combined length and girth of no more than 165 inches (419 cm). An //oversize charge of $30 per package will also apply to any package //measuring greater than 130 inches (330 cm) in combined length and //girth. //Shipping charges for packages smaller than three cubic feet are based //on actual weight // Dimensional Weight applies to packages with volume 5,184 cubic inches or more // cube root(5184) = 17.3 // Packages that exceed 130 inches in length and girth (2xHeight + 2xWidth) // are considered “oversize” packages. // Assume a cube (H=W=L) of that size: 130 = D + (2xD + 2xD) = 5xD : D = 130/5 = 26 // 26x26x26 = 17,576 // Avoid oversize by using 25" // 25x25x25 = 15,625 // Which is less $ - multiple small pakages, or one large package using dimensional weight // 15,625 / 5184 = 3.014 = 3 packages // Ground for total weight: 60lbs 15lbs // 3 packages 17x17x17 (20 lbs each) = $66.21 39.39 // 1 package 25x25x25 (60 lbs) = $71.70 71.70 var usedMeasureWeight = GetUsedMeasureWeight(); var usedMeasureDimension = GetUsedMeasureDimension(); int totalPackagesDims; int length; int height; int width; if (getShippingOptionRequest.Items.Count == 1 && getShippingOptionRequest.Items[0].Quantity == 1) { totalPackagesDims = 1; var pv = getShippingOptionRequest.Items[0].ProductVariant; length = ConvertFromPrimaryMeasureDimension(pv.Length, usedMeasureDimension); height = ConvertFromPrimaryMeasureDimension(pv.Height, usedMeasureDimension); width = ConvertFromPrimaryMeasureDimension(pv.Width, usedMeasureDimension); } else { decimal totalVolume = 0; foreach (var item in getShippingOptionRequest.Items) { var pv = item.ProductVariant; int pvLength = ConvertFromPrimaryMeasureDimension(pv.Length, usedMeasureDimension); int pvHeight = ConvertFromPrimaryMeasureDimension(pv.Height, usedMeasureDimension); int pvWidth = ConvertFromPrimaryMeasureDimension(pv.Width, usedMeasureDimension); totalVolume += item.Quantity * (pvHeight * pvWidth * pvLength); } int dimension; if (totalVolume == 0) { dimension = 0; totalPackagesDims = 1; } else { // cubic inches int packageVolume = _fedexSettings.PackingPackageVolume; if (packageVolume <= 0) packageVolume = 5184; // cube root (floor) dimension = Convert.ToInt32(Math.Floor(Math.Pow(Convert.ToDouble(packageVolume), (double)(1.0 / 3.0)))); if (IsPackageTooLarge(dimension, dimension, dimension)) throw new NasException("fedexSettings.PackingPackageVolume exceeds max package size"); // adjust packageVolume for dimensions calculated packageVolume = dimension * dimension * dimension; totalPackagesDims = Convert.ToInt32(Math.Ceiling(totalVolume / packageVolume)); } length = width = height = dimension; } if (length < 1) length = 1; if (height < 1) height = 1; if (width < 1) width = 1; int weight = ConvertFromPrimaryMeasureWeight(_shippingService.GetShoppingCartTotalWeight(getShippingOptionRequest.Items), usedMeasureWeight); if (weight < 1) weight = 1; int totalPackagesWeights = 1; if (IsPackageTooHeavy(weight)) { totalPackagesWeights = Convert.ToInt32(Math.Ceiling((decimal)weight / (decimal)MAXPACKAGEWEIGHT)); } int totalPackages = totalPackagesDims > totalPackagesWeights ? totalPackagesDims : totalPackagesWeights; decimal orderSubTotalPerPackage = orderSubTotal / totalPackages; int weightPerPackage = weight / totalPackages; request.RequestedShipment.PackageCount = totalPackages.ToString(); request.RequestedShipment.RequestedPackageLineItems = new RequestedPackageLineItem[totalPackages]; for (int i = 0; i < totalPackages; i++) { request.RequestedShipment.RequestedPackageLineItems[i] = new RequestedPackageLineItem(); request.RequestedShipment.RequestedPackageLineItems[i].SequenceNumber = (i + 1).ToString(); // package sequence number request.RequestedShipment.RequestedPackageLineItems[i].Weight = new RateServiceWebReference.Weight(); // package weight request.RequestedShipment.RequestedPackageLineItems[i].Weight.Units = RateServiceWebReference.WeightUnits.LB; request.RequestedShipment.RequestedPackageLineItems[i].Weight.Value = (decimal)weightPerPackage; request.RequestedShipment.RequestedPackageLineItems[i].Dimensions = new RateServiceWebReference.Dimensions(); // package dimensions request.RequestedShipment.RequestedPackageLineItems[i].Dimensions.Length = length.ToString(); request.RequestedShipment.RequestedPackageLineItems[i].Dimensions.Height = height.ToString(); request.RequestedShipment.RequestedPackageLineItems[i].Dimensions.Width = width.ToString(); request.RequestedShipment.RequestedPackageLineItems[i].Dimensions.Units = RateServiceWebReference.LinearUnits.IN; request.RequestedShipment.RequestedPackageLineItems[i].InsuredValue = new Money(); // insured value request.RequestedShipment.RequestedPackageLineItems[i].InsuredValue.Amount = orderSubTotalPerPackage; request.RequestedShipment.RequestedPackageLineItems[i].InsuredValue.Currency = currencyCode; } }
private int GetWeight(GetShippingOptionRequest getShippingOptionRequest) { var totalWeigth = _shippingService.GetShoppingCartTotalWeight(getShippingOptionRequest.Items); int value = Convert.ToInt32(Math.Ceiling(this._measureService.ConvertFromPrimaryMeasureWeight(totalWeigth, this.GatewayMeasureWeight))); return (value < MIN_WEIGHT ? MIN_WEIGHT : value); }
private void SetIndividualPackageLineItemsOneItemPerPackage(RateRequest request, GetShippingOptionRequest getShippingOptionRequest, decimal orderSubTotal, string currencyCode) { // Rate request setup - each Shopping Cart Item is a separate package var usedMeasureWeight = GetUsedMeasureWeight(); var usedMeasureDimension = GetUsedMeasureDimension(); var items = getShippingOptionRequest.Items; var totalItems = items.GetTotalProducts(); request.RequestedShipment.PackageCount = totalItems.ToString(); request.RequestedShipment.RequestedPackageLineItems = new RequestedPackageLineItem[totalItems]; int i = 0; foreach (var sci in items) { int length = ConvertFromPrimaryMeasureDimension(sci.ProductVariant.Length, usedMeasureDimension); int height = ConvertFromPrimaryMeasureDimension(sci.ProductVariant.Height, usedMeasureDimension); int width = ConvertFromPrimaryMeasureDimension(sci.ProductVariant.Width, usedMeasureDimension); int weight = ConvertFromPrimaryMeasureWeight(sci.ProductVariant.Weight, usedMeasureWeight); if (length < 1) length = 1; if (height < 1) height = 1; if (width < 1) width = 1; if (weight < 1) weight = 1; for (int j = 0; j < sci.Quantity; j++) { request.RequestedShipment.RequestedPackageLineItems[i] = new RequestedPackageLineItem(); request.RequestedShipment.RequestedPackageLineItems[i].SequenceNumber = (i + 1).ToString(); // package sequence number request.RequestedShipment.RequestedPackageLineItems[i].Weight = new RateServiceWebReference.Weight(); // package weight request.RequestedShipment.RequestedPackageLineItems[i].Weight.Units = RateServiceWebReference.WeightUnits.LB; request.RequestedShipment.RequestedPackageLineItems[i].Weight.Value = (decimal)weight; request.RequestedShipment.RequestedPackageLineItems[i].Dimensions = new RateServiceWebReference.Dimensions(); // package dimensions request.RequestedShipment.RequestedPackageLineItems[i].Dimensions.Length = length.ToString(); request.RequestedShipment.RequestedPackageLineItems[i].Dimensions.Height = height.ToString(); request.RequestedShipment.RequestedPackageLineItems[i].Dimensions.Width = width.ToString(); request.RequestedShipment.RequestedPackageLineItems[i].Dimensions.Units = RateServiceWebReference.LinearUnits.IN; request.RequestedShipment.RequestedPackageLineItems[i].InsuredValue = new Money(); // insured value request.RequestedShipment.RequestedPackageLineItems[i].InsuredValue.Amount = sci.ProductVariant.Price; request.RequestedShipment.RequestedPackageLineItems[i].InsuredValue.Currency = currencyCode; i++; } } }
/// <summary> /// Create shipment package from shopping cart /// </summary> /// <param name="cart">Shopping cart</param> /// <param name="shippingAddress">Shipping address</param> /// <returns>Shipment package</returns> public virtual GetShippingOptionRequest CreateShippingOptionRequest(IList<ShoppingCartItem> cart, Address shippingAddress) { var request = new GetShippingOptionRequest(); request.Customer = cart.GetCustomer(); request.Items = new List<ShoppingCartItem>(); foreach (var sc in cart) if (sc.IsShipEnabled) request.Items.Add(sc); request.ShippingAddress = shippingAddress; request.CountryFrom = null; request.StateProvinceFrom = null; request.ZipPostalCodeFrom = string.Empty; return request; }
private void SetOrigin(RateRequest request, GetShippingOptionRequest getShippingOptionRequest) { request.RequestedShipment.Shipper = new Party(); request.RequestedShipment.Shipper.Address = new RateServiceWebReference.Address(); // use request origin if present, else use settings if (getShippingOptionRequest.CountryFrom != null) { request.RequestedShipment.Shipper.Address.StreetLines = new string[1] { "" }; request.RequestedShipment.Shipper.Address.City = ""; if (IncludeStateProvinceCode(getShippingOptionRequest.CountryFrom.TwoLetterIsoCode)) { string stateProvinceAbbreviation = getShippingOptionRequest.StateProvinceFrom == null ? "" : getShippingOptionRequest.StateProvinceFrom.Abbreviation; request.RequestedShipment.Shipper.Address.StateOrProvinceCode = stateProvinceAbbreviation; } request.RequestedShipment.Shipper.Address.PostalCode = getShippingOptionRequest.ZipPostalCodeFrom; request.RequestedShipment.Shipper.Address.CountryCode = getShippingOptionRequest.CountryFrom.TwoLetterIsoCode; } else { request.RequestedShipment.Shipper.Address.StreetLines = new string[1] { _fedexSettings.Street }; request.RequestedShipment.Shipper.Address.City = _fedexSettings.City; if (IncludeStateProvinceCode(_fedexSettings.CountryCode)) { request.RequestedShipment.Shipper.Address.StateOrProvinceCode = _fedexSettings.StateOrProvinceCode; } request.RequestedShipment.Shipper.Address.PostalCode = _fedexSettings.PostalCode; request.RequestedShipment.Shipper.Address.CountryCode = _fedexSettings.CountryCode; } Debug.WriteLine(String.Format("Origin: {0}, {1} {2}", request.RequestedShipment.Shipper.Address.StateOrProvinceCode, request.RequestedShipment.Shipper.Address.PostalCode, request.RequestedShipment.Shipper.Address.CountryCode)); }