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) }