zjj
20 小时以前 0a0f8d7480b9ddab9ce7d62dede869ee8c57fe75
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
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
package com.vincent.rsf.server.api.service.impl;
 
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.vincent.rsf.framework.common.Cools;
import com.vincent.rsf.framework.exception.CoolException;
import com.vincent.rsf.server.api.entity.dto.InTaskMsgDto;
import com.vincent.rsf.server.api.entity.dto.LocTypeDto;
import com.vincent.rsf.server.api.controller.params.TaskInParam;
import com.vincent.rsf.server.api.entity.enums.OrderType;
import com.vincent.rsf.server.api.entity.enums.TaskStsType;
import com.vincent.rsf.server.api.entity.enums.TaskType;
import com.vincent.rsf.server.api.service.WcsService;
import com.vincent.rsf.server.api.utils.LocUtils;
import com.vincent.rsf.server.api.utils.SlaveProperties;
import com.vincent.rsf.server.manager.entity.*;
import com.vincent.rsf.server.manager.enums.PakinIOStatus;
import com.vincent.rsf.server.manager.service.*;
import com.vincent.rsf.server.manager.service.impl.LocServiceImpl;
import com.vincent.rsf.server.manager.utils.LocManageUtil;
import com.vincent.rsf.server.system.constant.SerialRuleCode;
import com.vincent.rsf.server.system.enums.LocStsType;
import com.vincent.rsf.server.system.utils.SerialRuleUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
 
@Service
public class WcsServiceImpl implements WcsService {
    @Autowired
    private DeviceSiteService deviceSiteService;
    @Autowired
    private WaitPakinService waitPakinService;
    @Autowired
    private DeviceBindService deviceBindService;
    @Autowired
    private LocServiceImpl locService;
    @Autowired
    private LocItemService locItemService;
    @Autowired
    private SlaveProperties slaveProperties;
    @Autowired
    private WarehouseAreasService warehouseAreasService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private TaskItemService taskItemService;
    @Autowired
    private WaitPakinItemService waitPakinItemService;
 
