parent item mutations
This commit is contained in:
@@ -4,9 +4,8 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
messages "git.k6n.net/mats/go-cart-actor/proto/cart"
|
||||
cart_messages "git.k6n.net/mats/go-cart-actor/proto/cart"
|
||||
)
|
||||
|
||||
// mutation_change_quantity.go
|
||||
@@ -15,8 +14,11 @@ import (
|
||||
//
|
||||
// Behavior:
|
||||
// - Locates an item by its cart-local line item Id (not source item_id).
|
||||
// - If requested quantity <= 0 the line is removed.
|
||||
// - Otherwise the line's Quantity field is updated.
|
||||
// - If requested quantity <= 0 the line AND any descendants are
|
||||
// removed via the shared RemoveItem cascade (transitive parent→child).
|
||||
// - Otherwise the line's Quantity is updated and direct children are
|
||||
// rescaled proportionally so a "2 of this + 2 of each accessory"
|
||||
// bundle stays internally consistent when the parent becomes 3.
|
||||
// - Totals are recalculated (WithTotals).
|
||||
//
|
||||
// Error handling:
|
||||
@@ -29,7 +31,7 @@ import (
|
||||
// (If strict locking is required around every mutation, wrap logic in
|
||||
// an explicit g.mu.Lock()/Unlock(), but current model mirrors prior code.)
|
||||
|
||||
func (c *CartMutationContext) ChangeQuantity(g *CartGrain, m *messages.ChangeQuantity) error {
|
||||
func (c *CartMutationContext) ChangeQuantity(g *CartGrain, m *cart_messages.ChangeQuantity) error {
|
||||
if m == nil {
|
||||
return fmt.Errorf("ChangeQuantity: nil payload")
|
||||
}
|
||||
@@ -48,23 +50,18 @@ func (c *CartMutationContext) ChangeQuantity(g *CartGrain, m *messages.ChangeQua
|
||||
}
|
||||
|
||||
if m.Quantity <= 0 {
|
||||
// Remove the item
|
||||
itemToRemove := g.Items[foundIndex]
|
||||
if itemToRemove.ReservationEndTime != nil && itemToRemove.ReservationEndTime.After(time.Now()) {
|
||||
err := c.ReleaseItem(ctx, g.Id, itemToRemove.Sku, itemToRemove.StoreId)
|
||||
if err != nil {
|
||||
log.Printf("unable to release reservation for %s in location: %v", itemToRemove.Sku, itemToRemove.StoreId)
|
||||
}
|
||||
}
|
||||
g.Items = append(g.Items[:foundIndex], g.Items[foundIndex+1:]...)
|
||||
g.UpdateTotals()
|
||||
return nil
|
||||
// Setting a parent line to 0 means "remove it AND its accessories".
|
||||
// Delegate to RemoveItem so the cascade logic in one place stays
|
||||
// the source of truth for descendant cleanup + reservation
|
||||
// release — otherwise we'd duplicate the transitive cascade here.
|
||||
return c.RemoveItem(g, &cart_messages.RemoveItem{Id: m.Id})
|
||||
}
|
||||
item := g.Items[foundIndex]
|
||||
if item == nil {
|
||||
return fmt.Errorf("ChangeQuantity: item id %d not found", m.Id)
|
||||
}
|
||||
if g.Type == messages.CartType_REGULAR && c.UseReservations(item) {
|
||||
oldQty := item.Quantity
|
||||
if g.Type == cart_messages.CartType_REGULAR && c.UseReservations(item) {
|
||||
if item.ReservationEndTime != nil {
|
||||
err := c.ReleaseItem(ctx, g.Id, item.Sku, item.StoreId)
|
||||
if err != nil {
|
||||
@@ -79,6 +76,14 @@ func (c *CartMutationContext) ChangeQuantity(g *CartGrain, m *messages.ChangeQua
|
||||
item.ReservationEndTime = endTime
|
||||
}
|
||||
item.Quantity = uint16(m.Quantity)
|
||||
// Rescale any direct child lines proportionally so accessories stay
|
||||
// in sync with their parent. Descends recursively into grandchildren
|
||||
// via CascadeChildQuantities itself. Skipped when the target itself
|
||||
// is a child line — direct qty edits on a child are treated as
|
||||
// explicit user intent and don't propagate further.
|
||||
if item.ParentId == nil {
|
||||
c.CascadeChildQuantities(ctx, g, item.Id, oldQty, item.Quantity)
|
||||
}
|
||||
g.UpdateTotals()
|
||||
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user