/// <summary> /// Prepare details to place an order. It also sets some properties to "processPaymentRequest" /// </summary> /// <param name="processPaymentRequest">Process payment request</param> /// <returns>Details</returns> protected override PlaceOrderContainer PreparePlaceOrderDetails(ProcessPaymentRequest processPaymentRequest) { var details = new PlaceOrderContainer { //customer Customer = _customerService.GetCustomerById(processPaymentRequest.CustomerId) }; if (details.Customer == null) { throw new ArgumentException("Customer is not set"); } //affiliate var affiliate = _affiliateService.GetAffiliateById(details.Customer.AffiliateId); if (affiliate != null && affiliate.Active && !affiliate.Deleted) { details.AffiliateId = affiliate.Id; } //check whether customer is guest if (details.Customer.IsGuest() && !_orderSettings.AnonymousCheckoutAllowed) { throw new QNetException("Anonymous checkout is not allowed"); } //customer currency var currencyTmp = _currencyService.GetCurrencyById( _genericAttributeService.GetAttribute <int>(details.Customer, QNetCustomerDefaults.CurrencyIdAttribute, processPaymentRequest.StoreId)); var customerCurrency = currencyTmp != null && currencyTmp.Published ? currencyTmp : _workContext.WorkingCurrency; var primaryStoreCurrency = _currencyService.GetCurrencyById(_currencySettings.PrimaryStoreCurrencyId); details.CustomerCurrencyCode = customerCurrency.CurrencyCode; details.CustomerCurrencyRate = customerCurrency.Rate / primaryStoreCurrency.Rate; //customer language details.CustomerLanguage = _languageService.GetLanguageById( _genericAttributeService.GetAttribute <int>(details.Customer, QNetCustomerDefaults.LanguageIdAttribute, processPaymentRequest.StoreId)); if (details.CustomerLanguage == null || !details.CustomerLanguage.Published) { details.CustomerLanguage = _workContext.WorkingLanguage; } //billing address if (details.Customer.BillingAddress == null) { throw new QNetException("Billing address is not provided"); } if (!CommonHelper.IsValidEmail(details.Customer.BillingAddress.Email)) { throw new QNetException("Email is not valid"); } details.BillingAddress = (Address)details.Customer.BillingAddress.Clone(); if (details.BillingAddress.Country != null && !details.BillingAddress.Country.AllowsBilling) { throw new QNetException($"Country '{details.BillingAddress.Country.Name}' is not allowed for billing"); } //checkout attributes details.CheckoutAttributesXml = _genericAttributeService.GetAttribute <string>(details.Customer, QNetCustomerDefaults.CheckoutAttributes, processPaymentRequest.StoreId); details.CheckoutAttributeDescription = _checkoutAttributeFormatter.FormatAttributes(details.CheckoutAttributesXml, details.Customer); //load shopping cart details.Cart = _shoppingCartService.GetShoppingCart(details.Customer, ShoppingCartType.ShoppingCart, processPaymentRequest.StoreId); if (!details.Cart.Any()) { throw new QNetException("Cart is empty"); } //validate the entire shopping cart var warnings = _shoppingCartService.GetShoppingCartWarnings(details.Cart, details.CheckoutAttributesXml, true); if (warnings.Any()) { throw new QNetException(warnings.Aggregate(string.Empty, (current, next) => $"{current}{next};")); } //validate individual cart items foreach (var sci in details.Cart) { var sciWarnings = _shoppingCartService.GetShoppingCartItemWarnings(details.Customer, sci.ShoppingCartType, sci.Product, processPaymentRequest.StoreId, sci.AttributesXml, sci.CustomerEnteredPrice, sci.RentalStartDateUtc, sci.RentalEndDateUtc, sci.Quantity, false, sci.Id); if (sciWarnings.Any()) { throw new QNetException(sciWarnings.Aggregate(string.Empty, (current, next) => $"{current}{next};")); } } //min totals validation if (!ValidateMinOrderSubtotalAmount(details.Cart)) { var minOrderSubtotalAmount = _currencyService.ConvertFromPrimaryStoreCurrency(_orderSettings.MinOrderSubtotalAmount, _workContext.WorkingCurrency); throw new QNetException(string.Format(_localizationService.GetResource("Checkout.MinOrderSubtotalAmount"), _priceFormatter.FormatPrice(minOrderSubtotalAmount, true, false))); } if (!ValidateMinOrderTotalAmount(details.Cart)) { var minOrderTotalAmount = _currencyService.ConvertFromPrimaryStoreCurrency(_orderSettings.MinOrderTotalAmount, _workContext.WorkingCurrency); throw new QNetException(string.Format(_localizationService.GetResource("Checkout.MinOrderTotalAmount"), _priceFormatter.FormatPrice(minOrderTotalAmount, true, false))); } //tax display type if (_taxSettings.AllowCustomersToSelectTaxDisplayType) { details.CustomerTaxDisplayType = (TaxDisplayType)_genericAttributeService.GetAttribute <int>(details.Customer, QNetCustomerDefaults.TaxDisplayTypeIdAttribute, processPaymentRequest.StoreId); } else { details.CustomerTaxDisplayType = _taxSettings.TaxDisplayType; } //sub total (incl tax) _orderTotalCalculationService.GetShoppingCartSubTotal(details.Cart, true, out var orderSubTotalDiscountAmount, out var orderSubTotalAppliedDiscounts, out var subTotalWithoutDiscountBase, out var _); details.OrderSubTotalInclTax = subTotalWithoutDiscountBase; details.OrderSubTotalDiscountInclTax = orderSubTotalDiscountAmount; //discount history foreach (var disc in orderSubTotalAppliedDiscounts) { if (!_discountService.ContainsDiscount(details.AppliedDiscounts, disc)) { details.AppliedDiscounts.Add(disc); } } //sub total (excl tax) _orderTotalCalculationService.GetShoppingCartSubTotal(details.Cart, false, out orderSubTotalDiscountAmount, out orderSubTotalAppliedDiscounts, out subTotalWithoutDiscountBase, out _); details.OrderSubTotalExclTax = subTotalWithoutDiscountBase; details.OrderSubTotalDiscountExclTax = orderSubTotalDiscountAmount; //shipping info if (_shoppingCartService.ShoppingCartRequiresShipping(details.Cart)) { var pickupPoint = _genericAttributeService.GetAttribute <PickupPoint>(details.Customer, QNetCustomerDefaults.SelectedPickupPointAttribute, processPaymentRequest.StoreId); if (_shippingSettings.AllowPickupInStore && pickupPoint != null) { var country = _countryService.GetCountryByTwoLetterIsoCode(pickupPoint.CountryCode); var state = _stateProvinceService.GetStateProvinceByAbbreviation(pickupPoint.StateAbbreviation, country?.Id); details.PickupInStore = true; details.PickupAddress = new Address { Address1 = pickupPoint.Address, City = pickupPoint.City, County = pickupPoint.County, Country = country, StateProvince = state, ZipPostalCode = pickupPoint.ZipPostalCode, CreatedOnUtc = DateTime.UtcNow }; } else { if (details.Customer.ShippingAddress == null) { throw new QNetException("Shipping address is not provided"); } if (!CommonHelper.IsValidEmail(details.Customer.ShippingAddress.Email)) { throw new QNetException("Email is not valid"); } //clone shipping address details.ShippingAddress = (Address)details.Customer.ShippingAddress.Clone(); if (details.ShippingAddress.Country != null && !details.ShippingAddress.Country.AllowsShipping) { throw new QNetException($"Country '{details.ShippingAddress.Country.Name}' is not allowed for shipping"); } } var shippingOption = _genericAttributeService.GetAttribute <ShippingOption>(details.Customer, QNetCustomerDefaults.SelectedShippingOptionAttribute, processPaymentRequest.StoreId); if (shippingOption != null) { details.ShippingMethodName = shippingOption.Name; details.ShippingRateComputationMethodSystemName = shippingOption.ShippingRateComputationMethodSystemName; } details.ShippingStatus = ShippingStatus.NotYetShipped; } else { details.ShippingStatus = ShippingStatus.ShippingNotRequired; } //LoadAllShippingRateComputationMethods var shippingRateComputationMethods = _shippingPluginManager.LoadActivePlugins(_workContext.CurrentCustomer, _storeContext.CurrentStore.Id); //shipping total var orderShippingTotalInclTax = _orderTotalCalculationService.GetShoppingCartShippingTotal(details.Cart, true, shippingRateComputationMethods, out var _, out var shippingTotalDiscounts); var orderShippingTotalExclTax = _orderTotalCalculationService.GetShoppingCartShippingTotal(details.Cart, false, shippingRateComputationMethods); if (!orderShippingTotalInclTax.HasValue || !orderShippingTotalExclTax.HasValue) { throw new QNetException("Shipping total couldn't be calculated"); } details.OrderShippingTotalInclTax = orderShippingTotalInclTax.Value; details.OrderShippingTotalExclTax = orderShippingTotalExclTax.Value; foreach (var disc in shippingTotalDiscounts) { if (!_discountService.ContainsDiscount(details.AppliedDiscounts, disc)) { details.AppliedDiscounts.Add(disc); } } //payment total var paymentAdditionalFee = _paymentService.GetAdditionalHandlingFee(details.Cart, processPaymentRequest.PaymentMethodSystemName); details.PaymentAdditionalFeeInclTax = _taxService.GetPaymentMethodAdditionalFee(paymentAdditionalFee, true, details.Customer); details.PaymentAdditionalFeeExclTax = _taxService.GetPaymentMethodAdditionalFee(paymentAdditionalFee, false, details.Customer); //tax amount details.OrderTaxTotal = _orderTotalCalculationService.GetTaxTotal(details.Cart, shippingRateComputationMethods, out var taxRatesDictionary); //Avalara plugin changes //get previously saved tax details received from the Avalara tax service var taxDetails = _httpContextAccessor.HttpContext.Session.Get <TaxDetails>(AvalaraTaxDefaults.TaxDetailsSessionValue); if (taxDetails != null) { //adjust tax total according to received value from the Avalara if (taxDetails.TaxTotal.HasValue) { details.OrderTaxTotal = taxDetails.TaxTotal.Value; } if (taxDetails.TaxRates?.Any() ?? false) { taxRatesDictionary = new SortedDictionary <decimal, decimal>(taxDetails.TaxRates); } } //Avalara plugin changes //VAT number var customerVatStatus = (VatNumberStatus)_genericAttributeService.GetAttribute <int>(details.Customer, QNetCustomerDefaults.VatNumberStatusIdAttribute); if (_taxSettings.EuVatEnabled && customerVatStatus == VatNumberStatus.Valid) { details.VatNumber = _genericAttributeService.GetAttribute <string>(details.Customer, QNetCustomerDefaults.VatNumberAttribute); } //tax rates details.TaxRates = taxRatesDictionary.Aggregate(string.Empty, (current, next) => $"{current}{next.Key.ToString(CultureInfo.InvariantCulture)}:{next.Value.ToString(CultureInfo.InvariantCulture)}; "); //order total (and applied discounts, gift cards, reward points) var orderTotal = _orderTotalCalculationService.GetShoppingCartTotal(details.Cart, out var orderDiscountAmount, out var orderAppliedDiscounts, out var appliedGiftCards, out var redeemedRewardPoints, out var redeemedRewardPointsAmount); if (!orderTotal.HasValue) { throw new QNetException("Order total couldn't be calculated"); } details.OrderDiscountAmount = orderDiscountAmount; details.RedeemedRewardPoints = redeemedRewardPoints; details.RedeemedRewardPointsAmount = redeemedRewardPointsAmount; details.AppliedGiftCards = appliedGiftCards; details.OrderTotal = orderTotal.Value; //discount history foreach (var disc in orderAppliedDiscounts) { if (!_discountService.ContainsDiscount(details.AppliedDiscounts, disc)) { details.AppliedDiscounts.Add(disc); } } processPaymentRequest.OrderTotal = details.OrderTotal; //Avalara plugin changes //delete custom value _httpContextAccessor.HttpContext.Session.Set <TaxDetails>(AvalaraTaxDefaults.TaxDetailsSessionValue, null); //Avalara plugin changes //recurring or standard shopping cart? details.IsRecurringShoppingCart = _shoppingCartService.ShoppingCartIsRecurring(details.Cart); if (!details.IsRecurringShoppingCart) { return(details); } var recurringCyclesError = _shoppingCartService.GetRecurringCycleInfo(details.Cart, out var recurringCycleLength, out var recurringCyclePeriod, out var recurringTotalCycles); if (!string.IsNullOrEmpty(recurringCyclesError)) { throw new QNetException(recurringCyclesError); } processPaymentRequest.RecurringCycleLength = recurringCycleLength; processPaymentRequest.RecurringCyclePeriod = recurringCyclePeriod; processPaymentRequest.RecurringTotalCycles = recurringTotalCycles; return(details); }
/// <summary> /// Move shopping cart items to order items /// </summary> /// <param name="details">Place order container</param> /// <param name="order">Order</param> protected override void MoveShoppingCartItemsToOrderItems(PlaceOrderContainer details, Order order) { //wgr var cart_size = details.Cart.Count(); int[] mms_item_ids = new int[cart_size]; int[] mms_item_qtys = new int[cart_size]; int mms_i = 0; var mmsDownloadList = new List <int>(); var firstName = details.BillingAddress.FirstName; var lastName = details.BillingAddress.LastName; var eMail = details.Customer.Email; //wgr Debug.WriteLine(" ****** In Override for MoveShoppingCartItemsToOrderItems"); foreach (var sc in details.Cart) { var product = _productService.GetProductById(sc.ProductId); //WGR build mms items for sales_order if (product.IsDownload == false) { var mms_id = _mmsadminService.MmsGetMmsItemId(sc.ProductId); if (mms_id > 0) { mms_item_ids[mms_i] = mms_id; mms_item_qtys[mms_i] = sc.Quantity; mms_i++; } } else { var mms_id = _mmsadminService.MmsGetMmsItemId(sc.ProductId); if (mms_id > 0) { mmsDownloadList.Add(mms_id); } } //WGR //prices var scUnitPrice = _shoppingCartService.GetUnitPrice(sc); var scSubTotal = _shoppingCartService.GetSubTotal(sc, true, out var discountAmount, out var scDiscounts, out _); var scUnitPriceInclTax = _taxService.GetProductPrice(product, scUnitPrice, true, details.Customer, out var _); var scUnitPriceExclTax = _taxService.GetProductPrice(product, scUnitPrice, false, details.Customer, out _); var scSubTotalInclTax = _taxService.GetProductPrice(product, scSubTotal, true, details.Customer, out _); var scSubTotalExclTax = _taxService.GetProductPrice(product, scSubTotal, false, details.Customer, out _); var discountAmountInclTax = _taxService.GetProductPrice(product, discountAmount, true, details.Customer, out _); var discountAmountExclTax = _taxService.GetProductPrice(product, discountAmount, false, details.Customer, out _); foreach (var disc in scDiscounts) { if (!_discountService.ContainsDiscount(details.AppliedDiscounts, disc)) { details.AppliedDiscounts.Add(disc); } } //attributes var attributeDescription = _productAttributeFormatter.FormatAttributes(product, sc.AttributesXml, details.Customer); var itemWeight = _shippingService.GetShoppingCartItemWeight(sc); //save order item var orderItem = new OrderItem { OrderItemGuid = Guid.NewGuid(), OrderId = order.Id, ProductId = product.Id, UnitPriceInclTax = scUnitPriceInclTax, UnitPriceExclTax = scUnitPriceExclTax, PriceInclTax = scSubTotalInclTax, PriceExclTax = scSubTotalExclTax, OriginalProductCost = _priceCalculationService.GetProductCost(product, sc.AttributesXml), AttributeDescription = attributeDescription, AttributesXml = sc.AttributesXml, Quantity = sc.Quantity, DiscountAmountInclTax = discountAmountInclTax, DiscountAmountExclTax = discountAmountExclTax, DownloadCount = 0, IsDownloadActivated = false, LicenseDownloadId = 0, ItemWeight = itemWeight, RentalStartDateUtc = sc.RentalStartDateUtc, RentalEndDateUtc = sc.RentalEndDateUtc }; _orderService.InsertOrderItem(orderItem); //gift cards AddGiftCards(product, sc.AttributesXml, sc.Quantity, orderItem, scUnitPriceExclTax); //inventory _productService.AdjustInventory(product, -sc.Quantity, sc.AttributesXml, string.Format(_localizationService.GetResource("Admin.StockQuantityHistory.Messages.PlaceOrder"), order.Id)); } //WGR Add to MMS SO _mmsadminService.MmsAddSOItems(mms_item_ids, mms_item_qtys); //WGR Add downloads var mmsSuccess = _mmsadminService.MmsJsonAddOrder(firstName, lastName, eMail, mmsDownloadList); if (mmsSuccess != "success") { Debug.WriteLine("Error Adding Downloads: " + mmsSuccess); } //clear shopping cart details.Cart.ToList().ForEach(sci => _shoppingCartService.DeleteShoppingCartItem(sci, false)); }
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)); }