自动化立体仓库 - WMS系统
zyx
2023-10-02 cda03cb23bc12f582029ac8d6df103d86e61fc8b
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
package com.zy.asrs.service.impl;
 
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.BaseRes;
import com.core.common.Cools;
import com.core.exception.CoolException;
import com.zy.asrs.entity.*;
import com.zy.asrs.entity.param.CombParam;
import com.zy.asrs.entity.param.MobileAdjustParam;
import com.zy.asrs.service.*;
import com.zy.common.model.DetlDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
 
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
 
/**
 * 移动端服务核心类
 * Created by vincent on 2020/6/28
 */
@Slf4j
@Service
public class AgvMobileServiceImpl implements AgvMobileService {
 
    @Autowired
    private MatService matService;
    @Autowired
    private AgvWaitPakinService agvWaitPakinService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private OrderDetlService orderDetlService;
    @Autowired
    private AgvBasDevpService agvBasDevpService;
 
 
    /*
    组托 + 绑定暂存位
     */
    @Override
    @Transactional
    public String comb(CombParam param, Long userId) {
        if (Cools.isEmpty(param.getBarcode(), param.getCombMats())) {
            throw new CoolException(BaseRes.PARAM);
        }
 
        //检查是否已存在相同的托盘条码,存在则抛出异常
        if (agvWaitPakinService.selectCount(new EntityWrapper<AgvWaitPakin>().
                eq("supp_code", param.getBarcode()).eq("io_status", "N")) > 0) {
            throw new CoolException(param.getBarcode() + "数据正在进行入库");
        }
 
        if (Cools.isEmpty(param.getOrderNo())) {
            //无单组托
            NoOrderComb(param,userId);
        }else {
            //有单组托
            OrderComb(param,userId);
        }
 
        if(StringUtils.isEmpty(param.getLocno())){
            return "组托成功";
        }else {
            combBinding(param.getBarcode(),param.getLocno());
            return "组托成功,绑定站点成功";
        }
 
    }
 
    /*
    AGV无单组托
     */
    private void NoOrderComb(CombParam param, Long userId){
        List<DetlDto> detlDtos = mappingDetlDtoByCombMat(param,null);
 
        //用于统一一个托盘下的入库通知档的生成时间
        Date now = new Date();
        detlDtos.forEach(detlDto -> {
            syncWaitPakin(detlDto,"",param.getBarcode(),userId,now);
        });
    }
 
    /*
    AGV有单组托
     */
    private void OrderComb(CombParam param, Long userId){
        //关联组托
        Order order = orderService.selectByNo(param.getOrderNo());
        if(Cools.isEmpty(order)){
            throw new CoolException("单据编号不存在");
        }
        //订单状态2以上为完成或者取消的订单
        if (order.getSettle() > 2) {
            throw new CoolException("单据编号已过期");
        }
        // 用于生成入库通知档所需参数
        List<DetlDto> detlDtos = mappingDetlDtoByCombMat(param,order);
        //用于统一一个托盘下的入库通知档的生成时间
        Date now = new Date();
        for (DetlDto detlDto : detlDtos) {
            //同步生成入库通知档
            syncWaitPakin(detlDto,order.getOrderNo(),param.getBarcode(),userId,now);
        }
        //修改单据状态为2.作业中
        orderService.updateSettle(order.getId(), 2L, userId);
    }
 
    /*
    根据PDA扫码所传的物料信息参数映射为DetlDto
     */
    private List<DetlDto> mappingDetlDtoByCombMat(CombParam param, Order order){
        List<DetlDto> detlDtos = new ArrayList<>();
        param.getCombMats().forEach(combMat -> {
 
            if(!Cools.isEmpty(order)){
                //检查入库数量
                checkOrderQty(order,combMat);
            }
 
            DetlDto detlDto = new DetlDto(combMat.getMatnr(), combMat.getBatch(), combMat.getAnfme(), combMat.getCsocode(), combMat.getIsoseq());
            //同一托盘下相同物料信息和批号转为一个入库通知档
            if (DetlDto.has(detlDtos, detlDto)) {
                DetlDto one = DetlDto.find(detlDtos, detlDto.getMatnr(), detlDto.getBatch(), detlDto.getCsocode(), detlDto.getIsoseq(),null);
                assert one != null;
                one.setAnfme(one.getAnfme() + detlDto.getAnfme());
            } else {
                detlDtos.add(detlDto);
            }
        });
 
        return detlDtos;
    }
 
