Esempio n. 1
0
        public override Task <EntityView> Run(EntityView arg, CommercePipelineExecutionContext context)
        {
            Condition.Requires(arg).IsNotNull(this.Name + ": The argument cannot be null");
            EntityViewArgument request = context.CommerceContext.GetObjects <EntityViewArgument>().FirstOrDefault();

            if (request == null)
            {
                return(Task.FromResult(arg));
            }

            bool isAddAction  = request.ForAction.Equals(context.GetPolicy <KnownPricingActionsPolicy>().AddPriceSnapshot, StringComparison.OrdinalIgnoreCase);
            bool isEditAction = request.ForAction.Equals(context.GetPolicy <KnownPricingActionsPolicy>().EditPriceSnapshot, StringComparison.OrdinalIgnoreCase);

            if (string.IsNullOrEmpty(request?.ViewName) ||
                !(request.Entity is PriceCard) ||
                !request.ViewName.Equals(context.GetPolicy <KnownPricingViewsPolicy>().Master, StringComparison.OrdinalIgnoreCase) &&
                !request.ViewName.Equals(context.GetPolicy <KnownPricingViewsPolicy>().PriceCardSnapshots, StringComparison.OrdinalIgnoreCase) &&
                !request.ViewName.Equals(context.GetPolicy <KnownPricingViewsPolicy>().PriceSnapshotDetails, StringComparison.OrdinalIgnoreCase) ||
                request.ViewName.Equals(context.GetPolicy <KnownPricingViewsPolicy>().PriceSnapshotDetails, StringComparison.OrdinalIgnoreCase) &&
                string.IsNullOrEmpty(request.ItemId) && !isAddAction)
            {
                return(Task.FromResult(arg));
            }

            PriceCard card = (PriceCard)request.Entity;

            if (request.ViewName.Equals(context.GetPolicy <KnownPricingViewsPolicy>().Master, StringComparison.OrdinalIgnoreCase) ||
                request.ViewName.Equals(context.GetPolicy <KnownPricingViewsPolicy>().PriceCardSnapshots, StringComparison.OrdinalIgnoreCase))
            {
                List <EntityView> views = new List <EntityView>();
                this.FindViews(views, arg, context.GetPolicy <KnownPricingViewsPolicy>().PriceSnapshotDetails, context.CommerceContext);
                views.ForEach(snapshotDetailsView =>
                {
                    EntityView view                 = snapshotDetailsView;
                    PriceCard priceCard             = card;
                    PriceSnapshotComponent snapshot = priceCard?.Snapshots.FirstOrDefault(s => s.Id.Equals(snapshotDetailsView.ItemId, StringComparison.OrdinalIgnoreCase));
                    int num1 = isAddAction ? 1 : 0;
                    int num2 = isEditAction ? 1 : 0;
                    this.PopulateSnapshotDetails(view, snapshot, num1 != 0, num2 != 0);
                });
                return(Task.FromResult(arg));
            }
            PriceSnapshotComponent snapshotComponent;

            if (isAddAction)
            {
                snapshotComponent = null;
            }
            else
            {
                PriceCard priceCard = card;
                snapshotComponent = priceCard?.Snapshots.FirstOrDefault(s => s.Id.Equals(request.ItemId, StringComparison.OrdinalIgnoreCase));
            }
            PriceSnapshotComponent snapshot1 = snapshotComponent;

            this.PopulateSnapshotDetails(arg, snapshot1, isAddAction, isEditAction);
            var          rawValue      = arg.Properties.FirstOrDefault((p => p.Name.Equals("BeginDate", StringComparison.OrdinalIgnoreCase))).RawValue;
            CultureInfo  cultureInfo   = CultureInfo.GetCultureInfo(context.CommerceContext.CurrentLanguage());
            string       str           = (string.IsNullOrEmpty(card.DisplayName) ? card.Name : card.DisplayName) + " (" + rawValue + ")";
            ViewProperty viewProperty1 = arg.Properties.FirstOrDefault(p => p.Name.Equals("DisplayName", StringComparison.OrdinalIgnoreCase));

            if (viewProperty1 != null)
            {
                viewProperty1.RawValue = str;
            }

            else if (!isAddAction && !isEditAction)
            {
                List <ViewProperty> properties    = arg.Properties;
                ViewProperty        viewProperty2 = new ViewProperty
                {
                    Name       = "DisplayName",
                    RawValue   = str,
                    IsReadOnly = true
                };
                properties.Add(viewProperty2);
            }
            return(Task.FromResult(arg));
        }
