Blame view

src/main/java/com/huaheng/api/wcs/service/warecellAllocation/WarecellAllocationServiceImpl.java 21.1 KB
pengcheng authored
1
2
package com.huaheng.api.wcs.service.warecellAllocation;
mahuandong authored
3
4
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
5
import com.huaheng.api.wcs.domain.WCSInfo;
mahuandong authored
6
import com.huaheng.common.exception.service.ServiceException;
7
import com.huaheng.common.support.Convert;
pengcheng authored
8
import com.huaheng.common.utils.StringUtils;
mahuandong authored
9
import com.huaheng.common.utils.security.ShiroUtils;
pengcheng authored
10
import com.huaheng.framework.web.domain.AjaxResult;
mahuandong authored
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import com.huaheng.pc.config.FilterConfigDetail.domain.FilterConfigDetail;
import com.huaheng.pc.config.FilterConfigDetail.service.FilterConfigDetailService;
import com.huaheng.pc.config.configValue.domain.ConfigValue;
import com.huaheng.pc.config.configValue.service.ConfigValueService;
import com.huaheng.pc.config.location.domain.Location;
import com.huaheng.pc.config.location.service.LocationService;
import com.huaheng.pc.config.locationType.domain.LocationType;
import com.huaheng.pc.config.locationType.service.LocationTypeService;
import com.huaheng.pc.config.material.domain.Material;
import com.huaheng.pc.config.material.service.MaterialService;
import com.huaheng.pc.config.materialType.domain.MaterialType;
import com.huaheng.pc.config.materialType.service.MaterialTypeService;
import com.huaheng.pc.config.receiptPreference.domain.ReceiptPreference;
import com.huaheng.pc.config.receiptPreference.service.ReceiptPreferenceService;
import com.huaheng.pc.receipt.receiptContainerDetail.domain.ReceiptContainerDetail;
import com.huaheng.pc.receipt.receiptContainerDetail.service.ReceiptContainerDetailService;
import com.huaheng.pc.receipt.receiptContainerHeader.domain.ReceiptContainerHeader;
import com.huaheng.pc.receipt.receiptContainerHeader.service.ReceiptContainerHeaderService;
import com.huaheng.pc.receipt.receiptDetail.service.ReceiptDetailService;
import com.huaheng.pc.task.taskDetail.domain.TaskDetail;
import com.huaheng.pc.task.taskDetail.service.TaskDetailService;
import com.huaheng.pc.task.taskHeader.domain.TaskHeader;
import com.huaheng.pc.task.taskHeader.service.TaskHeaderService;
34
35
import com.huaheng.pc.task.taskHeader.service.TransferTaskService;
import com.huaheng.pc.task.taskHeader.service.WorkTaskService;
pengcheng authored
36
import org.springframework.stereotype.Service;
mahuandong authored
37
38
import org.springframework.transaction.annotation.Transactional;
import com.huaheng.api.wcs.domain.WcsTask;
mahuandong authored
39
40
41
42
43
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
pengcheng authored
44
45
46
@Service
public class WarecellAllocationServiceImpl implements WarecellAllocationService {
mahuandong authored
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
    @Resource
    private LocationTypeService locationTypeService;
    @Resource
    private LocationService locationService;
    @Resource
    private ConfigValueService configValueService;
    @Resource
    private ReceiptPreferenceService receiptPreferenceService;
    @Resource
    private FilterConfigDetailService filterConfigDetailService;
    @Resource
    private TaskDetailService taskDetailService;
    @Resource
    private TaskHeaderService taskHeaderService;
    @Resource
    private ReceiptContainerDetailService receiptContainerDetailService;
    @Resource
    private ReceiptContainerHeaderService receiptContainerHeaderService;
    @Resource
    private ReceiptDetailService receiptDetailService;
    @Resource
    private MaterialService materialService;
    @Resource
    private MaterialTypeService materialTypeService;
71
72
73
74
    @Resource
    private WorkTaskService workTaskService;
    @Resource
    private TransferTaskService transferTaskService;
pengcheng authored
75
    /**
76
     * 立库仓位分配
pengcheng authored
77
78
     * 1、判断非空字段
     * 2、实体转换
mahuandong authored
79
     * 3、查询满足条件的库位类型
pengcheng authored
80
81
82
83
     * @param wcsTask
     * @return
     */
    @Override
mahuandong authored
84
85
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult warecellAllocation(WcsTask wcsTask) {
pengcheng authored
86
87
88
89
90

        //1、判断非空字段
        if(StringUtils.isEmpty(wcsTask.getTaskNo())){
            return AjaxResult.error("任务号为空");
        }
pengcheng authored
91
92
        if(StringUtils.isEmpty(wcsTask.getDestination())){
            return AjaxResult.error("目的为空");
pengcheng authored
93
        }
pengcheng authored
94
95
96
97
98
99
100
101
102
103
104
105
        if(StringUtils.isNull(wcsTask.getLength())){
            return AjaxResult.error("长为空");
        }
        if(StringUtils.isNull(wcsTask.getWidth())){
            return AjaxResult.error("宽为空");
        }
        if(StringUtils.isNull(wcsTask.getHeight())){
            return AjaxResult.error("高为空");
        }
        if(StringUtils.isNull(wcsTask.getWeight())){
            return AjaxResult.error("重为空");
        }
106
107
108
109
110
111
112
113
114
115
116
117
        String locationType = null;
        if(StringUtils.isNull(wcsTask.getLocationType())){
            locationType = "L";
         } else {
            locationType = wcsTask.getLocationType();
        }
        if(locationType.equals("L")) {
            return verticalWarehouseAllocation(wcsTask);
        }

        return AjaxResult.error("库位类型错误");
    }
pengcheng authored
118
119
    public AjaxResult verticalWarehouseAllocation(WcsTask wcsTask) {
mahuandong authored
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
        //查询满足条件的库位类型
        LambdaQueryWrapper<LocationType> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.gt(LocationType::getLength,wcsTask.getLength())
                .gt(LocationType::getWidth, wcsTask.getWidth())
                .gt(LocationType::getHeight, wcsTask.getHeight())
                .gt(LocationType::getMaxWeight, wcsTask.getWidth());
        List<LocationType> locationTypeList = locationTypeService.list(lambdaQueryWrapper);
        List<String> codeList = new ArrayList<>();
        for (LocationType locationType: locationTypeList) {
            codeList.add(locationType.getCode());
        }

        String locationCode = null;
        //查询任务明细
        LambdaQueryWrapper<TaskDetail> taskDetailLambda = Wrappers.lambdaQuery();
        taskDetailLambda.eq(TaskDetail::getTaskId, wcsTask.getTaskNo());
        List<TaskDetail> taskDetailList = taskDetailService.list(taskDetailLambda);
138
        TaskHeader taskHeader = taskHeaderService.getById(wcsTask.getTaskNo());
139
140
141
        if(taskHeader.getStatus() == 100) {
            return AjaxResult.error("任务已经完成,不能再分库位");
        }
142
mahuandong authored
143
        /* 循环查询入库组盘明细*/
mahuandong authored
144
145
146
147
148
149
150
        List<ReceiptContainerDetail> receiptContainerDetailList = new ArrayList<>();
        for (TaskDetail taskDetail : taskDetailList) {
            receiptContainerDetailList.add(receiptContainerDetailService.getById(taskDetail.getAllocationId()));
        }
        //去重
        receiptContainerDetailList = receiptContainerDetailList.stream().distinct().collect(Collectors.toList());
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
        if(receiptContainerDetailList != null && receiptContainerDetailList.size() > 0) {
            /* 循环入库组盘明细,重新分配库位*/
            for (ReceiptContainerDetail receiptContainerDetail : receiptContainerDetailList) {
                String locatingRule = null;
                ReceiptContainerHeader receiptContainerHeader= null;
                if(receiptContainerDetail != null) {
                    receiptContainerHeader = receiptContainerHeaderService.getById(receiptContainerDetail.getReceiptContainerId());
                    locatingRule  = this.taskPositioning(receiptContainerDetail);
                }
                if (StringUtils.isEmpty(locatingRule)){
                    //物料类别中定位规则为空时,查询入库首选项
                    LambdaQueryWrapper<ConfigValue> configValueLambda = Wrappers.lambdaQuery();
                    configValueLambda.eq(ConfigValue::getWarehouseCode, ShiroUtils.getWarehouseCode())
                            .eq(ConfigValue::getModuleType, "receipt")
                            .eq(ConfigValue::getRecordType, "入库首选项");
                    ConfigValue configValue = configValueService.getOne(configValueLambda);
                    LambdaQueryWrapper<ReceiptPreference> receiptPreferenceLambda = Wrappers.lambdaQuery();
                    receiptPreferenceLambda.eq(ReceiptPreference::getCode, configValue.getValue())
                            .eq(ReceiptPreference::getWarehouseCode, ShiroUtils.getWarehouseCode());
                    ReceiptPreference receiptPreference = receiptPreferenceService.getOne(receiptPreferenceLambda);
                    locatingRule = receiptPreferenceService.getOne(receiptPreferenceLambda).getLocationRule();
                }
                LambdaQueryWrapper<FilterConfigDetail> filterConfigDetailLambda = Wrappers.lambdaQuery();
                filterConfigDetailLambda.eq(FilterConfigDetail::getCode, locatingRule)
                        .eq(FilterConfigDetail::getWarehouseCode, ShiroUtils.getWarehouseCode());
                FilterConfigDetail filterConfigDetail = filterConfigDetailService.getOne(filterConfigDetailLambda);
                String[] locatingRules = filterConfigDetail.getStatement().split("cut");

                //根据定位规则查询库位编码
                LambdaQueryWrapper<Location> locationLambda = Wrappers.lambdaQuery();
                locationLambda.last(locatingRules[0]);
                locationLambda.eq(Location::getRoadway, wcsTask.getDestination());
                List<Location> locationList = locationService.list(locationLambda);
                if (locationList == null || locationList.size() == 0) {
                    locationLambda.last(locatingRules[1]);
                    locationList = locationService.list(locationLambda);
                }
                ;
                locationCode = filter(locationList, locationTypeList, wcsTask.getDestination());
                if (StringUtils.isEmpty(locationCode)) {
                    throw new ServiceException("没有库位可分配");
192
                }
mahuandong authored
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
                if (StringUtils.isNotEmpty(locationCode)) {
                    locationService.updateStatus(locationCode, "lock");
                    if (StringUtils.isNotEmpty(taskHeader.getToLocation()) && !locationCode.equals(taskHeader.getToLocation())) {
                        locationService.updateStatus(taskHeader.getToLocation(), "empty");
                    }
                } else {
                    throw new ServiceException("定位失败,请检查定位规则是否正确");
                }
                if(receiptContainerDetail != null) {
                    //更新库位编码到组盘头表
                    receiptContainerHeader.setToLocation(locationCode);
                    if (!receiptContainerHeaderService.updateById(receiptContainerHeader)) {
                        throw new ServiceException("更新库位失败");
                    }

                    //把库位编码赋到该入库组盘头表下的所有明细
                    LambdaQueryWrapper<ReceiptContainerDetail> lambda = Wrappers.lambdaQuery();
                    lambda.eq(ReceiptContainerDetail::getReceiptContainerId, receiptContainerHeader.getId())
                            .eq(ReceiptContainerDetail::getWarehouseCode, ShiroUtils.getWarehouseCode());
                    List<ReceiptContainerDetail> receiptContainerDetails = receiptContainerDetailService.list(lambda);
                    for (ReceiptContainerDetail receiptContainerDetail2 : receiptContainerDetails) {
                        receiptContainerDetail2.setLocationCode(locationCode);
                        if (!receiptContainerDetailService.updateById(receiptContainerDetail2)) {
                            throw new ServiceException("更新库位编码到入库组盘明细");
                        }
                    }
                }
mahuandong authored
221
222
            }
        }
223
mahuandong authored
224
225
226
227
228
229
230
        if (StringUtils.isNotEmpty(locationCode)){
            //修改任务明细目标库位
            for (TaskDetail taskDetail : taskDetailList) {
                taskDetail.setToLocation(locationCode);
                if (!taskDetailService.updateById(taskDetail)){ throw new ServiceException("更新任务明细目标库位失败");}
            }
pengcheng authored
231
232
233
234
235
            LambdaQueryWrapper<Location> locationLambdaQueryWrapper = Wrappers.lambdaQuery();
            locationLambdaQueryWrapper.eq(Location::getCode, locationCode);
            Location location = locationService.getOne(locationLambdaQueryWrapper);
            int rowFlag = location.getRowFlag().intValue();
236
            Integer preTaskNo = 0;
237
238
239
240
241
            //如果是外侧库位,那么就要判断该库位对应的内侧库位是不是有托盘
            if(rowFlag == 1) {
                Location insideLocation = locationService.getInsideNear(location);
                if(StringUtils.isNotEmpty(insideLocation.getContainerCode())) {
                    Location destinationLocation = locationService.getEmptyInsideLocation(insideLocation);
242
                    AjaxResult ajaxResult = transferTaskService.createTransferTask(insideLocation.getCode(), destinationLocation.getCode());
243
                    preTaskNo = (Integer) ajaxResult.getData();
244
245
246
                    if(ajaxResult.hasErr()) {
                        throw new ServiceException("创建移库任务失败");
                    }
247
                    taskHeaderService.sendTaskToWcs(Convert.toIntArray(String.valueOf(preTaskNo)));
248
249
                }
            }
250
251
252
253
254
255
256
257

            taskHeader.setPreTaskNo(preTaskNo);
            taskHeader.setToLocation(locationCode);
            if (!taskHeaderService.updateById(taskHeader)){throw new ServiceException("更新任务头表目标库位失败");}
            WCSInfo wcsInfo = new WCSInfo();
            wcsInfo.setLocationCode(locationCode);
            wcsInfo.setPreTask(String.valueOf(preTaskNo));
            return AjaxResult.success().setData(wcsInfo);
mahuandong authored
258
259
260
261
262
        }

        return AjaxResult.error("错误");
    }
mahuandong authored
263
264
    /**
     * 库位筛选
265
266
267
     * @param locationList 库位列表
     * @param locationTypeList 库位类型列表
     * @param roadway 巷道
mahuandong authored
268
269
     * @return
     */
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
    public String filter(List<Location> locationList, List<LocationType> locationTypeList, String roadway){
        List<String> codeList = locationTypeList.stream().map(t-> t.getCode()).collect(Collectors.toList());
        List<Location> newLocation = locationList.stream().filter(t-> codeList.contains(t.getLocationType()) && t.getRoadway().equals(roadway)).collect(Collectors.toList());
        if (newLocation.isEmpty()){
            return null;
        } else{
            return newLocation.get(0).getCode();
        }
    }

