我如何从愿望清单中将产品添加到后台购物车?

huangapple go评论100阅读模式
英文:

How can I add products on backend from a Wishlist to cart

问题

我一直在开发一个API,基本上是将愿望清单中的所有产品添加/更新到用户的购物车中。

API的要求如下:

  1. API应该接受愿望清单的ID作为输入,并将其所有产品添加到购物车中。
  2. 如果愿望清单中存储的产品已经存在于购物车中,那么购物车的数量应该更新为愿望清单和购物车中数量的总和。
  3. 添加产品后,愿望清单应该保留不变。

我实现的逻辑涉及到两个嵌套的for循环,一个循环遍历愿望清单条目,另一个循环遍历购物车条目(如果购物车不为空)。这个逻辑对于添加产品来说运行良好,但我在更新产品时遇到了问题。

当我在空购物车上调用API时,看不到任何问题,所有产品都被完美添加,但当我尝试再次调用API时,只有购物车中的一个项目被更新,而其他项目保持不变,这是因为愿望清单的索引在增加以检查下一个产品时,先前更新的产品现在被addToCart()方法覆盖了。

例如,如果愿望清单和购物车上都有两个相同的产品,分别是产品A和产品B,在两个for循环中将会出现四种情况:

sl cart   wishlist   operation
1   A         A       update
2   A         B        add
3   B         A        add
4   B         B       update

对于情况1,产品首先被更新,但在第二次迭代中被addToCart方法覆盖。

我该如何解决这个问题?

对于其他类型的实现建议也是欢迎的,但我不能更改大多数现有方法,比如AddToCart()UpdateCart()

以下是代码部分,不包括翻译:

public void addAllToCart(String wishListId) 
{
    // 通过ID查找愿望清单的代码,将愿望清单保存在类型为WishListModel的wishlist变量中
    // 获取会话购物车的代码,将购物车保存在类型为CartModel的cart变量中
    if (CollectionUtils.isNotEmpty(wishlist.getEntries())) 
    {
        for (WishListEntryModel wishListEntry : wishlist.getEntries()) 
        {
            checkInCartEntry(wishListEntry, cart.getEntries());
        }
    }
}

private void checkInCartEntry(WishListEntryModel wishListEntry, List<AbstractOrderEntryModel> cartEntries)
{
    if (CollectionUtils.isEmpty(cartEntries))
    {
        addToCart(wishListEntry);
    }
    else
    {
        for (AbstractOrderEntryModel cartEntry : cartEntries) 
        {
            if (wishListEntry.getProduct().getCode().equalsIgnoreCase(cartEntry.getProduct().getCode())) 
            {
                updateCartEntry(cartEntry.getEntryNumber, wishlist.getQuantity+cartEntry.getQuantity);
            } 
            else 
            {
                addToCart(wishListEntry);
            }
        }
    }
}
英文:

I have been working on developing am API which basically adds/updates all the products from a wishlist to the user's cart.

The requirements of the API are as follows:

  1. the API should take input of the ID of the wishlist and add all its products to cart
  2. If the products stored in the wishlist already exists on cart then the cart quantity is to be updated with the sum of both the quantity present on wishlist and the cart.
  3. the wishlist is to be retained after adding the products.

The logic that I had implemented deals with a 2 nested for loop, one loops the wishlist entries and the other loops the cart entries if the cart isn't empty. This logic works well for adding a product but I am having trouble updating the products.

When I hit the API on an empty cart I see no issue all the products were added perfectly, but when I try to hit the API again the only one item of the cart is getting updated while the others stay the same, this is happening cause when the index of the wishlist is incrementing to check for the next product the previously updated products which were updated to the sum of the both quantities are now overridden by the addToCart() method.

like if there are 2 same products on the wishlist and the cart namely Product A and Product B on the two for loops

There will be four conditions

sl cart   wishlist   operation
1   A         A       update
2   A         B        add
3   B         A        add
4   B         B       update

For case 1 the product gets updated at first but the is getting overridden by the addToCart method in the second iteration.

How do I solve this?

Suggestions to other type of implementation is also welcome but I can't change most of the pre-existing methods such as AddToCart() or UpdateCart().

The implementation

public void addAllToCart(String wishListId) 
{
    //code for finding the wishlist by ID saves the wishlist on wishlist of type WishListModel
    //code for getting session cart saves on cart of type CartModel
    if (CollectionUtils.isNotEmpty(wishlist.getEntries())) 
    {
        for (WishListEntryModel wishListEntry : wishlist.getEntries()) 
        {
            checkInCartEntry(wishListEntry, cart.getEntries());
        }
    }
}

