Files
go-cart-actor/pkg/cart/mutation_change_quantity.go
Mats Törnberg afa79e7b56
All checks were successful
Build and Publish / BuildAndDeployAmd64 (push) Successful in 36s
Build and Publish / BuildAndDeployArm64 (push) Successful in 3m43s
handle limited quantity
2025-11-26 21:35:40 +01:00

63 lines
1.6 KiB
Go

package cart
import (
"fmt"
messages "git.k6n.net/go-cart-actor/pkg/messages"
)
// mutation_change_quantity.go
//
// Registers the ChangeQuantity mutation.
//
// 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.
// - Totals are recalculated (WithTotals).
//
// Error handling:
// - Returns an error if the item Id is not found.
// - Returns an error if payload is nil (defensive).
//
// Concurrency:
// - Uses the grain's RW-safe mutation pattern: we mutate in place under
// the grain's implicit expectation that higher layers control access.
// (If strict locking is required around every mutation, wrap logic in
// an explicit g.mu.Lock()/Unlock(), but current model mirrors prior code.)
func ChangeQuantity(g *CartGrain, m *messages.ChangeQuantity) error {
if m == nil {
return fmt.Errorf("ChangeQuantity: nil payload")
}
foundIndex := -1
for i, it := range g.Items {
if it.Id == uint32(m.Id) {
foundIndex = i
break
}
}
if foundIndex == -1 {
return fmt.Errorf("ChangeQuantity: item id %d not found", m.Id)
}
if m.Quantity <= 0 {
// Remove the item
g.Items = append(g.Items[:foundIndex], g.Items[foundIndex+1:]...)
g.UpdateTotals()
return nil
}
item := g.Items[foundIndex]
if item == nil {
return fmt.Errorf("ChangeQuantity: item id %d not found", m.Id)
}
if item.ReservationEndTime != nil {
return fmt.Errorf("ChangeQuantity: cannot change quantity of reserved item id %d", m.Id)
} else {
item.Quantity = int(m.Quantity)
g.UpdateTotals()
}
return nil
}