public async void Should_qualify_when_operator_is_equal_and_fulfillment_method_is_same() { fixture.Factory.ClearAllEntities(); HttpClient client = fixture.Factory.CreateClient(); Promotion promotion = await new PromotionBuilder() .QualifiedBy(new CartFulfillmentConditionBuilder() .Equal() .WithValue("Standard")) .BenefitBy(new CartSubtotalPercentOffActionBuilder() .PercentOff(10)) .Build(fixture.Factory); fixture.Factory.AddEntityToList(promotion, CommerceEntity.ListName <Promotion>()); fixture.Factory.AddEntity(promotion); Cart cart = await new CartBuilder() .WithStandardFulfillment() .Build(); fixture.Factory.AddEntity(cart); Cart resultCart = await client.GetJsonAsync <Cart>( "api/Carts('Cart01')?$expand=Lines($expand=CartLineComponents($expand=ChildComponents)),Components"); Assert.Contains(resultCart.Adjustments, c => c.AwardingBlock == nameof(CartSubtotalPercentOffAction)); }
private void TransformCore(CommerceContext commerceContext, string[] rawFields, InventoryInformation item) { var inventorySetName = rawFields[InventoryIdIndex]; var productId = rawFields[ProductIdIndex]; int.TryParse(rawFields[QuantityIndex], out int quantity); string str = inventorySetName + "-" + productId; //if (!string.IsNullOrEmpty(arg.VariationId)) str = str + "-" + arg.VariationId; item.Id = CommerceEntity.IdPrefix <InventoryInformation>() + str; item.FriendlyId = str; item.InventorySet = new EntityReference(inventorySetName.ToEntityId <InventorySet>(), ""); item.SellableItem = new EntityReference(productId.ToEntityId <SellableItem>(), ""); //item.VariationId = arg.VariationId; item.Quantity = quantity; var component = item.GetComponent <ListMembershipsComponent>(); component.Memberships.Add(CommerceEntity.ListName <InventoryInformation>()); var component1 = item.GetComponent <PreorderableComponent>(); //component1.Preorderable = result1; //component1.PreorderAvailabilityDate = new DateTimeOffset?(); //component1.PreorderLimit = new int?(0); var component2 = item.GetComponent <BackorderableComponent>(); //component2.Backorderable = result3; //component2.BackorderAvailabilityDate = new DateTimeOffset?(); //component2.BackorderLimit = new int?(0); }
public async void Should_not_qualify_when_customer_is_not_registered() { fixture.Factory.ClearAllEntities(); HttpClient client = fixture.Factory.CreateClient(); var dateTime = new DateTimeOffset(new DateTime(2019, 12, 22)); Promotion promotion = await new PromotionBuilder() .QualifiedBy(new LastPurchaseDateConditionBuilder() .Operator(Operator.Equal) .Date(dateTime)) .BenefitBy(new CartSubtotalPercentOffActionBuilder() .PercentOff(10)) .Build(fixture.Factory); fixture.Factory.AddEntityToList(promotion, CommerceEntity.ListName <Promotion>()); fixture.Factory.AddEntity(promotion); Cart cart = await new CartBuilder().Build(); fixture.Factory.AddEntity(cart); Cart resultCart = await client.GetJsonAsync <Cart>( "api/Carts('Cart01')?$expand=Lines($expand=CartLineComponents($expand=ChildComponents)),Components", new Dictionary <string, string> { { "IsRegistered", "false" } }); Assert.DoesNotContain(resultCart.Adjustments, c => c.AwardingBlock == nameof(CartSubtotalPercentOffAction)); }
public async Task <Setting> Process(CommerceContext commerceContext, CreateSettingArg arg) { using (var activity = CommandActivity.Start(commerceContext, this)) { var setting = new Setting { Id = arg.Name.ToEntityId <Setting>(), DisplayName = arg.DisplayName, Name = arg.Name, IsActive = false }; var listMemberShipComponent = setting.GetComponent <ListMembershipsComponent>(); if (!listMemberShipComponent.Memberships.Contains(CommerceEntity.ListName <Setting>())) { listMemberShipComponent.Memberships.Add(CommerceEntity.ListName <Setting>()); setting.SetComponent(listMemberShipComponent); } var transientListMembershipComponent = setting.GetComponent <TransientListMembershipsComponent>(); if (!transientListMembershipComponent.Memberships.Contains(CommerceEntity.ListName <Setting>())) { transientListMembershipComponent.Memberships.Add(CommerceEntity.ListName <Setting>()); setting.SetComponent(transientListMembershipComponent); } var persistResult = await _commerceCommander.PersistEntity(commerceContext, setting); return(persistResult ? setting : null); } }
public async void Should_benefit_fulfillment_fee_if_discount_is_higher_than_fee() { fixture.Factory.ClearAllEntities(); HttpClient client = fixture.Factory.CreateClient(); Promotion promotion = await new PromotionBuilder() .QualifiedBy(new IsCurrentDayConditionBuilder() .Day(DateTime.Now.Day)) .BenefitBy(new CartAmountOffFulfillmentActionBuilder() .AmountOff(8)) // Fee = 5, Discount = 8 .Build(fixture.Factory); fixture.Factory.AddEntityToList(promotion, CommerceEntity.ListName <Promotion>()); fixture.Factory.AddEntity(promotion); Cart cart = await new CartBuilder() .WithLines(new LineBuilder().Quantity(1).Price(50)) .WithStandardFulfillment() // Default fulfillment fee = 5 .Build(); fixture.Factory.AddEntity(cart); Cart resultCart = await client.GetJsonAsync <Cart>( "api/Carts('Cart01')?$expand=Lines($expand=CartLineComponents($expand=ChildComponents)),Components"); AwardedAdjustment adjustment = resultCart.Adjustments.Single(x => x.AwardingBlock == nameof(CartAmountOffFulfillmentAction)); Assert.Equal(-5, adjustment.Adjustment.Amount); // Subtotal = 50, Tax is 10% = 5, Fulfillment fee = 5 - 5 = 0 Assert.Equal(55, resultCart.Totals.GrandTotal.Amount); }
public override async Task <WishList> Run(GetWishListArgument arg, CommercePipelineExecutionContext context) { GetWishListBlock getWishListBlock = this; Condition.Requires <string>(arg.WishListId).IsNotNullOrEmpty("The WishListId can not be null or empty"); List <WishList> objects = context.CommerceContext.GetObjects <WishList>(); if (objects.Any() && objects.FirstOrDefault(p => p.Id == arg.WishListId) != null) { context.Logger.LogWarning($"{getWishListBlock.Name}.AlreadyLoaded: CartId:{arg}", Array.Empty <object>()); } WishList wishlist = await getWishListBlock._findEntityPipeline.Run(new FindEntityArgument(typeof(WishList), arg.WishListId, true), context).ConfigureAwait(false) as WishList; if (wishlist == null || wishlist.IsPersisted) { return(wishlist); } wishlist.Id = arg.WishListId; wishlist.Name = arg.WishListName; wishlist.ShopName = arg.ShopName; wishlist.CustomerId = arg.ShopperId; wishlist.SetComponent(new ListMembershipsComponent() { Memberships = new List <string> { CommerceEntity.ListName <WishList>() } }); return(wishlist); }
protected override IEnumerable <string> GetListMemberships( CommercePipelineExecutionContext context) { return(new string[] { CommerceEntity.ListName <PriceCard>(), }); }
public async void Should_qualify_when_category_matches_multiple_orders() { fixture.Factory.ClearAllEntities(); HttpClient client = fixture.Factory.CreateClient(); Guid customerId = Guid.NewGuid(); Order order = new OrderBuilder() .WithLines(new LineBuilder() .Quantity(1) .Price(33) .InCategory("435345345")) .Build(); Order secondOrder = new OrderBuilder() .WithLines(new LineBuilder() .Quantity(1) .Price(33) .InCategory("435345345")) .Build(); fixture.Factory.AddEntitiesToList(string.Format(CultureInfo.InvariantCulture, "Orders-ByCustomer-{0}", customerId), order, secondOrder); Promotion promotion = await new PromotionBuilder() .QualifiedBy(new OrderHistoryTotalInCategoryConditionBuilder() .Operator(Operator.Equal) .Total(66) // Both orders have 1 product and total should be 2 .ForCategory("Laptops")) .BenefitBy(new CartSubtotalPercentOffActionBuilder() .PercentOff(10)) .Build(fixture.Factory); fixture.Factory.AddEntityToList(promotion, CommerceEntity.ListName <Promotion>()); fixture.Factory.AddEntity(promotion); fixture.Factory.AddEntity(new Category { Id = "Laptops".ToEntityId <Category>(), SitecoreId = "435345345" }); Cart cart = await new CartBuilder().Build(); fixture.Factory.AddEntity(cart); Cart resultCart = await client.GetJsonAsync <Cart>( "api/Carts('Cart01')?$expand=Lines($expand=CartLineComponents($expand=ChildComponents)),Components", new Dictionary <string, string> { { "IsRegistered", "true" }, { "CustomerId", customerId.ToString() } }); Assert.Contains(resultCart.Adjustments, c => c.AwardingBlock == nameof(CartSubtotalPercentOffAction)); }
public async void Should_match_operator(Operator @operator, int numberOfProductsInPromotion, int numberOfProductsInOrder, bool shouldQualify) { fixture.Factory.ClearAllEntities(); HttpClient client = fixture.Factory.CreateClient(); Guid customerId = Guid.NewGuid(); Order order = new OrderBuilder() .WithLines(new LineBuilder() .Quantity(numberOfProductsInOrder) .InCategory("435345345")) .Build(); fixture.Factory.AddEntityToList(order, string.Format(CultureInfo.InvariantCulture, "Orders-ByCustomer-{0}", customerId)); Promotion promotion = await new PromotionBuilder() .QualifiedBy(new OrderHistoryAmountInCategoryConditionBuilder() .Operator(@operator) .NumberOfProducts(numberOfProductsInPromotion) .ForCategory("Laptops")) .BenefitBy(new CartSubtotalPercentOffActionBuilder() .PercentOff(10)) .Build(fixture.Factory); fixture.Factory.AddEntityToList(promotion, CommerceEntity.ListName <Promotion>()); fixture.Factory.AddEntity(promotion); fixture.Factory.AddEntity(new Category { Id = "Laptops".ToEntityId <Category>(), SitecoreId = "435345345" }); Cart cart = await new CartBuilder().Build(); fixture.Factory.AddEntity(cart); Cart resultCart = await client.GetJsonAsync <Cart>( "api/Carts('Cart01')?$expand=Lines($expand=CartLineComponents($expand=ChildComponents)),Components", new Dictionary <string, string> { { "IsRegistered", "true" }, { "CustomerId", customerId.ToString() } }); if (shouldQualify) { Assert.Contains(resultCart.Adjustments, c => c.AwardingBlock == nameof(CartSubtotalPercentOffAction)); } else { Assert.DoesNotContain(resultCart.Adjustments, c => c.AwardingBlock == nameof(CartSubtotalPercentOffAction)); } }
/// <summary> /// The execute. /// </summary> /// <param name="arg"> /// The AddReviewArgument argument. /// </param> /// <param name="context"> /// The context. /// </param> /// <returns> /// The <see cref="Review"/>. /// </returns> public override async Task <Review> Run(AddReviewArgument arg, CommercePipelineExecutionContext context) { AddReviewBlock addReviewBlock = this; Condition.Requires(arg).IsNotNull($"{addReviewBlock.Name}: The block argument cannot be null."); string reviewId = Guid.NewGuid().ToString(); Review review = new Review { Id = $"{CommerceEntity.IdPrefix<Review>()}{reviewId}", Text = arg.ReviewsText, Author = arg.Author, Score = arg.Score }; DateTimeOffset?dateCreated = DateTimeOffset.UtcNow; review.DateCreated = dateCreated; DateTimeOffset?dateUpdated = DateTimeOffset.UtcNow; review.DateUpdated = dateUpdated; CommerceContext commerceContextRef = context.CommerceContext; string name = review.Name; review.ProductReference = new EntityReference() { EntityTarget = arg.Product.Id, Name = arg.Product.Name }; Review reviewRef = review; reviewRef.SetComponent(new ListMembershipsComponent() { Memberships = new List <string>() { CommerceEntity.ListName <Review>() } }); ReviewAddedModel reviewAdded = new ReviewAddedModel(review.FriendlyId) { Name = name }; commerceContextRef.AddModel(reviewAdded); context.CommerceContext.AddUniqueObjectByType(arg); await context.CommerceContext.AddMessage(context.GetPolicy <KnownResultCodes>().Information, null, null, "Generated unallocated review"); return(review); }
public async void Should_benefit_multiple_times_when_within_action_limit() { fixture.Factory.ClearAllEntities(); HttpClient client = fixture.Factory.CreateClient(); Promotion promotion = await new PromotionBuilder() .QualifiedBy(new IsCurrentDayConditionBuilder() .Day(DateTime.Now.Day)) .BenefitBy(new CartEveryXItemsInCategoryPriceDiscountActionBuilder() .AmountOff(10) .ForCategory("Laptops") .ItemsToAward(1) .ItemsToPurchase(2) .ApplyActionTo(ApplicationOrder.Ascending) .ActionLimit(2)) .Build(fixture.Factory); fixture.Factory.AddEntityToList(promotion, CommerceEntity.ListName <Promotion>()); fixture.Factory.AddEntity(promotion); fixture.Factory.AddEntity(new Category { Id = "Laptops".ToEntityId <Category>(), SitecoreId = "435345345" }); Cart cart = await new CartBuilder() .WithLines(new LineBuilder().IdentifiedBy("001").Quantity(1).InCategory("435345345").Price(40), new LineBuilder().IdentifiedBy("002").Quantity(1).InCategory("435345345").Price(50), new LineBuilder().IdentifiedBy("003").Quantity(1).InCategory("435345345").Price(40), new LineBuilder().IdentifiedBy("004").Quantity(1).InCategory("435345345").Price(50)) .Build(); fixture.Factory.AddEntity(cart); Cart resultCart = await client.GetJsonAsync <Cart>( "api/Carts('Cart01')?$expand=Lines($expand=CartLineComponents($expand=ChildComponents)),Components"); CartLineComponent firstLine = resultCart.Lines.Single(x => x.Id == "001"); AwardedAdjustment adjustment = firstLine.Adjustments.Single(x => x.AwardingBlock == nameof(CartEveryXItemsInCategoryPriceDiscountAction)); Assert.Equal(-10, adjustment.Adjustment.Amount); CartLineComponent secondLine = resultCart.Lines.Single(x => x.Id == "003"); AwardedAdjustment secondAdjustment = secondLine.Adjustments.Single(x => x.AwardingBlock == nameof(CartEveryXItemsInCategoryPriceDiscountAction)); Assert.Equal(-10, secondAdjustment.Adjustment.Amount); // Subtotal = 160, Tax is 10% = 16, Fulfillment fee = 5 Assert.Equal(181, resultCart.Totals.GrandTotal.Amount); }
public async void Should_benefit() { fixture.Factory.ClearAllEntities(); HttpClient client = fixture.Factory.CreateClient(); Promotion promotion = await new PromotionBuilder() .QualifiedBy(new IsCurrentDayConditionBuilder() .Day(DateTime.Now.Day)) .BenefitBy(new CartFreeGiftActionBuilder() .Quantity(1) .Gift("MyCatalog|999|")) .Build(fixture.Factory); var catalog = new Catalog { Id = "Entity-Catalog-MyCatalog", FriendlyId = "MyCatalog", Name = "MyCatalog" }; SellableItem sellableItem = new SellableItemBuilder() .IdentifiedBy("001") .Priced(40) .Catalog("MyCatalog") .Build(); SellableItem gift = new SellableItemBuilder() .IdentifiedBy("999") .Catalog("MyCatalog") .Named("Free Gift") .Priced(99) .Build(); Cart cart = await new CartBuilder() .WithLines(new LineBuilder() .IdentifiedBy("001").WithProductId("MyCatalog|001|").Quantity(1).Price(40)) .Build(); fixture.Factory.AddEntities(promotion, gift, sellableItem, catalog, cart); fixture.Factory.AddEntityToList(promotion, CommerceEntity.ListName <Promotion>()); Cart resultCart = await client.GetJsonAsync <Cart>( "api/Carts('Cart01')?$expand=Lines($expand=CartLineComponents($expand=ChildComponents)),Components"); CartLineComponent giftLine = resultCart.Lines.Single(x => x.ItemId == "MyCatalog|999|"); AwardedAdjustment adjustment = giftLine.Adjustments.Single(x => x.AwardingBlock == nameof(CartFreeGiftAction)); Assert.Equal(-99, adjustment.Adjustment.Amount); // Subtotal = 40, Tax is 10% = 4, Fulfillment fee = 5 Assert.Equal(49, resultCart.Totals.GrandTotal.Amount); }
public async void Should_match_operator(Operator @operator, int numberOfProductsInPromotion, int numberOfProductsInCart, bool shouldQualify) { fixture.Factory.ClearAllEntities(); HttpClient client = fixture.Factory.CreateClient(); Promotion promotion = await new PromotionBuilder() .QualifiedBy(new IsCurrentDayConditionBuilder() .Day(DateTime.Now.Day)) .BenefitBy(new CartItemsMatchingInCategoryPercentageDiscountActionBuilder() .PercentageOff(50) .ForCategory("Laptops") .Operator(@operator) .NumberOfProducts(numberOfProductsInPromotion) .ApplyActionTo(ApplicationOrder.Ascending) .ActionLimit(numberOfProductsInPromotion)) .Build(fixture.Factory); fixture.Factory.AddEntityToList(promotion, CommerceEntity.ListName <Promotion>()); fixture.Factory.AddEntity(promotion); fixture.Factory.AddEntity(new Category { Id = "Laptops".ToEntityId <Category>(), SitecoreId = "435345345" }); Cart cart = await new CartBuilder() .WithLines(new LineBuilder() .IdentifiedBy("001").Quantity(numberOfProductsInCart).InCategory("435345345").Price(40)) .Build(); fixture.Factory.AddEntity(cart); Cart resultCart = await client.GetJsonAsync <Cart>( "api/Carts('Cart01')?$expand=Lines($expand=CartLineComponents($expand=ChildComponents)),Components"); CartLineComponent line = resultCart.Lines.Single(x => x.Id == "001"); if (shouldQualify) { Assert.Contains(line.Adjustments, x => x.AwardingBlock == nameof(CartItemsMatchingInCategoryPercentageDiscountAction)); } else { Assert.DoesNotContain(line.Adjustments, x => x.AwardingBlock == nameof(CartItemsMatchingInCategoryPercentageDiscountAction)); } }
/// <summary> /// Generates the sales activity. /// </summary> /// <param name="order">The order.</param> /// <param name="existingPayment">The existingPayment.</param> /// <param name="paymentToRefund">The payment to refund</param> /// <param name="refundTransactionId">The refund transaction identifier.</param> /// <param name="context">The context.</param> /// <returns> /// A <see cref="Task" /> /// </returns> protected virtual async Task GenerateSalesActivity(Order order, PaymentComponent existingPayment, PaymentComponent paymentToRefund, string refundTransactionId, CommercePipelineExecutionContext context) { var salesActivity = new SalesActivity { Id = $"{CommerceEntity.IdPrefix<SalesActivity>()}{Guid.NewGuid():N}", ActivityAmount = new Money(existingPayment.Amount.CurrencyCode, paymentToRefund.Amount.Amount * -1), Customer = new EntityReference { EntityTarget = order.EntityComponents.OfType <ContactComponent>().FirstOrDefault()?.CustomerId }, Order = new EntityReference { EntityTarget = order.Id, EntityTargetUniqueId = order.UniqueId }, Name = "Refund the Federated Payment", PaymentStatus = context.GetPolicy <KnownSalesActivityStatusesPolicy>().Completed }; salesActivity.SetComponent(new ListMembershipsComponent { Memberships = new List <string> { CommerceEntity.ListName <SalesActivity>(), context.GetPolicy <KnownOrderListsPolicy>().SalesCredits, string.Format(CultureInfo.InvariantCulture, context.GetPolicy <KnownOrderListsPolicy>().OrderSalesActivities, order.FriendlyId) } }); if (existingPayment.Amount.Amount != paymentToRefund.Amount.Amount) { salesActivity.SetComponent(existingPayment); } if (!string.IsNullOrEmpty(refundTransactionId)) { salesActivity.SetComponent(new TransactionInformationComponent(refundTransactionId)); } var salesActivities = order.SalesActivity.ToList(); salesActivities.Add(new EntityReference { EntityTarget = salesActivity.Id, EntityTargetUniqueId = salesActivity.UniqueId }); order.SalesActivity = salesActivities; await _persistPipeline.Run(new PersistEntityArgument(salesActivity), context).ConfigureAwait(false); }
public virtual async Task <Cart> Process(CommerceContext commerceContext, string wishlistId, CartLineComponent line) { AddWishListLineItemCommand addCartLineCommand = this; Cart result = (Cart)null; using (CommandActivity.Start(commerceContext, (CommerceCommand)addCartLineCommand)) { await addCartLineCommand.PerformTransaction(commerceContext, (Func <Task>)(async() => { FindEntityArgument findEntityArgument = new FindEntityArgument(typeof(Cart), wishlistId, true); var context = commerceContext.GetPipelineContextOptions(); Cart cart = await this._getPipeline.Run(findEntityArgument, (IPipelineExecutionContextOptions)commerceContext.GetPipelineContextOptions()).ConfigureAwait(false) as Cart; if (cart == null) { string str = await context.CommerceContext.AddMessage(commerceContext.GetPolicy <KnownResultCodes>().ValidationError, "EntityNotFound", new object[1] { (object)wishlistId }, string.Format("Entity {0} was not found.", (object)wishlistId)); } else { if (!cart.IsPersisted) { cart.Id = wishlistId; cart.Name = wishlistId; cart.ShopName = commerceContext.CurrentShopName(); cart.SetComponent((Component) new ListMembershipsComponent() { Memberships = (IList <string>) new List <string>() { CommerceEntity.ListName <Cart>() } }); cart.SetComponent(new CartTypeComponent() { CartType = CartTypeEnum.Wishlist.ToString() }); } result = await this._addWishListLineItemPipeli.Run(new CartLineArgument(cart, line), (IPipelineExecutionContextOptions)context); } })); } return(result); }
public override async Task <EntityView> Run(EntityView entityView, CommercePipelineExecutionContext context) { Contract.Requires(entityView != null); Contract.Requires(context != null); Condition.Requires(entityView).IsNotNull($"{this.Name}: The argument cannot be null"); if (entityView.Name != "VatTaxDashboard") { return(entityView); } //var pluginPolicy = context.GetPolicy<PluginPolicy>(); var newEntityViewTable = entityView; entityView.UiHint = "Table"; entityView.Icon = "money_dollar"; entityView.ItemId = string.Empty; var sampleDashboardEntities = await _commerceCommander.Command <ListCommander>() .GetListItems <VatTaxEntity>(context.CommerceContext, CommerceEntity.ListName <VatTaxEntity>(), 0, 99).ConfigureAwait(false); //var sampleDashboardEntities = await this._commerceCommander.Command<ListCommander>().GetListItems<VatTaxEntity>(context.CommerceContext,CommerceEntity.ListName<VatTaxEntity>(), 0, 99); foreach (var sampleDashboardEntity in sampleDashboardEntities) { newEntityViewTable.ChildViews.Add( new EntityView { ItemId = sampleDashboardEntity.Id, Icon = "money_dollar", Properties = new List <ViewProperty> { new ViewProperty { Name = "TaxTag", RawValue = sampleDashboardEntity.TaxTag }, new ViewProperty { Name = "CountryCode", RawValue = sampleDashboardEntity.CountryCode }, new ViewProperty { Name = "TaxPct", RawValue = sampleDashboardEntity.TaxPct } } }); } /* STUDENT: Complete the body of the Run method. You should handle the * entity view for both a new and existing entity. */ return(entityView); }
private void TransformCore(CommerceContext commerceContext, string[] rawFields, Category item) { var catalogName = rawFields[CatalogNameIndex]; item.Name = rawFields[CategoryNameIndex]; item.Id = item.Name.ToCategoryId(catalogName); item.FriendlyId = item.Name.ToCategoryFriendlyId(catalogName); item.SitecoreId = GuidUtils.GetDeterministicGuidString(item.Id); item.DisplayName = rawFields[CategoryDisplayNameIndex]; //item.Description = arg.Description; var component = item.GetComponent <ListMembershipsComponent>(); component.Memberships.Add(string.Format("{0}", CommerceEntity.ListName <Category>())); component.Memberships.Add(commerceContext.GetPolicy <KnownCatalogListsPolicy>().CatalogItems); }
public async void Should_benefit_in_descending_order_when_category_matches() { fixture.Factory.ClearAllEntities(); HttpClient client = fixture.Factory.CreateClient(); Promotion promotion = await new PromotionBuilder() .QualifiedBy(new IsCurrentDayConditionBuilder() .Day(DateTime.Now.Day)) .BenefitBy(new CartItemsMatchingInCategoryPercentageDiscountActionBuilder() .PercentageOff(50) .ForCategory("Laptops") .Operator(Operator.Equal) .NumberOfProducts(2) .ApplyActionTo(ApplicationOrder.Descending) .ActionLimit(1)) .Build(fixture.Factory); fixture.Factory.AddEntityToList(promotion, CommerceEntity.ListName <Promotion>()); fixture.Factory.AddEntity(promotion); fixture.Factory.AddEntity(new Category { Id = "Laptops".ToEntityId <Category>(), SitecoreId = "435345345" }); Cart cart = await new CartBuilder() .WithLines(new LineBuilder().IdentifiedBy("001").Quantity(1).InCategory("435345345").Price(40), new LineBuilder().IdentifiedBy("002").Quantity(1).InCategory("435345345").Price(50)) .Build(); fixture.Factory.AddEntity(cart); Cart resultCart = await client.GetJsonAsync <Cart>( "api/Carts('Cart01')?$expand=Lines($expand=CartLineComponents($expand=ChildComponents)),Components"); CartLineComponent line = resultCart.Lines.Single(x => x.Id == "002"); AwardedAdjustment adjustment = line.Adjustments.Single(x => x.AwardingBlock == nameof(CartItemsMatchingInCategoryPercentageDiscountAction)); Assert.Equal(-25, adjustment.Adjustment.Amount); // Subtotal = 65, Tax is 10% = 6.5, Fulfillment fee = 5 Assert.Equal(76.5m, resultCart.Totals.GrandTotal.Amount); }
/// <summary> /// Bootstraps the audio. /// </summary> /// <param name="context">The context.</param> /// <returns>A <see cref="Task"/></returns> private async Task BootstrapAudio(CommercePipelineExecutionContext context) { var item = new SellableItem { Components = new List <Component> { new CatalogComponent { Name = "Habitat_Mater" }, new ListMembershipsComponent { Memberships = new List <string> { CommerceEntity.ListName <SellableItem>() } }, new ItemVariationsComponent { ChildComponents = new List <Component> { new ItemVariationComponent { Id = "56042122", Name = "XSound 7” CD DVD, In-Dash Receiver, 3-Way Speakers, and HabitatPro Installation", Policies = new List <Policy> { new ListPricingPolicy(new List <Money> { new Money("USD", 423.99M), new Money("CAD", 424.99M) }) }, ChildComponents = new List <Component> { new PhysicalItemComponent() } } } } }, Policies = new List <Policy> { new ListPricingPolicy(new List <Money> { new Money("USD", 423.99M), new Money("CAD", 424.99M) }) }, Id = $"{CommerceEntity.IdPrefix<SellableItem>()}6042122", Name = "XSound 7” CD DVD, In-Dash Receiver, 3-Way Speakers, and HabitatPro Installation" }; await this._persistEntityPipeline.Run(new PersistEntityArgument(item), context); }
public async void Should_match_operator(Operator @operator, DateTimeOffset promotionDate, DateTimeOffset firstOrderDate, bool shouldQualify) { fixture.Factory.ClearAllEntities(); HttpClient client = fixture.Factory.CreateClient(); Guid customerId = Guid.NewGuid(); Order order = new OrderBuilder().PlacedOn(firstOrderDate).Build(); Order laterOrder = new OrderBuilder().PlacedOn(firstOrderDate.AddDays(100)).Build(); fixture.Factory.AddEntitiesToList(string.Format(CultureInfo.InvariantCulture, "Orders-ByCustomer-{0}", customerId), order, laterOrder); Promotion promotion = await new PromotionBuilder() .QualifiedBy(new FirstPurchaseDateConditionBuilder() .Operator(@operator) .Date(promotionDate)) .BenefitBy(new CartSubtotalPercentOffActionBuilder() .PercentOff(10)) .Build(fixture.Factory); fixture.Factory.AddEntityToList(promotion, CommerceEntity.ListName <Promotion>()); fixture.Factory.AddEntity(promotion); Cart cart = await new CartBuilder().Build(); fixture.Factory.AddEntity(cart); Cart resultCart = await client.GetJsonAsync <Cart>( "api/Carts('Cart01')?$expand=Lines($expand=CartLineComponents($expand=ChildComponents)),Components", new Dictionary <string, string> { { "IsRegistered", "true" }, { "CustomerId", customerId.ToString() } }); if (shouldQualify) { Assert.Contains(resultCart.Adjustments, c => c.AwardingBlock == nameof(CartSubtotalPercentOffAction)); } else { Assert.DoesNotContain(resultCart.Adjustments, c => c.AwardingBlock == nameof(CartSubtotalPercentOffAction)); } }
/// <summary> /// Executes the pipeline block. /// </summary> /// <param name="arg">The entity view.</param> /// <param name="context">The context.</param> /// <returns></returns> public override async Task <EntityView> Run(EntityView entityView, CommercePipelineExecutionContext context) { Condition.Requires(entityView).IsNotNull($"{Name}: The argument cannot be null"); var viewsPolicy = context.GetPolicy <Policies.KnownInventoryViewsPolicy>(); var entityViewArgument = context.CommerceContext.GetObject <EntityViewArgument>(); var enablementPolicy = context.GetPolicy <Policies.InventoryFeatureEnablementPolicy>(); if (!enablementPolicy.InventoryFromProductView || string.IsNullOrEmpty(entityViewArgument?.ViewName) || !entityViewArgument.ViewName.Equals(viewsPolicy.SelectInventorySet, StringComparison.OrdinalIgnoreCase)) { return(await Task.FromResult(entityView).ConfigureAwait(false)); } var inventorySets = await CommerceCommander.Pipeline <FindEntitiesInListPipeline>().Run( new FindEntitiesInListArgument( typeof(InventorySet), $"{CommerceEntity.ListName<InventorySet>()}", 0, int.MaxValue), context).ConfigureAwait(false); var availableSelectionsPolicy = new AvailableSelectionsPolicy( inventorySets.List.Items.Select(s => new Selection { DisplayName = s.DisplayName, Name = s.Name }).ToList() ?? new List <Selection>()); var viewProperty = new ViewProperty() { Name = "Inventory Set", UiType = "SelectList", Policies = new List <Policy>() { availableSelectionsPolicy }, RawValue = availableSelectionsPolicy.List.Where(s => s.IsDefault).FirstOrDefault()?.Name ?? availableSelectionsPolicy.List?.FirstOrDefault().Name }; entityView.Properties.Add(viewProperty); return(entityView); }
/// <summary> /// The execute. /// </summary> /// <param name="arg"> /// The AddJobConnectionArgument argument. /// </param> /// <param name="context"> /// The context. /// </param> /// <returns> /// The <see cref="JobConnection"/>. /// </returns> public override async Task <JobConnection> Run(AddJobConnectionArgument arg, CommercePipelineExecutionContext context) { Condition.Requires <AddJobConnectionArgument>(arg).IsNotNull <AddJobConnectionArgument>("AddJobConnectionArgument The argument cannot be null."); Condition.Requires <string>(arg.Name).IsNotNullOrEmpty("The Job Connection name cannot be null or empty."); Condition.Requires <string>(arg.Type).IsNotNullOrEmpty("The Job Connection type cannot be null or empty."); TaskAwaiter <bool> awaiter = _findEntityPipeline.Run(new FindEntityArgument(typeof(JobConnection), $"{(object) CommerceEntity.IdPrefix<JobConnection>()}{ arg.Name}"), context).GetAwaiter(); if (awaiter.GetResult()) { CommerceContext commerceContext = context.CommerceContext; string validationError = context.GetPolicy <KnownResultCodes>().ValidationError; string commerceTermKey = "JobConnectionNameAlreadyInUse"; object[] args = new object[1] { (object)arg.Name }; string defaultMessage = $"Job Connection name {(object) arg.Name} is already in use."; context.Abort("Ok|" + await commerceContext.AddMessage(validationError, commerceTermKey, args, defaultMessage), context); context = null; return(null); } JobConnection jobConnection = new JobConnection(arg.Name, arg.Type); jobConnection.Id = $"{ CommerceEntity.IdPrefix<JobConnection>()}{ arg.Name}"; jobConnection.FriendlyId = $"{arg.Name}";; jobConnection.Description = arg.Description;; jobConnection.DisplayName = arg.DisplayName; var jobConnectionPolicy = context.GetPolicy <JobConnectionPolicy>(); jobConnectionPolicy.DbConnectionString = arg.DbConnectionString; jobConnectionPolicy.WebServiceUrl = arg.WebServiceUrl; jobConnectionPolicy.Username = arg.Username; jobConnectionPolicy.Password = arg.Password; jobConnection.SetPolicy(jobConnectionPolicy); jobConnection.SetComponent(new ListMembershipsComponent() { Memberships = new List <string>() { CommerceEntity.ListName <JobConnection>() } }); JobConnectionAdded jobConnectionAdded = new JobConnectionAdded(jobConnection.FriendlyId); jobConnectionAdded.Name = jobConnection.Name; context.CommerceContext.AddModel(jobConnectionAdded); return(jobConnection); }
public async void Should_match_operator(Operator @operator, int totalRequired, int totalInCart, bool shouldQualify) { fixture.Factory.ClearAllEntities(); HttpClient client = fixture.Factory.CreateClient(); Promotion promotion = await new PromotionBuilder() .QualifiedBy(new CartProductTotalInCategoryConditionBuilder() .Operator(@operator) .Total(totalRequired) .ForCategory("Laptops") .DoesNotIncludeSubCategories()) .BenefitBy(new CartSubtotalPercentOffActionBuilder() .PercentOff(10)) .Build(fixture.Factory); fixture.Factory.AddEntityToList(promotion, CommerceEntity.ListName <Promotion>()); fixture.Factory.AddEntity(promotion); fixture.Factory.AddEntity(new Category { Id = "Laptops".ToEntityId <Category>(), SitecoreId = "435345345" }); Cart cart = await new CartBuilder() .WithLines(new LineBuilder() .Quantity(1) .Price(totalInCart) .InCategory("435345345")) .Build(); fixture.Factory.AddEntity(cart); Cart resultCart = await client.GetJsonAsync <Cart>( "api/Carts('Cart01')?$expand=Lines($expand=CartLineComponents($expand=ChildComponents)),Components"); if (shouldQualify) { Assert.Contains(resultCart.Adjustments, c => c.AwardingBlock == nameof(CartSubtotalPercentOffAction)); } else { Assert.DoesNotContain(resultCart.Adjustments, c => c.AwardingBlock == nameof(CartSubtotalPercentOffAction)); } }
private async Task GenerateSalesActivity(Order order, PaymentComponent existingPayment, PaymentComponent paymentToRefund, CommercePipelineExecutionContext context) { var salesActivity = new SalesActivity { Id = $"{CommerceEntity.IdPrefix<SalesActivity>()}{Guid.NewGuid():N}", ActivityAmount = new Money(existingPayment.Amount.CurrencyCode, paymentToRefund.Amount.Amount * -1), Customer = new EntityReference { EntityTarget = order.EntityComponents.OfType <ContactComponent>().FirstOrDefault()?.CustomerId }, Order = new EntityReference { EntityTarget = order.Id }, Name = "Simple Payment Refund", PaymentStatus = context.GetPolicy <KnownSalesActivityStatusesPolicy>().Completed }; // Add the new sales activity to the OrderSalesActivities list salesActivity.SetComponent(new ListMembershipsComponent { Memberships = new List <string> { CommerceEntity.ListName <SalesActivity>(), context.GetPolicy <KnownOrderListsPolicy>().SalesCredits, string.Format(context.GetPolicy <KnownOrderListsPolicy>().OrderSalesActivities, order.FriendlyId) } }); if (existingPayment.Amount.Amount != paymentToRefund.Amount.Amount) { salesActivity.SetComponent(existingPayment); } var salesActivities = order.SalesActivity.ToList(); salesActivities.Add(new EntityReference { EntityTarget = salesActivity.Id }); order.SalesActivity = salesActivities; await Commander.PersistEntity(context.CommerceContext, salesActivity); }
/// <summary> /// Processes the specified commerce context. /// </summary> /// <param name="commerceContext">The commerce context.</param> /// <returns> /// Number of migrated customers /// </returns> public virtual async Task <int> Process(CommerceContext commerceContext) { using (CommandActivity.Start(commerceContext, this)) { var context = commerceContext.GetPipelineContextOptions(); var listName = CommerceEntity.ListName <Customer>(); var result = await this.Command <GetListMetadataCommand>().Process(commerceContext, listName); if (result == null) { await commerceContext.AddMessage( commerceContext.GetPolicy <KnownResultCodes>().Error, "EntityNotFound", new object[] { listName }, $"There is no customers in the list {listName}."); return(0); } if (result.Count == 0) { await context.CommerceContext.AddMessage( context.CommerceContext.GetPolicy <KnownResultCodes>().Error, "EntityNotFound", new object[] { listName }, $"There is no customers in the list {listName}."); return(0); } int customersCount = 0; int skip = 0; int take = 20; while (customersCount < result.Count) { customersCount += await this.UpgradeCustomersInList(context, listName, skip, take); skip += take; } return(customersCount); } }
public override async Task <EntityView> Run(EntityView entityView, CommercePipelineExecutionContext context) { Condition.Requires(entityView).IsNotNull($"{this.Name}: The argument cannot be null"); if (entityView.Name != "VatTaxDashboard") { return(entityView); } var pluginPolicy = context.GetPolicy <PluginPolicy>(); var newEntityViewTable = entityView; entityView.UiHint = "Table"; entityView.Icon = pluginPolicy.Icon; entityView.ItemId = string.Empty; var sampleDashboardEntities = await this._commerceCommander.Command <ListCommander>() .GetListItems <VatTaxTableEntity>(context.CommerceContext, CommerceEntity.ListName <VatTaxTableEntity>(), 0, 99); foreach (var sampleDashboardEntity in sampleDashboardEntities) { newEntityViewTable.ChildViews.Add( new EntityView { ItemId = sampleDashboardEntity.Id, Icon = pluginPolicy.Icon, Properties = new List <ViewProperty> { new ViewProperty { Name = "TaxTag", RawValue = sampleDashboardEntity.TaxTag }, new ViewProperty { Name = "CountryCode", RawValue = sampleDashboardEntity.CountryCode }, new ViewProperty { Name = "TaxPct", RawValue = sampleDashboardEntity.TaxPct } } }); } return(entityView); }
public async void Should_not_benefit_when_category_does_not_match() { fixture.Factory.ClearAllEntities(); HttpClient client = fixture.Factory.CreateClient(); Promotion promotion = await new PromotionBuilder() .QualifiedBy(new IsCurrentDayConditionBuilder() .Day(DateTime.Now.Day)) .BenefitBy(new CartEveryXItemsInCategoryPercentageDiscountActionBuilder() .PercentageOff(50) .ForCategory("Laptops") .ItemsToAward(1) .ItemsToPurchase(2) .ApplyActionTo(ApplicationOrder.Ascending) .ActionLimit(1)) .Build(fixture.Factory); fixture.Factory.AddEntityToList(promotion, CommerceEntity.ListName <Promotion>()); fixture.Factory.AddEntity(promotion); fixture.Factory.AddEntity(new Category { Id = "Laptops".ToEntityId <Category>(), SitecoreId = "435345345" }); Cart cart = await new CartBuilder() .WithLines(new LineBuilder().IdentifiedBy("001").Quantity(1).InCategory("34345454").Price(40), new LineBuilder().IdentifiedBy("002").Quantity(1).InCategory("454545454").Price(50)) .Build(); fixture.Factory.AddEntity(cart); Cart resultCart = await client.GetJsonAsync <Cart>( "api/Carts('Cart01')?$expand=Lines($expand=CartLineComponents($expand=ChildComponents)),Components"); CartLineComponent line = resultCart.Lines.Single(x => x.Id == "002"); Assert.DoesNotContain(line.Adjustments, x => x.AwardingBlock == nameof(CartEveryXItemsInCategoryPercentageDiscountAction)); }
public async void Should_benefit_split_fulfillments() { fixture.Factory.ClearAllEntities(); HttpClient client = fixture.Factory.CreateClient(); Promotion promotion = await new PromotionBuilder() .QualifiedBy(new IsCurrentDayConditionBuilder() .Day(DateTime.Now.Day)) .BenefitBy(new CartAmountOffFulfillmentActionBuilder() .AmountOff(3)) // Fee = 2 * 2, Discount = 3 .Build(fixture.Factory); fixture.Factory.AddEntityToList(promotion, CommerceEntity.ListName <Promotion>()); fixture.Factory.AddEntity(promotion); Cart cart = await new CartBuilder() .WithLines(new LineBuilder() .IdentifiedBy("001") .Quantity(1) .WithStandardFulfillment() // Default fulfillment fee per line item is 2 .Price(50), new LineBuilder() .IdentifiedBy("002") .Quantity(1) .WithStandardFulfillment() // Default fulfillment fee per line item is 2 .Price(50)) .WithSplitFulfillment() .Build(); fixture.Factory.AddEntity(cart); Cart resultCart = await client.GetJsonAsync <Cart>( "api/Carts('Cart01')?$expand=Lines($expand=CartLineComponents($expand=ChildComponents)),Components"); AwardedAdjustment adjustment = resultCart.Adjustments.Single(x => x.AwardingBlock == nameof(CartAmountOffFulfillmentAction)); Assert.Equal(-3, adjustment.Adjustment.Amount); // Subtotal = 100, Tax is 10% = 10, Fulfillment fee = 2*2 - 3 = 1 Assert.Equal(111, resultCart.Totals.GrandTotal.Amount); }
private Shop CreateShop(string id, string name, string displayName, string friendlyId = null) { var shop = new Shop { Id = id, Name = name, DisplayName = displayName, FriendlyId = friendlyId }; shop.AddComponents(new ListMembershipsComponent { Memberships = new List <string> { CommerceEntity.ListName <Shop>() } }); return(shop); }
/// <summary> /// Generates the sales activity. /// </summary> /// <param name="order">The order.</param> /// <param name="payment">The payment.</param> /// <param name="context">The context.</param> /// <returns>A <see cref="Task"/></returns> protected virtual async Task GenerateSalesActivity(Order order, PaymentComponent payment, CommercePipelineExecutionContext context) { var salesActivity = new SalesActivity { Id = CommerceEntity.IdPrefix <SalesActivity>() + Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture), ActivityAmount = new Money(payment.Amount.CurrencyCode, 0), Customer = new EntityReference { EntityTarget = order.EntityComponents.OfType <ContactComponent>().FirstOrDefault()?.CustomerId }, Order = new EntityReference { EntityTarget = order.Id, EntityTargetUniqueId = order.UniqueId }, Name = "Void the Federated payment", PaymentStatus = context.GetPolicy <KnownSalesActivityStatusesPolicy>().Void }; salesActivity.SetComponent(new ListMembershipsComponent { Memberships = new List <string> { CommerceEntity.ListName <SalesActivity>(), string.Format(CultureInfo.InvariantCulture, context.GetPolicy <KnownOrderListsPolicy>().OrderSalesActivities, order.FriendlyId) } }); salesActivity.SetComponent(payment); var salesActivities = order.SalesActivity.ToList(); salesActivities.Add(new EntityReference { EntityTarget = salesActivity.Id, EntityTargetUniqueId = salesActivity.UniqueId }); order.SalesActivity = salesActivities; await _persistEntityPipeline.Run(new PersistEntityArgument(salesActivity), context).ConfigureAwait(false); }