private void checkInCartEntry(WishListEntryModel wishListEntry, List<AbstractOrderEntryModel> cartEntries)
{
    if (CollectionUtils.isEmpty(cartEntries))
    {
        addToCart(wishListEntry);
    }
    else
    {
        for (AbstractOrderEntryModel cartEntry : cartEntries) 
        {
            if (wishListEntry.getProduct().getCode().equalsIgnoreCase(cartEntry.getProduct().getCode())) 
            {
                updateCartEntry(cartEntry.getEntryNumber, wishlist.getQuantity+cartEntry.getQuantity);
            } 
            else 
            {
                addToCart(wishListEntry);
            }
        }
    }
}

答案1

得分: 0

你的循环中有一个错误,所以嵌套的循环永远不会中断。假设你的愿望清单中有一个产品,购物车中有四个产品。在这种设置下,addToCart(wishListEntry) 方法将被调用四次。而且,如果愿望清单中可能有多次相同的产品,改变实现方式会更有意义,可以使用两个单独的循环来填充一个类似<productCode, finalQuantity>的映射,然后遍历映射,最后对每个产品只调用一次昂贵的添加/更新操作。

英文:

There is a mistake in your loops so the nested one does not ever break. Let's assume you have one product in a wish list and four products in a cart. In this setup addToCart(wishListEntry) method will be called four times. Also if there is a possibility to have the same product in a wish list multiple times it would make sense to change the implementation so there were two separate loops which would populate a map like <productCode, finalQuantity> and then iterate over the map and finally call expensive add/update operation just one time per each product.

答案2

得分: 0

我认为主要问题在于您在使用 de.hybris.platform.commercefacades.order.CartFacade 方法操作购物车条目后没有刷新 cart

