all the refactor
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"git.k6n.net/mats/go-redis-inventory/pkg/inventory"
|
||||
contract "git.k6n.net/mats/platform/order"
|
||||
"git.k6n.net/mats/platform/rabbit"
|
||||
"github.com/redis/go-redis/v9"
|
||||
)
|
||||
|
||||
// commitOrder applies an order.created event to inventory. The sale already
|
||||
// happened, so this is an unconditional permanent decrement (it may drive stock
|
||||
// negative — visible oversell, reconciled downstream as backorder), NOT a
|
||||
// check-and-reserve that could refuse. It then releases the cart's TTL hold and
|
||||
// emits the resulting level crossing. Idempotent per order via a Redis marker,
|
||||
// since the bus is at-least-once.
|
||||
func commitOrder(ctx context.Context, rdb *redis.Client, svc *inventory.RedisInventoryService, resv *inventory.RedisCartReservationService, conn *rabbit.Conn, country string, low int64, c contract.Created) {
|
||||
if c.OrderID == "" {
|
||||
return
|
||||
}
|
||||
// Idempotency: first writer wins; redelivery is a no-op.
|
||||
fresh, err := rdb.SetNX(ctx, "invcommit:"+c.OrderID, "1", 30*24*time.Hour).Result()
|
||||
if err != nil {
|
||||
log.Printf("inventory: commit idempotency order=%s: %v", c.OrderID, err)
|
||||
return
|
||||
}
|
||||
if !fresh {
|
||||
return // already committed
|
||||
}
|
||||
// Default location for lines that don't carry their own: the order country
|
||||
// (central stock), falling back to the service's configured country.
|
||||
defaultLoc := c.Country
|
||||
if defaultLoc == "" {
|
||||
defaultLoc = country
|
||||
}
|
||||
for _, line := range c.Lines {
|
||||
if line.SKU == "" || line.Quantity <= 0 {
|
||||
continue
|
||||
}
|
||||
loc := inventory.LocationID(defaultLoc)
|
||||
if line.Location != "" {
|
||||
loc = inventory.LocationID(line.Location)
|
||||
}
|
||||
sku := inventory.SKU(line.SKU)
|
||||
pipe := rdb.Pipeline()
|
||||
if err := svc.DecrementInventory(ctx, pipe, sku, loc, int64(line.Quantity)); err != nil {
|
||||
log.Printf("inventory: commit decrement sku=%s order=%s: %v", sku, c.OrderID, err)
|
||||
continue
|
||||
}
|
||||
if _, err := pipe.Exec(ctx); err != nil {
|
||||
log.Printf("inventory: commit exec sku=%s order=%s: %v", sku, c.OrderID, err)
|
||||
continue
|
||||
}
|
||||
// Release the cart's TTL hold now the sale is committed (best-effort —
|
||||
// it would expire on its own anyway).
|
||||
if c.CartID != "" && resv != nil {
|
||||
if err := resv.ReleaseForCart(ctx, sku, loc, inventory.CartID(c.CartID)); err != nil {
|
||||
log.Printf("inventory: commit release sku=%s cart=%s: %v", sku, c.CartID, err)
|
||||
}
|
||||
}
|
||||
// Emit the level crossing from the new on-hand.
|
||||
if newQty, err := svc.GetInventory(ctx, sku, loc); err == nil {
|
||||
emitLevelIfChanged(ctx, rdb, conn, country, low, string(sku), string(loc), newQty)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user