public void Can_save_and_load_orderItem_with_giftCard() { var orderItem = new OrderItem() { Order = GetTestOrder(), Product = GetTestProduct() }; orderItem.AssociatedGiftCards.Add(GetTestGiftCard()); var fromDb = SaveAndLoadEntity(orderItem); fromDb.ShouldNotBeNull(); fromDb.AssociatedGiftCards.ShouldNotBeNull(); (fromDb.AssociatedGiftCards.Count == 1).ShouldBeTrue(); fromDb.AssociatedGiftCards.First().Amount.ShouldEqual(10); }
public void Can_save_and_load_orderItem() { var orderItem = new OrderItem() { Order = GetTestOrder(), Product = GetTestProduct(), Quantity = 1, UnitPriceInclTax= 1.1M, UnitPriceExclTax = 2.1M, PriceInclTax = 3.1M, PriceExclTax = 4.1M, TaxRate = 19.0M, DiscountAmountInclTax = 5.1M, DiscountAmountExclTax = 6.1M, ProductCost = 7.1M, AttributeDescription= "AttributeDescription1", AttributesXml= "AttributesXml1", DownloadCount= 7, IsDownloadActivated=true, LicenseDownloadId= 8, ItemWeight = 9.87M }; var fromDb = SaveAndLoadEntity(orderItem); fromDb.ShouldNotBeNull(); fromDb.Order.ShouldNotBeNull(); fromDb.Product.ShouldNotBeNull(); fromDb.UnitPriceInclTax.ShouldEqual(1.1M); fromDb.UnitPriceExclTax.ShouldEqual(2.1M); fromDb.PriceInclTax.ShouldEqual(3.1M); fromDb.PriceExclTax.ShouldEqual(4.1M); fromDb.DiscountAmountInclTax.ShouldEqual(5.1M); fromDb.DiscountAmountExclTax.ShouldEqual(6.1M); fromDb.ProductCost.ShouldEqual(7.1M); fromDb.AttributeDescription.ShouldEqual("AttributeDescription1"); fromDb.AttributesXml.ShouldEqual("AttributesXml1"); fromDb.DownloadCount.ShouldEqual(7); fromDb.IsDownloadActivated.ShouldEqual(true); fromDb.LicenseDownloadId.ShouldEqual(8); fromDb.ItemWeight.ShouldEqual(9.87M); fromDb.Order.ShouldNotBeNull(); }
/// <summary> /// Delete an Order item /// </summary> /// <param name="orderItem">The Order item</param> public virtual void DeleteOrderItem(OrderItem orderItem) { if (orderItem == null) throw new ArgumentNullException("orderItem"); int orderId = orderItem.OrderId; _orderItemRepository.Delete(orderItem); //event notifications _eventPublisher.EntityDeleted(orderItem); var order = GetOrderById(orderId); _eventPublisher.PublishOrderUpdated(order); }
public virtual void AddReturnRequestTokens(IList<Token> tokens, ReturnRequest returnRequest, OrderItem orderItem) { tokens.Add(new Token("ReturnRequest.ID", returnRequest.Id.ToString())); tokens.Add(new Token("ReturnRequest.Product.Quantity", returnRequest.Quantity.ToString())); tokens.Add(new Token("ReturnRequest.Product.Name", orderItem.Product.Name)); tokens.Add(new Token("ReturnRequest.Reason", returnRequest.ReasonForReturn)); tokens.Add(new Token("ReturnRequest.RequestedAction", returnRequest.RequestedAction)); tokens.Add(new Token("ReturnRequest.CustomerComment", HtmlUtils.FormatText(returnRequest.CustomerComments, false, true, false, false, false, false), true)); tokens.Add(new Token("ReturnRequest.StaffNotes", HtmlUtils.FormatText(returnRequest.StaffNotes, false, true, false, false, false, false), true)); tokens.Add(new Token("ReturnRequest.Status", returnRequest.ReturnRequestStatus.GetLocalizedEnum(_localizationService, _workContext))); //event notification _eventPublisher.EntityTokensAdded(returnRequest, tokens); }
/// <summary> /// Places an order /// </summary> /// <param name="processPaymentRequest">Process payment request</param> /// <returns>Place order result</returns> public virtual PlaceOrderResult PlaceOrder(ProcessPaymentRequest processPaymentRequest, Dictionary<string, string> extraData) { //think about moving functionality of processing recurring orders (after the initial order was placed) to ProcessNextRecurringPayment() method if (processPaymentRequest == null) throw new ArgumentNullException("processPaymentRequest"); if (processPaymentRequest.OrderGuid == Guid.Empty) processPaymentRequest.OrderGuid = Guid.NewGuid(); var result = new PlaceOrderResult(); var utcNow = DateTime.UtcNow; try { #region Order details (customer, totals) //Recurring orders. Load initial order Order initialOrder = _orderService.GetOrderById(processPaymentRequest.InitialOrderId); if (processPaymentRequest.IsRecurringPayment) { if (initialOrder == null) throw new ArgumentException("Initial order is not set for recurring payment"); processPaymentRequest.PaymentMethodSystemName = initialOrder.PaymentMethodSystemName; } //customer var customer = _customerService.GetCustomerById(processPaymentRequest.CustomerId); if (customer == null) throw new ArgumentException("Customer is not set"); //affilites int affiliateId = 0; var affiliate = _affiliateService.GetAffiliateById(customer.AffiliateId); if (affiliate != null && affiliate.Active && !affiliate.Deleted) affiliateId = affiliate.Id; //customer currency string customerCurrencyCode = ""; decimal customerCurrencyRate = decimal.Zero; if (!processPaymentRequest.IsRecurringPayment) { var currencyTmp = _currencyService.GetCurrencyById(customer.GetAttribute<int>(SystemCustomerAttributeNames.CurrencyId, processPaymentRequest.StoreId)); var customerCurrency = (currencyTmp != null && currencyTmp.Published) ? currencyTmp : _workContext.WorkingCurrency; customerCurrencyCode = customerCurrency.CurrencyCode; var primaryStoreCurrency = _currencyService.GetCurrencyById(_currencySettings.PrimaryStoreCurrencyId); customerCurrencyRate = customerCurrency.Rate / primaryStoreCurrency.Rate; } else { customerCurrencyCode = initialOrder.CustomerCurrencyCode; customerCurrencyRate = initialOrder.CurrencyRate; } //customer language Language customerLanguage = null; if (!processPaymentRequest.IsRecurringPayment) { customerLanguage = _languageService.GetLanguageById(customer.GetAttribute<int>( SystemCustomerAttributeNames.LanguageId, processPaymentRequest.StoreId)); } else { customerLanguage = _languageService.GetLanguageById(initialOrder.CustomerLanguageId); } if (customerLanguage == null || !customerLanguage.Published) customerLanguage = _workContext.WorkingLanguage; //check whether customer is guest if (customer.IsGuest() && !_orderSettings.AnonymousCheckoutAllowed) throw new SmartException("Anonymous checkout is not allowed"); var storeId = _storeContext.CurrentStore.Id; //load and validate customer shopping cart IList<OrganizedShoppingCartItem> cart = null; if (!processPaymentRequest.IsRecurringPayment) { //load shopping cart cart = customer.GetCartItems(ShoppingCartType.ShoppingCart, processPaymentRequest.StoreId); if (cart.Count == 0) throw new SmartException("Cart is empty"); //validate the entire shopping cart var warnings = _shoppingCartService.GetShoppingCartWarnings(cart, customer.GetAttribute<string>(SystemCustomerAttributeNames.CheckoutAttributes), true); if (warnings.Count > 0) { var warningsSb = new StringBuilder(); foreach (string warning in warnings) { warningsSb.Append(warning); warningsSb.Append(";"); } throw new SmartException(warningsSb.ToString()); } //validate individual cart items foreach (var sci in cart) { var sciWarnings = _shoppingCartService.GetShoppingCartItemWarnings(customer, sci.Item.ShoppingCartType, sci.Item.Product, processPaymentRequest.StoreId, sci.Item.AttributesXml, sci.Item.CustomerEnteredPrice, sci.Item.Quantity, false, childItems: sci.ChildItems); if (sciWarnings.Count > 0) { var warningsSb = new StringBuilder(); foreach (string warning in sciWarnings) { warningsSb.Append(warning); warningsSb.Append(";"); } throw new SmartException(warningsSb.ToString()); } } } //min totals validation if (!processPaymentRequest.IsRecurringPayment) { bool minOrderSubtotalAmountOk = ValidateMinOrderSubtotalAmount(cart); if (!minOrderSubtotalAmountOk) { decimal minOrderSubtotalAmount = _currencyService.ConvertFromPrimaryStoreCurrency(_orderSettings.MinOrderSubtotalAmount, _workContext.WorkingCurrency); throw new SmartException(string.Format(_localizationService.GetResource("Checkout.MinOrderSubtotalAmount"), _priceFormatter.FormatPrice(minOrderSubtotalAmount, true, false))); } bool minOrderTotalAmountOk = ValidateMinOrderTotalAmount(cart); if (!minOrderTotalAmountOk) { decimal minOrderTotalAmount = _currencyService.ConvertFromPrimaryStoreCurrency(_orderSettings.MinOrderTotalAmount, _workContext.WorkingCurrency); throw new SmartException(string.Format(_localizationService.GetResource("Checkout.MinOrderTotalAmount"), _priceFormatter.FormatPrice(minOrderTotalAmount, true, false))); } } //tax display type var customerTaxDisplayType = TaxDisplayType.IncludingTax; if (!processPaymentRequest.IsRecurringPayment) { customerTaxDisplayType = _workContext.GetTaxDisplayTypeFor(customer, processPaymentRequest.StoreId); } else { customerTaxDisplayType = initialOrder.CustomerTaxDisplayType; } //checkout attributes string checkoutAttributeDescription, checkoutAttributesXml; if (!processPaymentRequest.IsRecurringPayment) { checkoutAttributesXml = customer.GetAttribute<string>(SystemCustomerAttributeNames.CheckoutAttributes); checkoutAttributeDescription = _checkoutAttributeFormatter.FormatAttributes(checkoutAttributesXml, customer); } else { checkoutAttributesXml = initialOrder.CheckoutAttributesXml; checkoutAttributeDescription = initialOrder.CheckoutAttributeDescription; } //applied discount (used to store discount usage history) var appliedDiscounts = new List<Discount>(); //sub total decimal orderSubTotalInclTax, orderSubTotalExclTax; decimal orderSubTotalDiscountInclTax = 0, orderSubTotalDiscountExclTax = 0; if (!processPaymentRequest.IsRecurringPayment) { //sub total (incl tax) decimal orderSubTotalDiscountAmount1 = decimal.Zero; Discount orderSubTotalAppliedDiscount1 = null; decimal subTotalWithoutDiscountBase1 = decimal.Zero; decimal subTotalWithDiscountBase1 = decimal.Zero; _orderTotalCalculationService.GetShoppingCartSubTotal(cart, true, out orderSubTotalDiscountAmount1, out orderSubTotalAppliedDiscount1, out subTotalWithoutDiscountBase1, out subTotalWithDiscountBase1); orderSubTotalInclTax = subTotalWithoutDiscountBase1; orderSubTotalDiscountInclTax = orderSubTotalDiscountAmount1; //discount history if (orderSubTotalAppliedDiscount1 != null && !appliedDiscounts.ContainsDiscount(orderSubTotalAppliedDiscount1)) appliedDiscounts.Add(orderSubTotalAppliedDiscount1); //sub total (excl tax) decimal orderSubTotalDiscountAmount2 = decimal.Zero; Discount orderSubTotalAppliedDiscount2 = null; decimal subTotalWithoutDiscountBase2 = decimal.Zero; decimal subTotalWithDiscountBase2 = decimal.Zero; _orderTotalCalculationService.GetShoppingCartSubTotal(cart, false, out orderSubTotalDiscountAmount2, out orderSubTotalAppliedDiscount2, out subTotalWithoutDiscountBase2, out subTotalWithDiscountBase2); orderSubTotalExclTax = subTotalWithoutDiscountBase2; orderSubTotalDiscountExclTax = orderSubTotalDiscountAmount2; } else { orderSubTotalInclTax = initialOrder.OrderSubtotalInclTax; orderSubTotalExclTax = initialOrder.OrderSubtotalExclTax; } //shipping info bool shoppingCartRequiresShipping = false; if (!processPaymentRequest.IsRecurringPayment) { shoppingCartRequiresShipping = cart.RequiresShipping(); } else { shoppingCartRequiresShipping = initialOrder.ShippingStatus != ShippingStatus.ShippingNotRequired; } string shippingMethodName = "", shippingRateComputationMethodSystemName = ""; if (shoppingCartRequiresShipping) { if (!processPaymentRequest.IsRecurringPayment) { var shippingOption = customer.GetAttribute<ShippingOption>(SystemCustomerAttributeNames.SelectedShippingOption, processPaymentRequest.StoreId); if (shippingOption != null) { shippingMethodName = shippingOption.Name; shippingRateComputationMethodSystemName = shippingOption.ShippingRateComputationMethodSystemName; } } else { shippingMethodName = initialOrder.ShippingMethod; shippingRateComputationMethodSystemName = initialOrder.ShippingRateComputationMethodSystemName; } } //shipping total decimal? orderShippingTotalInclTax, orderShippingTotalExclTax = null; if (!processPaymentRequest.IsRecurringPayment) { decimal taxRate = decimal.Zero; Discount shippingTotalDiscount = null; orderShippingTotalInclTax = _orderTotalCalculationService.GetShoppingCartShippingTotal(cart, true, out taxRate, out shippingTotalDiscount); orderShippingTotalExclTax = _orderTotalCalculationService.GetShoppingCartShippingTotal(cart, false); if (!orderShippingTotalInclTax.HasValue || !orderShippingTotalExclTax.HasValue) throw new SmartException("Shipping total couldn't be calculated"); if (shippingTotalDiscount != null && !appliedDiscounts.ContainsDiscount(shippingTotalDiscount)) appliedDiscounts.Add(shippingTotalDiscount); } else { orderShippingTotalInclTax = initialOrder.OrderShippingInclTax; orderShippingTotalExclTax = initialOrder.OrderShippingExclTax; } //payment total decimal paymentAdditionalFeeInclTax, paymentAdditionalFeeExclTax; if (!processPaymentRequest.IsRecurringPayment) { decimal paymentAdditionalFee = _paymentService.GetAdditionalHandlingFee(cart, processPaymentRequest.PaymentMethodSystemName); paymentAdditionalFeeInclTax = _taxService.GetPaymentMethodAdditionalFee(paymentAdditionalFee, true, customer); paymentAdditionalFeeExclTax = _taxService.GetPaymentMethodAdditionalFee(paymentAdditionalFee, false, customer); } else { paymentAdditionalFeeInclTax = initialOrder.PaymentMethodAdditionalFeeInclTax; paymentAdditionalFeeExclTax = initialOrder.PaymentMethodAdditionalFeeExclTax; } //tax total decimal orderTaxTotal = decimal.Zero; string vatNumber = "", taxRates = ""; if (!processPaymentRequest.IsRecurringPayment) { //tax amount SortedDictionary<decimal, decimal> taxRatesDictionary = null; orderTaxTotal = _orderTotalCalculationService.GetTaxTotal(cart, out taxRatesDictionary); //VAT number var customerVatStatus = (VatNumberStatus)customer.GetAttribute<int>(SystemCustomerAttributeNames.VatNumberStatusId); if (_taxSettings.EuVatEnabled && customerVatStatus == VatNumberStatus.Valid) vatNumber = customer.GetAttribute<string>(SystemCustomerAttributeNames.VatNumber); //tax rates foreach (var kvp in taxRatesDictionary) { var taxRate = kvp.Key; var taxValue = kvp.Value; taxRates += string.Format("{0}:{1}; ", taxRate.ToString(CultureInfo.InvariantCulture), taxValue.ToString(CultureInfo.InvariantCulture)); } } else { orderTaxTotal = initialOrder.OrderTax; //VAT number vatNumber = initialOrder.VatNumber; } processPaymentRequest.OrderTax = orderTaxTotal; //order total (and applied discounts, gift cards, reward points) decimal? orderTotal = null; decimal orderDiscountAmount = decimal.Zero; List<AppliedGiftCard> appliedGiftCards = null; int redeemedRewardPoints = 0; decimal redeemedRewardPointsAmount = decimal.Zero; if (!processPaymentRequest.IsRecurringPayment) { Discount orderAppliedDiscount = null; orderTotal = _orderTotalCalculationService.GetShoppingCartTotal(cart, out orderDiscountAmount, out orderAppliedDiscount, out appliedGiftCards, out redeemedRewardPoints, out redeemedRewardPointsAmount); if (!orderTotal.HasValue) throw new SmartException("Order total couldn't be calculated"); //discount history if (orderAppliedDiscount != null && !appliedDiscounts.ContainsDiscount(orderAppliedDiscount)) appliedDiscounts.Add(orderAppliedDiscount); } else { orderDiscountAmount = initialOrder.OrderDiscount; orderTotal = initialOrder.OrderTotal; } processPaymentRequest.OrderTotal = orderTotal.Value; #endregion #region Addresses & pre payment workflow // give payment processor the opportunity to fullfill billing address var preProcessPaymentResult = _paymentService.PreProcessPayment(processPaymentRequest); if (!preProcessPaymentResult.Success) { foreach (var paymentError in preProcessPaymentResult.Errors) { result.AddError(string.Format("Payment error: {0}", paymentError)); } throw new SmartException("Error while pre-processing the payment"); } Address billingAddress = null; if (!processPaymentRequest.IsRecurringPayment) { if (customer.BillingAddress == null) throw new SmartException("Billing address is not provided"); if (!customer.BillingAddress.Email.IsEmail()) throw new SmartException("Email is not valid"); billingAddress = (Address)customer.BillingAddress.Clone(); } else { if (initialOrder.BillingAddress == null) throw new SmartException("Billing address is not available"); billingAddress = (Address)initialOrder.BillingAddress.Clone(); } if (billingAddress.Country != null && !billingAddress.Country.AllowsBilling) throw new SmartException(string.Format("Country '{0}' is not allowed for billing", billingAddress.Country.Name)); Address shippingAddress = null; if (shoppingCartRequiresShipping) { if (!processPaymentRequest.IsRecurringPayment) { if (customer.ShippingAddress == null) throw new SmartException("Shipping address is not provided"); if (!customer.ShippingAddress.Email.IsEmail()) throw new SmartException("Email is not valid"); shippingAddress = (Address)customer.ShippingAddress.Clone(); } else { if (initialOrder.ShippingAddress == null) throw new SmartException("Shipping address is not available"); shippingAddress = (Address)initialOrder.ShippingAddress.Clone(); } if (shippingAddress.Country != null && !shippingAddress.Country.AllowsShipping) throw new SmartException(string.Format("Country '{0}' is not allowed for shipping", shippingAddress.Country.Name)); } #endregion #region Payment workflow //skip payment workflow if order total equals zero bool skipPaymentWorkflow = false; if (orderTotal.Value == decimal.Zero) skipPaymentWorkflow = true; //payment workflow Provider<IPaymentMethod> paymentMethod = null; if (!skipPaymentWorkflow) { paymentMethod = _paymentService.LoadPaymentMethodBySystemName(processPaymentRequest.PaymentMethodSystemName); if (paymentMethod == null) throw new SmartException("Payment method couldn't be loaded"); //ensure that payment method is active if (!paymentMethod.IsPaymentMethodActive(_paymentSettings)) throw new SmartException("Payment method is not active"); } else processPaymentRequest.PaymentMethodSystemName = ""; //recurring or standard shopping cart? bool isRecurringShoppingCart = false; if (!processPaymentRequest.IsRecurringPayment) { isRecurringShoppingCart = cart.IsRecurring(); if (isRecurringShoppingCart) { int recurringCycleLength = 0; RecurringProductCyclePeriod recurringCyclePeriod; int recurringTotalCycles = 0; string recurringCyclesError = cart.GetRecurringCycleInfo(_localizationService, out recurringCycleLength, out recurringCyclePeriod, out recurringTotalCycles); if (!string.IsNullOrEmpty(recurringCyclesError)) throw new SmartException(recurringCyclesError); processPaymentRequest.RecurringCycleLength = recurringCycleLength; processPaymentRequest.RecurringCyclePeriod = recurringCyclePeriod; processPaymentRequest.RecurringTotalCycles = recurringTotalCycles; } } else { isRecurringShoppingCart = true; } //process payment ProcessPaymentResult processPaymentResult = null; if (!skipPaymentWorkflow) { if (!processPaymentRequest.IsRecurringPayment) { if (isRecurringShoppingCart) { //recurring cart var recurringPaymentType = _paymentService.GetRecurringPaymentType(processPaymentRequest.PaymentMethodSystemName); switch (recurringPaymentType) { case RecurringPaymentType.NotSupported: throw new SmartException("Recurring payments are not supported by selected payment method"); case RecurringPaymentType.Manual: case RecurringPaymentType.Automatic: processPaymentResult = _paymentService.ProcessRecurringPayment(processPaymentRequest); break; default: throw new SmartException("Not supported recurring payment type"); } } else { //standard cart processPaymentResult = _paymentService.ProcessPayment(processPaymentRequest); } } else { if (isRecurringShoppingCart) { //Old credit card info processPaymentRequest.CreditCardType = initialOrder.AllowStoringCreditCardNumber ? _encryptionService.DecryptText(initialOrder.CardType) : ""; processPaymentRequest.CreditCardName = initialOrder.AllowStoringCreditCardNumber ? _encryptionService.DecryptText(initialOrder.CardName) : ""; processPaymentRequest.CreditCardNumber = initialOrder.AllowStoringCreditCardNumber ? _encryptionService.DecryptText(initialOrder.CardNumber) : ""; //MaskedCreditCardNumber processPaymentRequest.CreditCardCvv2 = initialOrder.AllowStoringCreditCardNumber ? _encryptionService.DecryptText(initialOrder.CardCvv2) : ""; try { processPaymentRequest.CreditCardExpireMonth = initialOrder.AllowStoringCreditCardNumber ? Convert.ToInt32(_encryptionService.DecryptText(initialOrder.CardExpirationMonth)) : 0; processPaymentRequest.CreditCardExpireYear = initialOrder.AllowStoringCreditCardNumber ? Convert.ToInt32(_encryptionService.DecryptText(initialOrder.CardExpirationYear)) : 0; } catch {} var recurringPaymentType = _paymentService.GetRecurringPaymentType(processPaymentRequest.PaymentMethodSystemName); switch (recurringPaymentType) { case RecurringPaymentType.NotSupported: throw new SmartException("Recurring payments are not supported by selected payment method"); case RecurringPaymentType.Manual: processPaymentResult = _paymentService.ProcessRecurringPayment(processPaymentRequest); break; case RecurringPaymentType.Automatic: //payment is processed on payment gateway site processPaymentResult = new ProcessPaymentResult(); break; default: throw new SmartException("Not supported recurring payment type"); } } else { throw new SmartException("No recurring products"); } } } else { //payment is not required if (processPaymentResult == null) processPaymentResult = new ProcessPaymentResult(); processPaymentResult.NewPaymentStatus = PaymentStatus.Paid; } if (processPaymentResult == null) throw new SmartException("processPaymentResult is not available"); #endregion if (processPaymentResult.Success) { //save order in data storage //uncomment this line to support transactions //using (var scope = new System.Transactions.TransactionScope()) { #region Save order details var shippingStatus = ShippingStatus.NotYetShipped; if (!shoppingCartRequiresShipping) shippingStatus = ShippingStatus.ShippingNotRequired; var order = new Order() { StoreId = processPaymentRequest.StoreId, OrderGuid = processPaymentRequest.OrderGuid, CustomerId = customer.Id, CustomerLanguageId = customerLanguage.Id, CustomerTaxDisplayType = customerTaxDisplayType, CustomerIp = _webHelper.GetCurrentIpAddress(), OrderSubtotalInclTax = orderSubTotalInclTax, OrderSubtotalExclTax = orderSubTotalExclTax, OrderSubTotalDiscountInclTax = orderSubTotalDiscountInclTax, OrderSubTotalDiscountExclTax = orderSubTotalDiscountExclTax, OrderShippingInclTax = orderShippingTotalInclTax.Value, OrderShippingExclTax = orderShippingTotalExclTax.Value, PaymentMethodAdditionalFeeInclTax = paymentAdditionalFeeInclTax, PaymentMethodAdditionalFeeExclTax = paymentAdditionalFeeExclTax, TaxRates = taxRates, OrderTax = orderTaxTotal, OrderTotal = orderTotal.Value, RefundedAmount = decimal.Zero, OrderDiscount = orderDiscountAmount, CheckoutAttributeDescription = checkoutAttributeDescription, CheckoutAttributesXml = checkoutAttributesXml, CustomerCurrencyCode = customerCurrencyCode, CurrencyRate = customerCurrencyRate, AffiliateId = affiliateId, OrderStatus = OrderStatus.Pending, AllowStoringCreditCardNumber = processPaymentResult.AllowStoringCreditCardNumber, CardType = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardType) : string.Empty, CardName = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardName) : string.Empty, CardNumber = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardNumber) : string.Empty, MaskedCreditCardNumber = _encryptionService.EncryptText(_paymentService.GetMaskedCreditCardNumber(processPaymentRequest.CreditCardNumber)), CardCvv2 = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardCvv2) : string.Empty, CardExpirationMonth = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardExpireMonth.ToString()) : string.Empty, CardExpirationYear = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardExpireYear.ToString()) : string.Empty, AllowStoringDirectDebit = processPaymentResult.AllowStoringDirectDebit, DirectDebitAccountHolder = processPaymentResult.AllowStoringDirectDebit ? _encryptionService.EncryptText(processPaymentRequest.DirectDebitAccountHolder) : string.Empty, DirectDebitAccountNumber = processPaymentResult.AllowStoringDirectDebit ? _encryptionService.EncryptText(processPaymentRequest.DirectDebitAccountNumber) : string.Empty, DirectDebitBankCode = processPaymentResult.AllowStoringDirectDebit ? _encryptionService.EncryptText(processPaymentRequest.DirectDebitBankCode) : string.Empty, DirectDebitBankName = processPaymentResult.AllowStoringDirectDebit ? _encryptionService.EncryptText(processPaymentRequest.DirectDebitBankName) : string.Empty, DirectDebitBIC = processPaymentResult.AllowStoringDirectDebit ? _encryptionService.EncryptText(processPaymentRequest.DirectDebitBic) : string.Empty, DirectDebitCountry = processPaymentResult.AllowStoringDirectDebit ? _encryptionService.EncryptText(processPaymentRequest.DirectDebitCountry) : string.Empty, DirectDebitIban = processPaymentResult.AllowStoringDirectDebit ? _encryptionService.EncryptText(processPaymentRequest.DirectDebitIban) : string.Empty, PaymentMethodSystemName = processPaymentRequest.PaymentMethodSystemName, AuthorizationTransactionId = processPaymentResult.AuthorizationTransactionId, AuthorizationTransactionCode = processPaymentResult.AuthorizationTransactionCode, AuthorizationTransactionResult = processPaymentResult.AuthorizationTransactionResult, CaptureTransactionId = processPaymentResult.CaptureTransactionId, CaptureTransactionResult = processPaymentResult.CaptureTransactionResult, SubscriptionTransactionId = processPaymentResult.SubscriptionTransactionId, PurchaseOrderNumber = processPaymentRequest.PurchaseOrderNumber, PaymentStatus = processPaymentResult.NewPaymentStatus, PaidDateUtc = null, BillingAddress = billingAddress, ShippingAddress = shippingAddress, ShippingStatus = shippingStatus, ShippingMethod = shippingMethodName, ShippingRateComputationMethodSystemName = shippingRateComputationMethodSystemName, VatNumber = vatNumber, CreatedOnUtc = utcNow, UpdatedOnUtc = utcNow, CustomerOrderComment = extraData.ContainsKey("CustomerComment") ? extraData["CustomerComment"] : "" }; _orderService.InsertOrder(order); result.PlacedOrder = order; if (!processPaymentRequest.IsRecurringPayment) { //move shopping cart items to order products foreach (var sc in cart) { //prices decimal taxRate = decimal.Zero; decimal scUnitPrice = _priceCalculationService.GetUnitPrice(sc, true); decimal scSubTotal = _priceCalculationService.GetSubTotal(sc, true); decimal scUnitPriceInclTax = _taxService.GetProductPrice(sc.Item.Product, scUnitPrice, true, customer, out taxRate); decimal scUnitPriceExclTax = _taxService.GetProductPrice(sc.Item.Product, scUnitPrice, false, customer, out taxRate); decimal scSubTotalInclTax = _taxService.GetProductPrice(sc.Item.Product, scSubTotal, true, customer, out taxRate); decimal scSubTotalExclTax = _taxService.GetProductPrice(sc.Item.Product, scSubTotal, false, customer, out taxRate); //discounts Discount scDiscount = null; decimal discountAmount = _priceCalculationService.GetDiscountAmount(sc, out scDiscount); decimal discountAmountInclTax = _taxService.GetProductPrice(sc.Item.Product, discountAmount, true, customer, out taxRate); decimal discountAmountExclTax = _taxService.GetProductPrice(sc.Item.Product, discountAmount, false, customer, out taxRate); if (scDiscount != null && !appliedDiscounts.ContainsDiscount(scDiscount)) appliedDiscounts.Add(scDiscount); //attributes string attributeDescription = _productAttributeFormatter.FormatAttributes(sc.Item.Product, sc.Item.AttributesXml, customer); var itemWeight = _shippingService.GetShoppingCartItemWeight(sc); //save order item var orderItem = new OrderItem() { OrderItemGuid = Guid.NewGuid(), Order = order, ProductId = sc.Item.ProductId, UnitPriceInclTax = scUnitPriceInclTax, UnitPriceExclTax = scUnitPriceExclTax, PriceInclTax = scSubTotalInclTax, PriceExclTax = scSubTotalExclTax, AttributeDescription = attributeDescription, AttributesXml = sc.Item.AttributesXml, Quantity = sc.Item.Quantity, DiscountAmountInclTax = discountAmountInclTax, DiscountAmountExclTax = discountAmountExclTax, DownloadCount = 0, IsDownloadActivated = false, LicenseDownloadId = 0, ItemWeight = itemWeight, ProductCost = _priceCalculationService.GetProductCost(sc.Item.Product, sc.Item.AttributesXml) }; if (sc.Item.Product.ProductType == ProductType.BundledProduct && sc.ChildItems != null) { var listBundleData = new List<ProductBundleItemOrderData>(); foreach (var childItem in sc.ChildItems) { decimal bundleItemSubTotal = _taxService.GetProductPrice(childItem.Item.Product, _priceCalculationService.GetSubTotal(childItem, true), out taxRate); string attributesInfo = _productAttributeFormatter.FormatAttributes(childItem.Item.Product, childItem.Item.AttributesXml, order.Customer, renderPrices: false, allowHyperlinks: false); childItem.BundleItemData.ToOrderData(listBundleData, bundleItemSubTotal, childItem.Item.AttributesXml, attributesInfo); } orderItem.SetBundleData(listBundleData); } order.OrderItems.Add(orderItem); _orderService.UpdateOrder(order); //gift cards if (sc.Item.Product.IsGiftCard) { string giftCardRecipientName, giftCardRecipientEmail, giftCardSenderName, giftCardSenderEmail, giftCardMessage; _productAttributeParser.GetGiftCardAttribute(sc.Item.AttributesXml, out giftCardRecipientName, out giftCardRecipientEmail, out giftCardSenderName, out giftCardSenderEmail, out giftCardMessage); for (int i = 0; i < sc.Item.Quantity; i++) { var gc = new GiftCard() { GiftCardType = sc.Item.Product.GiftCardType, PurchasedWithOrderItem = orderItem, Amount = scUnitPriceExclTax, IsGiftCardActivated = false, GiftCardCouponCode = _giftCardService.GenerateGiftCardCode(), RecipientName = giftCardRecipientName, RecipientEmail = giftCardRecipientEmail, SenderName = giftCardSenderName, SenderEmail = giftCardSenderEmail, Message = giftCardMessage, IsRecipientNotified = false, CreatedOnUtc = utcNow }; _giftCardService.InsertGiftCard(gc); } } //inventory _productService.AdjustInventory(sc, true); } //clear shopping cart cart.ToList().ForEach(sci => _shoppingCartService.DeleteShoppingCartItem(sci.Item, false)); } else { //recurring payment var initialOrderItems = initialOrder.OrderItems; foreach (var orderItem in initialOrderItems) { //save item var newOrderItem = new OrderItem() { OrderItemGuid = Guid.NewGuid(), Order = order, ProductId = orderItem.ProductId, UnitPriceInclTax = orderItem.UnitPriceInclTax, UnitPriceExclTax = orderItem.UnitPriceExclTax, PriceInclTax = orderItem.PriceInclTax, PriceExclTax = orderItem.PriceExclTax, AttributeDescription = orderItem.AttributeDescription, AttributesXml = orderItem.AttributesXml, Quantity = orderItem.Quantity, DiscountAmountInclTax = orderItem.DiscountAmountInclTax, DiscountAmountExclTax = orderItem.DiscountAmountExclTax, DownloadCount = 0, IsDownloadActivated = false, LicenseDownloadId = 0, ItemWeight = orderItem.ItemWeight, BundleData = orderItem.BundleData, ProductCost = orderItem.ProductCost }; order.OrderItems.Add(newOrderItem); _orderService.UpdateOrder(order); //gift cards if (orderItem.Product.IsGiftCard) { string giftCardRecipientName, giftCardRecipientEmail, giftCardSenderName, giftCardSenderEmail, giftCardMessage; _productAttributeParser.GetGiftCardAttribute(orderItem.AttributesXml, out giftCardRecipientName, out giftCardRecipientEmail, out giftCardSenderName, out giftCardSenderEmail, out giftCardMessage); for (int i = 0; i < orderItem.Quantity; i++) { var gc = new GiftCard() { GiftCardType = orderItem.Product.GiftCardType, PurchasedWithOrderItem = newOrderItem, Amount = orderItem.UnitPriceExclTax, IsGiftCardActivated = false, GiftCardCouponCode = _giftCardService.GenerateGiftCardCode(), RecipientName = giftCardRecipientName, RecipientEmail = giftCardRecipientEmail, SenderName = giftCardSenderName, SenderEmail = giftCardSenderEmail, Message = giftCardMessage, IsRecipientNotified = false, CreatedOnUtc = utcNow }; _giftCardService.InsertGiftCard(gc); } } //inventory _productService.AdjustInventory(orderItem, true, orderItem.Quantity); } } //discount usage history if (!processPaymentRequest.IsRecurringPayment) { foreach (var discount in appliedDiscounts) { var duh = new DiscountUsageHistory() { Discount = discount, Order = order, CreatedOnUtc = utcNow }; _discountService.InsertDiscountUsageHistory(duh); } } //gift card usage history if (!processPaymentRequest.IsRecurringPayment && appliedGiftCards != null) { foreach (var agc in appliedGiftCards) { decimal amountUsed = agc.AmountCanBeUsed; var gcuh = new GiftCardUsageHistory() { GiftCard = agc.GiftCard, UsedWithOrder = order, UsedValue = amountUsed, CreatedOnUtc = utcNow }; agc.GiftCard.GiftCardUsageHistory.Add(gcuh); _giftCardService.UpdateGiftCard(agc.GiftCard); } } //reward points history if (redeemedRewardPointsAmount > decimal.Zero) { customer.AddRewardPointsHistoryEntry(-redeemedRewardPoints, string.Format(_localizationService.GetResource("RewardPoints.Message.RedeemedForOrder", order.CustomerLanguageId), order.GetOrderNumber()), order, redeemedRewardPointsAmount); _customerService.UpdateCustomer(customer); } //recurring orders if (!processPaymentRequest.IsRecurringPayment && isRecurringShoppingCart) { //create recurring payment (the first payment) var rp = new RecurringPayment() { CycleLength = processPaymentRequest.RecurringCycleLength, CyclePeriod = processPaymentRequest.RecurringCyclePeriod, TotalCycles = processPaymentRequest.RecurringTotalCycles, StartDateUtc = utcNow, IsActive = true, CreatedOnUtc = utcNow, InitialOrder = order, }; _orderService.InsertRecurringPayment(rp); var recurringPaymentType = _paymentService.GetRecurringPaymentType(processPaymentRequest.PaymentMethodSystemName); switch (recurringPaymentType) { case RecurringPaymentType.NotSupported: { //not supported } break; case RecurringPaymentType.Manual: { //first payment var rph = new RecurringPaymentHistory() { RecurringPayment = rp, CreatedOnUtc = utcNow, OrderId = order.Id, }; rp.RecurringPaymentHistory.Add(rph); _orderService.UpdateRecurringPayment(rp); } break; case RecurringPaymentType.Automatic: { //will be created later (process is automated) } break; default: break; } } #endregion #region Notifications, notes and attributes //notes, messages order.OrderNotes.Add(new OrderNote() { Note = T("OrderPlaced"), DisplayToCustomer = false, CreatedOnUtc = utcNow }); _orderService.UpdateOrder(order); //send email notifications int orderPlacedStoreOwnerNotificationQueuedEmailId = _workflowMessageService.SendOrderPlacedStoreOwnerNotification(order, _localizationSettings.DefaultAdminLanguageId); if (orderPlacedStoreOwnerNotificationQueuedEmailId > 0) { order.OrderNotes.Add(new OrderNote() { Note = string.Format(T("MerchantEmailQueued"), orderPlacedStoreOwnerNotificationQueuedEmailId), DisplayToCustomer = false, CreatedOnUtc = utcNow }); _orderService.UpdateOrder(order); } int orderPlacedCustomerNotificationQueuedEmailId = _workflowMessageService.SendOrderPlacedCustomerNotification(order, order.CustomerLanguageId); if (orderPlacedCustomerNotificationQueuedEmailId > 0) { order.OrderNotes.Add(new OrderNote() { Note = string.Format(T("CustomerEmailQueued"), orderPlacedCustomerNotificationQueuedEmailId), DisplayToCustomer = false, CreatedOnUtc = utcNow }); _orderService.UpdateOrder(order); } //check order status CheckOrderStatus(order); //reset checkout data if (!processPaymentRequest.IsRecurringPayment) _customerService.ResetCheckoutData(customer, processPaymentRequest.StoreId, clearCouponCodes: true, clearCheckoutAttributes: true); // check for generic attributes to be inserted automatically foreach (var customProperty in processPaymentRequest.CustomProperties.Where(x => x.Key.HasValue() && x.Value.AutoCreateGenericAttribute)) { _genericAttributeService.SaveAttribute<object>(order, customProperty.Key, customProperty.Value.Value, order.StoreId); } //uncomment this line to support transactions //scope.Complete(); //raise event _eventPublisher.PublishOrderPlaced(order); if (!processPaymentRequest.IsRecurringPayment) { _customerActivityService.InsertActivity( "PublicStore.PlaceOrder", _localizationService.GetResource("ActivityLog.PublicStore.PlaceOrder"), order.GetOrderNumber()); } //raise event if (order.PaymentStatus == PaymentStatus.Paid) { _eventPublisher.PublishOrderPaid(order); } #endregion } } else { foreach (var paymentError in processPaymentResult.Errors) result.AddError(paymentError); } } catch (Exception exc) { _logger.Error(exc.Message, exc); result.AddError(exc.Message); } #region Process errors string error = ""; for (int i = 0; i < result.Errors.Count; i++) { error += string.Format("Error {0}: {1}", i + 1, result.Errors[i]); if (i != result.Errors.Count - 1) error += ". "; } if (!String.IsNullOrEmpty(error)) { //log it string logError = string.Format("Error while placing order. {0}", error); _logger.Error(logError); } #endregion return result; }
/// <summary> /// Sends 'Return Request status changed' message to a customer /// </summary> /// <param name="returnRequest">Return request</param> /// <param name="orderItem">Order item</param> /// <param name="languageId">Message language identifier</param> /// <returns>Queued email identifier</returns> public virtual int SendReturnRequestStatusChangedCustomerNotification(ReturnRequest returnRequest, OrderItem orderItem, int languageId) { if (returnRequest == null) throw new ArgumentNullException("returnRequest"); var store = _storeService.GetStoreById(orderItem.Order.StoreId) ?? _storeContext.CurrentStore; languageId = EnsureLanguageIsActive(languageId, store.Id); var messageTemplate = GetLocalizedActiveMessageTemplate("ReturnRequestStatusChanged.CustomerNotification", languageId, store.Id); if (messageTemplate == null) return 0; //tokens var tokens = new List<Token>(); _messageTokenProvider.AddStoreTokens(tokens, store); _messageTokenProvider.AddCustomerTokens(tokens, returnRequest.Customer); _messageTokenProvider.AddReturnRequestTokens(tokens, returnRequest, orderItem); //event notification _eventPublisher.MessageTokensAdded(messageTemplate, tokens); var emailAccount = GetEmailAccountOfMessageTemplate(messageTemplate, languageId); var toEmail = returnRequest.Customer.Email; var toName = returnRequest.Customer.GetFullName(); return SendNotification(messageTemplate, emailAccount, languageId, tokens, toEmail, toName); }
private OrderDetailsModel.OrderItemModel PrepareOrderItemModel(Order order, OrderItem orderItem) { orderItem.Product.MergeWithCombination(orderItem.AttributesXml); var model = new OrderDetailsModel.OrderItemModel() { Id = orderItem.Id, Sku = orderItem.Product.Sku, ProductId = orderItem.Product.Id, ProductName = orderItem.Product.GetLocalized(x => x.Name), ProductSeName = orderItem.Product.GetSeName(), ProductType = orderItem.Product.ProductType, Quantity = orderItem.Quantity, AttributeInfo = orderItem.AttributeDescription }; var quantityUnit = _quantityUnitService.GetQuantityUnitById(orderItem.Product.QuantityUnitId); model.QuantityUnit = quantityUnit == null ? "" : quantityUnit.GetLocalized(x => x.Name); if (orderItem.Product.ProductType == ProductType.BundledProduct && orderItem.BundleData.HasValue()) { var bundleData = orderItem.GetBundleData(); model.BundlePerItemPricing = orderItem.Product.BundlePerItemPricing; model.BundlePerItemShoppingCart = bundleData.Any(x => x.PerItemShoppingCart); foreach (var bundleItem in bundleData) { var bundleItemModel = new OrderDetailsModel.BundleItemModel() { Sku = bundleItem.Sku, ProductName = bundleItem.ProductName, ProductSeName = bundleItem.ProductSeName, VisibleIndividually = bundleItem.VisibleIndividually, Quantity = bundleItem.Quantity, DisplayOrder = bundleItem.DisplayOrder, AttributeInfo = bundleItem.AttributesInfo }; if (model.BundlePerItemShoppingCart) { decimal priceWithDiscount = _currencyService.ConvertCurrency(bundleItem.PriceWithDiscount, order.CurrencyRate); bundleItemModel.PriceWithDiscount = _priceFormatter.FormatPrice(priceWithDiscount, true, order.CustomerCurrencyCode, _services.WorkContext.WorkingLanguage, false, false); } model.BundleItems.Add(bundleItemModel); } } //unit price, subtotal switch (order.CustomerTaxDisplayType) { case TaxDisplayType.ExcludingTax: { var unitPriceExclTaxInCustomerCurrency = _currencyService.ConvertCurrency(orderItem.UnitPriceExclTax, order.CurrencyRate); model.UnitPrice = _priceFormatter.FormatPrice(unitPriceExclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, _services.WorkContext.WorkingLanguage, false, false); var priceExclTaxInCustomerCurrency = _currencyService.ConvertCurrency(orderItem.PriceExclTax, order.CurrencyRate); model.SubTotal = _priceFormatter.FormatPrice(priceExclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, _services.WorkContext.WorkingLanguage, false, false); } break; case TaxDisplayType.IncludingTax: { var unitPriceInclTaxInCustomerCurrency = _currencyService.ConvertCurrency(orderItem.UnitPriceInclTax, order.CurrencyRate); model.UnitPrice = _priceFormatter.FormatPrice(unitPriceInclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, _services.WorkContext.WorkingLanguage, true, false); var priceInclTaxInCustomerCurrency = _currencyService.ConvertCurrency(orderItem.PriceInclTax, order.CurrencyRate); model.SubTotal = _priceFormatter.FormatPrice(priceInclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, _services.WorkContext.WorkingLanguage, true, false); } break; } return model; }
/// <summary> /// Sends 'New Return Request' message to a store owner /// </summary> /// <param name="returnRequest">Return request</param> /// <param name="orderItem">Order item</param> /// <param name="languageId">Message language identifier</param> /// <returns>Queued email identifier</returns> public virtual int SendNewReturnRequestStoreOwnerNotification(ReturnRequest returnRequest, OrderItem orderItem, int languageId) { if (returnRequest == null) throw new ArgumentNullException("returnRequest"); var store = _storeService.GetStoreById(orderItem.Order.StoreId) ?? _storeContext.CurrentStore; languageId = EnsureLanguageIsActive(languageId, store.Id); var messageTemplate = GetActiveMessageTemplate("NewReturnRequest.StoreOwnerNotification", store.Id); if (messageTemplate == null) return 0; //tokens var tokens = new List<Token>(); _messageTokenProvider.AddStoreTokens(tokens, store); _messageTokenProvider.AddCustomerTokens(tokens, returnRequest.Customer); _messageTokenProvider.AddReturnRequestTokens(tokens, returnRequest, orderItem); //event notification _eventPublisher.MessageTokensAdded(messageTemplate, tokens); var emailAccount = GetEmailAccountOfMessageTemplate(messageTemplate, languageId); var toEmail = emailAccount.Email; var toName = emailAccount.DisplayName; // use customer email as reply address var replyTo = GetReplyToEmail(returnRequest.Customer); return SendNotification(messageTemplate, emailAccount, languageId, tokens, toEmail, toName, replyTo.Item1, replyTo.Item2); }
/// <summary> /// Gets a value indicating whether license download is allowed /// </summary> /// <param name="orderItem">Order item to check</param> /// <returns>True if license download is allowed; otherwise, false.</returns> public virtual bool IsLicenseDownloadAllowed(OrderItem orderItem) { if (orderItem == null) return false; return IsDownloadAllowed(orderItem) && orderItem.LicenseDownloadId.HasValue && orderItem.LicenseDownloadId > 0; }
/// <summary> /// Gets a value indicating whether download is allowed /// </summary> /// <param name="orderItem">Order item to check</param> /// <returns>True if download is allowed; otherwise, false.</returns> public virtual bool IsDownloadAllowed(OrderItem orderItem) { if (orderItem == null) return false; var order = orderItem.Order; if (order == null || order.Deleted) return false; //order status if (order.OrderStatus == OrderStatus.Cancelled) return false; var product = orderItem.Product; if (product == null || !product.IsDownload) return false; //payment status switch (product.DownloadActivationType) { case DownloadActivationType.WhenOrderIsPaid: { if (order.PaymentStatus == PaymentStatus.Paid && order.PaidDateUtc.HasValue) { //expiration date if (product.DownloadExpirationDays.HasValue) { if (order.PaidDateUtc.Value.AddDays(product.DownloadExpirationDays.Value) > DateTime.UtcNow) { return true; } } else { return true; } } } break; case DownloadActivationType.Manually: { if (orderItem.IsDownloadActivated) { //expiration date if (product.DownloadExpirationDays.HasValue) { if (order.CreatedOnUtc.AddDays(product.DownloadExpirationDays.Value) > DateTime.UtcNow) { return true; } } else { return true; } } } break; default: break; } return false; }
public ActionResult AddProductToOrderDetails(int orderId, int productId, bool adjustInventory, bool? updateTotals, FormCollection form) { if (!_permissionService.Authorize(StandardPermissionProvider.ManageOrders)) return AccessDeniedView(); var order = _orderService.GetOrderById(orderId); var product = _productService.GetProductById(productId); //save order item //basic properties var unitPriceInclTax = decimal.Zero; decimal.TryParse(form["UnitPriceInclTax"], out unitPriceInclTax); var unitPriceExclTax = decimal.Zero; decimal.TryParse(form["UnitPriceExclTax"], out unitPriceExclTax); var quantity = 1; int.TryParse(form["Quantity"], out quantity); var priceInclTax = decimal.Zero; decimal.TryParse(form["SubTotalInclTax"], out priceInclTax); var priceExclTax = decimal.Zero; decimal.TryParse(form["SubTotalExclTax"], out priceExclTax); var warnings = new List<string>(); string attributes = ""; if (product.ProductType != ProductType.BundledProduct) { var variantAttributes = _productAttributeService.GetProductVariantAttributesByProductId(product.Id); attributes = form.CreateSelectedAttributesXml(product.Id, variantAttributes, _productAttributeParser, _localizationService, _downloadService, _catalogSettings, this.Request, warnings, false); } #region Gift cards string recipientName = ""; string recipientEmail = ""; string senderName = ""; string senderEmail = ""; string giftCardMessage = ""; if (product.IsGiftCard) { foreach (string formKey in form.AllKeys) { if (formKey.Equals("giftcard.RecipientName", StringComparison.InvariantCultureIgnoreCase)) { recipientName = form[formKey]; continue; } if (formKey.Equals("giftcard.RecipientEmail", StringComparison.InvariantCultureIgnoreCase)) { recipientEmail = form[formKey]; continue; } if (formKey.Equals("giftcard.SenderName", StringComparison.InvariantCultureIgnoreCase)) { senderName = form[formKey]; continue; } if (formKey.Equals("giftcard.SenderEmail", StringComparison.InvariantCultureIgnoreCase)) { senderEmail = form[formKey]; continue; } if (formKey.Equals("giftcard.Message", StringComparison.InvariantCultureIgnoreCase)) { giftCardMessage = form[formKey]; continue; } } attributes = _productAttributeParser.AddGiftCardAttribute(attributes, recipientName, recipientEmail, senderName, senderEmail, giftCardMessage); } #endregion //warnings warnings.AddRange(_shoppingCartService.GetShoppingCartItemAttributeWarnings(order.Customer, ShoppingCartType.ShoppingCart, product, attributes, quantity)); warnings.AddRange(_shoppingCartService.GetShoppingCartItemGiftCardWarnings(ShoppingCartType.ShoppingCart, product, attributes)); if (warnings.Count == 0) { //attributes string attributeDescription = _productAttributeFormatter.FormatAttributes(product, attributes, order.Customer); //save item var orderItem = new OrderItem() { OrderItemGuid = Guid.NewGuid(), Order = order, ProductId = product.Id, UnitPriceInclTax = unitPriceInclTax, UnitPriceExclTax = unitPriceExclTax, PriceInclTax = priceInclTax, PriceExclTax = priceExclTax, AttributeDescription = attributeDescription, AttributesXml = attributes, Quantity = quantity, DiscountAmountInclTax = decimal.Zero, DiscountAmountExclTax = decimal.Zero, DownloadCount = 0, IsDownloadActivated = false, LicenseDownloadId = 0, ProductCost = _priceCalculationService.GetProductCost(product, attributes) }; if (product.ProductType == ProductType.BundledProduct) { var listBundleData = new List<ProductBundleItemOrderData>(); var bundleItems = _productService.GetBundleItems(product.Id); foreach (var bundleItem in bundleItems) { decimal taxRate; decimal finalPrice = _priceCalculationService.GetFinalPrice(bundleItem.Item.Product, bundleItems, order.Customer, decimal.Zero, true, bundleItem.Item.Quantity); decimal bundleItemSubTotalWithDiscountBase = _taxService.GetProductPrice(bundleItem.Item.Product, finalPrice, out taxRate); bundleItem.ToOrderData(listBundleData, bundleItemSubTotalWithDiscountBase); } orderItem.SetBundleData(listBundleData); } order.OrderItems.Add(orderItem); _orderService.UpdateOrder(order); //gift cards if (product.IsGiftCard) { for (int i = 0; i < orderItem.Quantity; i++) { var gc = new GiftCard() { GiftCardType = product.GiftCardType, PurchasedWithOrderItem = orderItem, Amount = unitPriceExclTax, IsGiftCardActivated = false, GiftCardCouponCode = _giftCardService.GenerateGiftCardCode(), RecipientName = recipientName, RecipientEmail = recipientEmail, SenderName = senderName, SenderEmail = senderEmail, Message = giftCardMessage, IsRecipientNotified = false, CreatedOnUtc = DateTime.UtcNow }; _giftCardService.InsertGiftCard(gc); } } if (adjustInventory || (updateTotals ?? false)) { var context = new AutoUpdateOrderItemContext() { IsNewOrderItem = true, OrderItem = orderItem, QuantityOld = 0, QuantityNew = orderItem.Quantity, AdjustInventory = adjustInventory, UpdateTotals = (updateTotals ?? false) }; _orderProcessingService.AutoUpdateOrderDetails(context); TempData[AutoUpdateOrderItemContext.InfoKey] = context.ToString(_localizationService); } //redirect to order details page return RedirectToAction("Edit", "Order", new { id = order.Id }); } else { //errors var model = PrepareAddProductToOrderModel(order.Id, product.Id); model.Warnings.AddRange(warnings); return View(model); } }
/// <summary> /// Delete an Order item /// </summary> /// <param name="orderItem">The Order item</param> public virtual void DeleteOrderItem(OrderItem orderItem) { if (orderItem == null) throw new ArgumentNullException("orderItem"); _orderItemRepository.Delete(orderItem); //event notification _eventPublisher.EntityDeleted(orderItem); }
/// <summary> /// Adjusts inventory /// </summary> /// <param name="orderItem">Order item</param> /// <param name="decrease">A value indicating whether to increase or descrease product stock quantity</param> /// <param name="quantity">Quantity</param> /// <returns>Adjust inventory result</returns> public virtual AdjustInventoryResult AdjustInventory(OrderItem orderItem, bool decrease, int quantity) { if (orderItem == null) throw new ArgumentNullException("orderItem"); if (orderItem.Product.ProductType == ProductType.BundledProduct && orderItem.Product.BundlePerItemShoppingCart) { if (orderItem.BundleData.HasValue()) { var bundleData = orderItem.GetBundleData(); if (bundleData.Count > 0) { var products = GetProductsByIds(bundleData.Select(x => x.ProductId).ToArray()); foreach (var item in bundleData) { var product = products.FirstOrDefault(x => x.Id == item.ProductId); if (product != null) AdjustInventory(product, decrease, quantity * item.Quantity, item.AttributesXml); } } } return new AdjustInventoryResult(); } else { return AdjustInventory(orderItem.Product, decrease, quantity, orderItem.AttributesXml); } }