例如,假设您有一个简单的购物车:

  • 1x 产品A(#1)

和一个愿望清单:

  • 1x 产品A(#1)
  • 1x 产品A(#2)

在这种情况下,当您遍历愿望清单条目时,您总是将购物车条目更新为一个值,即 wishlist.getQuantity+cartEntry.getQuantity,其中 cartEntry.getQuantity 始终返回1的数量(因为这是操作开始时购物车的数量)。

所以你会有类似这样的情况:

  1. 加载包含1x产品A的购物车到 cart
  2. 遍历愿望清单条目
    1. 对于愿望清单条目#1 - 遍历 cart.getEntries()
      1. 对于购物车条目#1 - 您有一个匹配的条目,因此使用在步骤1中加载的购物车条目#1的数量来调用updateCartEntry
    2. 对于愿望清单条目#2 - 遍历 cart.getEntries()
      1. 对于购物车条目#1 - 您有一个匹配的条目,因此使用在步骤1.1中加载的购物车条目#1的数量来调用updateCartEntry -> 问题在于这个值是陈旧的,在步骤2.1.1中没有被updateCartEntry更新

为了避免这个问题,您可以:

  1. 以某种方式更新在步骤1中加载的 cart 条目的数量
  2. 通过以下方式之一避免多次更新相同的购物车条目:
    1. 不允许包含相同产品的多个条目
    2. 或者在开始时合并包含相同产品的条目,就像Maksym Kosenko在他的答案中建议的那样。
英文:

I think that the main problem is that you don't refresh the cart after manipulating it's entries using de.hybris.platform.commercefacades.order.CartFacade methods.

For example let's assume that you have a simple cart:

  • 1x Product A (#1)

and a wishlist:

  • 1x Product A (#1)
  • 1x Product A (#2)

In such scenario when you iterate over wishlist entries you always update cart entry to a value wishlist.getQuantity+cartEntry.getQuantity where cartEntry.getQuantity always returns the quantity of 1 (because this was the cart quantity at the beginning of the operation).

So you have something like this:

  1. Load cart containing 1xProduct A into cart
  2. Iterate over wishlist entries
    1. For wishlist entry #1 - iterate over cart.getEntries():
      1. For cart entry #1 - you have a matching entry so call updateCartEntry using the quantity of cart entry #1 of the cart loaded in step 1
    2. For wishlist entry #2 - iterate over cart.getEntries():
      1. For cart entry #1 - you have a matching entry so call updateCartEntry using the quantity of cart entry #1 of the cart loaded in step 1 -> the problem is that this value is stale, it was not updated by updateCartEntry in step 2.1.1

To avoid this you could:

  1. Somehow update the quantities of entries of cart loaded in step 1
  2. Avoid updating the same cart entry multiple times by either:
    1. Disallowing multiple entries containing the same product
    2. Or merging entries containing the same product at the beginning just as Maksym Kosenko suggested in his answer.

答案3

得分: 0

感谢所有的评论和答案。
我通过在方法中分开添加和更新任务来解决了这个问题。
之前我使用的嵌套循环,正如@Mak在他们的答案中正确指出的那样,永远不会中断,从而导致addToCart()方法覆盖了之前的操作。
但是,我没有使用映射,而是使用了一个更简单的解决方案,如下所示:

  1. 调用会话购物车
  2. 复制购物车到另一个变量
  3. 调用addToCart()方法,并用愿望清单条目覆盖所有购物车条目
  4. 在用购物车的副本和购物车覆盖购物清单条目后,遍历购物车的副本和购物车,并更新相同的产品。

以下是代码:

public void addAllToCart(String wishListId) {
    WishListModel wishList = findByWishlistId(wishListId);
    CartModel cart = cartService.getSessionCart();
    CartModel tempCart = copyOf(cart);
    if(CollectionUtils.isNotEmpty(wishList.getEntries())) {
        for (WishListEntryModel wishListEntry : wishList.getEntries()) {
            cartFacade.addToCart(wishListEntry);
        }
        if(Objects.nonNull(tempCart)){
            for (AbstractOrderEntryModel tempCartEntry : tempCart.getEntries()) {
                checkInCartEntry(tempCartEntry, cart.getEntries());
            }
        }
    }
}

private void checkInCartEntry(AbstractOrderEntryModel tempCartEntry, List<AbstractOrderEntryModel> cartEntries) throws CommerceCartModificationException {
    for (AbstractOrderEntryModel cartEntry : cartEntries) {
        if(!tempCartEntry.getProduct().getCode().isEmpty() && !cartEntry.getProduct().getCode().isEmpty() && (tempCartEntry.getProduct().getCode().equalsIgnoreCase(cartEntry.getProduct().getCode()))) {
            cartFacade.updateCartEntry(cartEntry.getEntryNumber(), cartEntry.getQuantity());
        }
    }
}

希望对你有所帮助。

英文:

Thanks for all the comments and answers.
I solved this issue by separating adding, and updating tasks in the methods.
Nested loops which I was using earlier as correctly pointed out by @Mak in their answer never break thus causing the addToCart() method to override the manipulations made earlier.
but instead of using a map, I used a more simple solution and did the following:

  1. Called the session cart
  2. Copied the cart in another variable
  3. Called the addToCart() method and overwrite all the cart entries with the wishlist entry
  4. After overwriting the cart with the shopping list entries, I loop through the copy of the cart and the cart and update the product which are same.

The code is below

public void addAllToCart(String wishListId) {
    WishListModel wishList = findByWishlistId(wishListId)
    CartModel cart = cartService.getSessionCart();
    CartModel tempCart = copyOf(cart);
    if(CollectionUtils.isNotEmpty(wishList.getEntries())) {
        for (WishListEntryModel wishListEntry : wishlist.getEntries()) {
            cartFacade.addToCart(wishListEntry);
        }
        if(Objects.nonNull(tempCart)){
            for (AbstractOrderEntryModel tempCartEntry : tempCart.getEntries()) {
                checkInCartEntry(tempCartEntry, cart.getEntries());
            }
        }
    }
}
private void checkInCartEntry(AbstractOrderEntryModel tempCartEntry, List&lt;AbstractOrderEntryModel&gt; cartEntries) throws CommerceCartModificationException {
    for (AbstractOrderEntryModel cartEntry : cartEntries) {
        if(!tempCartEntry.getProduct().getCode().isEmpty() &amp;&amp;  !cartEntry.getProduct().getCode().isEmpty() &amp;&amp; (tempCartEntry.getProduct().getCode().equalsIgnoreCase(cartEntry.getProduct().getCode()))) {
                cartFacade.updateCartEntry(cartEntry.getEntryNumber(), cartEntry.getQuantity());

        }
    }
}

huangapple
  • 本文由 发表于 2023年7月20日 17:01:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/76728272.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定