/// <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));
        }
示例#3
0
        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));
        }