コード例 #1
0
        private void SetDestination(FedexRate.RateRequest request, GetShippingOptionRequest getShippingOptionRequest)
        {
            request.RequestedShipment.Recipient = new FedexRate.Party
            {
                Address = new FedexRate.Address()
            };
            if (_fedexSettings.UseResidentialRates)
            {
                request.RequestedShipment.Recipient.Address.Residential          = true;
                request.RequestedShipment.Recipient.Address.ResidentialSpecified = true;
            }

            request.RequestedShipment.Recipient.Address.StreetLines = new[] { getShippingOptionRequest.ShippingAddress.Address1 };
            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;
        }
コード例 #2
0
 private void SetPayment(FedexRate.RateRequest request)
 {
     request.RequestedShipment.ShippingChargesPayment = new FedexRate.Payment
     {
         PaymentType          = FedexRate.PaymentType.SENDER, // Payment options are RECIPIENT, SENDER, THIRD_PARTY
         PaymentTypeSpecified = true,
         Payor = new FedexRate.Payor
         {
             ResponsibleParty = new FedexRate.Party
             {
                 AccountNumber = _fedexSettings.AccountNumber
             }
         }
     }; // Payment Information
 }
コード例 #3
0
        /// <summary>
        /// Create packages (total dimensions of shopping cart items determines number of packages)
        /// </summary>
        /// <param name="request">Shipping request</param>
        /// <param name="getShippingOptionRequest">Shipping option request</param>
        /// <param name="orderSubTotal"></param>
        /// <param name="currencyCode">Currency code</param>
        private void SetIndividualPackageLineItems(FedexRate.RateRequest request, GetShippingOptionRequest getShippingOptionRequest, decimal orderSubTotal, string currencyCode)
        {
            var(length, height, width) = GetDimensions(getShippingOptionRequest.Items);
            var weight = GetWeight(getShippingOptionRequest);

            if (!IsPackageTooHeavy(weight) && !IsPackageTooLarge(length, height, width))
            {
                request.RequestedShipment.PackageCount = "1";

                var package = CreatePackage(width, length, height, weight, orderSubTotal, "1", currencyCode);
                package.GroupPackageCount = "1";

                request.RequestedShipment.RequestedPackageLineItems = new[] { package };
            }
            else
            {
                var totalPackagesDims    = 1;
                var totalPackagesWeights = 1;
                if (IsPackageTooHeavy(weight))
                {
                    totalPackagesWeights = Convert.ToInt32(Math.Ceiling(weight / FedexShippingDefaults.MAX_PACKAGE_WEIGHT));
                }
                if (IsPackageTooLarge(length, height, width))
                {
                    totalPackagesDims = Convert.ToInt32(Math.Ceiling(TotalPackageSize(length, height, width) / 108M));
                }
                var totalPackages = totalPackagesDims > totalPackagesWeights ? totalPackagesDims : totalPackagesWeights;
                if (totalPackages == 0)
                {
                    totalPackages = 1;
                }

                width  = Math.Max(width / totalPackages, 1);
                length = Math.Max(length / totalPackages, 1);
                height = Math.Max(height / totalPackages, 1);
                weight = Math.Max(weight / totalPackages, 1);

                var orderSubTotal2 = orderSubTotal / totalPackages;

                request.RequestedShipment.PackageCount = totalPackages.ToString();

                request.RequestedShipment.RequestedPackageLineItems = Enumerable.Range(1, totalPackages - 1)
                                                                      .Select(i => CreatePackage(width, length, height, weight, orderSubTotal2, i.ToString(), currencyCode)).ToArray();
            }
        }
