update
This commit is contained in:
@@ -41,7 +41,7 @@ type CartItem struct {
|
||||
Cgm string `json:"cgm,omitempty"`
|
||||
Tax int
|
||||
Stock uint16 `json:"stock"`
|
||||
Quantity int `json:"qty"`
|
||||
Quantity uint16 `json:"qty"`
|
||||
Discount *Price `json:"discount,omitempty"`
|
||||
Disclaimer string `json:"disclaimer,omitempty"`
|
||||
ArticleType string `json:"type,omitempty"`
|
||||
|
||||
@@ -2,6 +2,7 @@ package cart
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"git.k6n.net/go-cart-actor/pkg/actor"
|
||||
messages "git.k6n.net/go-cart-actor/pkg/messages"
|
||||
@@ -12,32 +13,48 @@ type CartMutationContext struct {
|
||||
reservationService inventory.CartReservationService
|
||||
}
|
||||
|
||||
func NewCartMutationContext(reservationService inventory.CartReservationService) CartMutationContext {
|
||||
return CartMutationContext{
|
||||
func NewCartMutationContext(reservationService inventory.CartReservationService) *CartMutationContext {
|
||||
return &CartMutationContext{
|
||||
reservationService: reservationService,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CartMutationContext) ReserveItem(ctx context.Context, cartId CartId, sku string, locationId string, quantity int) error {
|
||||
func (c *CartMutationContext) ReserveItem(ctx context.Context, cartId CartId, sku string, locationId *string, quantity uint16) (*time.Time, error) {
|
||||
if quantity <= 0 || c.reservationService == nil {
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
return c.reservationService.ReserveForCart(ctx, inventory.CartReserveRequest{
|
||||
l := inventory.LocationID("se")
|
||||
if locationId != nil {
|
||||
l = inventory.LocationID(*locationId)
|
||||
}
|
||||
ttl := time.Minute * 15
|
||||
endTime := time.Now().Add(ttl)
|
||||
err := c.reservationService.ReserveForCart(ctx, inventory.CartReserveRequest{
|
||||
CartID: inventory.CartID(cartId.String()),
|
||||
InventoryReference: &inventory.InventoryReference{
|
||||
SKU: inventory.SKU(sku),
|
||||
LocationID: inventory.LocationID(locationId),
|
||||
LocationID: l,
|
||||
},
|
||||
|
||||
TTL: ttl,
|
||||
Quantity: uint32(quantity),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &endTime, nil
|
||||
|
||||
}
|
||||
|
||||
func (c *CartMutationContext) ReleaseItem(ctx context.Context, cartId CartId, sku string, locationId string) error {
|
||||
func (c *CartMutationContext) ReleaseItem(ctx context.Context, cartId CartId, sku string, locationId *string) error {
|
||||
if c.reservationService == nil {
|
||||
return nil
|
||||
}
|
||||
return c.reservationService.ReleaseForCart(ctx, inventory.SKU(sku), inventory.LocationID(locationId), inventory.CartID(cartId.String()))
|
||||
l := inventory.LocationID("se")
|
||||
if locationId != nil {
|
||||
l = inventory.LocationID(*locationId)
|
||||
}
|
||||
return c.reservationService.ReleaseForCart(ctx, inventory.SKU(sku), l, inventory.CartID(cartId.String()))
|
||||
}
|
||||
|
||||
func NewCartMultationRegistry(context *CartMutationContext) actor.MutationRegistry {
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package cart
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
messages "git.k6n.net/go-cart-actor/pkg/messages"
|
||||
)
|
||||
@@ -21,6 +23,7 @@ import (
|
||||
// must keep this handler in sync.
|
||||
|
||||
func (c *CartMutationContext) AddItem(g *CartGrain, m *messages.AddItem) error {
|
||||
ctx := context.Background()
|
||||
if m == nil {
|
||||
return fmt.Errorf("AddItem: nil payload")
|
||||
}
|
||||
@@ -38,18 +41,15 @@ func (c *CartMutationContext) AddItem(g *CartGrain, m *messages.AddItem) error {
|
||||
if !sameStore {
|
||||
continue
|
||||
}
|
||||
if m.ReservationEndTime != nil {
|
||||
t := m.ReservationEndTime.AsTime()
|
||||
if existing.ReservationEndTime == nil || existing.ReservationEndTime.Before(m.ReservationEndTime.AsTime()) {
|
||||
existing.ReservationEndTime = &t
|
||||
existing.Quantity += int(m.Quantity)
|
||||
} else {
|
||||
existing.ReservationEndTime = &t
|
||||
}
|
||||
|
||||
} else {
|
||||
existing.Quantity += int(m.Quantity)
|
||||
if err := c.ReleaseItem(ctx, g.Id, existing.Sku, existing.StoreId); err != nil {
|
||||
log.Printf("failed to release item %d: %v", existing.Id, err)
|
||||
}
|
||||
endTime, err := c.ReserveItem(ctx, g.Id, existing.Sku, existing.StoreId, existing.Quantity+uint16(m.Quantity))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
existing.ReservationEndTime = endTime
|
||||
existing.Quantity += uint16(m.Quantity)
|
||||
existing.Stock = uint16(m.Stock)
|
||||
// If existing had nil store but new has one, adopt it.
|
||||
if existing.StoreId == nil && m.StoreId != nil {
|
||||
@@ -69,10 +69,15 @@ func (c *CartMutationContext) AddItem(g *CartGrain, m *messages.AddItem) error {
|
||||
}
|
||||
|
||||
pricePerItem := NewPriceFromIncVat(m.Price, taxRate)
|
||||
endTime, err := c.ReserveItem(ctx, g.Id, m.Sku, m.StoreId, uint16(m.Quantity))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cartItem := &CartItem{
|
||||
Id: g.lastItemId,
|
||||
ItemId: uint32(m.ItemId),
|
||||
Quantity: int(m.Quantity),
|
||||
Quantity: uint16(m.Quantity),
|
||||
Sku: m.Sku,
|
||||
Tax: int(taxRate * 100),
|
||||
Meta: &ItemMeta{
|
||||
@@ -101,12 +106,10 @@ func (c *CartMutationContext) AddItem(g *CartGrain, m *messages.AddItem) error {
|
||||
OrgPrice: getOrgPrice(m.OrgPrice, taxRate),
|
||||
ArticleType: m.ArticleType,
|
||||
|
||||
StoreId: m.StoreId,
|
||||
}
|
||||
if m.ReservationEndTime != nil {
|
||||
t := m.ReservationEndTime.AsTime()
|
||||
cartItem.ReservationEndTime = &t
|
||||
StoreId: m.StoreId,
|
||||
ReservationEndTime: endTime,
|
||||
}
|
||||
|
||||
g.Items = append(g.Items, cartItem)
|
||||
g.UpdateTotals()
|
||||
return nil
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package cart
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
messages "git.k6n.net/go-cart-actor/pkg/messages"
|
||||
)
|
||||
@@ -30,6 +32,7 @@ func (c *CartMutationContext) ChangeQuantity(g *CartGrain, m *messages.ChangeQua
|
||||
if m == nil {
|
||||
return fmt.Errorf("ChangeQuantity: nil payload")
|
||||
}
|
||||
ctx := context.Background()
|
||||
|
||||
foundIndex := -1
|
||||
for i, it := range g.Items {
|
||||
@@ -44,6 +47,11 @@ func (c *CartMutationContext) ChangeQuantity(g *CartGrain, m *messages.ChangeQua
|
||||
|
||||
if m.Quantity <= 0 {
|
||||
// Remove the item
|
||||
itemToRemove := g.Items[foundIndex]
|
||||
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
|
||||
@@ -53,10 +61,19 @@ func (c *CartMutationContext) ChangeQuantity(g *CartGrain, m *messages.ChangeQua
|
||||
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()
|
||||
err := c.ReleaseItem(ctx, g.Id, item.Sku, item.StoreId)
|
||||
if err != nil {
|
||||
log.Printf("unable to release reservation for %s in location: %v", item.Sku, item.StoreId)
|
||||
}
|
||||
|
||||
}
|
||||
endTime, err := c.ReserveItem(ctx, g.Id, item.Sku, item.StoreId, uint16(m.Quantity))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
item.ReservationEndTime = endTime
|
||||
item.Quantity = uint16(m.Quantity)
|
||||
g.UpdateTotals()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,8 +1,22 @@
|
||||
package cart
|
||||
|
||||
import "git.k6n.net/go-cart-actor/pkg/messages"
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"git.k6n.net/go-cart-actor/pkg/messages"
|
||||
)
|
||||
|
||||
func (c *CartMutationContext) InventoryReserved(g *CartGrain, m *messages.InventoryReserved) error {
|
||||
for _, item := range g.Items {
|
||||
if item.ReservationEndTime != nil && item.ReservationEndTime.After(time.Now()) {
|
||||
err := c.ReleaseItem(context.Background(), g.Id, item.Sku, item.StoreId)
|
||||
if err != nil {
|
||||
log.Printf("unable to release item reservation")
|
||||
}
|
||||
}
|
||||
}
|
||||
g.InventoryReserved = true
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package cart
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
messages "git.k6n.net/go-cart-actor/pkg/messages"
|
||||
)
|
||||
@@ -39,6 +42,14 @@ func (c *CartMutationContext) RemoveItem(g *CartGrain, m *messages.RemoveItem) e
|
||||
return fmt.Errorf("RemoveItem: item id %d not found", m.Id)
|
||||
}
|
||||
|
||||
item := g.Items[index]
|
||||
if item.ReservationEndTime != nil && item.ReservationEndTime.After(time.Now()) {
|
||||
err := c.ReleaseItem(context.Background(), g.Id, item.Sku, item.StoreId)
|
||||
if err != nil {
|
||||
log.Printf("unable to release item reservation")
|
||||
}
|
||||
}
|
||||
|
||||
g.Items = append(g.Items[:index], g.Items[index+1:]...)
|
||||
g.UpdateTotals()
|
||||
return nil
|
||||
|
||||
@@ -37,15 +37,25 @@ func (m *MockReservationService) ReleaseForCart(ctx context.Context, sku invento
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MockReservationService) GetAvailableInventory(ctx context.Context, sku inventory.SKU, locationID inventory.LocationID) (uint32, error) {
|
||||
func (m *MockReservationService) GetAvailableInventory(ctx context.Context, sku inventory.SKU, locationID inventory.LocationID) (int64, error) {
|
||||
return 1000, nil
|
||||
}
|
||||
|
||||
func (m *MockReservationService) GetReservationExpiry(ctx context.Context, sku inventory.SKU, locationID inventory.LocationID, cartID inventory.CartID) (time.Time, error) {
|
||||
return time.Time{}, nil
|
||||
}
|
||||
|
||||
func (m *MockReservationService) GetReservationStatus(ctx context.Context, sku inventory.SKU, locationID inventory.LocationID, cartID inventory.CartID) (*inventory.ReservationStatus, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *MockReservationService) GetReservationSummary(ctx context.Context, sku inventory.SKU, locationID inventory.LocationID) (*inventory.ReservationSummary, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func newRegistry() actor.MutationRegistry {
|
||||
cartCtx := &CartMutationContext{
|
||||
reservationService: &MockReservationService{
|
||||
reservations: []messages.Reservation{},
|
||||
},
|
||||
reservationService: &MockReservationService{},
|
||||
}
|
||||
return NewCartMultationRegistry(cartCtx)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user