chore: release server-v1.0.75
Deploy Server / release-deploy-server (push) Successful in 1m7s

出库售价(应收按售价) + 库存选择器分页上限修复 + seed 改为序列号模型

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YZ4DskSRKsSiheQonFtQvx
This commit is contained in:
wangjia
2026-06-22 13:01:25 +08:00
parent 6c43800354
commit 3641f1cf16
9 changed files with 420 additions and 323 deletions
+5 -1
View File
@@ -54,9 +54,13 @@ func (h *InventoryHandler) List(c *gin.Context) {
if page < 1 {
page = 1
}
if pageSize < 1 || pageSize > 500 {
if pageSize < 1 {
pageSize = 20
}
// 超出上限钳到上限(此前是回退默认 20,导致出库选货请求大 page_size 被打回只剩 20 条)
if pageSize > 5000 {
pageSize = 5000
}
baseWhere := "inv.shop_id = ? AND inv.deleted_at IS NULL"
args := []interface{}{shopID}
+4 -2
View File
@@ -110,8 +110,9 @@ func (h *StockOutHandler) Create(c *gin.Context) {
var total float64
for i := range req.Items {
req.Items[i].ShopID = shopID
// TotalPrice 记成本小计;应收(TotalAmount)按售价×数量
req.Items[i].TotalPrice = req.Items[i].Quantity * req.Items[i].UnitPrice
total += req.Items[i].TotalPrice
total += req.Items[i].Quantity * req.Items[i].SalePrice
}
req.TotalAmount = total
@@ -147,8 +148,9 @@ func (h *StockOutHandler) Update(c *gin.Context) {
for i := range req.Items {
req.Items[i].ShopID = shopID
req.Items[i].OrderID = order.ID
// TotalPrice 记成本小计;应收(TotalAmount)按售价×数量
req.Items[i].TotalPrice = req.Items[i].Quantity * req.Items[i].UnitPrice
total += req.Items[i].TotalPrice
total += req.Items[i].Quantity * req.Items[i].SalePrice
}
updates := map[string]interface{}{
"warehouse_id": req.WarehouseID,
+14 -7
View File
@@ -27,13 +27,21 @@ func TestStockReturn_StockOut_OwnAllowed(t *testing.T) {
// 操作员建出库单(本人) → 提交 → 审核
w := makeRequest(r, "POST", "/api/v1/stock-out/orders", opToken, map[string]interface{}{
"warehouse_id": wh.ID, "order_date": time.Now().Format(time.RFC3339),
"items": []map[string]interface{}{{"product_id": prod.ID, "quantity": 15.0, "unit_price": 20.0}},
"items": []map[string]interface{}{{"product_id": prod.ID, "quantity": 15.0, "unit_price": 20.0, "sale_price": 25.0}},
})
require.Equal(t, http.StatusCreated, w.Code)
orderID := extractID(w)
makeRequest(r, "PUT", fmt.Sprintf("/api/v1/stock-out/orders/%d/submit", orderID), opToken, nil)
makeRequest(r, "PUT", fmt.Sprintf("/api/v1/stock-out/orders/%d/approve", orderID), opToken, nil)
// 应收按售价口径:TotalAmount = 15 × 25 = 375(不是成本 15×20
var soOrder model.StockOutOrder
require.NoError(t, db.First(&soOrder, orderID).Error)
assert.Equal(t, float64(375), soOrder.TotalAmount)
var recv model.FinanceRecord
require.NoError(t, db.Where("shop_id = ? AND type = 'receivable' AND ref_type = 'stock_out'", shop.ID).First(&recv).Error)
assert.Equal(t, float64(375), recv.Amount, "应收应按售价×数量")
var item model.StockOutItem
require.NoError(t, db.Where("order_id = ?", orderID).First(&item).Error)
@@ -75,12 +83,11 @@ func TestStockReturn_StockOut_OwnAllowed(t *testing.T) {
db.First(&order, orderID)
assert.Equal(t, "full", order.ReturnState)
// 应收冲减:存在一条负向 receivable
var neg int64
db.Model(&model.FinanceRecord{}).
Where("shop_id = ? AND type = 'receivable' AND amount < 0 AND ref_type = 'stock_out_return'", shop.ID).
Count(&neg)
assert.Equal(t, int64(1), neg)
// 应收冲减:存在一条负向 receivable,金额按售价口径 = -375
var negRec model.FinanceRecord
require.NoError(t, db.Where("shop_id = ? AND type = 'receivable' AND amount < 0 AND ref_type = 'stock_out_return'", shop.ID).
First(&negRec).Error)
assert.Equal(t, float64(-375), negRec.Amount, "退单冲应收应按售价×数量")
}
func TestStockReturn_StockIn_AdminOnly_AndRemovesInventory(t *testing.T) {