    @Override
    public InTaskMsgDto createInTask(TaskInParam param, Long loginUserId) {
        InTaskMsgDto locNo = getLocNo(param);
        DeviceSite deviceSite = deviceSiteService.getOne(new LambdaQueryWrapper<DeviceSite>()
                .eq(DeviceSite::getSite, param.getSourceStaNo())
                .eq(DeviceSite::getType,param.getIoType())
        );
        if (Objects.isNull(deviceSite)) {
            throw new CoolException("站点不存在!!");
        }
 
        WaitPakin waitPakin = waitPakinService.getOne(new LambdaQueryWrapper<WaitPakin>()
                .eq(WaitPakin::getBarcode, param.getBarcode())
                .eq(WaitPakin::getIoStatus, Short.parseShort(PakinIOStatus.PAKIN_IO_STATUS_DONE.val)));
        if (Cools.isEmpty(waitPakin)) {
            throw new CoolException("请检查组拖状态是否完成!!");
        }
 
            List<TaskItem> taskItems = new ArrayList<>();
            String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_TASK_CODE, null);
            if (StringUtils.isBlank(ruleCode)) {
                throw new CoolException("编码错误:请确认编码「SYS_TASK_CODE」是否已生成!!");
            }
            Task task = new Task();
            task.setTaskCode(ruleCode)
                    .setTaskStatus(TaskStsType.GENERATE_IN.id.shortValue())
                    .setTaskType(TaskType.TASK_TYPE_IN.type.shortValue())
                    .setTargLoc(locNo.getLocNo())
                    .setBarcode(waitPakin.getBarcode())
                    .setTargSite(deviceSite.getDeviceSite())
                    .setCreateBy(loginUserId)
                    .setUpdateBy(loginUserId)
                    .setOrgSite(param.getSourceStaNo().toString());
 
 
 
 
            if (!taskService.save(task)) {
                throw new CoolException("任务保存失败!!");
            }
            if (!locService.update(new LambdaUpdateWrapper<Loc>().eq(Loc::getCode, task.getTargLoc())
                    .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_S.type).set(Loc::getBarcode, waitPakin.getBarcode()))) {
                throw new CoolException("库位预约失败!!");
            }
            /**获取组拖明细**/
            List<WaitPakinItem> waitPakinItems = waitPakinItemService.list(new LambdaQueryWrapper<WaitPakinItem>().eq(WaitPakinItem::getPakinId, waitPakin.getId()));
            if (waitPakinItems.isEmpty()) {
                throw new CoolException("数据错误:组拖明细不存在");
            }
            waitPakinItems.forEach(item -> {
                TaskItem taskItem = new TaskItem();
                BeanUtils.copyProperties(item, taskItem);
//                AsnOrder order = asnOrderService.getOne(new LambdaQueryWrapper<AsnOrder>().eq(AsnOrder::getId, item.getAsnId()));
//                if (Objects.isNull(order)) {
//                    throw new CoolException("数据错误: 单据不存在!!");
//                }
                taskItem.setTaskId(task.getId())
                        .setOrderType(OrderType.ORDER_RECEIPT.type)
                        .setSource(item.getId())
                        .setTrackCode(item.getTrackCode())
                        .setCreateBy(loginUserId)
                        .setUpdateBy(loginUserId)
                        .setOrderId(item.getAsnId())
                        .setOrderItemId(item.getAsnItemId());
                taskItems.add(taskItem);
            });
            if (!taskItemService.saveBatch(taskItems)) {
                throw new CoolException("任务明细保存失败!!");
            }
 
 
        if (!waitPakinService.update(new LambdaUpdateWrapper<WaitPakin>()
                .eq(WaitPakin::getBarcode, param.getBarcode())
                .set(WaitPakin::getUpdateBy, loginUserId)
                .set(WaitPakin::getCreateBy, loginUserId)
                .set(WaitPakin::getIoStatus, PakinIOStatus.PAKIN_IO_STATUS_TASK_EXCE.val))) {
            throw new CoolException("组托状态修改失败!!");
        }
        locNo.setWorkNo(ruleCode);
        return locNo;
    }
 
    public InTaskMsgDto getLocNo(TaskInParam param) {
        String matnr = null; String batch = null;
        List<WaitPakin> waitPakins = waitPakinService.list(new LambdaQueryWrapper<WaitPakin>().eq(WaitPakin::getBarcode, param.getBarcode()));
        if (Cools.isEmpty(waitPakins) && param.getIoType().equals(TaskType.TASK_TYPE_IN.type)) {
            throw new CoolException("未找到组托信息,请组托");
        }else if (!Cools.isEmpty(waitPakins)) {
            matnr = waitPakins.get(0).getCode();
            batch = waitPakins.get(0).getCode();
        }
        List<DeviceSite> deviceSites = deviceSiteService.list(new LambdaQueryWrapper<DeviceSite>()
                .eq(DeviceSite::getSite, param.getSourceStaNo())
                .eq(DeviceSite::getType,param.getIoType())
        );
        if (Cools.isEmpty(deviceSites)) {
            throw new CoolException("未找到站点路径信息");
        }
        WarehouseAreas warehouseArea = warehouseAreasService.getById(param.getArea());
        if (Cools.isEmpty(warehouseArea)) {
            throw new CoolException("未找到所属库区信息");
        }
        LocTypeDto locTypeDto = new LocTypeDto(param);
        InTaskMsgDto dto = null;
        switch (warehouseArea.getType()) {
            case "CRN": //堆垛机
                dto = getLocNoCrn(param.getArea(), param.getSourceStaNo(), matnr,batch, locTypeDto, 0, param.getIoType());
                break;
            case "SXC": //四向库
                break;
            case "CTU": //四向库
                break;
        }
        return dto;
    }
 
    private InTaskMsgDto getLocNoCrn(Integer area,Integer sourceStaNo, String matnr, String batch,LocTypeDto locTypeDto, int times,Integer ioType){
        if (Cools.isEmpty(matnr)) {  //物料号
            matnr = "";
        }
        if (Cools.isEmpty(batch)) {  //批次
            batch = "";
        }
        // 初始化参数
        int deviceNo = 0;      //堆垛机号
        int nearRow = 0;    //最浅库位排
        int curRow = 0;     //最深库位排
        int rowCount = 0;   //轮询轮次
        Loc loc = null;     // 目标库位
 
        InTaskMsgDto inTaskMsgDto = new InTaskMsgDto();
        DeviceBind deviceBind = deviceBindService.getById(LocUtils.getAreaType(sourceStaNo));
        if (Cools.isEmpty(deviceBind)) {
            throw new CoolException("数据异常,请联系管理员===>库位规则未知");
        }
        int sRow = deviceBind.getStartRow();
        int eRow = deviceBind.getEndRow();
        int deviceQty = deviceBind.getDeviceQty();
 
 
        // ===============>>>> 开始执行
        curRow = deviceBind.getCurrentRow();
 
        //此程序用于优化堆垛机异常时的运行时间
        for (int i = times; i <= deviceQty * 2; i++) {
            int[] locNecessaryParameters = LocUtils.LocNecessaryParameters(deviceBind, curRow, deviceQty);
            curRow = locNecessaryParameters[1];
            deviceNo = locNecessaryParameters[2];
            rowCount = locNecessaryParameters[0];
            nearRow = locNecessaryParameters[3];
            break;
        }
        if (nearRow == 0) {
            throw new CoolException("无可用堆垛机");
        }
        //入库靠近摆放
        if (ioType== 1 && deviceBind.getBeSimilar().equals("1") && !Cools.isEmpty(matnr)) {
            if (nearRow != curRow) {
                List<LocItem> locItems = locItemService.list(new LambdaQueryWrapper<LocItem>().eq(LocItem::getMatnrCode, matnr));
                for (LocItem locItem : locItems) {
                    Loc loc1 = locService.getById(locItem.getLocId());
                    if (LocUtils.isShallowLoc(slaveProperties, loc1.getCode())) {
                        continue;
                    }
                    String shallowLocNo = LocUtils.getShallowLoc(slaveProperties, loc1.getCode());
                    // 检测目标库位是否为空库位
                    Loc shallowLoc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getCode,shallowLocNo));
                    if (shallowLoc != null && shallowLoc.getUseStatus().equals("O")) {
                        if (LocUtils.locMoveCheckLocTypeComplete(shallowLoc, locTypeDto)) {
                                loc = shallowLoc;
                                deviceNo = shallowLoc.getDeviceNo();
                                break;
 
                        }
                    }
                }
            }
        }
 
