public async Task free_shipping_for_no_rates() { var shipItem1 = new ShipEstimateItem { LineItemID = "Line1" }; var line1 = new HSLineItem { ID = "Line1", LineSubtotal = 370, SupplierID = "010" }; var method1 = new HSShipMethod { ID = "NO_SHIPPING_RATES", xp = new ShipMethodXP() }; var worksheet = BuildOrderWorksheet(new HSLineItem[] { line1 }); var estimates = BuildEstimates(new[] { method1 }, new[] { shipItem1 }); var result = await estimates.ApplyShippingLogic(worksheet, _oc, FREE_SHIPPING_DAYS); var methods = result[0].ShipMethods; Assert.AreEqual(1, methods.Count()); Assert.AreEqual(0, methods[0].Cost); Assert.AreEqual(method1.Name, methods[0].Name); Assert.IsTrue(methods[0].xp.FreeShippingApplied); }
public async Task <HSLineItem> UpsertLineItem(string orderID, HSLineItem liReq, VerifiedUserContext user) { // get me product with markedup prices correct currency and the existing line items in parellel var productRequest = _meProductCommand.Get(liReq.ProductID, user); var existingLineItemsRequest = ListAllAsync.List((page) => _oc.LineItems.ListAsync <HSLineItem>(OrderDirection.Outgoing, orderID, page: page, pageSize: 100, filters: $"Product.ID={liReq.ProductID}", accessToken: user.AccessToken)); var orderRequest = _oc.Orders.GetAsync(OrderDirection.Incoming, orderID); var existingLineItems = await existingLineItemsRequest; var product = await productRequest; var li = new HSLineItem(); var markedUpPrice = ValidateLineItemUnitCost(orderID, product, existingLineItems, liReq); liReq.UnitPrice = await markedUpPrice; var order = await orderRequest; Require.That(!order.IsSubmitted, new ErrorCode("Invalid Order Status", 400, "Order has already been submitted")); liReq.xp.StatusByQuantity = LineItemStatusConstants.EmptyStatuses; liReq.xp.StatusByQuantity[LineItemStatus.Open] = liReq.Quantity; var preExistingLi = ((List <HSLineItem>)existingLineItems).Find(eli => LineItemsMatch(eli, liReq)); if (preExistingLi != null) { li = await _oc.LineItems.SaveAsync <HSLineItem>(OrderDirection.Incoming, orderID, preExistingLi.ID, liReq); } else { li = await _oc.LineItems.CreateAsync <HSLineItem>(OrderDirection.Incoming, orderID, liReq); } await _promotionCommand.AutoApplyPromotions(orderID); return(li); }
public static LineItemProductData MapToTemplateProduct(HSLineItem lineItem, LineItemStatusChange lineItemStatusChange, LineItemStatus status) { decimal lineTotal = 0M; if (status == LineItemStatus.ReturnDenied || status == LineItemStatus.CancelDenied && lineItemStatusChange.QuantityRequestedForRefund != lineItemStatusChange.Quantity) { int quantityApproved = lineItemStatusChange.QuantityRequestedForRefund - lineItemStatusChange.Quantity; decimal costPerUnitAfterTaxes = (decimal)(lineItemStatusChange.Refund / quantityApproved); lineTotal = Math.Round(costPerUnitAfterTaxes * lineItemStatusChange.Quantity, 2); } else { lineTotal = lineItemStatusChange.Refund ?? lineItem.LineTotal; } return(new LineItemProductData { ProductName = lineItem?.Product?.Name, ImageURL = lineItem?.xp?.ImageUrl, ProductID = lineItem?.ProductID, Quantity = lineItem?.Quantity, LineTotal = lineTotal, QuantityChanged = lineItemStatusChange?.Quantity, MessageToBuyer = lineItemStatusChange.Comment }); }
public void flatrateshipping_handle_second_tier() { // set shipping cost to $0 if line item cost is greater than $499.99 var shipItem1 = new ShipEstimateItem { LineItemID = "Line1" }; var line1 = new HSLineItem { ID = "Line1", LineSubtotal = 602, SupplierID = "027" }; var method1 = new HSShipMethod { Name = "FEDEX_GROUND", EstimatedTransitDays = 3, Cost = 60, xp = new ShipMethodXP { } }; var worksheet = BuildOrderWorksheet(line1); var estimates = BuildEstimates(new[] { method1 }, new[] { shipItem1 }); var result = ApplyFlatRateShipping(worksheet, estimates, "027", null); var methods = result[0].ShipMethods; Assert.AreEqual(1, methods.Count()); Assert.AreEqual(FLAT_RATE_SECOND_TIER, methods[0].Cost); Assert.AreEqual(method1.Name, methods[0].Name); }
public void CalculateAndUpdateLineTotalRefund(IEnumerable <RMALineItem> lineItemsToUpdate, HSOrderWorksheet orderWorksheet, CosmosListPage <RMA> allRMAsOnThisOrder, string supplierID) { IEnumerable <dynamic> orderWorksheetLines = orderWorksheet.OrderCalculateResponse.xp.TaxResponse.lines; foreach (RMALineItem rmaLineItem in lineItemsToUpdate) { if (!rmaLineItem.RefundableViaCreditCard) { HSLineItem lineItemFromOrder = orderWorksheet.LineItems.FirstOrDefault(li => li.ID == rmaLineItem.ID); rmaLineItem.LineTotalRefund = lineItemFromOrder.LineTotal / lineItemFromOrder.Quantity * rmaLineItem.QuantityProcessed; } else { int quantityToRefund = rmaLineItem.QuantityProcessed; dynamic orderWorksheetLineItem = orderWorksheetLines.FirstOrDefault(li => li.lineNumber == rmaLineItem.ID); // Exempt products will have an exempt amount instead of a taxable amount. decimal lineItemBaseCost = orderWorksheetLineItem.exemptAmount > 0 ? orderWorksheetLineItem.exemptAmount : orderWorksheetLineItem.taxableAmount; decimal totalRefundIfReturningAllLineItems = (decimal)(lineItemBaseCost + orderWorksheetLineItem.tax); double taxableAmountPerSingleLineItem = (double)(lineItemBaseCost / orderWorksheetLineItem.quantity); double taxPerSingleLineItem = (double)(orderWorksheetLineItem.tax / orderWorksheetLineItem.quantity); double singleQuantityLineItemRefund = Math.Round(taxableAmountPerSingleLineItem + taxPerSingleLineItem, 2); decimal expectedLineTotalRefund = (decimal)singleQuantityLineItemRefund * quantityToRefund; rmaLineItem.LineTotalRefund = ValidateExpectedLineTotalRefund(expectedLineTotalRefund, totalRefundIfReturningAllLineItems, allRMAsOnThisOrder, rmaLineItem, orderWorksheet, supplierID); } ApplyPercentToDiscount(rmaLineItem); rmaLineItem.Status = rmaLineItem.QuantityProcessed == rmaLineItem.QuantityRequested ? RMALineItemStatus.Complete : RMALineItemStatus.PartialQtyComplete; } }
public void flatrateshipping_ignore_zerocost() { // don't transform methods if they are zero cost var shipItem1 = new ShipEstimateItem { LineItemID = "Line1" }; var line1 = new HSLineItem { ID = "Line1", LineSubtotal = 0, SupplierID = "027" }; var method1 = new HSShipMethod { Name = "FEDEX_GROUND", EstimatedTransitDays = 3, Cost = 60, xp = new ShipMethodXP { } }; var worksheet = BuildOrderWorksheet(line1); var estimates = BuildEstimates(new[] { method1 }, new[] { shipItem1 }); var result = ApplyFlatRateShipping(worksheet, estimates, "027", null); var methods = result[0].ShipMethods; Assert.AreEqual(1, methods.Count()); Assert.AreEqual(method1.Cost, methods[0].Cost); Assert.AreEqual(method1.Name, methods[0].Name); }
public async Task shipping_ignore_zerocostAsync() { // don't transform methods if they are zero cost var shipItem1 = new ShipEstimateItem { LineItemID = "Line1" }; var line1 = new HSLineItem { ID = "Line1", LineSubtotal = 0, SupplierID = "027" }; var method1 = new HSShipMethod { Name = "FEDEX_GROUND", EstimatedTransitDays = 3, Cost = 60, xp = new ShipMethodXP { } }; var worksheet = BuildOrderWorksheet(new HSLineItem[] { line1 }); var estimates = BuildEstimates(new[] { method1 }, new[] { shipItem1 }); var result = await estimates.ApplyShippingLogic(worksheet, _oc, FREE_SHIPPING_DAYS); var methods = result[0].ShipMethods; Assert.AreEqual(1, methods.Count()); Assert.AreEqual(method1.Cost, methods[0].Cost); Assert.AreEqual(method1.Name, methods[0].Name); }
public static ZohoLineItem Map(ZohoLineItem zItem, HSLineItem item, Supplier supplier) { zItem.purchase_description = $"{item.Product.Name ?? item.Variant?.Name} {item.Variant?.xp?.SpecCombo ?? item.SKU()}".Trim(); zItem.purchase_rate = item.UnitPrice.HasValue ? Math.Round(decimal.ToDouble(item.UnitPrice.Value), 2) : 0; zItem.manufacturer = supplier.Name; return(zItem); }
public static LineItemProductData MapLineItemToProduct(HSLineItem lineItem) => lineItem == null ? null : new LineItemProductData() { ProductName = lineItem?.Product?.Name, ImageURL = lineItem?.xp?.ImageUrl, ProductID = lineItem?.ProductID, Quantity = lineItem?.Quantity, LineTotal = lineItem?.LineTotal, };
public static ZohoLineItem Map(ZohoLineItem zItem, HSLineItem item) { zItem.item_type = "sales_and_purchases"; zItem.name = $"{item.Variant?.Name ?? item.Product.Name} {item.Variant?.xp?.SpecCombo ?? item.SKU()}".Trim(); zItem.description = $"{item.Variant?.Name ?? item.Product.Name} {item.Variant?.xp?.SpecCombo ?? item.SKU()}".Trim(); zItem.purchase_description = $"{item.Variant?.Name ?? item.Product.Name} {item.Variant?.xp?.SpecCombo ?? item.SKU()}".Trim(); zItem.rate = item.UnitPrice.HasValue ? Math.Round(decimal.ToDouble(item.UnitPrice.Value), 2) : 0; zItem.unit = item.Product.xp?.UnitOfMeasure?.Unit; zItem.avatax_tax_code = item.Product.xp?.Tax.Code; return(zItem); }
public static LineItemProductData MapToTemplateProduct(HSLineItem lineItem, LineItemStatusChange lineItemStatusChange) { return(new LineItemProductData { ProductName = lineItem?.Product?.Name, ImageURL = lineItem?.xp?.ImageUrl, ProductID = lineItem?.ProductID, Quantity = lineItem?.Quantity, LineTotal = lineItem?.LineTotal, QuantityChanged = lineItemStatusChange?.Quantity }); }
public static ZohoLineItem Map(HSLineItem item) { return(new ZohoLineItem() { item_type = "sales_and_purchases", name = $"{item.Variant?.Name ?? item.Product.Name} {item.Variant?.xp?.SpecCombo ?? item.SKU()}".Trim(), rate = item.UnitPrice.HasValue ? Math.Round(decimal.ToDouble(item.UnitPrice.Value), 2) : 0, quantity = 1, description = $"{item.Variant?.Name ?? item.Product.Name} {item.Variant?.xp?.SpecCombo ?? item.SKU()}".Trim(), sku = item.SKU(), unit = item.Product.xp?.UnitOfMeasure?.Unit, avatax_tax_code = item.Product.xp?.Tax.Code }); }
public void flatrateshipping_multiple_methods_with_nonqualifyingflatrate() { // If DOESNT qualify for flat rate shipping then dont modify the rates var shipItem1 = new ShipEstimateItem { LineItemID = "Line1" }; var shipItem2 = new ShipEstimateItem { LineItemID = "Line2" }; var line1 = new HSLineItem { ID = "Line1", LineSubtotal = 250, SupplierID = "027" }; var line2 = new HSLineItem { ID = "Line2", LineSubtotal = 130, SupplierID = "027" }; var method1 = new HSShipMethod { Name = "SOMETHING_ELSE", EstimatedTransitDays = 3, Cost = 60, xp = new ShipMethodXP { } }; var method2 = new HSShipMethod { Name = "PRIORITY_OVERNIGHT", EstimatedTransitDays = 1, Cost = 120, xp = new ShipMethodXP { } }; var worksheet = BuildOrderWorksheet(line1, line2); var estimates = BuildEstimates(new[] { method1, method2 }, new[] { shipItem1, shipItem2 }); var result = ApplyFlatRateShipping(worksheet, estimates, "027", null); var methods = result[0].ShipMethods; Assert.AreEqual(2, methods.Count()); Assert.AreEqual(method1.Cost, methods[0].Cost); Assert.AreEqual(method1.Name, methods[0].Name); Assert.AreEqual(method2.Cost, methods[1].Cost); Assert.AreEqual(method2.Name, methods[1].Name); }
public void flatrateshipping_multiple_methods_with_qualifyingflatrate() { // If qualifies for flat rate shipping then the only rate that should be returned is the modified ground option // this test ensures the non-ground option is stripped out var shipItem1 = new ShipEstimateItem { LineItemID = "Line1" }; var shipItem2 = new ShipEstimateItem { LineItemID = "Line2" }; var line1 = new HSLineItem { ID = "Line1", LineSubtotal = 250, SupplierID = "027" }; var line2 = new HSLineItem { ID = "Line2", LineSubtotal = 130, SupplierID = "027" }; var method1 = new HSShipMethod { Name = "FEDEX_GROUND", EstimatedTransitDays = 3, Cost = 60, xp = new ShipMethodXP { } }; var method2 = new HSShipMethod { Name = "PRIORITY_OVERNIGHT", EstimatedTransitDays = 1, Cost = 120, xp = new ShipMethodXP { } }; var worksheet = BuildOrderWorksheet(line1, line2); var estimates = BuildEstimates(new[] { method1, method2 }, new[] { shipItem1, shipItem2 }); var result = ApplyFlatRateShipping(worksheet, estimates, "027", null); var methods = result[0].ShipMethods; Assert.AreEqual(1, methods.Count()); Assert.AreEqual(FLAT_RATE_FIRST_TIER, methods[0].Cost); Assert.AreEqual(method1.Name, methods[0].Name); }
public async Task default_shipping_for_no_rates() { var shipItem1 = new ShipEstimateItem { LineItemID = "Line1" }; var line1 = new HSLineItem { ID = "Line1", LineSubtotal = 370, SupplierID = "010" }; var worksheet = BuildOrderWorksheet(new HSLineItem[] { line1 }); var estimates = BuildEstimates(new HSShipMethod[] { }, new[] { shipItem1 }); var result = await estimates.CheckForEmptyRates(20, 5).ApplyShippingLogic(worksheet, _oc, FREE_SHIPPING_DAYS); var methods = result[0].ShipMethods; Assert.AreEqual(1, methods.Count()); Assert.AreEqual(20, methods[0].Cost); }
public void flatrateshipping_handle_first_tier_multiple_lines() { // set shipping cost to $29.99 if line item cost is between 0.01$ and $499.99 var shipItem1 = new ShipEstimateItem { LineItemID = "Line1" }; var shipItem2 = new ShipEstimateItem { LineItemID = "Line2" }; var line1 = new HSLineItem { ID = "Line1", LineSubtotal = 200, SupplierID = "027" }; var line2 = new HSLineItem { ID = "Line2", LineSubtotal = 250, SupplierID = "027" }; var method1 = new HSShipMethod { Name = "FEDEX_GROUND", EstimatedTransitDays = 3, Cost = 60, xp = new ShipMethodXP { } }; var worksheet = BuildOrderWorksheet(line1, line2); var estimates = BuildEstimates(new[] { method1 }, new[] { shipItem1, shipItem2 }); var result = ApplyFlatRateShipping(worksheet, estimates, "027", null); var methods = result[0].ShipMethods; Assert.AreEqual(1, methods.Count()); Assert.AreEqual(FLAT_RATE_FIRST_TIER, methods[0].Cost); Assert.AreEqual(method1.Name, methods[0].Name); }
private Dictionary <LineItemStatus, int> BuildNewLineItemStatusByQuantity(LineItemStatusChange lineItemStatusChange, HSLineItem existingLineItem, LineItemStatus newLineItemStatus) { Dictionary <LineItemStatus, int> statusDictionary = existingLineItem.xp.StatusByQuantity; var quantitySetting = lineItemStatusChange.Quantity; // increment statusDictionary[newLineItemStatus] += quantitySetting; var validPreviousStates = LineItemStatusConstants.ValidPreviousStateLineItemChangeMap[newLineItemStatus]; // decrement foreach (LineItemStatus status in validPreviousStates) { if (statusDictionary[status] != 0) { if (statusDictionary[status] <= quantitySetting) { quantitySetting -= statusDictionary[status]; statusDictionary[status] = 0; } else { statusDictionary[status] -= quantitySetting; quantitySetting = 0; } } } return(statusDictionary); }
public async Task <HSLineItem> UpsertLineItem(string orderID, [FromBody] HSLineItem li) { return(await _lineItemCommand.UpsertLineItem(orderID, li, UserContext)); }
public static string SKU(this HSLineItem item) { return(item.Product == null ? "" : $"{item.Product.ID}-{item.Variant?.ID}".TrimEnd("-")); }
public async Task <decimal> ValidateLineItemUnitCost(string orderID, SuperHSMeProduct product, List <HSLineItem> existingLineItems, HSLineItem li) { if (product.PriceSchedule.UseCumulativeQuantity) { int totalQuantity = li?.Quantity ?? 0; foreach (HSLineItem lineItem in existingLineItems) { if (li == null || !LineItemsMatch(li, lineItem)) { totalQuantity += lineItem.Quantity; } } decimal priceBasedOnQuantity = product.PriceSchedule.PriceBreaks.Last(priceBreak => priceBreak.Quantity <= totalQuantity).Price; foreach (HSLineItem lineItem in existingLineItems) { // Determine markup for all specs for this existing line item decimal lineItemTotal = priceBasedOnQuantity + GetSpecMarkup(lineItem.Specs, product.Specs); if (lineItem.UnitPrice != lineItemTotal) { PartialLineItem lineItemToPatch = new PartialLineItem(); lineItemToPatch.UnitPrice = lineItemTotal; await _oc.LineItems.PatchAsync <HSLineItem>(OrderDirection.Incoming, orderID, lineItem.ID, lineItemToPatch); } } // Return the item total for the li being added or modified return(li == null ? 0 : priceBasedOnQuantity + GetSpecMarkup(li.Specs, product.Specs)); } else { decimal lineItemTotal = 0; if (li != null) { // Determine price including quantity price break discount decimal priceBasedOnQuantity = product.PriceSchedule.PriceBreaks.Last(priceBreak => priceBreak.Quantity <= li.Quantity).Price; // Determine markup for the 1 line item lineItemTotal = priceBasedOnQuantity + GetSpecMarkup(li.Specs, product.Specs); } return(lineItemTotal); } }
public void flatrateshipping_handle_multiple_estimates() { // set shipping cost to $0 if line item cost is greater than $499.99 var shipItem1 = new ShipEstimateItem { LineItemID = "Supplier1Line1" }; var shipitem2 = new ShipEstimateItem { LineItemID = "Supplier2Line1" }; var line1 = new HSLineItem { ID = "Supplier1Line1", LineSubtotal = 110, SupplierID = "010" }; var line2 = new HSLineItem { ID = "Supplier1Line2", LineSubtotal = 125, SupplierID = "010" }; var line3 = new HSLineItem { ID = "Supplier2Line1", LineSubtotal = 130, SupplierID = "027" }; var line4 = new HSLineItem { ID = "Supplier2Line2", LineSubtotal = 180, SupplierID = "027" }; var method1 = new HSShipMethod { Name = "FEDEX_GROUND", EstimatedTransitDays = 1, Cost = 80, xp = new ShipMethodXP { } }; var method2 = new HSShipMethod { Name = "FEDEX_GROUND", EstimatedTransitDays = 3, Cost = 60, xp = new ShipMethodXP { } }; var worksheet = BuildOrderWorksheet(line1, line2, line3, line4); var estimates = BuildEstimates(new[] { method1 }, new[] { shipItem1 }); estimates.AddRange(BuildEstimates(new[] { method2 }, new[] { shipitem2 })); var result = ApplyFlatRateShipping(worksheet, estimates, "027", null); Assert.AreEqual(2, result.Count()); // compare first shipment item from first estimate (no changes because its not medline supplier) Assert.AreEqual(1, result[0].ShipMethods.Count()); Assert.AreEqual(method1.Name, result[0].ShipMethods[0].Name); Assert.AreEqual(method1.Cost, result[0].ShipMethods[0].Cost); // compare first shipment item from second estimate (cost falls in first tier between $0.01 and $499.9) Assert.AreEqual(1, result[0].ShipMethods.Count()); Assert.AreEqual(method2.Name, result[1].ShipMethods[0].Name); Assert.AreEqual(29.99M, result[1].ShipMethods[0].Cost); }