Esempio n. 2
0
        public virtual async Task <PriceCard> Process(CommerceContext commerceContext, PriceCard priceCard, PriceSnapshotComponent priceSnapshot, IEnumerable <CustomPriceTier> priceTiers)
        {
            PriceCard result = null;

            using (CommandActivity.Start(commerceContext, this))
            {
                var snapshot = await GetPriceSnapshot(commerceContext, priceCard, priceSnapshot.Id).ConfigureAwait(false);

                if (snapshot == null)
                {
                    return(null);
                }

                await PerformTransaction(commerceContext, async() =>
                {
                    foreach (CustomPriceTier priceTier in priceTiers)
                    {
                        result = await _removeCustomPriceTierPipeline.Run(new PriceCardSnapshotCustomTierArgument(priceCard, priceSnapshot, priceTier), commerceContext.GetPipelineContextOptions())
                                 .ConfigureAwait(false);

                        if (commerceContext.HasErrors())
                        {
                            break;
                        }
                    }
                }).ConfigureAwait(false);

                return(result);
            }
        }
        public override async Task <EntityView> Run(EntityView arg, CommercePipelineExecutionContext context)
        {
            if (string.IsNullOrEmpty(arg?.Action) ||
                !arg.Action.Equals(context.GetPolicy <KnownCustomPricingActionsPolicy>().EditMembershipCurrency, StringComparison.OrdinalIgnoreCase) ||
                !arg.Name.Equals(context.GetPolicy <KnownCustomPricingViewsPolicy>().PriceCustomRow, StringComparison.OrdinalIgnoreCase))
            {
                return(arg);
            }

            PriceCard card = context.CommerceContext.GetObjects <PriceCard>().FirstOrDefault(p => p.Id.Equals(arg.EntityId, StringComparison.OrdinalIgnoreCase));

            if (card == null)
            {
                return(arg);
            }

            KnownResultCodes errorsCodes = context.GetPolicy <KnownResultCodes>();

            if (string.IsNullOrEmpty(arg.ItemId))
            {
                await context.CommerceContext.AddMessage(errorsCodes.ValidationError, "InvalidOrMissingPropertyValue", new object[] { "ItemId" }, "Invalid or missing value for property 'ItemId'.")
                .ConfigureAwait(false);

                return(arg);
            }

            string snapshotId = arg.ItemId.Split('|')[0];
            PriceSnapshotComponent snapshot = card.Snapshots.FirstOrDefault(s => s.Id.Equals(snapshotId, StringComparison.OrdinalIgnoreCase));

            if (snapshot == null)
            {
                await context.CommerceContext.AddMessage(errorsCodes.ValidationError, "PriceSnapshotNotFound", new object[] { snapshotId, card.FriendlyId }, "Price snapshot " + snapshotId + " on price card " + card.FriendlyId + " was not found.")
                .ConfigureAwait(false);

                return(arg);
            }

            ViewProperty currency = arg.Properties.FirstOrDefault(p => p.Name.Equals("Currency", StringComparison.OrdinalIgnoreCase));

            if (string.IsNullOrEmpty(currency?.Value))
            {
                await context.CommerceContext.AddMessage(errorsCodes.ValidationError, "InvalidOrMissingPropertyValue", new object[] { currency == null ? "Currency" : currency.DisplayName }, "Invalid or missing value for property 'Currency'.")
                .ConfigureAwait(false);

                return(arg);
            }

            List <Model> list = arg.ChildViews.Where(v => v.Name.Equals(context.GetPolicy <KnownCustomPricingViewsPolicy>().PriceCustomCell, StringComparison.OrdinalIgnoreCase))
                                .ToList();

            if (!list.Any())
            {
                await context.CommerceContext.AddMessage(errorsCodes.ValidationError, "InvalidOrMissingPropertyValue", new object[] { "Tiers" }, "Invalid or missing value for property 'Tiers'.")
                .ConfigureAwait(false);

                return(arg);
            }

            List <CustomPriceTier> tiersToAdd    = new List <CustomPriceTier>();
            List <CustomPriceTier> tiersToEdit   = new List <CustomPriceTier>();
            List <CustomPriceTier> tiersToDelete = new List <CustomPriceTier>();
            bool hasError = false;

            foreach (EntityView entityView in list.Cast <EntityView>())
            {
                ViewProperty quantityViewProperty = entityView.Properties.FirstOrDefault(p => p.Name.Equals("Quantity", StringComparison.OrdinalIgnoreCase));
                decimal      quantity;

                if (!decimal.TryParse(quantityViewProperty?.Value, out quantity))
                {
                    await context.CommerceContext.AddMessage(errorsCodes.ValidationError, "InvalidOrMissingPropertyValue", new object[] { quantityViewProperty == null ? "Quantity" : quantityViewProperty.DisplayName }, "Invalid or missing value for property 'Quantity'.")
                    .ConfigureAwait(false);

                    hasError = true;
                }
                else
                {
                    ViewProperty membershipLevel = entityView.Properties.FirstOrDefault(p => p.Name.Equals("MembershipLevel", StringComparison.OrdinalIgnoreCase));

                    if (string.IsNullOrEmpty(currency?.Value))
                    {
                        await context.CommerceContext.AddMessage(errorsCodes.ValidationError, "InvalidOrMissingPropertyValue", new object[] { currency == null ? "MembershipLevel" : currency.DisplayName }, "Invalid or missing value for property 'MembershipLevel'.")
                        .ConfigureAwait(false);

                        hasError = true;
                    }
                    else
                    {
                        ViewProperty priceViewProperty = entityView.Properties.FirstOrDefault(p => p.Name.Equals("Price", StringComparison.OrdinalIgnoreCase));
                        decimal      result;
                        bool         isPriceParsed            = decimal.TryParse(priceViewProperty?.Value, out result);
                        var          membershipTiersComponent = snapshot.GetComponent <MembershipTiersComponent>();

                        CustomPriceTier priceTier = membershipTiersComponent.Tiers.FirstOrDefault(t => t.Currency == currency.Value && t.Quantity == quantity && t.MembershipLevel == membershipLevel.Value);

                        if (priceTier == null)
                        {
                            if (!isPriceParsed)
                            {
                                await context.CommerceContext.AddMessage(errorsCodes.ValidationError, "InvalidOrMissingPropertyValue", new object[] { priceViewProperty == null ? "Price" : priceViewProperty.DisplayName }, "Invalid or missing value for property 'Price'.")
                                .ConfigureAwait(false);

                                hasError = true;
                            }
                            else
                            {
                                tiersToAdd.Add(new CustomPriceTier(currency.Value, quantity, result, membershipLevel.Value));
                            }
                        }
                        else if (!isPriceParsed)
                        {
                            tiersToDelete.Add(priceTier);
                        }
                        else
                        {
                            priceTier.Price           = result;
                            priceTier.Quantity        = quantity;
                            priceTier.MembershipLevel = membershipLevel.Value;
                            tiersToEdit.Add(priceTier);
                        }
                    }
                }
            }

            if (hasError)
            {
                return(arg);
            }

            if (tiersToAdd.Any())
            {
                await _addPriceTierCommand.Process(context.CommerceContext, card, snapshot, tiersToAdd)
                .ConfigureAwait(false);
            }

            if (tiersToDelete.Any() && !context.CommerceContext.HasErrors())
            {
                await _removeCustomPriceTierCommand.Process(context.CommerceContext, card, snapshot, tiersToDelete)
                .ConfigureAwait(false);
            }

            if (tiersToEdit.Any() && !context.CommerceContext.HasErrors())
            {
                await _editPriceTierCommand.Process(context.CommerceContext, card, snapshot, tiersToEdit)
                .ConfigureAwait(false);
            }

            return(arg);
        }
Esempio n. 4
0
 public PriceCardSnapshotCustomTierArgument(PriceCard priceCard, PriceSnapshotComponent priceSnapshot, CustomPriceTier priceTier)
     : base(priceCard, priceSnapshot)
 {
     Condition.Requires(priceTier).IsNotNull("The price tier can not be null");
     PriceTier = priceTier;
 }
Esempio n. 5
0
        public virtual async Task <PriceCard> Process(CommerceContext commerceContext, PriceCard priceCard, PriceSnapshotComponent priceSnapshot, CustomPriceTier priceTier)
        {
            PriceCard result = null;

            using (CommandActivity.Start(commerceContext, this))
            {
                await PerformTransaction(commerceContext, async() =>
                {
                    result = await _removeCustomPriceTierPipeline.Run(new PriceCardSnapshotCustomTierArgument(priceCard, priceSnapshot, priceTier), commerceContext.GetPipelineContextOptions())
                             .ConfigureAwait(false);
                }).ConfigureAwait(false);
            }
            return(result);
        }
