public static Model.Cart.Shipment ToWebModel(this VirtoCommerceCartModuleWebModelShipment shipment, ShoppingCart cart)
        {
            var webModel = new Model.Cart.Shipment(cart.Currency);

            webModel.InjectFrom(shipment);
            webModel.Currency = cart.Currency;
            webModel.ShippingPrice = new Money(shipment.ShippingPrice ?? 0, cart.Currency);
            webModel.TaxTotal = new Money(shipment.TaxTotal ?? 0, cart.Currency);

            if (shipment.DeliveryAddress != null)
            {
                webModel.DeliveryAddress = shipment.DeliveryAddress.ToWebModel();
            }

            if (shipment.Items != null)
            {
                webModel.Items = shipment.Items.Select(i => i.ToWebModel(cart)).ToList();
            }

            if (shipment.TaxDetails != null)
            {
                webModel.TaxDetails = shipment.TaxDetails.Select(td => td.ToWebModel(cart.Currency)).ToList();
            }

            return webModel;
        }
예제 #2
0
        public async Task<CartBuilder> GetOrCreateNewTransientCartAsync(Store store, Customer customer, Language language, Currency currency)
        {
            _store = store;
            _customer = customer;
            _currency = currency;
            _language = language;
            _cartCacheKey = GetCartCacheKey(store.Id, customer.Id);

            _cart = await _cacheManager.GetAsync(_cartCacheKey, _cartCacheRegion, async () =>
            {
                ShoppingCart retVal;

                var cartSearchResult = await _cartApi.CartModuleGetCurrentCartAsync(_store.Id, _customer.Id);
                if (cartSearchResult == null)
                {
                    retVal = CreateNewTransientCart();
                }
                else
                {
                    var detalizedCart = await _cartApi.CartModuleGetCartByIdAsync(cartSearchResult.Id);
                    retVal = detalizedCart.ToWebModel(_currency, _language);
                }

                return retVal;
            });

            await EvaluatePromotionsAsync();

            return this;
        }
        public static CartShipmentItem ToWebModel(this VirtoCommerce.Client.Model.VirtoCommerceCartModuleWebModelShipmentItem shipmentItemDto, ShoppingCart cart)
        {
            var retVal = new CartShipmentItem();
            retVal.InjectFrom(shipmentItemDto);
            retVal.LineItem = cart.Items.FirstOrDefault(x => x.Id == shipmentItemDto.LineItemId);

            return retVal;
        }
예제 #4
0
        public async Task ValidateAsync(ShoppingCart cart)
        {
            if (cart.IsTransient())
            {
                return;
            }

            await Task.WhenAll(ValidateItemsAsync(cart), ValidateShipmentsAsync(cart));
        }
        public static CartShipmentItem ToWebModel(this VirtoCommerceCartModuleWebModelShipmentItem serviceModel, ShoppingCart cart)
        {
            var webModel = new CartShipmentItem();

            webModel.InjectFrom<NullableAndEnumValueInjecter>(serviceModel);

            webModel.LineItem = cart.Items.FirstOrDefault(x => x.Id == serviceModel.LineItemId);

            return webModel;
        }
예제 #6
0
        private async Task ValidateItemsAsync(ShoppingCart cart)
        {
            var workContext = _workContextFactory();
            var productIds = cart.Items.Select(i => i.ProductId).ToArray();
            var cacheKey = "CartValidator.ValidateItemsAsync-" + workContext.CurrentCurrency.Code + ":" + workContext.CurrentLanguage + ":" + string.Join(":", productIds);
            var products = await _cacheManager.GetAsync(cacheKey, "ApiRegion", async () => { return await _catalogService.GetProductsAsync(productIds, ItemResponseGroup.ItemWithPrices | ItemResponseGroup.ItemWithDiscounts | ItemResponseGroup.Inventory); });
       
            foreach (var lineItem in cart.Items.ToList())
            {
                lineItem.ValidationErrors.Clear();

                var product = products.FirstOrDefault(p => p.Id == lineItem.ProductId);
                if (product == null || (product != null && (!product.IsActive || !product.IsBuyable)))
                {
                    lineItem.ValidationErrors.Add(new ProductUnavailableError());
                }
                else if (product != null)
                {
                    if (product.TrackInventory && product.Inventory != null &&
                        (lineItem.ValidationType == ValidationType.PriceAndQuantity || lineItem.ValidationType == ValidationType.Quantity))
                    {
                        var availableQuantity = product.Inventory.InStockQuantity;
                        if (product.Inventory.ReservedQuantity.HasValue)
                        {
                            availableQuantity -= product.Inventory.ReservedQuantity.Value;
                        }
                        if (availableQuantity.HasValue && lineItem.Quantity > availableQuantity.Value)
                        {
                            lineItem.ValidationErrors.Add(new ProductQuantityError(availableQuantity.Value));
                        }
                    }
                    if (lineItem.ValidationType == ValidationType.PriceAndQuantity || lineItem.ValidationType == ValidationType.Price)
                    {
                        var tierPrice = product.Price.GetTierPrice(lineItem.Quantity);
                        if (tierPrice.ActualPrice != lineItem.PlacedPrice)
                        {
                            lineItem.ValidationWarnings.Add(new ProductPriceError(lineItem.PlacedPrice));
                            lineItem.SalePrice = tierPrice.Price;
                        }
                    }
                }
            }
        }
