package service import ( "testing" "github.com/shopspring/decimal" "github.com/wmms/wmms/internal/model" ) // ClassifyStock 是库存状态的唯一判定入口,这张表同时钉住"新增物料不误报"和 // "真的低于阈值要报警"两侧的边界。它必须与 repository.stockWarningHavingSQL 一致。 func TestClassifyStockBoundaries(t *testing.T) { cases := []struct { name string totalOnHand string warningStock string warningEnabled bool want string }{ // 阈值为 0 是合法配置,含义是"库存降到 0 时预警",不再被排除在预警之外。 {"阈值0启用且库存归零", "0", "0", true, model.StockStatusLow}, {"阈值0启用但还剩一点", "0.000001", "0", true, model.StockStatusNormal}, {"有货且阈值为0", "5", "0", true, model.StockStatusNormal}, // 没配过规则和手动关闭预警由同一个 warningEnabled=false 表达,一律不报警。 {"没配过预警规则", "0", "0", false, model.StockStatusNormal}, {"设了阈值但库存归零", "0", "10", true, model.StockStatusLow}, {"低于阈值", "5", "10", true, model.StockStatusLow}, {"恰好触达阈值即预警", "10", "10", true, model.StockStatusLow}, {"略高于阈值", "10.000001", "10", true, model.StockStatusNormal}, {"高于阈值", "15", "10", true, model.StockStatusNormal}, {"用完但手动关闭预警", "0", "10", false, model.StockStatusNormal}, {"低于阈值但手动关闭预警", "5", "10", false, model.StockStatusNormal}, {"有货且手动关闭预警", "15", "10", false, model.StockStatusNormal}, // 数量是 decimal 字符串,按字典序比较会把 "370" 判成小于 "50"。 {"大数按数值而非字典序比较", "370.000000", "50.000000", true, model.StockStatusNormal}, } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { got := ClassifyStock( decimal.RequireFromString(tc.totalOnHand), decimal.RequireFromString(tc.warningStock), tc.warningEnabled, ) if got != tc.want { t.Fatalf("ClassifyStock(%s, %s, %v) = %s, want %s", tc.totalOnHand, tc.warningStock, tc.warningEnabled, got, tc.want) } }) } } func TestSignedChangeQuantityUsesTheSameConventionForInboundAndOutbound(t *testing.T) { quantity := decimal.NewFromInt(100) cases := []struct { logType string want string }{ {logType: "in", want: "100"}, {logType: "out", want: "-100"}, } for _, tc := range cases { t.Run(tc.logType, func(t *testing.T) { if got := signedChangeQuantity(tc.logType, quantity); !got.Equal(decimal.RequireFromString(tc.want)) { t.Fatalf("signedChangeQuantity(%q, 100) = %s, want %s", tc.logType, got, tc.want) } }) } }