protected async virtual Task <string> GetInventoryStatus(string inventorySetName, SellableItem sellableItem, string variantId, CommercePipelineExecutionContext context)
        {
            if (sellableItem.IsBundle)
            {
                // TODO: Implement support for bundle
                return("Not Supported");
            }

            if (sellableItem.HasPolicy <AvailabilityAlwaysPolicy>())
            {
                return(Engine.CatalogConstants.InventoryStatus.Perpetual);
            }

            if (string.IsNullOrWhiteSpace(variantId) && !string.IsNullOrWhiteSpace(inventorySetName))
            {
                var inventoryInformation = await Commander.Command <GetInventoryInformationCommand>().Process(context.CommerceContext, inventorySetName, sellableItem.ProductId).ConfigureAwait(false);

                if (inventoryInformation != null)
                {
                    return(this.ToInventoryStatus(inventoryInformation));
                }
            }

            if (string.IsNullOrWhiteSpace(variantId))
            {
                var variants        = sellableItem.GetComponent <ItemVariationsComponent>().GetComponents <ItemVariationComponent>();
                var allNotAvailable = true;
                foreach (var variant in variants)
                {
                    var status = await GetVariantInventoryStatus(variant, inventorySetName, context).ConfigureAwait(false);

                    allNotAvailable &= status.Equals(Engine.CatalogConstants.InventoryStatus.NotAvailable, StringComparison.InvariantCultureIgnoreCase);
                    if (status.Equals(Engine.CatalogConstants.InventoryStatus.NotAvailable, StringComparison.InvariantCultureIgnoreCase) ||
                        status.Equals(Engine.CatalogConstants.InventoryStatus.OutOfStock, StringComparison.InvariantCultureIgnoreCase))
                    {
                        continue;
                    }

                    return(status);
                }

                return(allNotAvailable ? Engine.CatalogConstants.InventoryStatus.NotAvailable : Engine.CatalogConstants.InventoryStatus.OutOfStock);
            }
            else
            {
                var variant = sellableItem.GetVariation(variantId);
                return(await GetVariantInventoryStatus(variant, inventorySetName, context).ConfigureAwait(false));
            }
        }
        //public static void AddListPrice(this ImportSellableItemResponse sellableItem, decimal sellableItemListPrice)
        //{
        //    var listPricingPolicy = sellableItem.SellableItem.GetPolicy<ListPricingPolicy>();
        //    listPricingPolicy.ClearPrices();
        //    if (sellableItemListPrice == 0)
        //    {
        //        return;
        //    }
        //    listPricingPolicy.AddPrice(new Money("USD", sellableItemListPrice));
        //}

        public static decimal GetLisPrice(this SellableItem sellableItem)
        {
            if (!sellableItem.HasPolicy(typeof(ListPricingPolicy)))
            {
                return(0);
            }
            var listPricingPolicy = sellableItem.GetPolicy <ListPricingPolicy>();

            if (listPricingPolicy == null || listPricingPolicy.Prices == null || listPricingPolicy.Prices.Count() < 1)
            {
                return(0);
            }

            return(listPricingPolicy.Prices.ToList()[0].Amount);
        }
