自动化立体仓库 - WMS系统
#
1
1 天以前 ab6435ed8f14aa1eb4bc17b5eaf59fb2bdb994f7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package com.zy.asrs.task.kingdee.handler;
 
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.zy.asrs.entity.*;
import com.zy.asrs.service.*;
import com.zy.asrs.service.impl.ErpSecretServiceImpl;
import com.zy.asrs.service.impl.OrderDetlPakinServiceImpl;
import com.zy.asrs.service.impl.OrderDetlServiceImpl;
import com.zy.asrs.service.impl.OrderPakinServiceImpl;
import com.zy.asrs.task.AbstractHandler;
import com.zy.asrs.task.core.ReturnT;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
import java.util.List;
 
@Slf4j
@Service
public class AutoTransferHandler extends AbstractHandler<String> {
 
    @Autowired
    private OrderService orderService;
    @Autowired
    private ApiLogService apiLogService;
    @Autowired
    private DocTypeService docTypeService;
    @Autowired
    private LoginAuthenticationHandler loginAuthenticationHandler;
    @Autowired
    private ErpSecretServiceImpl erpSecretService;
    @Autowired
    private LocDetlService locDetlService;
    @Autowired
    private MatService matService;
    @Autowired
    private OrderDetlPakinServiceImpl orderDetlPakinService;
    @Autowired
    private OrderDetlServiceImpl orderDetlService;
    @Autowired
    private OrderPakinServiceImpl orderPakinServiceImpl;
 
    @Transactional(rollbackFor = Exception.class)
    public ReturnT<String> start(OrderPakin order) {
        // 获取该订单下的所有明细
        List<OrderDetlPakin> orderDetlPakins = orderDetlPakinService.selectList(
                new EntityWrapper<OrderDetlPakin>().eq("order_no", order.getOrderNo()));
 
        // 遍历每个订单明细进行库存转换
        for (OrderDetlPakin orderDetlPakin : orderDetlPakins) {
            double orderQuantity = orderDetlPakin.getAnfme(); // 本明细需要转换的数量
            double remainingQuantity = orderQuantity;        // 剩余未满足的数量
            double convertedQuantity = 0.0;                  // 已成功转换的数量
 
            log.info("开始处理订单明细: 订单号 = {}, 物料号 = {}, 需要转换数量 = {}",
                    order.getOrderNo(), orderDetlPakin.getMatnr(), orderQuantity);
 
            // 查询符合条件的可用库存:同一物料 + box_type3 以 HDU25 开头
            List<LocDetl> locDetls = locDetlService.selectList(
                    new EntityWrapper<LocDetl>()
                            .eq("matnr", orderDetlPakin.getMatnr())
                            .like("box_type3", "HDU25%")
                            .orderBy("anfme") // 可根据业务调整排序(如先进先出)
            );
 
            if (locDetls.isEmpty()) {
                log.error("无符合条件的库存: 订单 {} 物料 {}", order.getOrderNo(), orderDetlPakin.getMatnr());
                throw new IllegalArgumentException("无符合条件的库存满足订单 " + order.getOrderNo() +
                        " 的物料 " + orderDetlPakin.getMatnr());
            }
 
            // 逐条消耗库存
            for (LocDetl locDetl : locDetls) {
                if (remainingQuantity <= 0) {
                    break; // 已完全满足需求
                }
 
                double stockQty = locDetl.getAnfme();
                if (stockQty <= 0) {
                    continue; // 跳过空库存
                }
 
                // 本次实际消耗的数量
                double consumeQty = Math.min(stockQty, remainingQuantity);
 
                // 创建一条新的“已分配给订单”的库存记录(完整复制原记录)
                LocDetl allocated = new LocDetl();
                BeanUtils.copyProperties(locDetl, allocated);
 
                // 设置分配数量 + 覆盖指定字段
                allocated.setAnfme(consumeQty);
                allocated.setStandby1(orderDetlPakin.getStandby1());
                allocated.setStandby2(orderDetlPakin.getStandby2());
                allocated.setStandby3(orderDetlPakin.getStandby3());
                allocated.setBoxType1(orderDetlPakin.getBoxType1());
                allocated.setBoxType2(orderDetlPakin.getBoxType2());
                allocated.setBoxType3(orderDetlPakin.getBoxType3());
                allocated.setOrderNo(orderDetlPakin.getOrderNo());
 
                // 插入已分配记录
                locDetlService.insert(allocated);
                log.info("已分配库存记录: 位置={}, 数量={}, 剩余需求={}",
                        locDetl.getLocNo(), consumeQty, remainingQuantity - consumeQty);
 
                // 处理原库存记录:扣减后数量为0则删除,否则更新剩余数量
                double remainingStock = stockQty - consumeQty;
                if (remainingStock <= 0) {
                    // 数量正好耗尽或已为0,直接删除原记录
                    locDetlService.delete(new EntityWrapper<LocDetl>().eq("loc_no",locDetl.getLocNo()).eq("matnr",locDetl.getMatnr()).eq("box_type3",locDetl.getBoxType3()));
                    log.info("原库存已耗尽,删除记录: 位置={}, 原数量={}", locDetl.getLocNo(), stockQty);
                } else {
                    // 仍有剩余,更新数量
                    locDetl.setAnfme(remainingStock);
                    locDetlService.update(locDetl,new EntityWrapper<LocDetl>().eq("loc_no",locDetl.getLocNo()).eq("matnr",locDetl.getMatnr()).eq("box_type3",locDetl.getBoxType3()));
                    log.info("原库存部分消耗,更新剩余数量: 位置={}, 剩余={}", locDetl.getLocNo(), remainingStock);
                }
 
                // 更新统计量
                convertedQuantity += consumeQty;
                remainingQuantity -= consumeQty;
            }
 
            // 检查是否完全满足该明细的需求
            if (remainingQuantity > 0) {
                log.error("库存不足: 订单 {} 物料 {} 需求 {},仅转换 {},缺少 {}",
                        order.getOrderNo(), orderDetlPakin.getMatnr(), orderQuantity, convertedQuantity, remainingQuantity);
                throw new IllegalArgumentException("库存不足以满足订单 " + order.getOrderNo() +
                        " 的物料 " + orderDetlPakin.getMatnr() + " 需求,缺少 " + remainingQuantity);
            }
 
            // 更新订单明细已转换数量
            orderDetlPakin.setQty(convertedQuantity);
            orderDetlPakinService.updateById(orderDetlPakin);
 
            log.info("订单明细转换完成: 订单号 = {}, 物料号 = {}, 转换数量 = {}",
                    order.getOrderNo(), orderDetlPakin.getMatnr(), convertedQuantity);
        }
 
        // 所有明细均处理完成,设置订单 settle = 67
        order.setSettle(67L);
        orderPakinServiceImpl.updateById(order);
        log.info("订单全部明细转换完成,设置 settle = 67,订单号 = {}", order.getOrderNo());
 
        return SUCCESS;
    }
}