Esempio n. 6
0
        public virtual async Task <PriceCard> Process(CommerceContext commerceContext, PriceCard priceCard, PriceSnapshotComponent priceSnapshot, CustomPriceTier priceTier)
        {
            PriceCard result = null;

            using (CommandActivity.Start(commerceContext, this))
            {
                var priceSnapshotById = await GetPriceSnapshot(commerceContext, priceCard, priceSnapshot.Id)
                                        .ConfigureAwait(false);

                if (priceSnapshotById == null)
                {
                    return(null);
                }

                await PerformTransaction(commerceContext, (async() => result = await _addCustomPriceTierPipeline.Run(new PriceCardSnapshotCustomTierArgument(priceCard, priceSnapshotById, priceTier), commerceContext.GetPipelineContextOptions()).ConfigureAwait(false)))
                .ConfigureAwait(false);

                return(result);
            }
        }
        public override async Task <EntityView> Run(EntityView arg, CommercePipelineExecutionContext context)
        {
            if (string.IsNullOrEmpty(arg?.Action) || !arg.Action.Equals(context.GetPolicy <KnownCustomPricingActionsPolicy>().RemoveMembershipCurrency, StringComparison.OrdinalIgnoreCase))
            {
                return(arg);
            }

            PriceCard card = context.CommerceContext.GetObjects <PriceCard>().FirstOrDefault(p => p.Id.Equals(arg.EntityId, StringComparison.OrdinalIgnoreCase));

            if (card == null)
            {
                return(arg);
            }

            if (string.IsNullOrEmpty(arg.ItemId))
            {
                await context.CommerceContext.AddMessage(context.GetPolicy <KnownResultCodes>().ValidationError, "InvalidOrMissingPropertyValue", new object[] { "ItemId" }, "Invalid or missing value for property 'ItemId'.")
                .ConfigureAwait(false);

                return(arg);
            }

            string[] strArray = arg.ItemId.Split('|');

            if (strArray.Length != 2 || string.IsNullOrEmpty(strArray[0]) || string.IsNullOrEmpty(strArray[1]))
            {
                string str = await context.CommerceContext.AddMessage(context.GetPolicy <KnownResultCodes>().ValidationError, "InvalidOrMissingPropertyValue", new object[] { "ItemId (Correct format is snapshotId|currency)" }, "Invalid or missing value for property 'ItemId (Correct format is snapshotId|currency)'.")
                             .ConfigureAwait(false);

                return(arg);
            }
            string snapshotId = strArray[0];
            string currency   = strArray[1];
            PriceSnapshotComponent snapshotComponent = card.Snapshots.FirstOrDefault(s => s.Id.Equals(snapshotId, StringComparison.OrdinalIgnoreCase));

            if (snapshotComponent == null)
            {
                await context.CommerceContext.AddMessage(context.GetPolicy <KnownResultCodes>().ValidationError, "PriceSnapshotNotFound", new object[] { snapshotId, card.FriendlyId }, "Price snapshot " + snapshotId + " on price card " + card.FriendlyId + " was not found.")
                .ConfigureAwait(false);

                return(arg);
            }

            var membershipTiersComponent = snapshotComponent.GetComponent <MembershipTiersComponent>();

            List <CustomPriceTier> list = membershipTiersComponent.Tiers.Where(t => t.Currency.Equals(currency, StringComparison.OrdinalIgnoreCase)).ToList();

            if (!list.Any())
            {
                await context.CommerceContext.AddMessage(context.GetPolicy <KnownResultCodes>().ValidationError, "CurrencyNotFound", new object[] { currency, snapshotId, card.FriendlyId }, "Currency '" + currency + "' for price snapshot '" + snapshotId + "' on price card '" + card.FriendlyId + "' was not found.")
                .ConfigureAwait(false);

                return(arg);
            }

            foreach (CustomPriceTier priceTier in list)
            {
                PriceCard priceCard = await _removeCustomPriceTierCommand.Process(context.CommerceContext, card.FriendlyId, snapshotId, priceTier.Id).ConfigureAwait(false);
            }


            return(arg);
        }