Example #3
0
        private async Task <bool?> CalculateCartLinePrice(
            CartLineComponent arg,
            CommercePipelineExecutionContext context)
        {
            ProductArgument productArgument = ProductArgument.FromItemId(arg.ItemId);
            SellableItem    sellableItem    = null;

            if (productArgument.IsValid())
            {
                sellableItem = context.CommerceContext.GetEntity((Func <SellableItem, bool>)(s => s.ProductId.Equals(productArgument.ProductId, StringComparison.OrdinalIgnoreCase)));

                if (sellableItem == null)
                {
                    string simpleName = productArgument.ProductId.SimplifyEntityName();
                    sellableItem = context.CommerceContext.GetEntity((Func <SellableItem, bool>)(s => s.ProductId.Equals(simpleName, StringComparison.OrdinalIgnoreCase)));

                    if (sellableItem != null)
                    {
                        sellableItem.ProductId = simpleName;
                    }
                }
            }
            if (sellableItem == null)
            {
                CommercePipelineExecutionContext executionContext = context;
                CommerceContext commerceContext = context.CommerceContext;
                string          error           = context.GetPolicy <KnownResultCodes>().Error;
                object[]        args            = new object[] { arg.ItemId };
                string          defaultMessage  = "Item '" + arg.ItemId + "' is not purchasable.";
                executionContext.Abort(await commerceContext.AddMessage(error, "LineIsNotPurchasable", args, defaultMessage), context);
                executionContext = null;
                return(new bool?());
            }

            MessagesComponent messagesComponent = arg.GetComponent <MessagesComponent>();

            messagesComponent.Clear(context.GetPolicy <KnownMessageCodePolicy>().Pricing);

            if (sellableItem.HasComponent <MessagesComponent>())
            {
                List <MessageModel> messages = sellableItem.GetComponent <MessagesComponent>().GetMessages(context.GetPolicy <KnownMessageCodePolicy>().Pricing);
                messagesComponent.AddMessages(messages);
            }
            arg.UnitListPrice = sellableItem.ListPrice;
            string listPriceMessage = "CartItem.ListPrice<=SellableItem.ListPrice: Price=" + arg.UnitListPrice.AsCurrency(false, null);
            string sellPriceMessage = string.Empty;
            PurchaseOptionMoneyPolicy optionMoneyPolicy = new PurchaseOptionMoneyPolicy();

            if (sellableItem.HasPolicy <PurchaseOptionMoneyPolicy>())
            {
                optionMoneyPolicy.SellPrice = sellableItem.GetPolicy <PurchaseOptionMoneyPolicy>().SellPrice;
                sellPriceMessage            = "CartItem.SellPrice<=SellableItem.SellPrice: Price=" + optionMoneyPolicy.SellPrice.AsCurrency(false, null);
            }

            PriceSnapshotComponent snapshotComponent;

            if (sellableItem.HasComponent <ItemVariationsComponent>())
            {
                ItemVariationSelectedComponent lineVariant             = arg.ChildComponents.OfType <ItemVariationSelectedComponent>().FirstOrDefault();
                ItemVariationsComponent        itemVariationsComponent = sellableItem.GetComponent <ItemVariationsComponent>();
                ItemVariationComponent         itemVariationComponent;

                if (itemVariationsComponent == null)
                {
                    itemVariationComponent = null;
                }
                else
                {
                    IList <Component> childComponents = itemVariationsComponent.ChildComponents;
                    itemVariationComponent = childComponents?.OfType <ItemVariationComponent>().FirstOrDefault(v =>
                    {
                        return(!string.IsNullOrEmpty(v.Id) ? v.Id.Equals(lineVariant?.VariationId, StringComparison.OrdinalIgnoreCase) : false);
                    });
                }

                if (itemVariationComponent != null)
                {
                    if (itemVariationComponent.HasComponent <MessagesComponent>())
                    {
                        List <MessageModel> messages = itemVariationComponent.GetComponent <MessagesComponent>().GetMessages(context.GetPolicy <KnownMessageCodePolicy>().Pricing);
                        messagesComponent.AddMessages(messages);
                    }

                    arg.UnitListPrice = itemVariationComponent.ListPrice;
                    listPriceMessage  = "CartItem.ListPrice<=SellableItem.Variation.ListPrice: Price=" + arg.UnitListPrice.AsCurrency(false, null);

                    if (itemVariationComponent.HasPolicy <PurchaseOptionMoneyPolicy>())
                    {
                        optionMoneyPolicy.SellPrice = itemVariationComponent.GetPolicy <PurchaseOptionMoneyPolicy>().SellPrice;
                        sellPriceMessage            = "CartItem.SellPrice<=SellableItem.Variation.SellPrice: Price=" + optionMoneyPolicy.SellPrice.AsCurrency(false, null);
                    }
                }
                snapshotComponent = itemVariationComponent != null?itemVariationComponent.ChildComponents.OfType <PriceSnapshotComponent>().FirstOrDefault() : null;
            }
            else
            {
                snapshotComponent = sellableItem.Components.OfType <PriceSnapshotComponent>().FirstOrDefault();
            }

            string currentCurrency = context.CommerceContext.CurrentCurrency();

            PriceTier priceTier = snapshotComponent?.Tiers.OrderByDescending(t => t.Quantity).FirstOrDefault(t =>
            {
                return(t.Currency.Equals(currentCurrency, StringComparison.OrdinalIgnoreCase) ? t.Quantity <= arg.Quantity : false);
            });

            Customer customer = await _findEntityPipeline.Run(new FindEntityArgument(typeof(Customer), context.CommerceContext.CurrentCustomerId(), false), context) as Customer;

            bool isMembershipLevelPrice = false;

            if (customer != null && customer.HasComponent <MembershipSubscriptionComponent>())
            {
                var membershipSubscriptionComponent = customer.GetComponent <MembershipSubscriptionComponent>();
                var membershipLevel = membershipSubscriptionComponent.MemerbshipLevelName;

                if (snapshotComponent != null && snapshotComponent.HasComponent <MembershipTiersComponent>())
                {
                    var membershipTiersComponent = snapshotComponent.GetComponent <MembershipTiersComponent>();
                    var membershipPriceTier      = membershipTiersComponent.Tiers.FirstOrDefault(x => x.MembershipLevel == membershipLevel);

                    if (membershipPriceTier != null)
                    {
                        optionMoneyPolicy.SellPrice = new Money(membershipPriceTier.Currency, membershipPriceTier.Price);
                        isMembershipLevelPrice      = true;

                        sellPriceMessage = string.Format("CartItem.SellPrice<=PriceCard.ActiveSnapshot: MembershipLevel={0}|Price={1}|Qty={2}", membershipSubscriptionComponent.MemerbshipLevelName, optionMoneyPolicy.SellPrice.AsCurrency(false, null), membershipPriceTier.Quantity);
                    }
                }
            }

            if (!isMembershipLevelPrice && priceTier != null)
            {
                optionMoneyPolicy.SellPrice = new Money(priceTier.Currency, priceTier.Price);
                sellPriceMessage            = string.Format("CartItem.SellPrice<=PriceCard.ActiveSnapshot: Price={0}|Qty={1}", optionMoneyPolicy.SellPrice.AsCurrency(false, null), priceTier.Quantity);
            }

            arg.Policies.Remove(arg.Policies.OfType <PurchaseOptionMoneyPolicy>().FirstOrDefault());

            if (optionMoneyPolicy.SellPrice == null)
            {
                return(false);
            }

            arg.SetPolicy(optionMoneyPolicy);

            if (!string.IsNullOrEmpty(sellPriceMessage))
            {
                messagesComponent.AddMessage(context.GetPolicy <KnownMessageCodePolicy>().Pricing, sellPriceMessage);
            }

            if (!string.IsNullOrEmpty(listPriceMessage))
            {
                messagesComponent.AddMessage(context.GetPolicy <KnownMessageCodePolicy>().Pricing, listPriceMessage);
            }

            return(true);
        }
        public override async Task <Cart> Run(Cart arg, CommercePipelineExecutionContext context)
        {
            Condition.Requires <Cart>(arg).IsNotNull <Cart>(string.Format("{0}: the cart can not be null.", (object)this.Name));
            if (arg.HasComponent <TemporaryCartComponent>())
            {
                return(arg);
            }

            AddToCartBundlesBlock addBundlesBlock = this;

            context.CommerceContext.AddObject((object)arg);
            Cart cart = arg;

            FindEntityArgument getSavedCartArg = new FindEntityArgument(typeof(Cart), arg.Id, false);
            Cart savedCart = await this._findEntityPipeline.Run(getSavedCartArg, (CommercePipelineExecutionContext)context).ConfigureAwait(false) as Cart;

            CartLineComponent existingLine;

            IList <CartLineComponent> savedCartLines   = new List <CartLineComponent>();
            IList <CartLineComponent> currentCartLines = new List <CartLineComponent>();

            if (savedCart == null)
            {
                existingLine = arg.Lines.FirstOrDefault <CartLineComponent>();
            }
            else
            {
                savedCartLines   = savedCart.Lines;
                currentCartLines = cart.Lines;
                var addedCartLine = cart.Lines.Where(l => savedCartLines.Where(sc => sc.Id == l.Id).FirstOrDefault() == null).FirstOrDefault();
                existingLine = addedCartLine;
            }
            if (existingLine != null)
            {
                FindEntityArgument getProductArg  = new FindEntityArgument(typeof(SellableItem), "Entity-SellableItem-" + (existingLine.ItemId.Split('|').Count() > 1 ? existingLine.ItemId.Split('|')[1] : existingLine.ItemId), false);
                SellableItem       carLineProduct = await this._findEntityPipeline.Run(getProductArg, (CommercePipelineExecutionContext)context).ConfigureAwait(false) as SellableItem;

                bool hasTag = carLineProduct.Tags.Any <Tag>((Func <Tag, bool>)(t => t.Name.Equals("bundle", StringComparison.OrdinalIgnoreCase)));

                if (hasTag)
                {
                    string listId = String.Format("relatedproduct-{0}", existingLine.ItemId.Split('|').Count() > 1 ? existingLine.ItemId.Split('|')[1] : existingLine.ItemId);

                    var relatedProducts = await _findEntitiesInListPipeline.Run(
                        new FindEntitiesInListArgument(typeof(CommerceEntity), listId, 0, 10)
                    {
                        LoadEntities = true
                    },
                        context);

                    foreach (var relProd in relatedProducts.List.Items)
                    {
                        if (savedCartLines.Any(l => l.ItemId.Contains(relProd.FriendlyId)) || currentCartLines.Any(l => l.ItemId.Contains(relProd.FriendlyId)))
                        {
                            FindEntityArgument getRelatedProductArg = new FindEntityArgument(typeof(SellableItem), "Entity-SellableItem-" + relProd.FriendlyId, false);
                            SellableItem       relatedProduct       = await this._findEntityPipeline.Run(getRelatedProductArg, (CommercePipelineExecutionContext)context).ConfigureAwait(false) as SellableItem;

                            string listPrice = String.Empty;
                            if (relatedProduct.HasPolicy <ListPricingPolicy>())
                            {
                                ListPricingPolicy policy = relatedProduct.GetPolicy <ListPricingPolicy>();
                                listPrice = policy.Prices.FirstOrDefault().Amount.ToString();
                            }
                            existingLine.Comments += relProd.FriendlyId + ',' + relProd.DisplayName + ',' + listPrice + '|';
                        }
                    }

                    cart.Lines.Remove(existingLine);
                }
            }
            return(cart);
        }