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