Files
go-cart-actor/pkg/cart/mutation_remove_item.go
T
mats 60722e3414
Build and Publish / BuildAndDeployArm64 (push) Failing after 49s
Build and Publish / BuildAndDeployAmd64 (push) Has been cancelled
fixes
2026-06-16 13:14:35 +02:00

80 lines
2.1 KiB
Go

package cart
import (
"context"
"fmt"
"log"
"time"
messages "git.k6n.net/go-cart-actor/proto/cart"
)
// mutation_remove_item.go
//
// Registers the RemoveItem mutation.
//
// Behavior:
// - Removes the cart line whose local cart line Id == payload.Id
// - Cascades: also removes any line whose ParentId points at a removed line
// (transitively), so removing a parent removes its child sub-articles
// - If no such line exists returns an error
// - Releases reservations for every removed line and recalculates totals
//
// Notes:
// - This removes only the line items; any deliveries referencing a removed
// item are NOT automatically adjusted (mirrors prior logic). If future
// semantics require pruning delivery.item_ids you can extend this handler.
// - If multiple lines somehow shared the same Id (should not happen), all
// matches are removed—data integrity relies on unique line Ids.
func (c *CartMutationContext) RemoveItem(g *CartGrain, m *messages.RemoveItem) error {
if m == nil {
return fmt.Errorf("RemoveItem: nil payload")
}
targetID := uint32(m.Id)
found := false
for _, it := range g.Items {
if it.Id == targetID {
found = true
break
}
}
if !found {
return fmt.Errorf("RemoveItem: item id %d not found", m.Id)
}
// Collect the target and, transitively, any children pointing at a removed
// line. Loops until no further descendants are found (handles nesting).
remove := map[uint32]bool{targetID: true}
for {
grew := false
for _, it := range g.Items {
if it.ParentId != nil && remove[*it.ParentId] && !remove[it.Id] {
remove[it.Id] = true
grew = true
}
}
if !grew {
break
}
}
kept := g.Items[:0]
for _, it := range g.Items {
if remove[it.Id] {
if it.ReservationEndTime != nil && it.ReservationEndTime.After(time.Now()) {
if err := c.ReleaseItem(context.Background(), g.Id, it.Sku, it.StoreId); err != nil {
log.Printf("unable to release reservation for item %d: %v", it.Id, err)
}
}
continue
}
kept = append(kept, it)
}
g.Items = kept
g.UpdateTotals()
return nil
}