Esempio n. 8
0
        public override async Task <PriceCard> Run(PriceCard arg, CommercePipelineExecutionContext context)
        {
            Condition.Requires(arg).IsNotNull(Name + ": The price card can not be null");
            PriceCard card     = arg;
            var       argument = context.CommerceContext.GetObjects <PriceCardSnapshotCustomTierArgument>().FirstOrDefault();
            CommercePipelineExecutionContext executionContext;

            if (argument == null)
            {
                executionContext = context;
                CommerceContext commerceContext = context.CommerceContext;
                string          error           = context.GetPolicy <KnownResultCodes>().Error;
                string          defaultMessage  = "Argument of type " + typeof(PriceCardSnapshotCustomTierArgument).Name + " was not found in context.";
                executionContext.Abort(await commerceContext.AddMessage(error, "ArgumentNotFound", new object[] { typeof(PriceCardSnapshotCustomTierArgument).Name }, defaultMessage)
                                       .ConfigureAwait(false), context);
                executionContext = null;

                return(card);
            }

            Condition.Requires(argument.PriceSnapshot).IsNotNull(Name + ": The price snapshot can not be null");
            Condition.Requires(argument.PriceSnapshot.Id).IsNotNullOrEmpty(Name + ": The price snapshot id can not be null or empty");
            Condition.Requires(argument.PriceTier).IsNotNull(Name + ": The price tier can not be null");
            Condition.Requires(argument.PriceTier.Currency).IsNotNullOrEmpty(Name + ": The price tier currency can not be null or empty");

            PriceBook book = await _findEntityPipeline.Run(new FindEntityArgument(typeof(PriceBook), card.Book.EntityTarget, false), context)
                             .ConfigureAwait(false) as PriceBook;

            CurrencySet currencySet = await _getCurrencySetPipeline.Run(book?.CurrencySet?.EntityTarget, context)
                                      .ConfigureAwait(false);

            if (!(currencySet != null &&
                  currencySet.HasComponent <CurrenciesComponent>() &&
                  currencySet.GetComponent <CurrenciesComponent>().Currencies.Any(c => c.Code.Equals(argument.PriceTier.Currency, StringComparison.OrdinalIgnoreCase))))
            {
                executionContext = context;
                CommerceContext commerceContext = context.CommerceContext;
                string          error           = context.GetPolicy <KnownResultCodes>().Error;
                string          defaultMessage  = "Currency '" + argument.PriceTier.Currency + "' is no longer valid for book '" + book?.FriendlyId + "'. Either remove the tier or modify the book to include the currency.";
                executionContext.Abort(await commerceContext.AddMessage(error, "CurrencyNotLongerValid", new object[] { argument.PriceTier.Currency, book?.FriendlyId }, defaultMessage).ConfigureAwait(false), (object)context);
                executionContext = null;

                return(card);
            }

            GlobalPricingPolicy policy = context.GetPolicy <GlobalPricingPolicy>();

            if (argument.PriceTier.Price < policy.MinimumPrice)
            {
                executionContext = context;
                CommerceContext commerceContext = context.CommerceContext;
                string          error           = context.GetPolicy <KnownResultCodes>().Error;
                string          defaultMessage  = string.Format("Invalid price. Minimum price allowed is '{0}'.", (object)policy.MinimumPrice);
                executionContext.Abort(await commerceContext.AddMessage(error, "InvalidPrice", new object[] { policy.MinimumPrice }, defaultMessage).ConfigureAwait(false), context);
                executionContext = null;

                return(card);
            }

            PriceSnapshotComponent snapshot          = argument.PriceSnapshot;
            PriceSnapshotComponent snapshotComponent = card.Snapshots.FirstOrDefault(n => n.Id.Equals(snapshot.Id, StringComparison.OrdinalIgnoreCase));

            if (snapshotComponent == null)
            {
                await context.CommerceContext.AddMessage(context.GetPolicy <KnownResultCodes>().ValidationError, "PriceSnapshotNotFound", new object[] { snapshot.Id, card.FriendlyId }, "Price snapshot '" + snapshot.Id + "' on price card '" + card.FriendlyId + "' was not found.")
                .ConfigureAwait(false);

                return(card);
            }

            var tier = argument.PriceTier;

            if (string.IsNullOrEmpty(tier.Id))
            {
                tier.Id = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture);
            }

            var membershipTiersComponent = snapshotComponent.GetComponent <MembershipTiersComponent>();
            var existingTier             = membershipTiersComponent?.Tiers.FirstOrDefault(t => t.Id.Equals(tier.Id, StringComparison.OrdinalIgnoreCase));

            if (existingTier == null)
            {
                executionContext = context;
                CommerceContext commerceContext = context.CommerceContext;
                string          validationError = context.GetPolicy <KnownResultCodes>().ValidationError;
                string          defaultMessage  = "Price tier '" + tier.Id + "' was not found in snapshot '" + snapshot.Id + "' for card '" + card.FriendlyId + ".";
                executionContext.Abort(await commerceContext.AddMessage(validationError, "PriceTierNotFound", new object[] { tier.Id, snapshot.Id, card.FriendlyId }, defaultMessage).ConfigureAwait(false), context);
                executionContext = null;
                return(card);
            }

            await context.CommerceContext.AddMessage(context.GetPolicy <KnownResultCodes>().Information, null, null, "Edited price tier '" + tier.Id + "' from price snapshot '" + snapshot.Id + "'").ConfigureAwait(false);

            existingTier.Price = tier.Price;

            return(card);
        }
Esempio n. 9
0
        public override async Task <PriceCard> Run(PriceCard arg, CommercePipelineExecutionContext context)
        {
            Condition.Requires(arg).IsNotNull(Name + ": The price card can not be null");
            PriceCard card = arg;
            PriceCardSnapshotCustomTierArgument argument = context.CommerceContext.GetObjects <PriceCardSnapshotCustomTierArgument>().FirstOrDefault();
            CommercePipelineExecutionContext    executionContext;

            if (argument == null)
            {
                executionContext = context;
                var    commerceContext = context.CommerceContext;
                string error           = context.GetPolicy <KnownResultCodes>().Error;
                string defaultMessage  = "Argument of type " + typeof(PriceCardSnapshotCustomTierArgument).Name + " was not found in context.";
                executionContext.Abort(await commerceContext.AddMessage(error, "ArgumentNotFound", new object[] { typeof(PriceCardSnapshotCustomTierArgument).Name }, defaultMessage)
                                       .ConfigureAwait(false), context);
                executionContext = null;

                return(card);
            }

            Condition.Requires(argument.PriceSnapshot).IsNotNull(Name + ": The price snapshot cannot be null.");
            Condition.Requires(argument.PriceSnapshot.Id).IsNotNullOrEmpty(Name + ": The price snapshot id cannot be null or empty.");
            Condition.Requires(argument.PriceTier).IsNotNull(Name + ": The price tier cannot be null.");
            Condition.Requires(argument.PriceTier.Currency).IsNotNullOrEmpty(Name + ": The price tier currency cannot be null or empty.");
            Condition.Requires(argument.PriceTier.Quantity).IsNotNull(Name + ": The price tier quantity cannot be null.");
            Condition.Requires(argument.PriceTier.Price).IsNotNull(Name + ": The price tier price cannot be null.");

            var snapshot = argument.PriceSnapshot;
            var tier     = argument.PriceTier;
            var membershipTiersComponent = snapshot.GetComponent <MembershipTiersComponent>();

            if (membershipTiersComponent.Tiers.Any(x => x.Currency == tier.Currency && x.MembershipLevel == tier.MembershipLevel && x.Quantity == tier.Quantity))
            {
                executionContext = context;
                CommerceContext commerceContext = context.CommerceContext;
                string          validationError = context.GetPolicy <KnownResultCodes>().ValidationError;
                string          defaultMessage  = "A tier for specified Currency, Membership Level and Quantity already exists for price snapshot '" + snapshot.Id + "' in price card '" + card.FriendlyId + "'.";
                executionContext.Abort(await commerceContext.AddMessage(validationError, "PriceTierAlreadyExists", new object[] { snapshot.Id, card.FriendlyId }, defaultMessage)
                                       .ConfigureAwait(false), context);
                executionContext = null;

                return(card);
            }

            GlobalPricingPolicy policy = context.GetPolicy <GlobalPricingPolicy>();

            if (argument.PriceTier.Quantity <= policy.MinimumPricingQuantity)
            {
                executionContext = context;
                CommerceContext commerceContext = context.CommerceContext;
                string          error           = context.GetPolicy <KnownResultCodes>().Error;
                string          defaultMessage  = string.Format("Invalid quantity. Quantity must be greater than '{0}'.", policy.MinimumPricingQuantity);
                executionContext.Abort(await commerceContext.AddMessage(error, "InvalidQuantity", new object[] { policy.MinimumPricingQuantity }, defaultMessage)
                                       .ConfigureAwait(false), context);
                executionContext = null;

                return(card);
            }

            if (argument.PriceTier.Price < policy.MinimumPrice)
            {
                executionContext = context;
                CommerceContext commerceContext = context.CommerceContext;
                string          error           = context.GetPolicy <KnownResultCodes>().Error;
                string          defaultMessage  = string.Format("Invalid price. Minimum price allowed is '{0}'.", policy.MinimumPrice);
                executionContext.Abort(await commerceContext.AddMessage(error, "InvalidPrice", new object[] { policy.MinimumPrice }, defaultMessage)
                                       .ConfigureAwait(false), context);
                executionContext = null;

                return(card);
            }

            PriceBook priceBook = await _findEntityPipeline.Run(new FindEntityArgument(typeof(PriceBook), card.Book.EntityTarget, false), context)
                                  .ConfigureAwait(false) as PriceBook;

            CurrencySet currencySet = await _getCurrencySetPipeline.Run(priceBook?.CurrencySet?.EntityTarget, context)
                                      .ConfigureAwait(false);

            bool   flag = false;
            string str  = string.Empty;

            if (currencySet != null && currencySet.HasComponent <CurrenciesComponent>())
            {
                CurrenciesComponent component = currencySet.GetComponent <CurrenciesComponent>();
                str = string.Join(", ", component.Currencies.Select(c => c.Code));
                if (component.Currencies.Any(c => c.Code.Equals(argument.PriceTier.Currency, StringComparison.OrdinalIgnoreCase)))
                {
                    flag = true;
                }
            }

            if (!flag)
            {
                executionContext = context;
                CommerceContext commerceContext = context.CommerceContext;
                string          validationError = context.GetPolicy <KnownResultCodes>().ValidationError;
                string          defaultMessage  = "Invalid currency '" + argument.PriceTier.Currency + "'. Valid currencies are '" + str + "'.";
                executionContext.Abort(await commerceContext.AddMessage(validationError, "InvalidCurrency", new object[] { argument.PriceTier.Currency, str }, defaultMessage)
                                       .ConfigureAwait(false), context);
                executionContext = null;

                return(card);
            }

            tier.Id = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture);
            PriceSnapshotComponent snapshotComponent = card.Snapshots.FirstOrDefault(n => n.Id.Equals(snapshot.Id, StringComparison.OrdinalIgnoreCase));

            if (snapshotComponent != null)
            {
                var component = snapshotComponent.GetComponent <MembershipTiersComponent>();
                if (component != null)
                {
                    component.Tiers.Add(tier);
                }
            }

            PriceTierAdded priceTierAdded = new PriceTierAdded(tier.Id)
            {
                Name = tier.Name
            };

            context.CommerceContext.AddModel(priceTierAdded);

            return(card);
        }
        protected virtual async Task <CustomPriceTier> GetCustomPriceTier(CommerceContext context, PriceCard priceCard, PriceSnapshotComponent priceSnapshot, string priceTierId)
        {
            if (priceCard == null ||
                priceSnapshot == null ||
                string.IsNullOrEmpty(priceTierId))
            {
                return(null);
            }

            var membershipTiersComponent = priceSnapshot.GetComponent <MembershipTiersComponent>();
            var existingPriceTier        = membershipTiersComponent.Tiers.FirstOrDefault(t => t.Id.Equals(priceTierId, StringComparison.OrdinalIgnoreCase));

            if (existingPriceTier != null)
            {
                return(existingPriceTier);
            }

            await context.AddMessage(context.GetPolicy <KnownResultCodes>().ValidationError, "PriceTierNotFound",
                                     new object[] { priceTierId, priceSnapshot.Id, priceCard.FriendlyId }, "Price tier " + priceTierId + " was not found in snapshot " + priceSnapshot.Id + " for card " + priceCard.FriendlyId + ".")
            .ConfigureAwait(false);

            return(existingPriceTier);
        }