//        // 靠近摆放规则 --- 空托 //互通版
//        if (ioType == 10 && deviceBind.getEmptySimilar().equals("1")) {
//            List<LocMast> locMasts = locMastService.selectList(new EntityWrapper<LocMast>()
//                    .eq("loc_sts", "D").ge("row1", sRow).le("row1", eRow).eq("whs_type", rowLastnoType.getType().longValue()));
//            if (!locMasts.isEmpty()) {
//                for (LocMast loc : locMasts) {
//                    if (Utils.isShallowLoc(slaveProperties, loc.getLocNo())) {
//                        continue;
//                    }
//                    String shallowLocNo = Utils.getShallowLoc(slaveProperties, loc.getLocNo());
//                    // 检测目标库位是否为空库位
//                    LocMast shallowLoc = locMastService.selectById(shallowLocNo);
//                    if (shallowLoc != null && shallowLoc.getLocSts().equals("O")) {
//                        if (VersionUtils.locMoveCheckLocTypeComplete(shallowLoc, locTypeDto)) {
//                            if (basCrnpService.checkSiteError(shallowLoc.getCrnNo(), true)) {
//                                locMast = shallowLoc;
//                                crnNo = locMast.getCrnNo();
//                                break;
//                            }
//                        }
//                    }
//                }
//            }
//        }
        //查找路径
        DeviceSite deviceSite = deviceSiteService.getOne(new LambdaQueryWrapper<DeviceSite>()
                .eq(DeviceSite::getType, ioType)
                .eq(DeviceSite::getSite, sourceStaNo)
                .eq(DeviceSite::getDeviceCode, deviceNo)
        );
        if (Cools.isEmpty(deviceSite)){
            deviceNo = 0;
        }else {
            inTaskMsgDto.setStaNo(Integer.parseInt(deviceSite.getDeviceSite()));
        }
 
        //更新当前排
        deviceBind.setCurrentRow(curRow);
        deviceBindService.updateById(deviceBind);
 
        // 开始查找库位 ==============================>>
 
        // 1.按规则查找库位
        if (Cools.isEmpty(loc) && deviceNo != 0) {
            List<Loc> locMasts = null;
            locMasts = locService.list(new LambdaQueryWrapper<Loc>()
                    .eq(Loc::getRow, nearRow)
                    .eq(Loc::getUseStatus, "O")
                    .eq(Loc::getType, locTypeDto.getLocType1())
                    .eq(Loc::getAreaId,area)
                    .orderByAsc(Loc::getLev)
                    .orderByAsc(Loc::getCol)
            );
            for (Loc locMast1 : locMasts) {
                if (!LocUtils.locMoveCheckLocTypeComplete(locMast1, locTypeDto)) {
                    continue;
                }
                String shallowLoc = LocUtils.getDeepLoc(slaveProperties, locMast1.getCode());
                if ((ioType== 1 && deviceBind.getBeSimilar().equals("1"))) {
                    //相似物料打开,判断深库位有没有货,没货就放深库位,有货就不操作
                    Loc locMast2 = locService.getOne(new LambdaQueryWrapper<Loc>()
                            .eq(Loc::getRow, shallowLoc)
                            .eq(Loc::getUseStatus, "O")
                            .eq(Loc::getAreaId,area)
                    );
                    if (!Cools.isEmpty(locMast2)) {
                        loc = locMast2;
                        break;
                    }
                } else {
                    //相似物料关闭,判断深库位有没有货,有货就放浅库位,无货就不操作
                    Loc locMast2 = locService.getOne(new LambdaQueryWrapper<Loc>()
                            .eq(Loc::getCode, shallowLoc)
                            .in(Loc::getUseStatus, "D","F")
                            .eq(Loc::getAreaId,area)
                    );
                    if (!Cools.isEmpty(locMast2)) {
                        loc = locMast1;
                        break;
                    }else{
                        locMast2 = locService.getOne(new LambdaQueryWrapper<Loc>()
                                .eq(Loc::getCode, shallowLoc)
                                .eq(Loc::getUseStatus, "O")
                                .eq(Loc::getAreaId,area)
                        );
                        if (!Cools.isEmpty(locMast2)) {
                            loc = locMast2;
                            break;
                        }
                    }
                }
            }
            if (Cools.isEmpty(loc) && deviceBind.getBeSimilar().equals("1")) {
                for (Loc locMast1 : locMasts) {
                    if (!LocUtils.locMoveCheckLocTypeComplete(locMast1, locTypeDto)) {
                        continue;
                    }
                    if (deviceBind.getBeSimilar().equals("1")) {
                        String shallowLoc = LocUtils.getDeepLoc(slaveProperties, locMast1.getCode());
                        Loc locMast2 = locService.getOne(new LambdaQueryWrapper<Loc>()
                                .eq(Loc::getCode, shallowLoc)
                                .eq(Loc::getUseStatus, "O")
                                .eq(Loc::getAreaId,area)
                        );
                        if (!Cools.isEmpty(locMast2)) {
                            loc = locMast2;
                            break;
                        } else {
                            locMast2 = locService.getOne(new LambdaQueryWrapper<Loc>()
                                    .eq(Loc::getCode, shallowLoc)
                                    .in(Loc::getUseStatus, "D","F")
                                    .eq(Loc::getAreaId,area)
                            );
                            if (!Cools.isEmpty(locMast2)) {
                                loc = locMast1;
                                break;
                            }
                        }
                    } else {
                        if (!Cools.isEmpty(locMast1)) {
                            loc = locMast1;
                            break;
                        }
                    }
                }
            }
        }
        //查询当前库位类型空库位 小于5个则locmast = null
        List<Loc> locTypeLocMasts = locService.list(new LambdaQueryWrapper<Loc>()
                .eq(Loc::getUseStatus, "O")
                .eq(Loc::getDeviceNo, deviceNo)
                .eq(Loc::getType, locTypeDto.getLocType1())
                .eq(Loc::getAreaId,area)
        );
        if (null !=locTypeLocMasts && locTypeLocMasts.size()<=5){
            loc = null;
        }
        // 递归查询
        if (Cools.isEmpty(loc) || !loc.getUseStatus().equals("O")) {
            // 当前巷道无空库位时,递归调整至下一巷道,检索全部巷道无果后,跳出递归
            if (times < rowCount * 2) {
                times = times + 1;
                return getLocNoCrn(area,sourceStaNo,matnr,batch,locTypeDto,times, ioType);
 
            }
            // 2.库位当前所属尺寸无空库位时,调整尺寸参数,向上兼容检索库位
            if (locTypeDto.getLocType1() < 3) {
                int i = locTypeDto.getLocType1() + 1;
                locTypeDto.setLocType1(i);
                return getLocNoCrn(area,sourceStaNo,matnr,batch,locTypeDto,0, ioType);
            }
            throw new CoolException("没有空库位");
        }
        String locNo = loc.getCode();
 
        // 返回dto
        inTaskMsgDto.setDeviceNo(deviceNo);
        inTaskMsgDto.setSourceStaNo(sourceStaNo);
//        inTaskMsgDto.setStaNo();
        inTaskMsgDto.setLocNo(locNo);
        return inTaskMsgDto;
    }
}