From bbeca03f7835eb031c237838a395c746f3b45574 Mon Sep 17 00:00:00 2001 From: Konstantin Savosteev Date: Tue, 3 Dec 2024 18:15:59 +0200 Subject: [PATCH 1/6] feat: add changeCartCurrency mutation --- .../Commands/ChangeCartCurrencyCommand.cs | 9 +++ .../Schemas/InputChangeCartCurrencyType.cs | 12 ++++ .../ChangeCartCurrencyCommandHandler.cs | 59 +++++++++++++++++++ .../Schemas/PurchaseSchema.cs | 19 ++++++ 4 files changed, 99 insertions(+) create mode 100644 src/VirtoCommerce.XCart.Core/Commands/ChangeCartCurrencyCommand.cs create mode 100644 src/VirtoCommerce.XCart.Core/Schemas/InputChangeCartCurrencyType.cs create mode 100644 src/VirtoCommerce.XCart.Data/Commands/ChangeCartCurrencyCommandHandler.cs diff --git a/src/VirtoCommerce.XCart.Core/Commands/ChangeCartCurrencyCommand.cs b/src/VirtoCommerce.XCart.Core/Commands/ChangeCartCurrencyCommand.cs new file mode 100644 index 0000000..f51a877 --- /dev/null +++ b/src/VirtoCommerce.XCart.Core/Commands/ChangeCartCurrencyCommand.cs @@ -0,0 +1,9 @@ +using VirtoCommerce.XCart.Core.Commands.BaseCommands; + +namespace VirtoCommerce.XCart.Core.Commands +{ + public class ChangeCartCurrencyCommand : CartCommand + { + public string NewCurrencyCode { get; set; } + } +} diff --git a/src/VirtoCommerce.XCart.Core/Schemas/InputChangeCartCurrencyType.cs b/src/VirtoCommerce.XCart.Core/Schemas/InputChangeCartCurrencyType.cs new file mode 100644 index 0000000..c042fd6 --- /dev/null +++ b/src/VirtoCommerce.XCart.Core/Schemas/InputChangeCartCurrencyType.cs @@ -0,0 +1,12 @@ +using GraphQL.Types; + +namespace VirtoCommerce.XCart.Core.Schemas +{ + public class InputChangeCartCurrencyType : InputCartBaseType + { + public InputChangeCartCurrencyType() + { + Field>("newCurrencyCode", "Second cart currency"); + } + } +} diff --git a/src/VirtoCommerce.XCart.Data/Commands/ChangeCartCurrencyCommandHandler.cs b/src/VirtoCommerce.XCart.Data/Commands/ChangeCartCurrencyCommandHandler.cs new file mode 100644 index 0000000..499c0e3 --- /dev/null +++ b/src/VirtoCommerce.XCart.Data/Commands/ChangeCartCurrencyCommandHandler.cs @@ -0,0 +1,59 @@ +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using VirtoCommerce.XCart.Core; +using VirtoCommerce.XCart.Core.Commands; +using VirtoCommerce.XCart.Core.Commands.BaseCommands; +using VirtoCommerce.XCart.Core.Models; +using VirtoCommerce.XCart.Core.Services; + +namespace VirtoCommerce.XCart.Data.Commands +{ + public class ChangeCartCurrencyCommandHandler : CartCommandHandler + { + private readonly ICartProductService _cartProductService; + + public ChangeCartCurrencyCommandHandler( + ICartAggregateRepository cartAggregateRepository, + ICartProductService cartProductService) + : base(cartAggregateRepository) + { + _cartProductService = cartProductService; + } + + public override async Task Handle(ChangeCartCurrencyCommand request, CancellationToken cancellationToken) + { + // get (or create) both carts + var currentCurrencyCartAggregate = await GetOrCreateCartFromCommandAsync(request); + + var newCurrencyCartRequest = new ChangeCartCurrencyCommand + { + StoreId = request.StoreId ?? currentCurrencyCartAggregate.Cart.StoreId, + CartName = request.CartName ?? currentCurrencyCartAggregate.Cart.Name, + CartType = request.CartType ?? currentCurrencyCartAggregate.Cart.Type, + UserId = request.UserId ?? currentCurrencyCartAggregate.Cart.CustomerId, + OrganizationId = request.OrganizationId ?? currentCurrencyCartAggregate.Cart.OrganizationId, + CultureName = request.CultureName ?? currentCurrencyCartAggregate.Cart.LanguageCode, + CurrencyCode = request.NewCurrencyCode, + }; + + var newCurrencyCartAggregate = await GetOrCreateCartFromCommandAsync(newCurrencyCartRequest); + + // get items to convert + var excludedProductsIds = newCurrencyCartAggregate.LineItems.Select(x => x.ProductId).ToArray(); + + var newCartItems = currentCurrencyCartAggregate.LineItems + .Where(x => !excludedProductsIds.Contains(x.ProductId)) + .Select(x => new NewCartItem(x.ProductId, x.Quantity) + { + Comment = x.Note, + }) + .ToArray(); + + await newCurrencyCartAggregate.AddItemsAsync(newCartItems); + + await CartRepository.SaveAsync(newCurrencyCartAggregate); + return newCurrencyCartAggregate; + } + } +} diff --git a/src/VirtoCommerce.XCart.Data/Schemas/PurchaseSchema.cs b/src/VirtoCommerce.XCart.Data/Schemas/PurchaseSchema.cs index bae0f28..ad1666c 100644 --- a/src/VirtoCommerce.XCart.Data/Schemas/PurchaseSchema.cs +++ b/src/VirtoCommerce.XCart.Data/Schemas/PurchaseSchema.cs @@ -829,6 +829,25 @@ public void Build(ISchema schema) schema.Mutation.AddField(margeCartField); + var changeCartCurrency = FieldBuilder.Create(GraphTypeExtenstionHelper.GetActualType()) + .Name("changeCartCurrency") + .Argument(GraphTypeExtenstionHelper.GetActualComplexType>(), SchemaConstants.CommandName) + .ResolveSynchronizedAsync(CartPrefix, "userId", _distributedLockService, async context => + { + var cartCommand = context.GetCartCommand(); + + await CheckAuthByCartCommandAsync(context, cartCommand); + + //We need to add cartAggregate to the context to be able use it on nested cart types resolvers (e.g for currency) + var cartAggregate = await _mediator.Send(cartCommand); + + //store cart aggregate in the user context for future usage in the graph types resolvers + context.SetExpandedObjectGraph(cartAggregate); + return cartAggregate; + }).FieldType; + + schema.Mutation.AddField(changeCartCurrency); + /// /// This is an example JSON request for a mutation /// { From 16fbea3ac27534b8712ce97f9899aecf3efb0e63 Mon Sep 17 00:00:00 2001 From: Konstantin Savosteev Date: Wed, 4 Dec 2024 12:28:49 +0200 Subject: [PATCH 2/6] feat: clear items before merge --- src/VirtoCommerce.XCart.Core/CartAggregate.cs | 3 ++- .../Models/NewCartItem.cs | 2 ++ .../ChangeCartCurrencyCommandHandler.cs | 20 ++++++++++--------- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/VirtoCommerce.XCart.Core/CartAggregate.cs b/src/VirtoCommerce.XCart.Core/CartAggregate.cs index b1636e5..d408654 100644 --- a/src/VirtoCommerce.XCart.Core/CartAggregate.cs +++ b/src/VirtoCommerce.XCart.Core/CartAggregate.cs @@ -223,7 +223,7 @@ public virtual async Task AddItemAsync(NewCartItem newCartItem) var lineItem = _mapper.Map(newCartItem.CartProduct); - lineItem.SelectedForCheckout = IsSelectedForCheckout; + lineItem.SelectedForCheckout = newCartItem.IsSelectedForCheckout ?? IsSelectedForCheckout; lineItem.Quantity = newCartItem.Quantity; if (newCartItem.Price != null) @@ -270,6 +270,7 @@ await AddItemAsync(new NewCartItem(item.ProductId, item.Quantity) DynamicProperties = item.DynamicProperties, Price = item.Price, IsWishlist = item.IsWishlist, + IsSelectedForCheckout = item.IsSelectedForCheckout, CartProduct = product, }); } diff --git a/src/VirtoCommerce.XCart.Core/Models/NewCartItem.cs b/src/VirtoCommerce.XCart.Core/Models/NewCartItem.cs index f1a167a..d5f37b3 100644 --- a/src/VirtoCommerce.XCart.Core/Models/NewCartItem.cs +++ b/src/VirtoCommerce.XCart.Core/Models/NewCartItem.cs @@ -33,5 +33,7 @@ public NewCartItem(string productId, int quantity) public IList DynamicProperties { get; set; } public bool IsWishlist { get; set; } + + public bool? IsSelectedForCheckout { get; set; } } } diff --git a/src/VirtoCommerce.XCart.Data/Commands/ChangeCartCurrencyCommandHandler.cs b/src/VirtoCommerce.XCart.Data/Commands/ChangeCartCurrencyCommandHandler.cs index 499c0e3..ea359c1 100644 --- a/src/VirtoCommerce.XCart.Data/Commands/ChangeCartCurrencyCommandHandler.cs +++ b/src/VirtoCommerce.XCart.Data/Commands/ChangeCartCurrencyCommandHandler.cs @@ -1,6 +1,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; +using VirtoCommerce.Xapi.Core.Models; using VirtoCommerce.XCart.Core; using VirtoCommerce.XCart.Core.Commands; using VirtoCommerce.XCart.Core.Commands.BaseCommands; @@ -11,14 +12,9 @@ namespace VirtoCommerce.XCart.Data.Commands { public class ChangeCartCurrencyCommandHandler : CartCommandHandler { - private readonly ICartProductService _cartProductService; - - public ChangeCartCurrencyCommandHandler( - ICartAggregateRepository cartAggregateRepository, - ICartProductService cartProductService) + public ChangeCartCurrencyCommandHandler(ICartAggregateRepository cartAggregateRepository) : base(cartAggregateRepository) { - _cartProductService = cartProductService; } public override async Task Handle(ChangeCartCurrencyCommand request, CancellationToken cancellationToken) @@ -39,14 +35,20 @@ public override async Task Handle(ChangeCartCurrencyCommand reque var newCurrencyCartAggregate = await GetOrCreateCartFromCommandAsync(newCurrencyCartRequest); - // get items to convert - var excludedProductsIds = newCurrencyCartAggregate.LineItems.Select(x => x.ProductId).ToArray(); + // clear (old) cart items and add items from the currency cart + newCurrencyCartAggregate.Cart.Items.Clear(); var newCartItems = currentCurrencyCartAggregate.LineItems - .Where(x => !excludedProductsIds.Contains(x.ProductId)) .Select(x => new NewCartItem(x.ProductId, x.Quantity) { Comment = x.Note, + IsSelectedForCheckout = x.SelectedForCheckout, + DynamicProperties = x.DynamicProperties.SelectMany(x => x.Values.Select(y => new DynamicPropertyValue() + { + Name = x.Name, + Value = y.Value, + Locale = y.Locale, + })).ToArray(), }) .ToArray(); From ed3b585c3070ce8f7d68046ce02bd6c554dad8cf Mon Sep 17 00:00:00 2001 From: Konstantin Savosteev Date: Wed, 11 Dec 2024 13:36:03 +0200 Subject: [PATCH 3/6] feat: add IgnoreValidationErrors flag --- src/VirtoCommerce.XCart.Core/CartAggregate.cs | 64 +++++++++++-------- .../Models/NewCartItem.cs | 2 + .../ChangeCartCurrencyCommandHandler.cs | 1 + 3 files changed, 40 insertions(+), 27 deletions(-) diff --git a/src/VirtoCommerce.XCart.Core/CartAggregate.cs b/src/VirtoCommerce.XCart.Core/CartAggregate.cs index f0c9072..7366f06 100644 --- a/src/VirtoCommerce.XCart.Core/CartAggregate.cs +++ b/src/VirtoCommerce.XCart.Core/CartAggregate.cs @@ -205,47 +205,56 @@ public virtual async Task AddConfiguredItemAsync(NewCartItem newC public virtual async Task AddItemAsync(NewCartItem newCartItem) { - EnsureCartExists(); - ArgumentNullException.ThrowIfNull(newCartItem); + EnsureCartExists(); + var validationResult = await AbstractTypeFactory.TryCreateInstance().ValidateAsync(newCartItem, options => options.IncludeRuleSets(ValidationRuleSet)); if (!validationResult.IsValid) { OperationValidationErrors.AddRange(validationResult.Errors); - } - else if (newCartItem.CartProduct != null) - { - if (newCartItem.IsWishlist && newCartItem.CartProduct.Price == null) + + if (!newCartItem.IgnoreValidationErrors) { - newCartItem.CartProduct.Price = new ProductPrice(Currency); + return this; } + } - var lineItem = _mapper.Map(newCartItem.CartProduct); + if (newCartItem.CartProduct == null) + { + return this; + } - lineItem.SelectedForCheckout = newCartItem.IsSelectedForCheckout ?? IsSelectedForCheckout; - lineItem.Quantity = newCartItem.Quantity; + if (newCartItem.IsWishlist && newCartItem.CartProduct.Price == null) + { + newCartItem.CartProduct.Price = new ProductPrice(Currency); + } - if (newCartItem.Price != null) - { - lineItem.ListPrice = newCartItem.Price.Value; - lineItem.SalePrice = newCartItem.Price.Value; - } - else - { - SetLineItemTierPrice(newCartItem.CartProduct.Price, newCartItem.Quantity, lineItem); - } + var lineItem = _mapper.Map(newCartItem.CartProduct); - if (!string.IsNullOrEmpty(newCartItem.Comment)) - { - lineItem.Note = newCartItem.Comment; - } + lineItem.Currency ??= Currency.Code; + lineItem.SelectedForCheckout = newCartItem.IsSelectedForCheckout ?? IsSelectedForCheckout; + lineItem.Quantity = newCartItem.Quantity; - CartProducts[newCartItem.CartProduct.Id] = newCartItem.CartProduct; - await SetItemFulfillmentCenterAsync(lineItem, newCartItem.CartProduct); - await UpdateVendor(lineItem, newCartItem.CartProduct); - await InnerAddLineItemAsync(lineItem, newCartItem.CartProduct, newCartItem.DynamicProperties); + if (newCartItem.Price != null) + { + lineItem.ListPrice = newCartItem.Price.Value; + lineItem.SalePrice = newCartItem.Price.Value; } + else + { + SetLineItemTierPrice(newCartItem.CartProduct.Price, newCartItem.Quantity, lineItem); + } + + if (!string.IsNullOrEmpty(newCartItem.Comment)) + { + lineItem.Note = newCartItem.Comment; + } + + CartProducts[newCartItem.CartProduct.Id] = newCartItem.CartProduct; + await SetItemFulfillmentCenterAsync(lineItem, newCartItem.CartProduct); + await UpdateVendor(lineItem, newCartItem.CartProduct); + await InnerAddLineItemAsync(lineItem, newCartItem.CartProduct, newCartItem.DynamicProperties); return this; } @@ -272,6 +281,7 @@ await AddItemAsync(new NewCartItem(item.ProductId, item.Quantity) IsWishlist = item.IsWishlist, IsSelectedForCheckout = item.IsSelectedForCheckout, CartProduct = product, + IgnoreValidationErrors = item.IgnoreValidationErrors, }); } else diff --git a/src/VirtoCommerce.XCart.Core/Models/NewCartItem.cs b/src/VirtoCommerce.XCart.Core/Models/NewCartItem.cs index d5f37b3..2025082 100644 --- a/src/VirtoCommerce.XCart.Core/Models/NewCartItem.cs +++ b/src/VirtoCommerce.XCart.Core/Models/NewCartItem.cs @@ -35,5 +35,7 @@ public NewCartItem(string productId, int quantity) public bool IsWishlist { get; set; } public bool? IsSelectedForCheckout { get; set; } + + public bool IgnoreValidationErrors { get; set; } } } diff --git a/src/VirtoCommerce.XCart.Data/Commands/ChangeCartCurrencyCommandHandler.cs b/src/VirtoCommerce.XCart.Data/Commands/ChangeCartCurrencyCommandHandler.cs index ea359c1..5939ccd 100644 --- a/src/VirtoCommerce.XCart.Data/Commands/ChangeCartCurrencyCommandHandler.cs +++ b/src/VirtoCommerce.XCart.Data/Commands/ChangeCartCurrencyCommandHandler.cs @@ -41,6 +41,7 @@ public override async Task Handle(ChangeCartCurrencyCommand reque var newCartItems = currentCurrencyCartAggregate.LineItems .Select(x => new NewCartItem(x.ProductId, x.Quantity) { + IgnoreValidationErrors = true, Comment = x.Note, IsSelectedForCheckout = x.SelectedForCheckout, DynamicProperties = x.DynamicProperties.SelectMany(x => x.Values.Select(y => new DynamicPropertyValue() From daf38fc1d208e1fe01ed5d94259a7a83ca3a5282 Mon Sep 17 00:00:00 2001 From: Konstantin Savosteev Date: Tue, 17 Dec 2024 15:16:20 +0200 Subject: [PATCH 4/6] fix: throw exception on null cart --- .../Commands/ChangeCartCurrencyCommandHandler.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/VirtoCommerce.XCart.Data/Commands/ChangeCartCurrencyCommandHandler.cs b/src/VirtoCommerce.XCart.Data/Commands/ChangeCartCurrencyCommandHandler.cs index 5939ccd..6c2c4bf 100644 --- a/src/VirtoCommerce.XCart.Data/Commands/ChangeCartCurrencyCommandHandler.cs +++ b/src/VirtoCommerce.XCart.Data/Commands/ChangeCartCurrencyCommandHandler.cs @@ -1,3 +1,4 @@ +using System; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -20,7 +21,8 @@ public ChangeCartCurrencyCommandHandler(ICartAggregateRepository cartAggregateRe public override async Task Handle(ChangeCartCurrencyCommand request, CancellationToken cancellationToken) { // get (or create) both carts - var currentCurrencyCartAggregate = await GetOrCreateCartFromCommandAsync(request); + var currentCurrencyCartAggregate = await GetOrCreateCartFromCommandAsync(request) + ?? throw new OperationCanceledException("Cart not found"); var newCurrencyCartRequest = new ChangeCartCurrencyCommand { From 71cc772771023e263b18a1c563c419ad09d3c3ff Mon Sep 17 00:00:00 2001 From: Konstantin Savosteev Date: Thu, 19 Dec 2024 11:41:42 +0200 Subject: [PATCH 5/6] fix: fix for configurable products --- src/VirtoCommerce.XCart.Core/CartAggregate.cs | 29 +++-- .../ChangeCartCurrencyCommandHandler.cs | 117 ++++++++++++++++-- 2 files changed, 120 insertions(+), 26 deletions(-) diff --git a/src/VirtoCommerce.XCart.Core/CartAggregate.cs b/src/VirtoCommerce.XCart.Core/CartAggregate.cs index 7366f06..b782137 100644 --- a/src/VirtoCommerce.XCart.Core/CartAggregate.cs +++ b/src/VirtoCommerce.XCart.Core/CartAggregate.cs @@ -180,26 +180,28 @@ public virtual async Task AddConfiguredItemAsync(NewCartItem newC EnsureCartExists(); - if (newCartItem.CartProduct != null) + if (newCartItem.CartProduct == null) { - CartProducts[newCartItem.CartProduct.Id] = newCartItem.CartProduct; + return this; + } - newConfiguredItem.Id = null; - newConfiguredItem.SelectedForCheckout = IsSelectedForCheckout; - newConfiguredItem.Quantity = newCartItem.Quantity; - newConfiguredItem.Note = newCartItem.Comment; + CartProducts[newCartItem.CartProduct.Id] = newCartItem.CartProduct; - Cart.Items.Add(newConfiguredItem); + newConfiguredItem.Id = null; + newConfiguredItem.SelectedForCheckout = IsSelectedForCheckout; + newConfiguredItem.Quantity = newCartItem.Quantity; + newConfiguredItem.Note = newCartItem.Comment; - if (newCartItem.DynamicProperties != null) - { - await UpdateCartItemDynamicProperties(newConfiguredItem, newCartItem.DynamicProperties); - } + Cart.Items.Add(newConfiguredItem); - await SetItemFulfillmentCenterAsync(newConfiguredItem, newCartItem.CartProduct); - await UpdateVendor(newConfiguredItem, newCartItem.CartProduct); + if (newCartItem.DynamicProperties != null) + { + await UpdateCartItemDynamicProperties(newConfiguredItem, newCartItem.DynamicProperties); } + await SetItemFulfillmentCenterAsync(newConfiguredItem, newCartItem.CartProduct); + await UpdateVendor(newConfiguredItem, newCartItem.CartProduct); + return this; } @@ -1161,6 +1163,7 @@ public virtual async Task UpdateConfiguredLineItemPrice(IList.TryCreateInstance(); + contaner.Currency = Currency; if (CartProducts.TryGetValue(configurationLineItem.ProductId, out var configurableProduct)) { diff --git a/src/VirtoCommerce.XCart.Data/Commands/ChangeCartCurrencyCommandHandler.cs b/src/VirtoCommerce.XCart.Data/Commands/ChangeCartCurrencyCommandHandler.cs index 6c2c4bf..c812785 100644 --- a/src/VirtoCommerce.XCart.Data/Commands/ChangeCartCurrencyCommandHandler.cs +++ b/src/VirtoCommerce.XCart.Data/Commands/ChangeCartCurrencyCommandHandler.cs @@ -1,7 +1,12 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; +using MediatR; +using VirtoCommerce.CartModule.Core.Model; +using VirtoCommerce.CatalogModule.Core.Search; +using VirtoCommerce.Platform.Core.Common; using VirtoCommerce.Xapi.Core.Models; using VirtoCommerce.XCart.Core; using VirtoCommerce.XCart.Core.Commands; @@ -13,9 +18,20 @@ namespace VirtoCommerce.XCart.Data.Commands { public class ChangeCartCurrencyCommandHandler : CartCommandHandler { - public ChangeCartCurrencyCommandHandler(ICartAggregateRepository cartAggregateRepository) + private readonly IProductConfigurationSearchService _productConfigurationSearchService; + private readonly ICartProductService _cartProductService; + private readonly IMediator _mediator; + + public ChangeCartCurrencyCommandHandler( + ICartAggregateRepository cartAggregateRepository, + IProductConfigurationSearchService productConfigurationSearchService, + ICartProductService cartProductService, + IMediator mediator) : base(cartAggregateRepository) { + _productConfigurationSearchService = productConfigurationSearchService; + _cartProductService = cartProductService; + _mediator = mediator; } public override async Task Handle(ChangeCartCurrencyCommand request, CancellationToken cancellationToken) @@ -40,25 +56,100 @@ public override async Task Handle(ChangeCartCurrencyCommand reque // clear (old) cart items and add items from the currency cart newCurrencyCartAggregate.Cart.Items.Clear(); - var newCartItems = currentCurrencyCartAggregate.LineItems - .Select(x => new NewCartItem(x.ProductId, x.Quantity) + await CopyItems(currentCurrencyCartAggregate, newCurrencyCartAggregate); + + await CartRepository.SaveAsync(newCurrencyCartAggregate); + return newCurrencyCartAggregate; + } + + protected virtual async Task CopyItems(CartAggregate currentCurrencyCartAggregate, CartAggregate newCurrencyCartAggregate) + { + var ordinaryItems = currentCurrencyCartAggregate.LineItems + .Where(x => !x.IsConfigured) + .ToArray(); + + if (ordinaryItems.Length > 0) + { + var newCartItems = ordinaryItems + .Select(x => new NewCartItem(x.ProductId, x.Quantity) + { + IgnoreValidationErrors = true, + Comment = x.Note, + IsSelectedForCheckout = x.SelectedForCheckout, + DynamicProperties = x.DynamicProperties.SelectMany(x => x.Values.Select(y => new DynamicPropertyValue() + { + Name = x.Name, + Value = y.Value, + Locale = y.Locale, + })).ToArray(), + }) + .ToArray(); + + await newCurrencyCartAggregate.AddItemsAsync(newCartItems); + } + + // copy configured items + var configuredItems = currentCurrencyCartAggregate.LineItems + .Where(x => x.IsConfigured) + .ToArray(); + + await CopyConfiguredItems(newCurrencyCartAggregate, configuredItems); + } + + protected virtual async Task CopyConfiguredItems(CartAggregate newCurrencyCartAggregate, IList configuredItems) + { + if (configuredItems.Count == 0) + { + return; + } + + var configProductsIds = configuredItems + .Where(x => !x.ConfigurationItems.IsNullOrEmpty()) + .SelectMany(x => x.ConfigurationItems.Select(x => x.ProductId)) + .Distinct() + .ToList(); + + configProductsIds.AddRange(configuredItems.Select(x => x.ProductId)); + + var configProducts = await _cartProductService.GetCartProductsByIdsAsync(newCurrencyCartAggregate, configProductsIds); + + foreach (var configurationLineItem in configuredItems) + { + var contaner = AbstractTypeFactory.TryCreateInstance(); + contaner.Currency = newCurrencyCartAggregate.Currency; + contaner.Store = newCurrencyCartAggregate.Store; + + var configurableProduct = configProducts.FirstOrDefault(x => x.Product.Id == configurationLineItem.ProductId); + if (configurableProduct != null) + { + contaner.ConfigurableProduct = configurableProduct; + } + + foreach (var configurationItem in configurationLineItem.ConfigurationItems ?? []) { + var product = configProducts.FirstOrDefault(x => x.Product.Id == configurationItem.ProductId); + if (product != null) + { + contaner.AddItem(product, configurationItem.Quantity, configurationItem.SectionId); + } + } + + var expItem = contaner.CreateConfiguredLineItem(configurationLineItem.Quantity); + + await newCurrencyCartAggregate.AddConfiguredItemAsync(new NewCartItem(configurableProduct.Id, configurationLineItem.Quantity) + { + CartProduct = configurableProduct, IgnoreValidationErrors = true, - Comment = x.Note, - IsSelectedForCheckout = x.SelectedForCheckout, - DynamicProperties = x.DynamicProperties.SelectMany(x => x.Values.Select(y => new DynamicPropertyValue() + Comment = configurationLineItem.Note, + IsSelectedForCheckout = configurationLineItem.SelectedForCheckout, + DynamicProperties = configurationLineItem.DynamicProperties.SelectMany(x => x.Values.Select(y => new DynamicPropertyValue() { Name = x.Name, Value = y.Value, Locale = y.Locale, })).ToArray(), - }) - .ToArray(); - - await newCurrencyCartAggregate.AddItemsAsync(newCartItems); - - await CartRepository.SaveAsync(newCurrencyCartAggregate); - return newCurrencyCartAggregate; + }, expItem.Item); + } } } } From a27bea95081ba3f1ab191743e0ba1019223e0d4f Mon Sep 17 00:00:00 2001 From: Konstantin Savosteev Date: Thu, 19 Dec 2024 11:59:16 +0200 Subject: [PATCH 6/6] fix: sonar --- .../ChangeCartCurrencyCommandHandler.cs | 20 ++++--------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/src/VirtoCommerce.XCart.Data/Commands/ChangeCartCurrencyCommandHandler.cs b/src/VirtoCommerce.XCart.Data/Commands/ChangeCartCurrencyCommandHandler.cs index c812785..63d930c 100644 --- a/src/VirtoCommerce.XCart.Data/Commands/ChangeCartCurrencyCommandHandler.cs +++ b/src/VirtoCommerce.XCart.Data/Commands/ChangeCartCurrencyCommandHandler.cs @@ -3,9 +3,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; -using MediatR; using VirtoCommerce.CartModule.Core.Model; -using VirtoCommerce.CatalogModule.Core.Search; using VirtoCommerce.Platform.Core.Common; using VirtoCommerce.Xapi.Core.Models; using VirtoCommerce.XCart.Core; @@ -18,20 +16,14 @@ namespace VirtoCommerce.XCart.Data.Commands { public class ChangeCartCurrencyCommandHandler : CartCommandHandler { - private readonly IProductConfigurationSearchService _productConfigurationSearchService; private readonly ICartProductService _cartProductService; - private readonly IMediator _mediator; public ChangeCartCurrencyCommandHandler( ICartAggregateRepository cartAggregateRepository, - IProductConfigurationSearchService productConfigurationSearchService, - ICartProductService cartProductService, - IMediator mediator) + ICartProductService cartProductService) : base(cartAggregateRepository) { - _productConfigurationSearchService = productConfigurationSearchService; _cartProductService = cartProductService; - _mediator = mediator; } public override async Task Handle(ChangeCartCurrencyCommand request, CancellationToken cancellationToken) @@ -119,11 +111,7 @@ protected virtual async Task CopyConfiguredItems(CartAggregate newCurrencyCartAg contaner.Currency = newCurrencyCartAggregate.Currency; contaner.Store = newCurrencyCartAggregate.Store; - var configurableProduct = configProducts.FirstOrDefault(x => x.Product.Id == configurationLineItem.ProductId); - if (configurableProduct != null) - { - contaner.ConfigurableProduct = configurableProduct; - } + contaner.ConfigurableProduct = configProducts.FirstOrDefault(x => x.Product.Id == configurationLineItem.ProductId); foreach (var configurationItem in configurationLineItem.ConfigurationItems ?? []) { @@ -136,9 +124,9 @@ protected virtual async Task CopyConfiguredItems(CartAggregate newCurrencyCartAg var expItem = contaner.CreateConfiguredLineItem(configurationLineItem.Quantity); - await newCurrencyCartAggregate.AddConfiguredItemAsync(new NewCartItem(configurableProduct.Id, configurationLineItem.Quantity) + await newCurrencyCartAggregate.AddConfiguredItemAsync(new NewCartItem(configurationLineItem.ProductId, configurationLineItem.Quantity) { - CartProduct = configurableProduct, + CartProduct = contaner.ConfigurableProduct, IgnoreValidationErrors = true, Comment = configurationLineItem.Note, IsSelectedForCheckout = configurationLineItem.SelectedForCheckout,