protected async override Task MoveShoppingCartItemsToOrderItemsAsync( PlaceOrderContainer details, Order order ) { foreach (var sc in details.Cart) { var product = await _productService.GetProductByIdAsync(sc.ProductId); //prices var scUnitPrice = (await _shoppingCartService.GetUnitPriceAsync(sc, true)).unitPrice; var(scSubTotal, discountAmount, scDiscounts, _) = await _shoppingCartService.GetSubTotalAsync(sc, true); // var scUnitPriceInclTax = // await _taxService.GetProductPriceAsync(product, scUnitPrice, true, details.Customer); var scUnitPriceExclTax = await _taxService.GetProductPriceAsync(product, scUnitPrice, false, details.Customer); // var scSubTotalInclTax = // await _taxService.GetProductPriceAsync(product, scSubTotal, true, details.Customer); var scSubTotalExclTax = await _taxService.GetProductPriceAsync(product, scSubTotal, false, details.Customer); // custom - getting warranty tax var(_, scSubTotalInclTax, scUnitPriceInclTax, _, _) = await _warrantyTaxService.CalculateWarrantyTaxAsync(sc, details.Customer, scSubTotalExclTax.price, scUnitPriceExclTax.price); var discountAmountInclTax = await _taxService.GetProductPriceAsync(product, discountAmount, true, details.Customer); var discountAmountExclTax = await _taxService.GetProductPriceAsync(product, discountAmount, false, details.Customer); foreach (var disc in scDiscounts) { if (!_discountService.ContainsDiscount(details.AppliedDiscounts, disc)) { details.AppliedDiscounts.Add(disc); } } //attributes var attributeDescription = await _productAttributeFormatter.FormatAttributesAsync(product, sc.AttributesXml, details.Customer); var itemWeight = await _shippingService.GetShoppingCartItemWeightAsync(sc); //save order item var orderItem = new OrderItem { OrderItemGuid = Guid.NewGuid(), OrderId = order.Id, ProductId = product.Id, UnitPriceInclTax = scUnitPriceInclTax, UnitPriceExclTax = scUnitPriceExclTax.price, PriceInclTax = scSubTotalInclTax, PriceExclTax = scSubTotalExclTax.price, OriginalProductCost = await _priceCalculationService.GetProductCostAsync(product, sc.AttributesXml), AttributeDescription = attributeDescription, AttributesXml = sc.AttributesXml, Quantity = sc.Quantity, DiscountAmountInclTax = discountAmountInclTax.price, DiscountAmountExclTax = discountAmountExclTax.price, DownloadCount = 0, IsDownloadActivated = false, LicenseDownloadId = 0, ItemWeight = itemWeight, RentalStartDateUtc = sc.RentalStartDateUtc, RentalEndDateUtc = sc.RentalEndDateUtc }; await _orderService.InsertOrderItemAsync(orderItem); //gift cards await AddGiftCardsAsync(product, sc.AttributesXml, sc.Quantity, orderItem, scUnitPriceExclTax.price); //inventory await _productService.AdjustInventoryAsync(product, -sc.Quantity, sc.AttributesXml, string.Format(await _localizationService.GetResourceAsync("Admin.StockQuantityHistory.Messages.PlaceOrder"), order.Id)); } //clear shopping cart details.Cart.ToList().ForEach(async sci => await _shoppingCartService.DeleteShoppingCartItemAsync(sci, false)); }
public override async Task <(decimal discountAmount, List <Discount> appliedDiscounts, decimal subTotalWithoutDiscount, decimal subTotalWithDiscount, SortedDictionary <decimal, decimal> taxRates)> GetShoppingCartSubTotalAsync( IList <ShoppingCartItem> cart, bool includingTax) { var discountAmount = decimal.Zero; var appliedDiscounts = new List <Discount>(); var subTotalWithoutDiscount = decimal.Zero; var subTotalWithDiscount = decimal.Zero; var taxRates = new SortedDictionary <decimal, decimal>(); if (!cart.Any()) { return(discountAmount, appliedDiscounts, subTotalWithoutDiscount, subTotalWithDiscount, taxRates); } //get the customer var customer = await _customerService.GetShoppingCartCustomerAsync(cart); //sub totals var subTotalExclTaxWithoutDiscount = decimal.Zero; var subTotalInclTaxWithoutDiscount = decimal.Zero; foreach (var shoppingCartItem in cart) { var sciSubTotal = (await _shoppingCartService.GetSubTotalAsync(shoppingCartItem, true)).subTotal; var product = await _productService.GetProductByIdAsync(shoppingCartItem.ProductId); var(sciExclTax, taxRate) = await _taxService.GetProductPriceAsync(product, sciSubTotal, false, customer); // custom var(_, sciInclTax) = await _warrantyTaxService.CalculateWarrantyTaxAsync(shoppingCartItem, customer, sciExclTax); subTotalExclTaxWithoutDiscount += sciExclTax; subTotalInclTaxWithoutDiscount += sciInclTax; //tax rates var sciTax = sciInclTax - sciExclTax; if (taxRate <= decimal.Zero || sciTax <= decimal.Zero) { continue; } if (!taxRates.ContainsKey(taxRate)) { taxRates.Add(taxRate, sciTax); } else { taxRates[taxRate] = taxRates[taxRate] + sciTax; } } //checkout attributes if (customer != null) { var checkoutAttributesXml = await _genericAttributeService.GetAttributeAsync <string>(customer, NopCustomerDefaults.CheckoutAttributes, (await _storeContext.GetCurrentStoreAsync()).Id); var attributeValues = _checkoutAttributeParser.ParseCheckoutAttributeValues(checkoutAttributesXml); if (attributeValues != null) { await foreach (var(attribute, values) in attributeValues) { await foreach (var attributeValue in values) { var(caExclTax, taxRate) = await _taxService.GetCheckoutAttributePriceAsync(attribute, attributeValue, false, customer); var(caInclTax, _) = await _taxService.GetCheckoutAttributePriceAsync(attribute, attributeValue, true, customer); subTotalExclTaxWithoutDiscount += caExclTax; subTotalInclTaxWithoutDiscount += caInclTax; //tax rates var caTax = caInclTax - caExclTax; if (taxRate <= decimal.Zero || caTax <= decimal.Zero) { continue; } if (!taxRates.ContainsKey(taxRate)) { taxRates.Add(taxRate, caTax); } else { taxRates[taxRate] = taxRates[taxRate] + caTax; } } } } } //subtotal without discount subTotalWithoutDiscount = includingTax ? subTotalInclTaxWithoutDiscount : subTotalExclTaxWithoutDiscount; if (subTotalWithoutDiscount < decimal.Zero) { subTotalWithoutDiscount = decimal.Zero; } if (_shoppingCartSettings.RoundPricesDuringCalculation) { subTotalWithoutDiscount = await _priceCalculationService.RoundPriceAsync(subTotalWithoutDiscount); } //We calculate discount amount on order subtotal excl tax (discount first) //calculate discount amount ('Applied to order subtotal' discount) decimal discountAmountExclTax; (discountAmountExclTax, appliedDiscounts) = await GetOrderSubtotalDiscountAsync(customer, subTotalExclTaxWithoutDiscount); if (subTotalExclTaxWithoutDiscount < discountAmountExclTax) { discountAmountExclTax = subTotalExclTaxWithoutDiscount; } var discountAmountInclTax = discountAmountExclTax; //subtotal with discount (excl tax) var subTotalExclTaxWithDiscount = subTotalExclTaxWithoutDiscount - discountAmountExclTax; var subTotalInclTaxWithDiscount = subTotalExclTaxWithDiscount; //add tax for shopping items & checkout attributes var tempTaxRates = new Dictionary <decimal, decimal>(taxRates); foreach (var kvp in tempTaxRates) { var taxRate = kvp.Key; var taxValue = kvp.Value; if (taxValue == decimal.Zero) { continue; } //discount the tax amount that applies to subtotal items if (subTotalExclTaxWithoutDiscount > decimal.Zero) { var discountTax = taxRates[taxRate] * (discountAmountExclTax / subTotalExclTaxWithoutDiscount); discountAmountInclTax += discountTax; taxValue = taxRates[taxRate] - discountTax; if (_shoppingCartSettings.RoundPricesDuringCalculation) { taxValue = await _priceCalculationService.RoundPriceAsync(taxValue); } taxRates[taxRate] = taxValue; } //subtotal with discount (incl tax) subTotalInclTaxWithDiscount += taxValue; } if (_shoppingCartSettings.RoundPricesDuringCalculation) { discountAmountInclTax = await _priceCalculationService.RoundPriceAsync(discountAmountInclTax); discountAmountExclTax = await _priceCalculationService.RoundPriceAsync(discountAmountExclTax); } if (includingTax) { subTotalWithDiscount = subTotalInclTaxWithDiscount; discountAmount = discountAmountInclTax; } else { subTotalWithDiscount = subTotalExclTaxWithDiscount; discountAmount = discountAmountExclTax; } if (subTotalWithDiscount < decimal.Zero) { subTotalWithDiscount = decimal.Zero; } if (_shoppingCartSettings.RoundPricesDuringCalculation) { subTotalWithDiscount = await _priceCalculationService.RoundPriceAsync(subTotalWithDiscount); } return(discountAmount, appliedDiscounts, subTotalWithoutDiscount, subTotalWithDiscount, taxRates); }