/// <summary> /// Get shipping method rates. /// </summary> ShippingMethodCollection GetRates(RealTimeRateCalculationContext context) { // Build shipments var shipments = BuildShipments(context); // Set shipment info var realTimeShipping = new RTShipping { ShipmentWeight = GetHeaviestPackageWeightTotal(context.CartItems), DestinationResidenceType = context.ShipmentAddress.ResidenceType, ShipmentValue = context.ShipmentValue, }; // Get carriers var carriers = shipments.Any() ? shipments.IsInternational ? AppLogic.AppConfig("RTShipping.InternationalCarriers") : AppLogic.AppConfig("RTShipping.DomesticCarriers") : AppLogic.AppConfig("RTShipping.ActiveCarrier"); if (string.IsNullOrWhiteSpace(carriers)) { carriers = AppLogic.AppConfig("RTShipping.ActiveCarrier"); } // Get results string rtShipRequest, rtShipResponse; var shippingMethods = (ShippingMethodCollection)realTimeShipping.GetRates( shipments, carriers, context.ShippingTaxRate, out rtShipRequest, out rtShipResponse, context.ShippingHandlingExtraFee, AppLogic.AppConfigUSDecimal("RTShipping.MarkupPercent"), realTimeShipping.ShipmentValue); DB.ExecuteSQL( "update customer set RTShipRequest = @rtShipRequest, RTShipResponse = @rtShipResponse where CustomerID = @customerId", new SqlParameter("rtShipRequest", rtShipRequest), new SqlParameter("rtShipResponse", rtShipResponse), new SqlParameter("customerId", context.CustomerId)); return(shippingMethods); }
Shipments BuildShipments(RealTimeRateCalculationContext context) { var useDistributors = context.CartItems.HasDistributorComponents() && AppLogic.AppConfigBool("RTShipping.MultiDistributorCalculation"); var freeShippingAllowsRateSelection = AppLogic.AppConfigBool("FreeShippingAllowsRateSelection"); var shipments = new Shipments { HasDistributorItems = useDistributors, }; // Get ship separately cart items var packageId = 1; foreach (var cartItem in context.CartItems.Where(ci => ci.IsShipSeparately)) { // Only calculate rates for products that require shipping if (cartItem.IsDownload || cartItem.IsSystem || !cartItem.Shippable || GiftCard.ProductIsEmailGiftCard(cartItem.ProductID) || (cartItem.FreeShipping && !freeShippingAllowsRateSelection)) { continue; } var packages = new Packages(); ApplyDestinationForAddress(packages, context.ShipmentAddress); if (useDistributors && cartItem.DistributorID > 0) { ApplyOriginForDistributor(packages, cartItem.DistributorID); } packages.AddPackage(new Package(cartItem) { PackageId = packageId++, }); shipments.Add(packages); } // Now get all itmes that do not ship separately, but group them into shipments by distributor. // Note that distributor ID 0 will be all of the items without a distributor. var maxDistributorId = useDistributors ? DB.GetSqlN("select max(DistributorID) N from ProductDistributor") : 0; for (int distributorId = 0; distributorId <= maxDistributorId; distributorId++) { var remainingItemsWeight = 0m; var remainingItemsInsuranceValue = 0m; foreach (var cartItem in context.CartItems.Where(ci => !ci.IsShipSeparately)) { // Only calculate rates for products that require shipping if (cartItem.IsDownload || cartItem.IsSystem || !cartItem.Shippable || GiftCard.ProductIsEmailGiftCard(cartItem.ProductID) || (cartItem.FreeShipping && !freeShippingAllowsRateSelection)) { continue; } if (useDistributors && cartItem.DistributorID != distributorId) { continue; } var weight = cartItem.Weight; if (weight == 0m) { weight = AppLogic.AppConfigUSDecimal("RTShipping.DefaultItemWeight"); } if (weight == 0m) { weight = 0.5m; // must have SOMETHING to use! } remainingItemsWeight += (weight * cartItem.Quantity); remainingItemsInsuranceValue += (cartItem.Price * cartItem.Quantity); } if (remainingItemsWeight == 0m) { continue; } var package = new Package { PackageId = packageId++, Weight = remainingItemsWeight + AppLogic.AppConfigUSDecimal("RTShipping.PackageExtraWeight"), Insured = AppLogic.AppConfigBool("RTShipping.Insured"), InsuredValue = remainingItemsInsuranceValue, }; var packages = new Packages(); ApplyDestinationForAddress(packages, context.ShipmentAddress); if (useDistributors && distributorId != 0) { ApplyOriginForDistributor(packages, distributorId); } packages.AddPackage(package); shipments.Add(packages); } return(shipments); }