    /*
    检查入库数量是否小于等于单据数量,合理则修改OrderDetl作业数量信息,否则抛出异常
     */
    private void checkOrderQty(Order order, CombParam.CombMat combMat){
        // 订单明细数量校验,如果作业数量大于单据数量则抛出异常
        OrderDetl orderDetl = orderDetlService.selectItem(order.getId(), combMat.getMatnr(), combMat.getBatch());
        if(Cools.isEmpty(orderDetl)){
            throw new CoolException("未匹配到该单据下的物料");
        }
        if (combMat.getAnfme() > orderDetl.getEnableQty()) {
            throw new CoolException(orderDetl.getMatnr() + "入库数量不合法");
        }
        // 修改订单明细数量
        if (!orderDetlService.increase(order.getId(), combMat.getMatnr(), combMat.getBatch(), combMat.getAnfme())) {
            throw new CoolException("修改单据明细数量失败");
        }
    }
 
    /*
    同步生成AGV入库通知档数据
     */
    private void syncWaitPakin(DetlDto detlDto, String orderNo, String zpallet, Long userId, Date now ){
        Mat mat = matService.selectByMatnr(detlDto.getMatnr());
        if (Cools.isEmpty(mat)) {
            throw new CoolException(detlDto.getMatnr() + "商品档案不存在");
        }
        AgvWaitPakin waitPakin = new AgvWaitPakin();
        waitPakin.sync(mat);
        waitPakin.setOrderNo(orderNo);   // 单据编号
        waitPakin.setBatch(detlDto.getBatch());     // 序列码
        //waitPakin.setZpallet(zpallet);   // 托盘码
        waitPakin.setSuppCode(zpallet);   // 托盘码
        waitPakin.setIoStatus("N");     // 入出状态
        waitPakin.setAnfme(detlDto.getAnfme());  // 数量
        waitPakin.setStatus("Y");    // 状态
 
        ////销售订单号
        waitPakin.setThreeCode(detlDto.getCsocode());
        //销售订单行号
        waitPakin.setDeadTime(detlDto.getIsoseq());
 
 
        waitPakin.setAppeUser(userId);
        waitPakin.setAppeTime(now);
        waitPakin.setModiUser(userId);
        waitPakin.setModiTime(now);
        if (!agvWaitPakinService.insert(waitPakin)) {
            throw new CoolException("保存入库通知档失败");
        }
    }
 
 
    @Override
    @Transactional
    public void adjust(MobileAdjustParam param, Long userId) {
 
    }
 
    @Override
    @Transactional
    public void packComb(CombParam param, Long userId) {
 
    }
 
    @Override
    public void combBinding(String barcode, String stationCode) {
 
        AgvBasDevp agvBasDevp = agvBasDevpService.selectOne(new EntityWrapper<AgvBasDevp>().eq("barcode", barcode));
 
        if(!Cools.isEmpty(agvBasDevp)){
            throw new CoolException(barcode + "已经绑定在"+ agvBasDevp.getDevNo() +"站点");
        }
 
        agvBasDevp = agvBasDevpService.selectOne(new EntityWrapper<AgvBasDevp>().eq("dev_no",stationCode));
        if(agvBasDevp == null){
            throw new CoolException(stationCode + "站点信息错误");
        }
        if(!"O".equals(agvBasDevp.getLocSts())){
            throw new CoolException(stationCode + "该站点货位状态非空");
        }
 
        agvBasDevp.setBarcode(barcode);
        agvBasDevp.setLocSts("F");
        agvBasDevpService.update(agvBasDevp,(new EntityWrapper<AgvBasDevp>().eq("dev_no",stationCode)));
    }
 
    public List<AgvBasDevp> getAgvBasDevpByFloor(int floor) {
        EntityWrapper<AgvBasDevp> wrapper = new EntityWrapper<>();
        wrapper.eq("floor",floor).eq("cache_shelves","Y").eq("loc_sts","F");
        return agvBasDevpService.selectList(wrapper);
    }
 
}