public static decimal CalculateBreakEven(DimensionContainer dimensionContainer, FeeCategory feeCategory, decimal purchasePrice, Func <decimal, decimal> funcShippingcost = null) { List <decimal> dimensions = new List <decimal> { dimensionContainer.Length, dimensionContainer.Width, dimensionContainer.Height, } .OrderByDescending(o => o) .ToList(); decimal weight = dimensionContainer.Weight; decimal longestSide = dimensions[0]; decimal medianSide = dimensions[1]; decimal shortestSide = dimensions[2]; ProductSizeTier productSizeTier = GetProductSize(longestSide, medianSide, shortestSide, weight); // Shipping Cost to Amazon (estimate) = 0.72 * max(0.25, product weight) decimal estimateShippingCostToAmazon = funcShippingcost != null ? funcShippingcost.Invoke(weight) : c_costPerPoundToShip *Math.Max(0.25m, weight); // Cost to get to AMZN = Base Price + Shipping Cost to Amazon (estimate) decimal costToGetToAmazon = purchasePrice + estimateShippingCostToAmazon; // Average Storage Fee = 1.2 * (Width/12) * (Length/12) * (Height/12) // TODO: Update storage fee cost to update starting 3/1/2016: http://www.amazon.com/gp/help/customer/display.html?nodeId=201648210 decimal averageStorageFee = 1.2m * (longestSide / 12) * (medianSide / 12) * (shortestSide / 12); // Need to use the Outbound Shipping Weight for calculating the weight fee. decimal dimensionalWeight = CalculateDimensionalWeight(longestSide, medianSide, shortestSide); decimal outboundShippingWeight = CalculateOutboundShippingWeight(weight, dimensionalWeight, productSizeTier); // Size Fee => Multiply flat fee * ProductSizeTier decimal sizeFee = GetSizeFee(productSizeTier); decimal weightFee = GetWeightFee(productSizeTier, outboundShippingWeight); decimal feeCategoryPercentage = GetCategoryFee(feeCategory); // TODO: Implement the Zero Fee Fulfillment. Which applies to Small Standard-Size and Large Standard-Size. Price > $300, means no fulfillment fees. // Break Even Price = (Cost to get to AMZN + Average Storage Fee + Size Fee + Weight Fee) / (1 - Category Fee Pct) return((costToGetToAmazon + averageStorageFee + sizeFee + weightFee) / (1 - feeCategoryPercentage)); }
// Follow this documentation for fulfillment fees. // http://www.amazon.com/gp/help/customer/display.html?nodeId=201648210 private static decimal GetSizeFee(ProductSizeTier productSizeTier) { decimal sizeFee; // Each sizeFee contains both the "Order Handling" and "Pick & Pack per unit" switch (productSizeTier) { case ProductSizeTier.SmallStandardSize: sizeFee = 2.06m; break; case ProductSizeTier.LargeStandardSize: sizeFee = 2.06m; break; case ProductSizeTier.SmallOversize: sizeFee = 4.09m; break; case ProductSizeTier.MediumOversize: sizeFee = 5.20m; break; case ProductSizeTier.LargeOversize: sizeFee = 8.40m; break; case ProductSizeTier.SpecialOversize: sizeFee = 10.53m; break; default: sizeFee = 2.06m; break; } return(sizeFee); }
// How to calculate the Outbound Shipping Weight for the Weight Handling fee // This is used to calculate the Weight Handling fee. // https://www.amazon.com/gp/help/customer/display.html/ref=help_search_1-1?ie=UTF8&nodeId=201119410&qid=1448996314&sr=1-1#calc private static decimal CalculateOutboundShippingWeight(decimal unitWeight, decimal dimensionalWeight, ProductSizeTier productSizeTier) { decimal outboundShippingWeight; decimal packagingWeight; if (productSizeTier == ProductSizeTier.SmallStandardSize || productSizeTier == ProductSizeTier.LargeStandardSize) { packagingWeight = 0.25m; } else if (productSizeTier == ProductSizeTier.SmallOversize || productSizeTier == ProductSizeTier.MediumOversize || productSizeTier == ProductSizeTier.LargeOversize || productSizeTier == ProductSizeTier.SpecialOversize) { packagingWeight = 1.00m; } else { // Default to ensure a value is set. packagingWeight = 1.00m; } if (productSizeTier == ProductSizeTier.SmallStandardSize || productSizeTier == ProductSizeTier.LargeStandardSize) { if (unitWeight <= 1) { // 1 lb. or less. outboundShippingWeight = unitWeight + packagingWeight; } else { // more than 1 lb. outboundShippingWeight = Math.Max(unitWeight, dimensionalWeight) + packagingWeight; } } else if (productSizeTier == ProductSizeTier.SmallOversize || productSizeTier == ProductSizeTier.MediumOversize || productSizeTier == ProductSizeTier.LargeOversize) { outboundShippingWeight = Math.Max(unitWeight, dimensionalWeight) + packagingWeight; } else if (productSizeTier == ProductSizeTier.SpecialOversize) { outboundShippingWeight = unitWeight + packagingWeight; } else { // Default. outboundShippingWeight = Math.Max(unitWeight, dimensionalWeight) + packagingWeight; } // Round up to the nearest whole pound. return(Math.Ceiling(outboundShippingWeight)); }
private static decimal GetWeightFee(ProductSizeTier productSizeTier, decimal weight) { decimal weightFee = 0.00m; decimal weightCeiling = Math.Ceiling(weight); switch (productSizeTier) { case ProductSizeTier.SmallStandardSize: weightFee = weightCeiling * 0.50m; break; case ProductSizeTier.LargeStandardSize: if (weightCeiling <= 1) { weightFee = 0.96m; } else { weightFee = 1.95m; if (weightCeiling > 2) { weightFee += (weightCeiling - 2) * 0.39m; } } break; case ProductSizeTier.SmallOversize: weightFee = 2.06m; if (weightCeiling > 2) { weightFee += (weightCeiling - 2) * 0.39m; } break; case ProductSizeTier.MediumOversize: weightFee = 2.73m; if (weightCeiling > 2) { weightFee += (weightCeiling - 2) * 0.39m; } break; case ProductSizeTier.LargeOversize: weightFee = 63.98m; if (weightCeiling > 90) { weightFee += (weightCeiling - 90) * 0.80m; } break; case ProductSizeTier.SpecialOversize: weightFee = 124.58m; if (weightCeiling > 90) { weightFee += (weightCeiling - 90) * 0.92m; } break; } return(weightFee); }