private async Task ValidateGiftCardAmountsAsync() { // grab every gift card that the customer applied to this order IList <GiftCard> appliedGiftCards = await _giftCardService.GetActiveGiftCardsAppliedByCustomerAsync(await _workContext.GetCurrentCustomerAsync()); if (appliedGiftCards.Count > 1) { throw new Exception("Only one gift card may be applied to an order"); } foreach (GiftCard nopGiftCard in appliedGiftCards) { // check isam to make sure each gift card has the right $$ GiftCard isamGiftCard = _isamGiftCardService.GetGiftCardInfo(nopGiftCard.GiftCardCouponCode).GiftCard; decimal nopAmtLeft = nopGiftCard.Amount; List <GiftCardUsageHistory> nopGcHistory = (await _giftCardService.GetGiftCardUsageHistoryAsync(nopGiftCard)).ToList(); foreach (var history in nopGcHistory) { nopAmtLeft -= history.UsedValue; } if (isamGiftCard.Amount != nopAmtLeft) { throw new Exception("A gift card has been used since it was placed on this order"); } } }
/// <summary> /// Prepare paged gift usage history card list model /// </summary> /// <param name="searchModel">Gift card usage history search model</param> /// <param name="giftCard">Gift card</param> /// <returns> /// A task that represents the asynchronous operation /// The task result contains the gift card usage history list model /// </returns> public virtual async Task <GiftCardUsageHistoryListModel> PrepareGiftCardUsageHistoryListModelAsync(GiftCardUsageHistorySearchModel searchModel, GiftCard giftCard) { if (searchModel == null) { throw new ArgumentNullException(nameof(searchModel)); } if (giftCard == null) { throw new ArgumentNullException(nameof(giftCard)); } //get gift card usage history var usageHistory = (await _giftCardService.GetGiftCardUsageHistoryAsync(giftCard)) .OrderByDescending(historyEntry => historyEntry.CreatedOnUtc).ToList() .ToPagedList(searchModel); //prepare list model var model = await new GiftCardUsageHistoryListModel().PrepareToGridAsync(searchModel, usageHistory, () => { return(usageHistory.SelectAwait(async historyEntry => { //fill in model values from the entity var giftCardUsageHistoryModel = historyEntry.ToModel <GiftCardUsageHistoryModel>(); //convert dates to the user time giftCardUsageHistoryModel.CreatedOn = await _dateTimeHelper.ConvertToUserTimeAsync(historyEntry.CreatedOnUtc, DateTimeKind.Utc); //fill in additional values (not existing in the entity) giftCardUsageHistoryModel.OrderId = historyEntry.UsedWithOrderId; giftCardUsageHistoryModel.CustomOrderNumber = (await _orderService.GetOrderByIdAsync(historyEntry.UsedWithOrderId))?.CustomOrderNumber; giftCardUsageHistoryModel.UsedValue = await _priceFormatter.FormatPriceAsync(historyEntry.UsedValue, true, false); return giftCardUsageHistoryModel; })); }); return(model); }
private async Task <(string GiftCardCode, decimal GiftCardUsage)> CalculateGiftCardAsync(Order order, decimal backendOrderTotal) { var giftCardCode = ""; decimal giftCardUsed = 0; var gcUsage = (await _giftCardService.GetGiftCardUsageHistoryAsync(order)).FirstOrDefault(); if (gcUsage != null) { giftCardCode = (await _giftCardService.GetGiftCardByIdAsync(gcUsage.GiftCardId)).GiftCardCouponCode.Substring(3); if (gcUsage.UsedValue >= backendOrderTotal) { giftCardUsed = backendOrderTotal; } else { giftCardUsed = gcUsage.UsedValue; } giftCardUsed = await _priceCalculationService.RoundPriceAsync(giftCardUsed); gcUsage.UsedValue -= giftCardUsed; } return(giftCardCode, giftCardUsed); }
/// <summary> /// Prepare the order details model /// </summary> /// <param name="order">Order</param> /// <returns> /// A task that represents the asynchronous operation /// The task result contains the order details model /// </returns> public virtual async Task <OrderDetailsModel> PrepareOrderDetailsModelAsync(Order order) { if (order == null) { throw new ArgumentNullException(nameof(order)); } var model = new OrderDetailsModel { Id = order.Id, CreatedOn = await _dateTimeHelper.ConvertToUserTimeAsync(order.CreatedOnUtc, DateTimeKind.Utc), OrderStatus = await _localizationService.GetLocalizedEnumAsync(order.OrderStatus), IsReOrderAllowed = _orderSettings.IsReOrderAllowed, IsReturnRequestAllowed = await _orderProcessingService.IsReturnRequestAllowedAsync(order), PdfInvoiceDisabled = _pdfSettings.DisablePdfInvoicesForPendingOrders && order.OrderStatus == OrderStatus.Pending, CustomOrderNumber = order.CustomOrderNumber, //shipping info ShippingStatus = await _localizationService.GetLocalizedEnumAsync(order.ShippingStatus) }; if (order.ShippingStatus != ShippingStatus.ShippingNotRequired) { model.IsShippable = true; model.PickupInStore = order.PickupInStore; if (!order.PickupInStore) { var shippingAddress = await _addressService.GetAddressByIdAsync(order.ShippingAddressId ?? 0); await _addressModelFactory.PrepareAddressModelAsync(model.ShippingAddress, address : shippingAddress, excludeProperties : false, addressSettings : _addressSettings); } else if (order.PickupAddressId.HasValue && await _addressService.GetAddressByIdAsync(order.PickupAddressId.Value) is Address pickupAddress) { model.PickupAddress = new AddressModel { Address1 = pickupAddress.Address1, City = pickupAddress.City, County = pickupAddress.County, StateProvinceName = await _stateProvinceService.GetStateProvinceByAddressAsync(pickupAddress) is StateProvince stateProvince ? await _localizationService.GetLocalizedAsync(stateProvince, entity => entity.Name) : string.Empty, CountryName = await _countryService.GetCountryByAddressAsync(pickupAddress) is Country country ? await _localizationService.GetLocalizedAsync(country, entity => entity.Name) : string.Empty, ZipPostalCode = pickupAddress.ZipPostalCode }; } model.ShippingMethod = order.ShippingMethod; //shipments (only already shipped or ready for pickup) var shipments = (await _shipmentService.GetShipmentsByOrderIdAsync(order.Id, !order.PickupInStore, order.PickupInStore)).OrderBy(x => x.CreatedOnUtc).ToList(); foreach (var shipment in shipments) { var shipmentModel = new OrderDetailsModel.ShipmentBriefModel { Id = shipment.Id, TrackingNumber = shipment.TrackingNumber, }; if (shipment.ShippedDateUtc.HasValue) { shipmentModel.ShippedDate = await _dateTimeHelper.ConvertToUserTimeAsync(shipment.ShippedDateUtc.Value, DateTimeKind.Utc); } if (shipment.ReadyForPickupDateUtc.HasValue) { shipmentModel.ReadyForPickupDate = await _dateTimeHelper.ConvertToUserTimeAsync(shipment.ReadyForPickupDateUtc.Value, DateTimeKind.Utc); } if (shipment.DeliveryDateUtc.HasValue) { shipmentModel.DeliveryDate = await _dateTimeHelper.ConvertToUserTimeAsync(shipment.DeliveryDateUtc.Value, DateTimeKind.Utc); } model.Shipments.Add(shipmentModel); } } var billingAddress = await _addressService.GetAddressByIdAsync(order.BillingAddressId); //billing info await _addressModelFactory.PrepareAddressModelAsync(model.BillingAddress, address : billingAddress, excludeProperties : false, addressSettings : _addressSettings); //VAT number model.VatNumber = order.VatNumber; var languageId = (await _workContext.GetWorkingLanguageAsync()).Id; //payment method var customer = await _customerService.GetCustomerByIdAsync(order.CustomerId); var paymentMethod = await _paymentPluginManager .LoadPluginBySystemNameAsync(order.PaymentMethodSystemName, customer, order.StoreId); model.PaymentMethod = paymentMethod != null ? await _localizationService.GetLocalizedFriendlyNameAsync(paymentMethod, languageId) : order.PaymentMethodSystemName; model.PaymentMethodStatus = await _localizationService.GetLocalizedEnumAsync(order.PaymentStatus); model.CanRePostProcessPayment = await _paymentService.CanRePostProcessPaymentAsync(order); //custom values model.CustomValues = _paymentService.DeserializeCustomValues(order); //order subtotal if (order.CustomerTaxDisplayType == TaxDisplayType.IncludingTax && !_taxSettings.ForceTaxExclusionFromOrderSubtotal) { //including tax //order subtotal var orderSubtotalInclTaxInCustomerCurrency = _currencyService.ConvertCurrency(order.OrderSubtotalInclTax, order.CurrencyRate); model.OrderSubtotal = await _priceFormatter.FormatPriceAsync(orderSubtotalInclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, languageId, true); model.OrderSubtotalValue = orderSubtotalInclTaxInCustomerCurrency; //discount (applied to order subtotal) var orderSubTotalDiscountInclTaxInCustomerCurrency = _currencyService.ConvertCurrency(order.OrderSubTotalDiscountInclTax, order.CurrencyRate); if (orderSubTotalDiscountInclTaxInCustomerCurrency > decimal.Zero) { model.OrderSubTotalDiscount = await _priceFormatter.FormatPriceAsync(-orderSubTotalDiscountInclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, languageId, true); model.OrderSubTotalDiscountValue = orderSubTotalDiscountInclTaxInCustomerCurrency; } } else { //excluding tax //order subtotal var orderSubtotalExclTaxInCustomerCurrency = _currencyService.ConvertCurrency(order.OrderSubtotalExclTax, order.CurrencyRate); model.OrderSubtotal = await _priceFormatter.FormatPriceAsync(orderSubtotalExclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, languageId, false); model.OrderSubtotalValue = orderSubtotalExclTaxInCustomerCurrency; //discount (applied to order subtotal) var orderSubTotalDiscountExclTaxInCustomerCurrency = _currencyService.ConvertCurrency(order.OrderSubTotalDiscountExclTax, order.CurrencyRate); if (orderSubTotalDiscountExclTaxInCustomerCurrency > decimal.Zero) { model.OrderSubTotalDiscount = await _priceFormatter.FormatPriceAsync(-orderSubTotalDiscountExclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, languageId, false); model.OrderSubTotalDiscountValue = orderSubTotalDiscountExclTaxInCustomerCurrency; } } if (order.CustomerTaxDisplayType == TaxDisplayType.IncludingTax) { //including tax //order shipping var orderShippingInclTaxInCustomerCurrency = _currencyService.ConvertCurrency(order.OrderShippingInclTax, order.CurrencyRate); model.OrderShipping = await _priceFormatter.FormatShippingPriceAsync(orderShippingInclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, languageId, true); model.OrderShippingValue = orderShippingInclTaxInCustomerCurrency; //payment method additional fee var paymentMethodAdditionalFeeInclTaxInCustomerCurrency = _currencyService.ConvertCurrency(order.PaymentMethodAdditionalFeeInclTax, order.CurrencyRate); if (paymentMethodAdditionalFeeInclTaxInCustomerCurrency > decimal.Zero) { model.PaymentMethodAdditionalFee = await _priceFormatter.FormatPaymentMethodAdditionalFeeAsync(paymentMethodAdditionalFeeInclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, languageId, true); model.PaymentMethodAdditionalFeeValue = paymentMethodAdditionalFeeInclTaxInCustomerCurrency; } } else { //excluding tax //order shipping var orderShippingExclTaxInCustomerCurrency = _currencyService.ConvertCurrency(order.OrderShippingExclTax, order.CurrencyRate); model.OrderShipping = await _priceFormatter.FormatShippingPriceAsync(orderShippingExclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, languageId, false); model.OrderShippingValue = orderShippingExclTaxInCustomerCurrency; //payment method additional fee var paymentMethodAdditionalFeeExclTaxInCustomerCurrency = _currencyService.ConvertCurrency(order.PaymentMethodAdditionalFeeExclTax, order.CurrencyRate); if (paymentMethodAdditionalFeeExclTaxInCustomerCurrency > decimal.Zero) { model.PaymentMethodAdditionalFee = await _priceFormatter.FormatPaymentMethodAdditionalFeeAsync(paymentMethodAdditionalFeeExclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, languageId, false); model.PaymentMethodAdditionalFeeValue = paymentMethodAdditionalFeeExclTaxInCustomerCurrency; } } //tax var displayTax = true; var displayTaxRates = true; if (_taxSettings.HideTaxInOrderSummary && order.CustomerTaxDisplayType == TaxDisplayType.IncludingTax) { displayTax = false; displayTaxRates = false; } else { if (order.OrderTax == 0 && _taxSettings.HideZeroTax) { displayTax = false; displayTaxRates = false; } else { var taxRates = _orderService.ParseTaxRates(order, order.TaxRates); displayTaxRates = _taxSettings.DisplayTaxRates && taxRates.Any(); displayTax = !displayTaxRates; var orderTaxInCustomerCurrency = _currencyService.ConvertCurrency(order.OrderTax, order.CurrencyRate); model.Tax = await _priceFormatter.FormatPriceAsync(orderTaxInCustomerCurrency, true, order.CustomerCurrencyCode, false, languageId); foreach (var tr in taxRates) { model.TaxRates.Add(new OrderDetailsModel.TaxRate { Rate = _priceFormatter.FormatTaxRate(tr.Key), Value = await _priceFormatter.FormatPriceAsync(_currencyService.ConvertCurrency(tr.Value, order.CurrencyRate), true, order.CustomerCurrencyCode, false, languageId), }); } } } model.DisplayTaxRates = displayTaxRates; model.DisplayTax = displayTax; model.DisplayTaxShippingInfo = _catalogSettings.DisplayTaxShippingInfoOrderDetailsPage; model.PricesIncludeTax = order.CustomerTaxDisplayType == TaxDisplayType.IncludingTax; //discount (applied to order total) var orderDiscountInCustomerCurrency = _currencyService.ConvertCurrency(order.OrderDiscount, order.CurrencyRate); if (orderDiscountInCustomerCurrency > decimal.Zero) { model.OrderTotalDiscount = await _priceFormatter.FormatPriceAsync(-orderDiscountInCustomerCurrency, true, order.CustomerCurrencyCode, false, languageId); model.OrderTotalDiscountValue = orderDiscountInCustomerCurrency; } //gift cards foreach (var gcuh in await _giftCardService.GetGiftCardUsageHistoryAsync(order)) { model.GiftCards.Add(new OrderDetailsModel.GiftCard { CouponCode = (await _giftCardService.GetGiftCardByIdAsync(gcuh.GiftCardId)).GiftCardCouponCode, Amount = await _priceFormatter.FormatPriceAsync(-(_currencyService.ConvertCurrency(gcuh.UsedValue, order.CurrencyRate)), true, order.CustomerCurrencyCode, false, languageId), }); } //reward points if (order.RedeemedRewardPointsEntryId.HasValue && await _rewardPointService.GetRewardPointsHistoryEntryByIdAsync(order.RedeemedRewardPointsEntryId.Value) is RewardPointsHistory redeemedRewardPointsEntry) { model.RedeemedRewardPoints = -redeemedRewardPointsEntry.Points; model.RedeemedRewardPointsAmount = await _priceFormatter.FormatPriceAsync(-(_currencyService.ConvertCurrency(redeemedRewardPointsEntry.UsedAmount, order.CurrencyRate)), true, order.CustomerCurrencyCode, false, languageId); } //total var orderTotalInCustomerCurrency = _currencyService.ConvertCurrency(order.OrderTotal, order.CurrencyRate); model.OrderTotal = await _priceFormatter.FormatPriceAsync(orderTotalInCustomerCurrency, true, order.CustomerCurrencyCode, false, languageId); model.OrderTotalValue = orderTotalInCustomerCurrency; //checkout attributes model.CheckoutAttributeInfo = order.CheckoutAttributeDescription; //order notes foreach (var orderNote in (await _orderService.GetOrderNotesByOrderIdAsync(order.Id, true)) .OrderByDescending(on => on.CreatedOnUtc) .ToList()) { model.OrderNotes.Add(new OrderDetailsModel.OrderNote { Id = orderNote.Id, HasDownload = orderNote.DownloadId > 0, Note = _orderService.FormatOrderNoteText(orderNote), CreatedOn = await _dateTimeHelper.ConvertToUserTimeAsync(orderNote.CreatedOnUtc, DateTimeKind.Utc) }); } //purchased products model.ShowSku = _catalogSettings.ShowSkuOnProductDetailsPage; model.ShowVendorName = _vendorSettings.ShowVendorOnOrderDetailsPage; var orderItems = await _orderService.GetOrderItemsAsync(order.Id); foreach (var orderItem in orderItems) { var product = await _productService.GetProductByIdAsync(orderItem.ProductId); var orderItemModel = new OrderDetailsModel.OrderItemModel { Id = orderItem.Id, OrderItemGuid = orderItem.OrderItemGuid, Sku = await _productService.FormatSkuAsync(product, orderItem.AttributesXml), VendorName = (await _vendorService.GetVendorByIdAsync(product.VendorId))?.Name ?? string.Empty, ProductId = product.Id, ProductName = await _localizationService.GetLocalizedAsync(product, x => x.Name), ProductSeName = await _urlRecordService.GetSeNameAsync(product), Quantity = orderItem.Quantity, AttributeInfo = orderItem.AttributeDescription, }; //rental info if (product.IsRental) { var rentalStartDate = orderItem.RentalStartDateUtc.HasValue ? _productService.FormatRentalDate(product, orderItem.RentalStartDateUtc.Value) : ""; var rentalEndDate = orderItem.RentalEndDateUtc.HasValue ? _productService.FormatRentalDate(product, orderItem.RentalEndDateUtc.Value) : ""; orderItemModel.RentalInfo = string.Format(await _localizationService.GetResourceAsync("Order.Rental.FormattedDate"), rentalStartDate, rentalEndDate); } model.Items.Add(orderItemModel); //unit price, subtotal if (order.CustomerTaxDisplayType == TaxDisplayType.IncludingTax) { //including tax var unitPriceInclTaxInCustomerCurrency = _currencyService.ConvertCurrency(orderItem.UnitPriceInclTax, order.CurrencyRate); orderItemModel.UnitPrice = await _priceFormatter.FormatPriceAsync(unitPriceInclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, languageId, true); orderItemModel.UnitPriceValue = unitPriceInclTaxInCustomerCurrency; var priceInclTaxInCustomerCurrency = _currencyService.ConvertCurrency(orderItem.PriceInclTax, order.CurrencyRate); orderItemModel.SubTotal = await _priceFormatter.FormatPriceAsync(priceInclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, languageId, true); orderItemModel.SubTotalValue = priceInclTaxInCustomerCurrency; } else { //excluding tax var unitPriceExclTaxInCustomerCurrency = _currencyService.ConvertCurrency(orderItem.UnitPriceExclTax, order.CurrencyRate); orderItemModel.UnitPrice = await _priceFormatter.FormatPriceAsync(unitPriceExclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, languageId, false); orderItemModel.UnitPriceValue = unitPriceExclTaxInCustomerCurrency; var priceExclTaxInCustomerCurrency = _currencyService.ConvertCurrency(orderItem.PriceExclTax, order.CurrencyRate); orderItemModel.SubTotal = await _priceFormatter.FormatPriceAsync(priceExclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, languageId, false); orderItemModel.SubTotalValue = priceExclTaxInCustomerCurrency; } //downloadable products if (await _orderService.IsDownloadAllowedAsync(orderItem)) { orderItemModel.DownloadId = product.DownloadId; } if (await _orderService.IsLicenseDownloadAllowedAsync(orderItem)) { orderItemModel.LicenseId = orderItem.LicenseDownloadId ?? 0; } } return(model); }
/// <summary> /// Inserts an entire order from nopcommerce into isam /// </summary> /// <param name="order"></param> public async Task InsertOrderAsync(Order order) { var shipToRows = await _yahooService.GetYahooShipToRowsAsync(order); foreach (var row in shipToRows) { InsertUsingService( SHIPTO_TABLE_NAME, _shiptoCols, _shiptoParams, row.ToStringValues() ); } var headerRows = await _yahooService.GetYahooHeaderRowsAsync(order); foreach (var row in headerRows) { InsertUsingService( HEADER_TABLE_NAME, _headerCols, _headerParams, row.ToStringValues() ); } var detailRows = await _yahooService.GetYahooDetailRowsAsync(order); foreach (var row in detailRows) { InsertUsingService( DETAIL_TABLE_NAME, _detailCols, _detailParams, row.ToStringValues() ); } _baseIsamService.ExecuteBatch(); // store amount used before insert order // insert order changes the amount in the object memory to properly calculate gift card amounts // for multiple orders decimal giftCardAmtUsed = 0; var giftCardUsageHistory = await _giftCardService.GetGiftCardUsageHistoryAsync(order); if (giftCardUsageHistory.Any()) { giftCardAmtUsed = giftCardUsageHistory.OrderByDescending(gcu => gcu.CreatedOnUtc).FirstOrDefault().UsedValue; } // if there is a gift card, update gift card amt in isam if (giftCardUsageHistory.Any()) { GiftCardUsageHistory orderGcUsage = giftCardUsageHistory.FirstOrDefault(); GiftCard orderGiftCard = await _giftCardService.GetGiftCardByIdAsync(orderGcUsage.GiftCardId); var isamGiftCardInfo = _isamGiftCardService.GetGiftCardInfo(orderGiftCard.GiftCardCouponCode); GiftCard isamGiftCard = isamGiftCardInfo.GiftCard; decimal isamGiftCardAmtUsed = isamGiftCardInfo.AmountUsed; _isamGiftCardService.UpdateGiftCardAmt(isamGiftCard, isamGiftCardAmtUsed + giftCardAmtUsed); await _giftCardUsageHistoryRepository.DeleteAsync(orderGcUsage); await _giftCardService.UpdateGiftCardAsync(orderGiftCard); } }