    /**
     * 定位
     * @param receiptContainerDetail
     * @return
     */
285
    @Override
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
    public String taskPositioning(ReceiptContainerDetail receiptContainerDetail){
        ReceiptContainerHeader receiptContainerHeader = receiptContainerHeaderService.getById(receiptContainerDetail.getReceiptContainerId());
        String locatingRule = receiptContainerHeader.getLocatingRule(); //定位规则
        if (StringUtils.isEmpty(locatingRule)){
            locatingRule = receiptDetailService.getById(receiptContainerDetail.getReceiptDetailId()).getLocatingRule();
            //入库单明细定位规则不为空时执行
            if (StringUtils.isEmpty(locatingRule)){
                //入库单明细为空时,查询物料表中是否含有定位规则
                LambdaQueryWrapper<Material> materialLambda = Wrappers.lambdaQuery();
                materialLambda.eq(Material::getCode, receiptContainerDetail.getMaterialCode());
                Material material = materialService.getOne(materialLambda);
                locatingRule = material.getLocatingRule();

                if (StringUtils.isEmpty(locatingRule)){
                    //物料表中定位规则为空时,查询物料类别
                    LambdaQueryWrapper<MaterialType> materialTypeLambda = Wrappers.lambdaQuery();
                    materialTypeLambda.eq(MaterialType::getCode, material.getType());
                    MaterialType materialType = materialTypeService.getOne(materialTypeLambda);
                    locatingRule = materialType.getLocatingRule();
                    if (StringUtils.isEmpty(locatingRule)){
                        //物料类别中定位规则为空时,查询入库首选项
                        LambdaQueryWrapper<ConfigValue> configValueLambda = Wrappers.lambdaQuery();
                        configValueLambda.eq(ConfigValue::getWarehouseCode, ShiroUtils.getWarehouseCode())
                                .eq(ConfigValue::getModuleType, "receipt")
                                .eq(ConfigValue::getRecordType, "入库首选项");
                        ConfigValue configValue = configValueService.getOne(configValueLambda);
                        LambdaQueryWrapper<ReceiptPreference> receiptPreferenceLambda = Wrappers.lambdaQuery();
mahuandong authored
313
314
                        receiptPreferenceLambda.eq(ReceiptPreference::getCode, configValue.getValue())
                                .eq(ReceiptPreference::getWarehouseCode, ShiroUtils.getWarehouseCode());
315
316
317
                        ReceiptPreference receiptPreference = receiptPreferenceService.getOne(receiptPreferenceLambda);
                        locatingRule = receiptPreferenceService.getOne(receiptPreferenceLambda).getLocationRule();
                    }
mahuandong authored
318
319
320
                }
            }
        }
321
322
323
324
325
326
        //通过定位规则查找自定义sql
        if (StringUtils.isEmpty(locatingRule)){
            throw new ServiceException("未绑定定位规则");
        }

        return locatingRule;
pengcheng authored
327
    }
pengcheng authored
328
329
mahuandong authored
330
331
332
    /**
     *  去向分配
     */
pengcheng authored
333
334
335
    @Override
    public AjaxResult destinationAllocation(WcsTask wcsTask) {
mahuandong authored
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
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
        //1、判断非空字段
        if(StringUtils.isEmpty(wcsTask.getTaskNo())){
            return AjaxResult.error("任务号为空");
        }
        if(StringUtils.isNull(wcsTask.getLength())){
            return AjaxResult.error("长为空");
        }
        if(StringUtils.isNull(wcsTask.getWidth())){
            return AjaxResult.error("宽为空");
        }
        if(StringUtils.isNull(wcsTask.getHeight())){
            return AjaxResult.error("高为空");
        }
        if(StringUtils.isNull(wcsTask.getWeight())){
            return AjaxResult.error("重为空");
        }

        //查询满足条件的库位类型
        LambdaQueryWrapper<LocationType> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.gt(LocationType::getLength,wcsTask.getLength())
                .gt(LocationType::getWidth, wcsTask.getWidth())
                .gt(LocationType::getHeight, wcsTask.getHeight())
                .gt(LocationType::getMaxWeight, wcsTask.getWidth());
        List<LocationType> locationTypeList = locationTypeService.list(lambdaQueryWrapper);

        if (locationTypeList.isEmpty()){
            return AjaxResult.error("没有区域可分配");
        }
        List<String> codeList = new ArrayList<>();
        for (LocationType locationType: locationTypeList) {
            codeList.add(locationType.getCode());
        }

        //定位库位List
        List<String> positioningLocationCodeList = null;
        //查询任务明细
        LambdaQueryWrapper<TaskDetail> taskDetailLambda = Wrappers.lambdaQuery();
        taskDetailLambda.eq(TaskDetail::getTaskId, wcsTask.getTaskNo());
        List<TaskDetail> taskDetailList = taskDetailService.list(taskDetailLambda);

        /* 循环查询入库组盘明细*/
        List<ReceiptContainerDetail> receiptContainerDetailList = new ArrayList<>();
        for (TaskDetail taskDetail : taskDetailList) {
            receiptContainerDetailList.add(receiptContainerDetailService.getById(taskDetail.getAllocationId()));
        }
        //去重
        receiptContainerDetailList = receiptContainerDetailList.stream().distinct().collect(Collectors.toList());

        for (ReceiptContainerDetail receiptContainerDetail : receiptContainerDetailList) {
            String locatingRule = this.taskPositioning(receiptContainerDetail);

            LambdaQueryWrapper<FilterConfigDetail> filterConfigDetailLambda = Wrappers.lambdaQuery();
            filterConfigDetailLambda.eq(FilterConfigDetail::getCode, locatingRule)
                    .eq(FilterConfigDetail::getWarehouseCode, ShiroUtils.getWarehouseCode());
            FilterConfigDetail filterConfigDetail = filterConfigDetailService.getOne(filterConfigDetailLambda);
            String[] locatingRules = filterConfigDetail.getStatement().split("limit");

            //根据定位规则查询库位编码
            LambdaQueryWrapper<Location> locationLambda = Wrappers.lambdaQuery();
            locationLambda.last(locatingRules[0]);
            List<Location> locationList = locationService.list(locationLambda);
            List<String> locationCodeList = locationTypeList.stream().map(t-> t.getCode()).collect(Collectors.toList());
            List<Location> newLocation = locationList.stream().filter(t-> locationCodeList.contains(t.getLocationType())).collect(Collectors.toList());
            if (!newLocation.isEmpty()){
                positioningLocationCodeList.add(newLocation.get(0).getCode());
            }

            if (StringUtils.isEmpty(positioningLocationCodeList)){
                throw new ServiceException("没有区域可分配");
            }
        }

        LambdaQueryWrapper<Location> locationLambdaQueryWrapper = Wrappers.lambdaQuery();
        locationLambdaQueryWrapper.eq(Location::getCode, positioningLocationCodeList.get(0));
        Location location = locationService.getOne(locationLambdaQueryWrapper);
        String destinationArea = location.getRoadway();
        return AjaxResult.success(destinationArea);
pengcheng authored
413
    }
mahuandong authored
414
}