Esempio n. 11
0
        public override async Task <SellableItem> Run(
            SellableItem arg,
            CommercePipelineExecutionContext context)
        {
            if (arg == null)
            {
                return(null);
            }

            if (arg.HasPolicy <PurchaseOptionMoneyPolicy>() && arg.GetPolicy <PurchaseOptionMoneyPolicy>().Expires > DateTimeOffset.UtcNow && arg.GetPolicy <PurchaseOptionMoneyPolicy>().SellPrice.CurrencyCode.Equals(context.CommerceContext.CurrentCurrency(), StringComparison.OrdinalIgnoreCase))
            {
                return(arg);
            }

            if (arg.HasComponent <PriceSnapshotComponent>())
            {
                arg.Components.Remove(arg.GetComponent <PriceSnapshotComponent>());
            }

            string                 currentCurrency   = context.CommerceContext.CurrentCurrency();
            MessagesComponent      messagesComponent = arg.GetComponent <MessagesComponent>();
            Money                  sellPrice         = null;
            PriceCardPolicy        priceCardPolicy   = arg.Policies.OfType <PriceCardPolicy>().FirstOrDefault();
            PriceSnapshotComponent snapshotComponent = null;
            bool pricingByTags = false;

            if (!string.IsNullOrEmpty(priceCardPolicy?.PriceCardName))
            {
                snapshotComponent = await _resolveSnapshotByCardPipeline.Run(priceCardPolicy.PriceCardName, context);
            }
            else if (arg.Tags.Any())
            {
                snapshotComponent = await _resolveSnapshotByTagsPipeline.Run(arg.Tags, context);

                pricingByTags = true;
            }

            PriceTier priceTier = snapshotComponent?.Tiers.FirstOrDefault(t =>
            {
                return(t.Currency.Equals(currentCurrency, StringComparison.OrdinalIgnoreCase) ? t.Quantity == decimal.One : 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 customerMemerbshipLevelName     = membershipSubscriptionComponent.MemerbshipLevelName;
                var memerbshipLevelName             = membershipSubscriptionComponent.MemerbshipLevelName;

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

                    if (membershipPriceTier != null)
                    {
                        sellPrice = new Money(membershipPriceTier.Currency, membershipPriceTier.Price);
                        isMembershipLevelPrice = true;
                        messagesComponent.AddMessage(context.GetPolicy <KnownMessageCodePolicy>().Pricing, pricingByTags
                            ? string.Format("SellPrice<=Tags.Snapshot: MembershipLevel={0}|Price={1}|Qty={2}|Tags='{3}'", customerMemerbshipLevelName, sellPrice.AsCurrency(false, null), membershipPriceTier.Quantity, string.Join(", ", snapshotComponent.Tags.Select(c => c.Name)))
                            : string.Format("SellPrice<=PriceCard.Snapshot: MembershipLevel={0}|Price={1}|Qty={2}|PriceCard={3}", customerMemerbshipLevelName, sellPrice.AsCurrency(false, null), membershipPriceTier.Quantity, priceCardPolicy.PriceCardName));
                    }
                }
            }

            if (!isMembershipLevelPrice && priceTier != null)
            {
                sellPrice = new Money(priceTier.Currency, priceTier.Price);
                messagesComponent.AddMessage(context.GetPolicy <KnownMessageCodePolicy>().Pricing, pricingByTags ? string.Format("SellPrice<=Tags.Snapshot: Price={0}|Qty={1}|Tags='{2}'", sellPrice.AsCurrency(false, null), priceTier.Quantity, string.Join(", ", snapshotComponent.Tags.Select(c => c.Name))) : string.Format("SellPrice<=PriceCard.Snapshot: Price={0}|Qty={1}|PriceCard={2}", sellPrice.AsCurrency(false, null), priceTier.Quantity, priceCardPolicy.PriceCardName));
            }

            if (snapshotComponent != null)
            {
                arg.SetComponent(snapshotComponent);
            }

            if (sellPrice != null)
            {
                arg.SetPolicy(new PurchaseOptionMoneyPolicy()
                {
                    SellPrice = sellPrice
                });
            }

            return(arg);
        }
        protected virtual async Task PopulateRowDetails(EntityView view, PriceCard card, string itemId, bool isAddAction, bool isEditAction, CommercePipelineExecutionContext context)
        {
            if (view == null || card == null || string.IsNullOrEmpty(itemId))
            {
                return;
            }

            if (isAddAction)
            {
                CurrencySet currencySet  = null;
                string      entityTarget = (await _findEntityCommand.Process(context.CommerceContext, typeof(PriceBook), card.Book.EntityTarget, false).ConfigureAwait(false) as PriceBook)?.CurrencySet.EntityTarget;

                if (!string.IsNullOrEmpty(entityTarget))
                {
                    currencySet = await _getCurrencySetCommand.Process(context.CommerceContext, entityTarget).ConfigureAwait(false);
                }

                List <Policy> commercePolicies = new List <Policy>()
                {
                    new AvailableSelectionsPolicy(currencySet == null ||
                                                  !currencySet.HasComponent <CurrenciesComponent>() ?  new List <Selection>() :  currencySet.GetComponent <CurrenciesComponent>().Currencies.Select(c =>
                    {
                        return(new Selection()
                        {
                            DisplayName = c.Code,
                            Name = c.Code
                        });
                    }).ToList(), false)
                };

                ViewProperty item = new ViewProperty()
                {
                    Name     = "Currency",
                    RawValue = string.Empty,
                    Policies = commercePolicies
                };
                view.Properties.Add(item);
            }
            else
            {
                string[] strArray = itemId.Split('|');
                if (strArray.Length != 2 || string.IsNullOrEmpty(strArray[0]) || string.IsNullOrEmpty(strArray[1]))
                {
                    context.Logger.LogError("Expecting a SnapshotId and Currency in the ItemId: " + itemId + ". Correct format is 'snapshotId|currency'", Array.Empty <object>());
                }
                else
                {
                    string snapshotId = strArray[0];
                    string currency   = strArray[1];
                    PriceSnapshotComponent snapshotComponent = card.Snapshots.FirstOrDefault(s => s.Id.Equals(snapshotId, StringComparison.OrdinalIgnoreCase));

                    if (snapshotComponent == null)
                    {
                        context.Logger.LogError("Price snapshot " + snapshotId + " on price card " + card.FriendlyId + " was not found.", Array.Empty <object>());
                    }
                    else
                    {
                        var list = snapshotComponent.GetComponent <MembershipTiersComponent>().Tiers;
                        IGrouping <string, CustomPriceTier> currencyGroup = list.GroupBy(t => t.Currency)
                                                                            .ToList()
                                                                            .FirstOrDefault(g => g.Key.Equals(currency, StringComparison.OrdinalIgnoreCase));

                        if (currencyGroup == null)
                        {
                            context.Logger.LogError("Price row " + currency + " was not found in snapshot " + snapshotId + " for card " + card.FriendlyId + ".", Array.Empty <object>());
                        }
                        else
                        {
                            view.Properties.Add(new ViewProperty
                            {
                                Name       = "Currency",
                                RawValue   = currencyGroup.Key,
                                IsReadOnly = true
                            });

                            if (isEditAction)
                            {
                                view.UiHint = "Grid";
                                currencyGroup.ForEach(tier =>
                                {
                                    EntityView entityView = new EntityView()
                                    {
                                        Name     = context.GetPolicy <KnownCustomPricingViewsPolicy>().PriceCustomCell,
                                        EntityId = card.Id,
                                        ItemId   = itemId
                                    };

                                    var membershipLevels = context.GetPolicy <MembershipLevelPolicy>().MembershipLevels;

                                    ViewProperty item1 = new ViewProperty()
                                    {
                                        Name         = "MembershipLevel",
                                        RawValue     = tier.MembershipLevel,
                                        OriginalType = typeof(string).FullName,
                                        IsReadOnly   = true,
                                        Policies     = new List <Policy>()
                                        {
                                            new AvailableSelectionsPolicy(membershipLevels.Select(c =>
                                            {
                                                return(new Selection()
                                                {
                                                    DisplayName = c.MemerbshipLevelName,
                                                    Name = c.MemerbshipLevelName
                                                });
                                            }).ToList(), false)
                                        }
                                    };
                                    entityView.Properties.Add(item1);

                                    entityView.Properties.Add(new ViewProperty()
                                    {
                                        Name       = "Quantity",
                                        RawValue   = tier.Quantity,
                                        IsReadOnly = true
                                    });

                                    entityView.Properties.Add(new ViewProperty()
                                    {
                                        Name       = "Price",
                                        RawValue   = tier.Price,
                                        IsRequired = false
                                    });

                                    view.ChildViews.Add(entityView);
                                });
                            }
                            else
                            {
                                view.Properties.Add(new ViewProperty
                                {
                                    Name       = "ItemId",
                                    RawValue   = itemId,
                                    IsReadOnly = true,
                                    IsHidden   = true
                                });

                                list.Select(t => t.MembershipLevel).Distinct().OrderBy(q => q).ToList().ForEach(availableMembershipLevel =>
                                {
                                    CustomPriceTier priceTier      = currencyGroup.FirstOrDefault(ct => ct.MembershipLevel == availableMembershipLevel);
                                    List <ViewProperty> properties = view.Properties;
                                    properties.Add(new ViewProperty()
                                    {
                                        Name       = availableMembershipLevel.ToString(CultureInfo.InvariantCulture),
                                        RawValue   = priceTier?.Price,
                                        IsReadOnly = true
                                    });
                                });
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        ///     Creates the tags card.
        /// </summary>
        /// <param name="book">The book.</param>
        /// <param name="context">The context.</param>
        private async Task CreateTagsCard(PriceBook book, CommercePipelineExecutionContext context)
        {
            // TAGS CARD
            PriceCard card = await _addPriceCardPipeline
                             .Run(new AddPriceCardArgument(book, "Habitat_TagsPriceCard"), context).ConfigureAwait(false);

            // TAGS CARD FIRST SNAPSHOT
            card = await _addPriceSnapshotPipeline
                   .Run(new PriceCardSnapshotArgument(card, new PriceSnapshotComponent(DateTimeOffset.UtcNow)), context)
                   .ConfigureAwait(false);

            PriceSnapshotComponent firstSnapshot = card.Snapshots.FirstOrDefault();

            // TAGS CARD FIRST SNAPSHOT  TIERS
            card = await _addPriceTierPipeline
                   .Run(new PriceCardSnapshotTierArgument(card, firstSnapshot, new PriceTier("USD", 1, 250M)), context)
                   .ConfigureAwait(false);

            card = await _addPriceTierPipeline
                   .Run(new PriceCardSnapshotTierArgument(card, firstSnapshot, new PriceTier("USD", 5, 200M)), context)
                   .ConfigureAwait(false);

            card = await _addPriceTierPipeline
                   .Run(new PriceCardSnapshotTierArgument(card, firstSnapshot, new PriceTier("CAD", 1, 251M)), context)
                   .ConfigureAwait(false);

            card = await _addPriceTierPipeline
                   .Run(new PriceCardSnapshotTierArgument(card, firstSnapshot, new PriceTier("CAD", 5, 201M)), context)
                   .ConfigureAwait(false);

            // TAGS CARD FIRST SNAPSHOT TAGS
            card = await _addPriceSnapshotTagPipeline
                   .Run(new PriceCardSnapshotTagArgument(card, firstSnapshot, new Tag("Habitat")), context)
                   .ConfigureAwait(false);

            card = await _addPriceSnapshotTagPipeline
                   .Run(new PriceCardSnapshotTagArgument(card, firstSnapshot, new Tag("Habitat 2")), context)
                   .ConfigureAwait(false);

            card = await _addPriceSnapshotTagPipeline
                   .Run(new PriceCardSnapshotTagArgument(card, firstSnapshot, new Tag("common")), context)
                   .ConfigureAwait(false);

            // TAGS CARD SECOND SNAPSHOT
            card = await _addPriceSnapshotPipeline
                   .Run(new PriceCardSnapshotArgument(card, new PriceSnapshotComponent(DateTimeOffset.UtcNow.AddSeconds(1))),
                        context).ConfigureAwait(false);

            PriceSnapshotComponent secondSnapshot =
                card.Snapshots.FirstOrDefault(s => !s.Id.Equals(firstSnapshot?.Id, StringComparison.OrdinalIgnoreCase));

            // TAGS CARD SECOND SNAPSHOT TIERS
            card = await _addPriceTierPipeline
                   .Run(new PriceCardSnapshotTierArgument(card, secondSnapshot, new PriceTier("USD", 1, 150M)), context)
                   .ConfigureAwait(false);

            card = await _addPriceTierPipeline
                   .Run(new PriceCardSnapshotTierArgument(card, secondSnapshot, new PriceTier("USD", 5, 100M)), context)
                   .ConfigureAwait(false);

            card = await _addPriceTierPipeline
                   .Run(new PriceCardSnapshotTierArgument(card, secondSnapshot, new PriceTier("CAD", 1, 101M)), context)
                   .ConfigureAwait(false);

            card = await _addPriceTierPipeline
                   .Run(new PriceCardSnapshotTierArgument(card, secondSnapshot, new PriceTier("CAD", 5, 151M)), context)
                   .ConfigureAwait(false);

            // TAGS CARD SECOND SNAPSHOT TAGS
            card = await _addPriceSnapshotTagPipeline
                   .Run(new PriceCardSnapshotTagArgument(card, secondSnapshot, new Tag("Habitat variants")), context)
                   .ConfigureAwait(false);

            card = await _addPriceSnapshotTagPipeline
                   .Run(new PriceCardSnapshotTagArgument(card, secondSnapshot, new Tag("Habitat variants 2")), context)
                   .ConfigureAwait(false);

            card = await _addPriceSnapshotTagPipeline
                   .Run(new PriceCardSnapshotTagArgument(card, secondSnapshot, new Tag("common")), context)
                   .ConfigureAwait(false);

            // TAGS CARD APPROVAl COMPONENT
            card.Snapshots.ForEach(s =>
            {
                s.SetComponent(new ApprovalComponent(context.GetPolicy <ApprovalStatusPolicy>().Approved));
            });
            await _persistEntityPipeline.Run(new PersistEntityArgument(card), context).ConfigureAwait(false);
        }
        /// <summary>
        ///     Creates the variants card.
        /// </summary>
        /// <param name="book">The book.</param>
        /// <param name="context">The context.</param>
        private async Task CreateVariantsCard(PriceBook book, CommercePipelineExecutionContext context)
        {
            context.CommerceContext.RemoveModels(m => m is PriceSnapshotAdded || m is PriceTierAdded);

            DateTimeOffset date = DateTimeOffset.UtcNow;

            // VARIANTS CARD
            PriceCard adventureVariantsCard = await _addPriceCardPipeline
                                              .Run(new AddPriceCardArgument(book, "Habitat_VariantsPriceCard"), context)
                                              .ConfigureAwait(false);

            // READY FOR APPROVAL SNAPSHOT
            adventureVariantsCard = await _addPriceSnapshotPipeline
                                    .Run(
                new PriceCardSnapshotArgument(adventureVariantsCard,
                                              new PriceSnapshotComponent(date.AddMinutes(-10))), context)
                                    .ConfigureAwait(false);

            PriceSnapshotComponent readyForApprovalSnapshot =
                adventureVariantsCard.Snapshots.FirstOrDefault(s =>
                                                               s.Id.Equals(context.CommerceContext.GetModel <PriceSnapshotAdded>()?.PriceSnapshotId,
                                                                           StringComparison.OrdinalIgnoreCase));

            adventureVariantsCard = await _addPriceTierPipeline
                                    .Run(
                new PriceCardSnapshotTierArgument(adventureVariantsCard, readyForApprovalSnapshot,
                                                  new PriceTier("USD", 1, 2000M)), context).ConfigureAwait(false);

            context.CommerceContext.RemoveModels(m => m is PriceSnapshotAdded || m is PriceTierAdded);

            // FIRST APPROVED SNAPSHOT
            adventureVariantsCard = await _addPriceSnapshotPipeline
                                    .Run(
                new PriceCardSnapshotArgument(adventureVariantsCard,
                                              new PriceSnapshotComponent(date.AddHours(-1))), context).ConfigureAwait(false);

            PriceSnapshotComponent firstSnapshot = adventureVariantsCard.Snapshots.FirstOrDefault(s =>
                                                                                                  s.Id.Equals(
                                                                                                      context.CommerceContext
                                                                                                      .GetModel <PriceSnapshotAdded>()
                                                                                                      ?.PriceSnapshotId,
                                                                                                      StringComparison.OrdinalIgnoreCase));

            adventureVariantsCard = await _addPriceTierPipeline
                                    .Run(
                new PriceCardSnapshotTierArgument(adventureVariantsCard, firstSnapshot,
                                                  new PriceTier("USD", 1, 9M)), context).ConfigureAwait(false);

            adventureVariantsCard = await _addPriceTierPipeline
                                    .Run(
                new PriceCardSnapshotTierArgument(adventureVariantsCard, firstSnapshot,
                                                  new PriceTier("USD", 5, 6M)), context).ConfigureAwait(false);

            adventureVariantsCard = await _addPriceTierPipeline
                                    .Run(
                new PriceCardSnapshotTierArgument(adventureVariantsCard, firstSnapshot,
                                                  new PriceTier("USD", 10, 3M)), context).ConfigureAwait(false);

            adventureVariantsCard = await _addPriceTierPipeline
                                    .Run(
                new PriceCardSnapshotTierArgument(adventureVariantsCard, firstSnapshot,
                                                  new PriceTier("CAD", 1, 7M)), context).ConfigureAwait(false);

            adventureVariantsCard = await _addPriceTierPipeline
                                    .Run(
                new PriceCardSnapshotTierArgument(adventureVariantsCard, firstSnapshot,
                                                  new PriceTier("CAD", 5, 4M)), context).ConfigureAwait(false);

            adventureVariantsCard = await _addPriceTierPipeline
                                    .Run(
                new PriceCardSnapshotTierArgument(adventureVariantsCard, firstSnapshot,
                                                  new PriceTier("CAD", 10, 2M)), context).ConfigureAwait(false);

            adventureVariantsCard = await _addPriceTierPipeline
                                    .Run(
                new PriceCardSnapshotTierArgument(adventureVariantsCard, firstSnapshot,
                                                  new PriceTier("EUR", 1, 2M)), context).ConfigureAwait(false);

            context.CommerceContext.RemoveModels(m => m is PriceSnapshotAdded || m is PriceTierAdded);

            // DRAFT SNAPSHOT
            adventureVariantsCard = await _addPriceSnapshotPipeline
                                    .Run(
                new PriceCardSnapshotArgument(adventureVariantsCard,
                                              new PriceSnapshotComponent(date)), context).ConfigureAwait(false);

            PriceSnapshotComponent draftSnapshot = adventureVariantsCard.Snapshots.FirstOrDefault(s =>
                                                                                                  s.Id.Equals(
                                                                                                      context.CommerceContext
                                                                                                      .GetModel <PriceSnapshotAdded>()
                                                                                                      ?.PriceSnapshotId,
                                                                                                      StringComparison.OrdinalIgnoreCase));

            adventureVariantsCard = await _addPriceTierPipeline
                                    .Run(
                new PriceCardSnapshotTierArgument(adventureVariantsCard, draftSnapshot,
                                                  new PriceTier("USD", 1, 1000M)), context).ConfigureAwait(false);

            context.CommerceContext.RemoveModels(m => m is PriceSnapshotAdded || m is PriceTierAdded);

            // SECOND APPROVED SNAPSHOT
            adventureVariantsCard = await _addPriceSnapshotPipeline
                                    .Run(
                new PriceCardSnapshotArgument(adventureVariantsCard,
                                              new PriceSnapshotComponent(date.AddDays(30))), context).ConfigureAwait(false);

            PriceSnapshotComponent secondSnapshot = adventureVariantsCard.Snapshots.FirstOrDefault(s =>
                                                                                                   s.Id.Equals(
                                                                                                       context.CommerceContext
                                                                                                       .GetModel <PriceSnapshotAdded>()
                                                                                                       ?.PriceSnapshotId,
                                                                                                       StringComparison.OrdinalIgnoreCase));

            adventureVariantsCard = await _addPriceTierPipeline
                                    .Run(
                new PriceCardSnapshotTierArgument(adventureVariantsCard, secondSnapshot,
                                                  new PriceTier("USD", 1, 8M)), context).ConfigureAwait(false);

            adventureVariantsCard = await _addPriceTierPipeline
                                    .Run(
                new PriceCardSnapshotTierArgument(adventureVariantsCard, secondSnapshot,
                                                  new PriceTier("USD", 5, 4M)), context).ConfigureAwait(false);

            adventureVariantsCard = await _addPriceTierPipeline
                                    .Run(
                new PriceCardSnapshotTierArgument(adventureVariantsCard, secondSnapshot,
                                                  new PriceTier("USD", 10, 2M)), context).ConfigureAwait(false);

            adventureVariantsCard = await _addPriceTierPipeline
                                    .Run(
                new PriceCardSnapshotTierArgument(adventureVariantsCard, secondSnapshot,
                                                  new PriceTier("CAD", 1, 7M)), context).ConfigureAwait(false);

            adventureVariantsCard = await _addPriceTierPipeline
                                    .Run(
                new PriceCardSnapshotTierArgument(adventureVariantsCard, secondSnapshot,
                                                  new PriceTier("CAD", 5, 3M)), context).ConfigureAwait(false);

            adventureVariantsCard = await _addPriceTierPipeline
                                    .Run(
                new PriceCardSnapshotTierArgument(adventureVariantsCard, secondSnapshot,
                                                  new PriceTier("CAD", 10, 1M)), context).ConfigureAwait(false);

            adventureVariantsCard = await _addPriceTierPipeline
                                    .Run(
                new PriceCardSnapshotTierArgument(adventureVariantsCard, secondSnapshot,
                                                  new PriceTier("EUR", 1, 2M)), context).ConfigureAwait(false);

            context.CommerceContext.RemoveModels(m => m is PriceSnapshotAdded || m is PriceTierAdded);

            readyForApprovalSnapshot?.SetComponent(
                new ApprovalComponent(context.GetPolicy <ApprovalStatusPolicy>().ReadyForApproval));
            firstSnapshot?.SetComponent(new ApprovalComponent(context.GetPolicy <ApprovalStatusPolicy>().Approved));
            secondSnapshot?.SetComponent(new ApprovalComponent(context.GetPolicy <ApprovalStatusPolicy>().Approved));
            await _persistEntityPipeline.Run(new PersistEntityArgument(adventureVariantsCard), context).ConfigureAwait(false);
        }