public async Task <QuoteRequestTotals> CalculateTotalsAsync(QuoteRequest quote) { var retVal = new QuoteRequestTotals(); var cartFromQuote = quote.ToCartModel(AbstractTypeFactory <ShoppingCart> .TryCreateInstance()); //Calculate shipment total //first try to get manual amount retVal.ShippingTotal = quote.ManualShippingTotal; if (retVal.ShippingTotal == 0 && quote.ShipmentMethod != null) { //calculate total by using shipment gateways var evalContext = new ShippingEvaluationContext(cartFromQuote); var searchCriteria = AbstractTypeFactory <ShippingMethodsSearchCriteria> .TryCreateInstance(); searchCriteria.StoreId = quote.StoreId; searchCriteria.IsActive = true; searchCriteria.Codes = new[] { quote.ShipmentMethod.ShipmentMethodCode }; var storeShippingMethods = await _shippingMethodsSearchService.SearchShippingMethodsAsync(searchCriteria); var rate = storeShippingMethods.Results .SelectMany(x => x.CalculateRates(evalContext)) .FirstOrDefault(x => (quote.ShipmentMethod.OptionName == null) || quote.ShipmentMethod.OptionName == x.OptionName); retVal.ShippingTotal = rate != null ? rate.Rate : 0m; } //Calculate taxes var taxSearchCriteria = AbstractTypeFactory <TaxProviderSearchCriteria> .TryCreateInstance(); taxSearchCriteria.StoreIds = new[] { quote.StoreId }; taxSearchCriteria.Sort = nameof(TaxProvider.Priority); var taxProvider = (await _taxProviderSearchService.SearchTaxProvidersAsync(taxSearchCriteria)).Results.FirstOrDefault(); if (taxProvider != null) { var taxEvalContext = quote.ToTaxEvalContext(AbstractTypeFactory <TaxEvaluationContext> .TryCreateInstance()); retVal.TaxTotal = taxProvider.CalculateRates(taxEvalContext).Select(x => x.Rate).DefaultIfEmpty(0).Sum(x => x); } //Calculate subtotal var items = quote.Items.Where(x => x.SelectedTierPrice != null); if (quote.Items != null) { retVal.OriginalSubTotalExlTax = items.Sum(x => x.SalePrice * x.SelectedTierPrice.Quantity); retVal.SubTotalExlTax = items.Sum(x => x.SelectedTierPrice.Price * x.SelectedTierPrice.Quantity); if (quote.ManualSubTotal > 0) { retVal.DiscountTotal = retVal.SubTotalExlTax - quote.ManualSubTotal; retVal.SubTotalExlTax = quote.ManualSubTotal; } else if (quote.ManualRelDiscountAmount > 0) { retVal.DiscountTotal = retVal.SubTotalExlTax * quote.ManualRelDiscountAmount * 0.01m; } } return(retVal); }
public QuoteRequestTotals CalculateTotals(QuoteRequest quote) { var retVal = new QuoteRequestTotals(); var cartFromQuote = quote.ToCartModel(); var store = _storeService.GetById(quote.StoreId); if (store != null) { //Calculate shipment total //firts try to get manual amount retVal.ShippingTotal = quote.ManualShippingTotal; if (retVal.ShippingTotal == 0 && quote.ShipmentMethod != null) { //calculate total by using shipment gateways var evalContext = new ShippingEvaluationContext(cartFromQuote); var rate = store.ShippingMethods.Where(x => x.IsActive && x.Code == quote.ShipmentMethod.ShipmentMethodCode) .SelectMany(x => x.CalculateRates(evalContext)) .Where(x => quote.ShipmentMethod.OptionName != null ? quote.ShipmentMethod.OptionName == x.OptionName : true) .FirstOrDefault(); retVal.ShippingTotal = rate != null ? rate.Rate : 0m; } //Calculate taxes var taxProvider = store.TaxProviders.Where(x => x.IsActive).OrderBy(x => x.Priority).FirstOrDefault(); if (taxProvider != null) { var taxRequest = quote.ToTaxRequest(); var taxEvalContext = new TaxEvaluationContext(taxRequest); retVal.TaxTotal = taxProvider.CalculateRates(taxEvalContext).Select(x => x.Rate).DefaultIfEmpty(0).Sum(x => x); } } //Calculate subtotal var items = quote.Items.Where(x => x.SelectedTierPrice != null); if (quote.Items != null) { retVal.OriginalSubTotalExlTax = items.Sum(x => x.SalePrice * x.SelectedTierPrice.Quantity); retVal.SubTotalExlTax = items.Sum(x => x.SelectedTierPrice.Price * x.SelectedTierPrice.Quantity); if (quote.ManualSubTotal > 0) { retVal.DiscountTotal = retVal.SubTotalExlTax - quote.ManualSubTotal; retVal.SubTotalExlTax = quote.ManualSubTotal; } else if (quote.ManualRelDiscountAmount > 0) { retVal.DiscountTotal = retVal.SubTotalExlTax * quote.ManualRelDiscountAmount * 0.01m; } } return(retVal); }