コード例 #4
0
        private void SetOrigin(FedexRate.RateRequest request, GetShippingOptionRequest getShippingOptionRequest)
        {
            request.RequestedShipment.Shipper = new FedexRate.Party
            {
                Address = new FedexRate.Address()
            };

            if (getShippingOptionRequest.CountryFrom is null)
            {
                throw new Exception("FROM country is not specified");
            }

            request.RequestedShipment.Shipper.Address.StreetLines = new[] { getShippingOptionRequest.AddressFrom };
            request.RequestedShipment.Shipper.Address.City        = getShippingOptionRequest.CityFrom;
            if (IncludeStateProvinceCode(getShippingOptionRequest.CountryFrom.TwoLetterIsoCode))
            {
                var stateProvinceAbbreviation = getShippingOptionRequest.StateProvinceFrom is 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;
        }
コード例 #5
0
        /// <summary>
        /// Create packages (each shopping cart item is a separate package)
        /// </summary>
        /// <param name="request">Shipping request</param>
        /// <param name="getShippingOptionRequest">Shipping option request</param>
        /// <param name="currencyCode">Currency code</param>
        private void SetIndividualPackageLineItemsOneItemPerPackage(FedexRate.RateRequest request, GetShippingOptionRequest getShippingOptionRequest, string currencyCode)
        {
            // Rate request setup - each Shopping Cart Item is a separate package
            var i          = 1;
            var items      = getShippingOptionRequest.Items;
            var totalItems = items.Sum(x => x.GetQuantity());

            request.RequestedShipment.PackageCount = totalItems.ToString();
            request.RequestedShipment.RequestedPackageLineItems = getShippingOptionRequest.Items.SelectMany(packageItem =>
            {
                //get dimensions and weight of the single item
                var(width, length, height) = GetDimensionsForSingleItem(packageItem.ShoppingCartItem);
                var weight = GetWeightForSingleItem(packageItem.ShoppingCartItem);

                var package = CreatePackage(width, length, height, weight, packageItem.ShoppingCartItem.Product.Price, (i + 1).ToString(), currencyCode);
                package.GroupPackageCount = "1";

                var packs = Enumerable.Range(i, packageItem.GetQuantity())
                            .Select(j => CreatePackage(width, length, height, weight, packageItem.ShoppingCartItem.Product.Price, j.ToString(), currencyCode)).ToArray();
                i += packageItem.GetQuantity();

                return(packs);
            }).ToArray();
        }
コード例 #6
0
        private void SetShipmentDetails(FedexRate.RateRequest request, decimal orderSubTotal, string currencyCode)
        {
            //set drop off type
            switch (_fedexSettings.DropoffType)
            {
            case DropoffType.BusinessServiceCenter:
                request.RequestedShipment.DropoffType = FedexRate.DropoffType.BUSINESS_SERVICE_CENTER;
                break;

            case DropoffType.DropBox:
                request.RequestedShipment.DropoffType = FedexRate.DropoffType.DROP_BOX;
                break;

            case DropoffType.RegularPickup:
                request.RequestedShipment.DropoffType = FedexRate.DropoffType.REGULAR_PICKUP;
                break;

            case DropoffType.RequestCourier:
                request.RequestedShipment.DropoffType = FedexRate.DropoffType.REQUEST_COURIER;
                break;

            case DropoffType.Station:
                request.RequestedShipment.DropoffType = FedexRate.DropoffType.STATION;
                break;

            default:
                request.RequestedShipment.DropoffType = FedexRate.DropoffType.BUSINESS_SERVICE_CENTER;
                break;
            }
            request.RequestedShipment.TotalInsuredValue = new FedexRate.Money
            {
                Amount   = orderSubTotal,
                Currency = currencyCode
            };

            //Saturday pickup is available for certain FedEx Express U.S. service types:
            //http://www.fedex.com/us/developer/product/WebServices/MyWebHelp/Services/Options/c_SaturdayShipAndDeliveryServiceDetails.html
            //If the customer orders on a Saturday, the rate calculation will use Saturday as the shipping date, and the rates will include a Saturday pickup surcharge
            //More info: https://www.nopcommerce.com/boards/t/27348/fedex-rate-can-be-excessive-for-express-methods-if-calculated-on-a-saturday.aspx
            var shipTimestamp = DateTime.Now;

            if (shipTimestamp.DayOfWeek == DayOfWeek.Saturday)
            {
                shipTimestamp = shipTimestamp.AddDays(2);
            }
            request.RequestedShipment.ShipTimestamp          = shipTimestamp; // Shipping date and time
            request.RequestedShipment.ShipTimestampSpecified = true;

            request.RequestedShipment.RateRequestTypes = new[] {
                FedexRate.RateRequestType.PREFERRED,
                FedexRate.RateRequestType.LIST
            };
            //request.RequestedShipment.PackageDetail = RequestedPackageDetailType.INDIVIDUAL_PACKAGES;
            //request.RequestedShipment.PackageDetailSpecified = true;

            //for India domestic shipping add additional details
            if (request.RequestedShipment.Shipper.Address.CountryCode.Equals("IN", StringComparison.InvariantCultureIgnoreCase) &&
                request.RequestedShipment.Recipient.Address.CountryCode.Equals("IN", StringComparison.InvariantCultureIgnoreCase))
            {
                var commodity = new FedexRate.Commodity
                {
                    Name           = "1",
                    NumberOfPieces = "1",
                    CustomsValue   = new FedexRate.Money
                    {
                        Amount          = orderSubTotal,
                        AmountSpecified = true,
                        Currency        = currencyCode
                    }
                };

                request.RequestedShipment.CustomsClearanceDetail = new FedexRate.CustomsClearanceDetail
                {
                    CommercialInvoice = new FedexRate.CommercialInvoice
                    {
                        Purpose          = FedexRate.PurposeOfShipmentType.SOLD,
                        PurposeSpecified = true
                    },
                    Commodities = new[] { commodity }
                };
            }
        }
コード例 #7
0
        /// <summary>
        /// Create packages (total volume of shopping cart items determines number of packages)
        /// </summary>
        /// <param name="request">Shipping request</param>
        /// <param name="getShippingOptionRequest">Shipping option request</param>
        /// <param name="orderSubTotal"></param>
        /// <param name="currencyCode">Currency code</param>
        private void SetIndividualPackageLineItemsCubicRootDimensions(FedexRate.RateRequest request, GetShippingOptionRequest getShippingOptionRequest, decimal orderSubTotal, string currencyCode)
        {
            //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 packages, 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 totalPackagesDims = 1;
            var length            = 0M;
            var height            = 0M;
            var width             = 0M;

            if (getShippingOptionRequest.Items.Count == 1 && getShippingOptionRequest.Items[0].GetQuantity() == 1)
            {
                var sci = getShippingOptionRequest.Items[0].ShoppingCartItem;

                //get dimensions and weight of the single cubic size of package
                var item = getShippingOptionRequest.Items.FirstOrDefault().ShoppingCartItem;
                (width, length, height) = GetDimensionsForSingleItem(item);
            }
            else
            {
                //or try to get them
                var dimension = 0;

                //get total volume of the package
                var totalVolume = getShippingOptionRequest.Items.Sum(item =>
                {
                    //get dimensions and weight of the single item
                    var(itemWidth, itemLength, itemHeight) = GetDimensionsForSingleItem(item.ShoppingCartItem);
                    return(item.GetQuantity() * itemWidth * itemLength * itemHeight);
                });
                if (totalVolume > decimal.Zero)
                {
                    //use default value (in cubic inches) if not specified
                    var packageVolume = _fedexSettings.PackingPackageVolume;
                    if (packageVolume <= 0)
                    {
                        packageVolume = 5184;
                    }

                    //calculate cube root (floor)
                    dimension = Convert.ToInt32(Math.Floor(Math.Pow(Convert.ToDouble(packageVolume), 1.0 / 3.0)));
                    if (IsPackageTooLarge(dimension, dimension, dimension))
                    {
                        throw new NopException("fedexSettings.PackingPackageVolume exceeds max package size");
                    }

                    //adjust package volume for dimensions calculated
                    packageVolume = dimension * dimension * dimension;

                    totalPackagesDims = Convert.ToInt32(Math.Ceiling(totalVolume / packageVolume));
                }

                width = length = height = dimension;
            }

            width  = Math.Max(width, 1);
            length = Math.Max(length, 1);
            height = Math.Max(height, 1);

            var weight = GetWeight(getShippingOptionRequest);

            var totalPackagesWeights = 1;

            if (IsPackageTooHeavy(weight))
            {
                totalPackagesWeights = Convert.ToInt32(Math.Ceiling(weight / FedexShippingDefaults.MAX_PACKAGE_WEIGHT));
            }

            var totalPackages = totalPackagesDims > totalPackagesWeights ? totalPackagesDims : totalPackagesWeights;

            var orderSubTotalPerPackage = orderSubTotal / totalPackages;
            var weightPerPackage        = weight / totalPackages;

            request.RequestedShipment.PackageCount = totalPackages.ToString();

            request.RequestedShipment.RequestedPackageLineItems = Enumerable.Range(1, totalPackages)
                                                                  .Select(i => CreatePackage(width, length, height, weightPerPackage, orderSubTotalPerPackage, i.ToString(), currencyCode))
                                                                  .ToArray();
        }
コード例 #8
0
        /// <summary>
        /// Create request details to get shipping rates
        /// </summary>
        /// <param name="shippingOptionRequest">Shipping option request</param>
        /// <param name="saturdayDelivery">Whether to get rates for Saturday Delivery</param>
        /// <returns>Rate request details</returns>
        private FedexRate.RateRequest CreateRateRequest(GetShippingOptionRequest shippingOptionRequest, out Currency requestedShipmentCurrency)
        {
            // Build the RateRequest
            var request = new FedexRate.RateRequest
            {
                WebAuthenticationDetail = new FedexRate.WebAuthenticationDetail
                {
                    UserCredential = new FedexRate.WebAuthenticationCredential
                    {
                        Key      = _fedexSettings.Key,
                        Password = _fedexSettings.Password
                    }
                },

                ClientDetail = new FedexRate.ClientDetail
                {
                    AccountNumber = _fedexSettings.AccountNumber,
                    MeterNumber   = _fedexSettings.MeterNumber
                },

                TransactionDetail = new FedexRate.TransactionDetail
                {
                    CustomerTransactionId = "***Rate Available Services v16 Request - nopCommerce***" // This is a reference field for the customer.  Any value can be used and will be provided in the response.
                },

                Version = new FedexRate.VersionId(), // WSDL version information, value is automatically set from wsdl

                ReturnTransitAndCommit          = true,
                ReturnTransitAndCommitSpecified = true,
                // Insert the Carriers you would like to see the rates for
                CarrierCodes = new[] {
                    FedexRate.CarrierCodeType.FDXE,
                    FedexRate.CarrierCodeType.FDXG
                }
            };

            //TODO we should use getShippingOptionRequest.Items.GetQuantity() method to get subtotal
            _orderTotalCalculationService.GetShoppingCartSubTotal(
                shippingOptionRequest.Items.Select(x => x.ShoppingCartItem).ToList(),
                false, out var _, out var _, out var _, out var subTotalWithDiscountBase);

            request.RequestedShipment = new FedexRate.RequestedShipment();

            SetOrigin(request, shippingOptionRequest);
            SetDestination(request, shippingOptionRequest);

            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 = subTotalWithDiscountBase;
            }
            else
            {
                subTotalShipmentCurrency = _currencyService.ConvertFromPrimaryStoreCurrency(subTotalWithDiscountBase, requestedShipmentCurrency);
            }

            Debug.WriteLine($"SubTotal (Primary Currency) : {subTotalWithDiscountBase} ({primaryStoreCurrency.CurrencyCode})");
            Debug.WriteLine($"SubTotal (Shipment Currency): {subTotalShipmentCurrency} ({requestedShipmentCurrency.CurrencyCode})");

            SetShipmentDetails(request, subTotalShipmentCurrency, requestedShipmentCurrency.CurrencyCode);
            SetPayment(request);

            //set packages details
            switch (_fedexSettings.PackingType)
            {
            case PackingType.PackByOneItemPerPackage:
                SetIndividualPackageLineItemsOneItemPerPackage(request, shippingOptionRequest, requestedShipmentCurrency.CurrencyCode);
                break;

            case PackingType.PackByVolume:
                SetIndividualPackageLineItemsCubicRootDimensions(request, shippingOptionRequest, subTotalShipmentCurrency, requestedShipmentCurrency.CurrencyCode);
                break;

            case PackingType.PackByDimensions:
            default:
                SetIndividualPackageLineItems(request, shippingOptionRequest, subTotalShipmentCurrency, requestedShipmentCurrency.CurrencyCode);
                break;
            }
            return(request);
        }