Skip to content

Commit

Permalink
feat(cart): add update bundle item mutation and service method (#493)
Browse files Browse the repository at this point in the history
---------

Co-authored-by: Karol Nowak <karol.nowak@omnevo.net>
Co-authored-by: Stanislav Müller <stanislav.mueller@omnevo.net>
Co-authored-by: Carsten Dietrich <carsten.dietrich@omnevo.net>
Co-authored-by: christopher.schwab <christopher.schwab@omnevo.net>
  • Loading branch information
5 people authored Oct 16, 2023
1 parent ead410a commit d94d942
Show file tree
Hide file tree
Showing 25 changed files with 1,324 additions and 14 deletions.
9 changes: 7 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,13 @@
* Introduce an Action to search result to advise the frontend to perform an action for that search different from displaying the result page.
The action model is completely open to anything, but the most common use case is to redirect certain searches directly to product detail pages or special brand landing pages.

**product**
* Add to cart of bundle products now only fails for missing required bundle choices. As prior passing all choices with qty of zero have been required. Now optional choices with qty of zero can be omitted.
**cart**
* Fix: Add to cart of bundle products now only fails for missing required bundle choices. As prior passing all choices with qty of zero have been required. Now optional choices with qty of zero can be omitted.
* Fix: Correctly evaluate min / max quantities of bundle choices. Previously it was possible to add bundle choices with qty 0 even if min qty was 1.
* **Breaking**(In case you have implemented a custom cart service): Extend the cart service interface with `UpdateItemBundleConfig` to allow updating bundles that have already been placed inside the cart.
* GraphQL:
* Add new mutation `Commerce_Cart_UpdateItemBundleConfig` to update bundle configs for existing cart items


## v3.8.0

Expand Down
81 changes: 80 additions & 1 deletion cart/application/cartService.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,11 @@ func (e *RestrictionError) Error() string {
return e.message
}

var _ Service = &CartService{}
var (
_ Service = &CartService{}
ErrBundleConfigNotProvided = errors.New("error no bundle config provided")
ErrProductNotTypeBundle = errors.New("product not of type bundle")
)

// Inject dependencies
func (cs *CartService) Inject(
Expand Down Expand Up @@ -410,6 +414,81 @@ func (cs *CartService) UpdateItems(ctx context.Context, session *web.Session, up
return nil
}

// UpdateItemBundleConfig updates multiple item
func (cs *CartService) UpdateItemBundleConfig(ctx context.Context, session *web.Session, updateCommand cartDomain.ItemUpdateCommand) error {
cart, behaviour, err := cs.cartReceiverService.GetCart(ctx, session)
if err != nil {
return err
}

if updateCommand.BundleConfiguration == nil {
return ErrBundleConfigNotProvided
}

item, err := cart.GetByItemID(updateCommand.ItemID)
if err != nil {
return err
}

product, err := cs.productService.Get(ctx, item.MarketplaceCode)
if err != nil {
cs.logger.WithContext(ctx).WithField(flamingo.LogKeySubCategory, "UpdateItemBundleConfig").Error(err)

return err
}

product, err = cs.getBundleWithActiveChoices(ctx, product, updateCommand.BundleConfiguration)
if err != nil {
return fmt.Errorf("error converting product to bundle: %w", err)
}

if cs.itemValidator != nil {
decoratedCart, _ := cs.cartReceiverService.DecorateCart(ctx, cart)
delivery, err := cart.GetDeliveryByItemID(updateCommand.ItemID)
if err != nil {
return fmt.Errorf("delivery code not found by item, while updating bundle: %w", err)
}

if err := cs.itemValidator.Validate(ctx, session, decoratedCart, delivery.DeliveryInfo.Code, cartDomain.AddRequest{}, product); err != nil {
return fmt.Errorf("error validating bundle update: %w", err)
}
}

// cart cache must be updated - with the current value of cart
var defers cartDomain.DeferEvents
defer func() {
cs.updateCartInCacheIfCacheIsEnabled(ctx, session, cart)
cs.dispatchAllEvents(ctx, defers)
}()

cart, defers, err = behaviour.UpdateItem(ctx, cart, updateCommand)
if err != nil {
cs.handleCartNotFound(session, err)
cs.logger.WithContext(ctx).WithField(flamingo.LogKeySubCategory, "UpdateItemSourceId").Error(err)

return err
}

return nil
}

//nolint:wrapcheck // error wrapped in the code above, no need to wrap twice
func (cs *CartService) getBundleWithActiveChoices(_ context.Context, product productDomain.BasicProduct, bundleConfig productDomain.BundleConfiguration) (productDomain.BasicProduct, error) {
var err error

bundleProduct, ok := product.(productDomain.BundleProduct)
if !ok {
return nil, ErrProductNotTypeBundle
}

product, err = bundleProduct.GetBundleProductWithActiveChoices(bundleConfig)
if err != nil {
return nil, err
}

return product, nil
}

// DeleteItem in current cart
func (cs *CartService) DeleteItem(ctx context.Context, session *web.Session, itemID string, deliveryCode string) error {
cart, behaviour, err := cs.cartReceiverService.GetCart(ctx, session)
Expand Down
Loading

0 comments on commit d94d942

Please sign in to comment.