1. 新增预警表添加工单号字段,支持按工单号检索预警 2. 添加工单过滤在制品/绩效报表/预警中心查询 3. 补全WMS台账字段口径与权限配置 4. 修复备料单与数量不符处理流程 5. 新增配送进度/库位联动/自动出库功能 6. 修复AGV配送状态更新逻辑 7. 优化退料与库存管理细节
104 lines
3.4 KiB
Go
104 lines
3.4 KiB
Go
package logic
|
||
|
||
import (
|
||
"context"
|
||
"errors"
|
||
|
||
"bj_power_mes/ent/materialrequest"
|
||
)
|
||
|
||
// ============ 配送进度(跨系统只读聚合,不新增账本) ============
|
||
//
|
||
// 口径(2026-09-19 定稿):一个字段只有一个写者;跨系统只读聚合、绝不双写。
|
||
//
|
||
// WMS 台账(唯一真源):totalQty 需求 / outQty 已发出 / returnedQty 已退回 / consumedQty 已消耗
|
||
// MES 备料单(唯一真源):receivedQty 已接料(工位扫码接料累加)
|
||
//
|
||
// 派生(本接口现算,不落库):
|
||
//
|
||
// 净领用 netOut = outQty − returnedQty
|
||
// 待发缺口 gap = totalQty − netOut
|
||
// 在途 inTransit = outQty − receivedQty
|
||
// 线边 lineSide = receivedQty − consumedQty
|
||
//
|
||
// 恒等式:入库总量 = 在库 + 在途 + 线边 + 已消耗 + 退库回仓 + 盘点差异
|
||
type DeliveryProgressRow struct {
|
||
OrderNo string `json:"orderNo"`
|
||
MaterialCode string `json:"materialCode"`
|
||
MaterialName string `json:"materialName"`
|
||
TargetStation string `json:"targetStation"`
|
||
TotalQty int `json:"totalQty"`
|
||
OutQty int `json:"outQty"`
|
||
ReturnedQty int `json:"returnedQty"`
|
||
ConsumedQty int `json:"consumedQty"`
|
||
NetOut int `json:"netOut"`
|
||
Gap int `json:"gap"`
|
||
ReceivedQty int `json:"receivedQty"`
|
||
InTransit int `json:"inTransit"`
|
||
LineSide int `json:"lineSide"`
|
||
Status string `json:"status"`
|
||
CompletedAt int64 `json:"completedAt"`
|
||
}
|
||
|
||
// DeliveryProgress 配送进度:WMS 台账四段量 + MES 已接料 → 派生在途/线边。
|
||
// 仅读不写;WMS 不可达时返回错误由前端提示(不伪造数据)。
|
||
func (s *Service) DeliveryProgress(ctx context.Context, orderNo, materialCode string, page, pageSize int) (map[string]any, error) {
|
||
if s.ctx.Wms == nil {
|
||
return nil, errors.New("WMS 未配置,无法获取配送进度")
|
||
}
|
||
if page < 1 {
|
||
page = 1
|
||
}
|
||
if pageSize < 1 || pageSize > 200 {
|
||
pageSize = 50
|
||
}
|
||
rows, total, err := s.ctx.Wms.LedgerProgress(ctx, orderNo, materialCode, page, pageSize)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
// MES 侧已接料量:按「工单+图号」汇总。一次查询 + 内存聚合,避免逐行查询。
|
||
type lk struct{ orderNo, materialCode string }
|
||
recv := map[lk]int{}
|
||
orders := make([]string, 0, len(rows))
|
||
seen := map[string]bool{}
|
||
for _, r := range rows {
|
||
if r.OrderNo != "" && !seen[r.OrderNo] {
|
||
seen[r.OrderNo] = true
|
||
orders = append(orders, r.OrderNo)
|
||
}
|
||
}
|
||
if len(orders) > 0 {
|
||
list, e := s.ctx.EntClient.MaterialRequest.Query().
|
||
Where(materialrequest.OrderNoIn(orders...)).All(ctx)
|
||
if e == nil {
|
||
for _, mr := range list {
|
||
recv[lk{mr.OrderNo, mr.MaterialCode}] += int(mr.ReceivedQty + 0.5)
|
||
}
|
||
}
|
||
}
|
||
|
||
out := make([]DeliveryProgressRow, 0, len(rows))
|
||
for _, r := range rows {
|
||
got := recv[lk{r.OrderNo, r.MaterialCode}]
|
||
out = append(out, DeliveryProgressRow{
|
||
OrderNo: r.OrderNo,
|
||
MaterialCode: r.MaterialCode,
|
||
MaterialName: r.MaterialName,
|
||
TargetStation: r.TargetStation,
|
||
TotalQty: r.TotalQty,
|
||
OutQty: r.OutQty,
|
||
ReturnedQty: r.ReturnedQty,
|
||
ConsumedQty: r.ConsumedQty,
|
||
NetOut: r.NetOut,
|
||
Gap: r.Gap,
|
||
ReceivedQty: got,
|
||
InTransit: r.OutQty - got,
|
||
LineSide: got - r.ConsumedQty,
|
||
Status: r.Status,
|
||
CompletedAt: r.CompletedAt,
|
||
})
|
||
}
|
||
return map[string]any{"total": total, "list": out, "page": page, "pageSize": pageSize}, nil
|
||
}
|