feat(backend): 出入库编码搜索双路匹配+建单填快照;finance 趋势/日期区间;partner/product 拼音搜索
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JJ1g8XV1YhhmHRzhwWEW7o
This commit is contained in:
@@ -287,6 +287,79 @@ func TestInventoryHandler_List_DeletedProductFallsBackToSnapshot(t *testing.T) {
|
||||
assert.Equal(t, float64(1), parseResponse(w)["total"].(float64))
|
||||
}
|
||||
|
||||
// 商品编码独立筛选(?code=,库存屏第二个搜索框)
|
||||
func TestInventoryHandler_List_FilterByCode(t *testing.T) {
|
||||
db := testutil.SetupTestDB()
|
||||
shop := testutil.CreateTestShop(db, "INV_CODE")
|
||||
user := testutil.CreateTestUser(db, shop.ID, "admin", "pass", "admin")
|
||||
warehouse := testutil.CreateTestWarehouse(db, shop.ID, "Warehouse")
|
||||
product1 := testutil.CreateTestProduct(db, shop.ID, "Beer1") // code=P-Beer1
|
||||
product2 := testutil.CreateTestProduct(db, shop.ID, "Wine2") // code=P-Wine2
|
||||
token := getAuthToken(user.ID, shop.ID, "admin")
|
||||
r := setupProtectedRouter(db)
|
||||
|
||||
db.Create(&model.Inventory{ShopID: shop.ID, WarehouseID: &warehouse.ID, ProductID: &product1.ID, Quantity: 10})
|
||||
db.Create(&model.Inventory{ShopID: shop.ID, WarehouseID: &warehouse.ID, ProductID: &product2.ID, Quantity: 20})
|
||||
|
||||
// 精确前缀命中一条
|
||||
w := makeRequest(r, "GET", "/api/v1/inventory?code=P-Beer1", token, nil)
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.Equal(t, float64(1), parseResponse(w)["total"].(float64))
|
||||
|
||||
// 模糊命中两条
|
||||
w = makeRequest(r, "GET", "/api/v1/inventory?code=P-", token, nil)
|
||||
assert.Equal(t, float64(2), parseResponse(w)["total"].(float64))
|
||||
|
||||
// 无命中
|
||||
w = makeRequest(r, "GET", "/api/v1/inventory?code=NOPE", token, nil)
|
||||
assert.Equal(t, float64(0), parseResponse(w)["total"].(float64))
|
||||
}
|
||||
|
||||
// Summary 月初快照字段:月初数量 = 当前数量 − 本月净流水
|
||||
func TestInventoryHandler_Summary_LastMonth(t *testing.T) {
|
||||
db := testutil.SetupTestDB()
|
||||
shop := testutil.CreateTestShop(db, "INV_SUM")
|
||||
user := testutil.CreateTestUser(db, shop.ID, "admin", "pass", "admin")
|
||||
warehouse := testutil.CreateTestWarehouse(db, shop.ID, "Warehouse")
|
||||
product1 := testutil.CreateTestProduct(db, shop.ID, "Old")
|
||||
product2 := testutil.CreateTestProduct(db, shop.ID, "New")
|
||||
token := getAuthToken(user.ID, shop.ID, "admin")
|
||||
r := setupProtectedRouter(db)
|
||||
|
||||
now := time.Now()
|
||||
monthStart := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())
|
||||
price1 := 100.0
|
||||
|
||||
// inv1:上月已存在(月初数量 = 30 − (25−5) = 10)
|
||||
inv1 := model.Inventory{
|
||||
ShopID: shop.ID, WarehouseID: &warehouse.ID, ProductID: &product1.ID,
|
||||
Quantity: 30, UnitPrice: &price1,
|
||||
CreatedAt: monthStart.AddDate(0, 0, -10),
|
||||
}
|
||||
require.NoError(t, db.Create(&inv1).Error)
|
||||
// 本月流水:入 25、出 5 → 净 +20
|
||||
db.Create(&model.InventoryLog{ShopID: shop.ID, WarehouseID: warehouse.ID, ProductID: product1.ID, Direction: "in", Quantity: 25})
|
||||
db.Create(&model.InventoryLog{ShopID: shop.ID, WarehouseID: warehouse.ID, ProductID: product1.ID, Direction: "out", Quantity: 5})
|
||||
|
||||
// inv2:本月新入库,不计入月初快照
|
||||
price2 := 10.0
|
||||
db.Create(&model.Inventory{
|
||||
ShopID: shop.ID, WarehouseID: &warehouse.ID, ProductID: &product2.ID,
|
||||
Quantity: 5, UnitPrice: &price2,
|
||||
})
|
||||
db.Create(&model.InventoryLog{ShopID: shop.ID, WarehouseID: warehouse.ID, ProductID: product2.ID, Direction: "in", Quantity: 5})
|
||||
|
||||
w := makeRequest(r, "GET", "/api/v1/inventory/summary", token, nil)
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
resp := parseResponse(w)
|
||||
assert.Equal(t, float64(2), resp["sku_count"].(float64))
|
||||
assert.Equal(t, float64(35), resp["in_stock_qty"].(float64))
|
||||
assert.Equal(t, float64(30*100+5*10), resp["stock_value"].(float64))
|
||||
assert.Equal(t, float64(1), resp["last_month_sku"].(float64))
|
||||
assert.Equal(t, float64(10), resp["last_month_qty"].(float64))
|
||||
assert.Equal(t, float64(10*100), resp["last_month_value"].(float64))
|
||||
}
|
||||
|
||||
func TestInventoryHandler_AfterStockInApprove(t *testing.T) {
|
||||
db := testutil.SetupTestDB()
|
||||
shop := testutil.CreateTestShop(db, "INV008")
|
||||
|
||||
Reference in New Issue
Block a user