예제 #7
0
        private ICollection<PromotionProductEntry> GetCartPromoEntries(ShoppingCart cart)
        {
            var cartPromoEntries = new List<PromotionProductEntry>();

            foreach (var lineItem in cart.Items)
            {
                cartPromoEntries.Add(new PromotionProductEntry
                {
                    CatalogId = lineItem.CatalogId,
                    CategoryId = lineItem.CategoryId,
                    Price = lineItem.SalePrice,
                    ProductId = lineItem.ProductId,
                    Quantity = lineItem.Quantity
                });
            }

            return cartPromoEntries;
        }
예제 #8
0
 public OrderPlacedEvent(CustomerOrder order, ShoppingCart cart)
 {
     Cart = cart;
     Order = order;
 }
예제 #9
0
        public static ShoppingCart ToWebModel(this VirtoCommerceCartModuleWebModelShoppingCart serviceModel, Currency currency, Language language)
        {
            var webModel = new ShoppingCart(currency, language);

            webModel.InjectFrom(serviceModel);

            if (!string.IsNullOrEmpty(serviceModel.Coupon))
            {
                webModel.Coupon = new Coupon
                {
                    AppliedSuccessfully = true,
                    Code = serviceModel.Coupon
                };
            }

            if (serviceModel.Items != null)
            {
                webModel.Items = serviceModel.Items.Select(i => i.ToWebModel(currency, language)).ToList();
                webModel.HasPhysicalProducts = webModel.Items.Any(i =>
                    string.IsNullOrEmpty(i.ProductType) ||
                    !string.IsNullOrEmpty(i.ProductType) && i.ProductType.Equals("Physical", StringComparison.OrdinalIgnoreCase));
            }

            if (serviceModel.Addresses != null)
            {
                webModel.Addresses = serviceModel.Addresses.Select(a => a.ToWebModel()).ToList();

                var billingAddress = webModel.Addresses.FirstOrDefault(a => a.Type == AddressType.Billing);
                if (billingAddress == null)
                {
                    billingAddress = new Address { Type = AddressType.Billing };
                }

                if (webModel.HasPhysicalProducts)
                {
                    var shippingAddress = webModel.Addresses.FirstOrDefault(a => a.Type == AddressType.Shipping);
                    if (shippingAddress == null)
                    {
                        shippingAddress = new Address { Type = AddressType.Shipping };
                    }
                }
            }

            if (serviceModel.Payments != null)
            {
                webModel.Payments = serviceModel.Payments.Select(p => p.TowebModel(currency)).ToList();
            }

            if (serviceModel.Shipments != null)
            {
                webModel.Shipments = serviceModel.Shipments.Select(s => s.ToWebModel(webModel)).ToList();
            }

            if (serviceModel.DynamicProperties != null)
            {
                webModel.DynamicProperties = serviceModel.DynamicProperties.Select(dp => dp.ToWebModel()).ToList();
            }

            if (serviceModel.TaxDetails != null)
            {
                webModel.TaxDetails = serviceModel.TaxDetails.Select(td => td.ToWebModel(currency)).ToList();
            }

            webModel.HandlingTotal = new Money(serviceModel.HandlingTotal ?? 0, currency);
            webModel.Height = (decimal)(serviceModel.Height ?? 0);
            webModel.IsAnonymous = serviceModel.IsAnonymous == true;
            webModel.IsRecuring = serviceModel.IsRecuring == true;
            webModel.Length = (decimal)(serviceModel.Length ?? 0);
            webModel.TaxIncluded = serviceModel.TaxIncluded == true;
            webModel.TaxTotal = new Money(serviceModel.TaxTotal ?? 0, currency);
            webModel.VolumetricWeight = (decimal)(serviceModel.VolumetricWeight ?? 0);
            webModel.Weight = (decimal)(serviceModel.Weight ?? 0);
            webModel.Width = (decimal)(serviceModel.Width ?? 0);
            webModel.ValidationType = EnumUtility.SafeParse(serviceModel.ValidationType, ValidationType.PriceAndQuantity);

            return webModel;
        }
