Files
2026-10-19 01:13:17 +08:00

111 lines
3.2 KiB
Go

package controllers
// 移动端进销存库存接口:结存查询、流水追溯、预警、补货建议、批次效期。
//
// 与 /backend/erp/stock* 共用 erp_stock_core.go:结存只能由流水驱动,
// 因此这里全部是只读接口,手机端同样没有任何直接改库存的入口。
// AppErpStockController 库存查询(移动端)
type AppErpStockController struct {
AppErpBaseController
}
// List GET /api/erp/stock/list 库存结存(group_by=product 时按商品聚合)
func (c *AppErpStockController) List() {
cl, err := c.erpClaims()
if c.erpDenied(err) {
return
}
page, pageSize := c.erpPage()
f := erpStockFilter{
WarehouseID: c.erpUint("warehouse_id"),
ProductID: c.erpUint("product_id"),
BatchNo: c.erpQuery("batch_no"),
OnlyStock: c.erpFlag("only_stock"),
GroupByProduct: c.erpQuery("group_by") == "product",
Keyword: c.erpQuery("keyword"),
CategoryID: c.erpUint("category_id"),
SafetyState: c.erpQuery("safety_state"),
}
list, total, sumAmount, code, msg := erpStockListCore(c.actor(cl), f, page, pageSize)
if msg != "" {
c.erpFail(code, code, msg)
return
}
c.erpListOK(list, total, page, pageSize, map[string]interface{}{"sum_amount": sumAmount})
}
// Ledger GET /api/erp/stock/ledger 库存流水(收发存明细追溯)
func (c *AppErpStockController) Ledger() {
cl, err := c.erpClaims()
if c.erpDenied(err) {
return
}
page, pageSize := c.erpPage()
f := erpLedgerFilter{
ProductID: c.erpUint("product_id"),
WarehouseID: c.erpUint("warehouse_id"),
DocType: c.erpQuery("doc_type"),
BatchNo: c.erpQuery("batch_no"),
DocNo: c.erpQuery("doc_no"),
DateFrom: c.erpQuery("date_from"),
DateTo: c.erpQuery("date_to"),
}
list, total, code, msg := erpLedgerCore(c.actor(cl), f, page, pageSize)
if msg != "" {
c.erpFail(code, code, msg)
return
}
c.erpListOK(list, total, page, pageSize, nil)
}
// Warning GET /api/erp/stock/warning 库存预警:低于安全库存 / 超储 / 缺货 / 效期临近
func (c *AppErpStockController) Warning() {
cl, err := c.erpClaims()
if c.erpDenied(err) {
return
}
data, code, msg := erpWarningCore(c.actor(cl))
if msg != "" {
c.erpFail(code, code, msg)
return
}
c.erpOk(data)
}
// Replenish GET /api/erp/stock/replenish 智能补货建议
func (c *AppErpStockController) Replenish() {
cl, err := c.erpClaims()
if c.erpDenied(err) {
return
}
list, code, msg := erpReplenishCore(c.actor(cl))
if msg != "" {
c.erpFail(code, code, msg)
return
}
c.erpOk(map[string]interface{}{"list": list, "total": len(list)})
}
// Batch GET /api/erp/stock/batch 批次与效期台账
func (c *AppErpStockController) Batch() {
cl, err := c.erpClaims()
if c.erpDenied(err) {
return
}
page, pageSize := c.erpPage()
f := erpBatchFilter{
WarehouseID: c.erpUint("warehouse_id"),
ProductID: c.erpUint("product_id"),
OnlyPositive: c.erpFlag("only_positive"),
Keyword: c.erpQuery("keyword"),
ExpireState: c.erpQuery("expire_state"),
}
list, total, code, msg := erpBatchCore(c.actor(cl), f, page, pageSize)
if msg != "" {
c.erpFail(code, code, msg)
return
}
c.erpListOK(list, total, page, pageSize, nil)
}