예제 #10
0
        private ShoppingCart CreateNewTransientCart()
        {
            var cart = new ShoppingCart(_currency, _language);

            cart.CustomerId = _customer.Id;
            cart.Name = "Default";
            cart.StoreId = _store.Id;

            if (_customer.UserName.Equals(StorefrontConstants.AnonymousUsername, StringComparison.OrdinalIgnoreCase))
            {
                cart.CustomerName = StorefrontConstants.AnonymousUsername;
            }
            else
            {
                cart.CustomerName = string.Format("{0} {1}", _customer.FirstName, _customer.LastName);
            }

            return cart;
        }
예제 #11
0
        public async Task<CartBuilder> MergeWithCartAsync(ShoppingCart cart)
        {
            foreach (var lineItem in cart.Items)
            {
                AddLineItem(lineItem);
            }

            _cart.Coupon = cart.Coupon;

            _cart.Shipments.Clear();
            _cart.Shipments = cart.Shipments;

            _cart.Payments.Clear();
            _cart.Payments = cart.Payments;

            await EvaluatePromotionsAsync();

            await _cartApi.CartModuleDeleteCartsAsync(new List<string> { cart.Id });
            _cacheManager.Remove(_cartCacheKey, _cartCacheRegion);

            return this;
        }
예제 #12
0
        private async Task ValidateShipmentsAsync(ShoppingCart cart)
        {
            var workContext = _workContextFactory();
            foreach (var shipment in cart.Shipments)
            {
                shipment.ValidationErrors.Clear();
                var availableShippingMethods = await _cacheManager.GetAsync("CartValidator.ValidateShipmentsAsync-" + workContext.CurrentCurrency + ":" + cart.Id, "ApiRegion", async () => { return await _cartApi.CartModuleGetShipmentMethodsAsync(cart.Id); });
                if (availableShippingMethods.Count == 0)
                {
                    shipment.ValidationWarnings.Add(new ShippingUnavailableError());
                    break;
                }
                if (!string.IsNullOrEmpty(shipment.ShipmentMethodCode))
                {
                    var existingShippingMethod = availableShippingMethods.FirstOrDefault(sm => sm.ShipmentMethodCode == shipment.ShipmentMethodCode);
                    if (existingShippingMethod == null)
                    {
                        shipment.ValidationWarnings.Add(new ShippingUnavailableError());
                        break;
                    }
                    if (existingShippingMethod != null)
                    {
                        var shippingMethod = existingShippingMethod.ToWebModel(workContext.AllCurrencies, workContext.CurrentLanguage);
                        if (shippingMethod.Price != shipment.ShippingPrice &&
                            (cart.ValidationType == ValidationType.PriceAndQuantity || cart.ValidationType == ValidationType.Price))
                        {
                            shipment.ValidationWarnings.Add(new ShippingPriceError(shipment.ShippingPrice));

                            cart.Shipments.Clear();
                            cart.Shipments.Add(shippingMethod.ToShipmentModel(cart.Currency));
                        }
                    }
                }
            }
        }
예제 #13
0
        private async Task MergeShoppingCartsAsync(string username, ShoppingCart anonymousShoppingCart)
        {
            if (anonymousShoppingCart.ItemsCount > 0)
            {
                var user = await _commerceCoreApi.StorefrontSecurityGetUserByNameAsync(username);
                if (user != null)
                {
                    var customer = await _customerApi.CustomerModuleGetContactByIdAsync(user.Id);

                    await _cartBuilder.GetOrCreateNewTransientCartAsync(WorkContext.CurrentStore, customer.ToWebModel(username), WorkContext.CurrentLanguage, WorkContext.CurrentCurrency);
                    await _cartBuilder.MergeWithCartAsync(anonymousShoppingCart);
                    await _cartBuilder.SaveAsync();
                }
            }
        }