Blame view

src/main/java/com/huaheng/api/wcs/service/warecellAllocation/WarecellAllocationServiceImpl.java 19 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;
游杰 authored
6
import com.huaheng.common.constant.QuantityConstant;
mahuandong authored
7
import com.huaheng.common.exception.service.ServiceException;
8
import com.huaheng.common.support.Convert;
pengcheng authored
9
import com.huaheng.common.utils.StringUtils;
mahuandong authored
10
import com.huaheng.common.utils.security.ShiroUtils;
pengcheng authored
11
import com.huaheng.framework.web.domain.AjaxResult;
mahuandong authored
12
13
14
15
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;
游杰 authored
16
17
18
19
import com.huaheng.pc.config.container.domain.Container;
import com.huaheng.pc.config.container.service.ContainerService;
import com.huaheng.pc.config.containerType.domain.ContainerType;
import com.huaheng.pc.config.containerType.service.ContainerTypeService;
mahuandong authored
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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;
39
40
import com.huaheng.pc.task.taskHeader.service.TransferTaskService;
import com.huaheng.pc.task.taskHeader.service.WorkTaskService;
pengcheng authored
41
import org.springframework.stereotype.Service;
mahuandong authored
42
43
import org.springframework.transaction.annotation.Transactional;
import com.huaheng.api.wcs.domain.WcsTask;
44
mahuandong authored
45
46
47
48
49
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
pengcheng authored
50
51
52
@Service
public class WarecellAllocationServiceImpl implements WarecellAllocationService {
mahuandong authored
53
54
55
56
57
    @Resource
    private LocationTypeService locationTypeService;
    @Resource
    private LocationService locationService;
    @Resource
游杰 authored
58
59
60
61
    private ContainerService containerService;
    @Resource
    private ContainerTypeService containerTypeService;
    @Resource
mahuandong authored
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
    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;
81
82
83
84
    @Resource
    private WorkTaskService workTaskService;
    @Resource
    private TransferTaskService transferTaskService;
游杰 authored
85
86
    @Resource
    private LocationAllocationService locationAllocationService;
87
pengcheng authored
88
    /**
89
     * 立库仓位分配
pengcheng authored
90
91
     * 1、判断非空字段
     * 2、实体转换
mahuandong authored
92
     * 3、查询满足条件的库位类型
93
     *
pengcheng authored
94
95
96
97
     * @param wcsTask
     * @return
     */
    @Override
mahuandong authored
98
99
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult warecellAllocation(WcsTask wcsTask) {
pengcheng authored
100
        //1、判断非空字段
101
        if (StringUtils.isEmpty(wcsTask.getTaskNo())) {
pengcheng authored
102
103
            return AjaxResult.error("任务号为空");
        }
104
        if (StringUtils.isEmpty(wcsTask.getDestination())) {
105
            return AjaxResult.error("目的区域为空");
pengcheng authored
106
        }
107
        if (StringUtils.isNull(wcsTask.getLength())) {
pengcheng authored
108
109
            return AjaxResult.error("长为空");
        }
110
        if (StringUtils.isNull(wcsTask.getWidth())) {
pengcheng authored
111
112
            return AjaxResult.error("宽为空");
        }
113
        if (StringUtils.isNull(wcsTask.getHeight())) {
pengcheng authored
114
115
            return AjaxResult.error("高为空");
        }
116
        if (StringUtils.isNull(wcsTask.getWeight())) {
pengcheng authored
117
118
            return AjaxResult.error("重为空");
        }
游杰 authored
119
        return verticalWarehouseAllocation(wcsTask);
120
    }
pengcheng authored
121
122
    public AjaxResult verticalWarehouseAllocation(WcsTask wcsTask) {
游杰 authored
123
        String warehouseCode = wcsTask.getWarehouseCode();
mahuandong authored
124
125
        //查询满足条件的库位类型
        LambdaQueryWrapper<LocationType> lambdaQueryWrapper = Wrappers.lambdaQuery();
126
        lambdaQueryWrapper.gt(LocationType::getLength, wcsTask.getLength())
mahuandong authored
127
128
                .gt(LocationType::getWidth, wcsTask.getWidth())
                .gt(LocationType::getHeight, wcsTask.getHeight())
游杰 authored
129
                .gt(LocationType::getMaxWeight, wcsTask.getWidth())
游杰 authored
130
                .eq(LocationType::getWarehouseCode, warehouseCode);
mahuandong authored
131
132
133
134
135
136
137
138
        List<LocationType> locationTypeList = locationTypeService.list(lambdaQueryWrapper);

        String locationCode = null;
        //查询任务明细
        LambdaQueryWrapper<TaskDetail> taskDetailLambda = Wrappers.lambdaQuery();
        taskDetailLambda.eq(TaskDetail::getTaskId, wcsTask.getTaskNo());
        List<TaskDetail> taskDetailList = taskDetailService.list(taskDetailLambda);
139
        TaskHeader taskHeader = taskHeaderService.getById(wcsTask.getTaskNo());
140
        if (taskHeader.getStatus() == 100) {
141
142
            return AjaxResult.error("任务已经完成,不能再分库位");
        }
游杰 authored
143
        String containerCode = taskHeader.getContainerCode();
游杰 authored
144
mahuandong authored
145
        /* 循环查询入库组盘明细*/
mahuandong authored
146
147
        List<ReceiptContainerDetail> receiptContainerDetailList = new ArrayList<>();
        for (TaskDetail taskDetail : taskDetailList) {
游杰 authored
148
149
150
151
            ReceiptContainerDetail receiptContainerDetail = receiptContainerDetailService.getById(taskDetail.getAllocationId());
            if (receiptContainerDetail != null) {
                receiptContainerDetailList.add(receiptContainerDetail);
            }
mahuandong authored
152
153
154
155
        }
        //去重
        receiptContainerDetailList = receiptContainerDetailList.stream().distinct().collect(Collectors.toList());
156
        String locatingRule = null;
157
158
        ReceiptContainerHeader receiptContainerHeader = null;
        if (StringUtils.isEmpty(locatingRule)) {
159
160
            //物料类别中定位规则为空时,查询入库首选项
            LambdaQueryWrapper<ConfigValue> configValueLambda = Wrappers.lambdaQuery();
游杰 authored
161
            configValueLambda.eq(ConfigValue::getWarehouseCode, warehouseCode)
162
163
164
165
166
                    .eq(ConfigValue::getModuleType, "receipt")
                    .eq(ConfigValue::getRecordType, "入库首选项");
            ConfigValue configValue = configValueService.getOne(configValueLambda);
            LambdaQueryWrapper<ReceiptPreference> receiptPreferenceLambda = Wrappers.lambdaQuery();
            receiptPreferenceLambda.eq(ReceiptPreference::getCode, configValue.getValue())
游杰 authored
167
                    .eq(ReceiptPreference::getWarehouseCode, warehouseCode);
168
            ReceiptPreference receiptPreference = receiptPreferenceService.getOne(receiptPreferenceLambda);
169
            locatingRule = receiptPreference.getLocationRule();
170
        }
171
游杰 authored
172
173
174
        if (StringUtils.isEmpty(locatingRule)){
            throw new ServiceException("未绑定定位规则");
        }
游杰 authored
175
176
177
178
179
180
181
        Integer materialAreas = 0;
        if(receiptContainerDetailList != null && receiptContainerDetailList.size() > 0) {
            String materialCode = receiptContainerDetailList.get(0).getMaterialCode();
            Material material = materialService.findAllByCode(materialCode, warehouseCode);
            materialAreas = material.getMaterialAreas();
        }
        locationCode = locationAllocationService.allocation(locatingRule, wcsTask.getDestination(), warehouseCode, containerCode, materialAreas);
182
        if (StringUtils.isEmpty(locationCode)) {
游杰 authored
183
            return AjaxResult.error("没有库位可分配");
184
        }
mahuandong authored
185
186
        if (StringUtils.isNotEmpty(locationCode)) {
游杰 authored
187
            locationService.updateStatus(locationCode, QuantityConstant.STATUS_LOCATION_LOCK, warehouseCode);
188
            if (StringUtils.isNotEmpty(taskHeader.getToLocation()) && !locationCode.equals(taskHeader.getToLocation())) {
游杰 authored
189
                locationService.updateStatus(taskHeader.getToLocation(), QuantityConstant.STATUS_LOCATION_EMPTY, warehouseCode);
190
191
192
193
            }
        } else {
            throw new ServiceException("定位失败,请检查定位规则是否正确");
        }
194
        if (receiptContainerDetailList != null && receiptContainerDetailList.size() > 0) {
195
196
            //更新库位编码到组盘头表
            ReceiptContainerDetail receiptContainerDetail = receiptContainerDetailList.get(0);
197
            if (receiptContainerDetail != null) {
198
199
200
201
                receiptContainerHeader = receiptContainerHeaderService.getById(receiptContainerDetail.getReceiptContainerId());
                receiptContainerHeader.setToLocation(locationCode);
                if (!receiptContainerHeaderService.updateById(receiptContainerHeader)) {
                    throw new ServiceException("更新库位失败");
202
203
                }
204
205
206
                //把库位编码赋到该入库组盘头表下的所有明细
                LambdaQueryWrapper<ReceiptContainerDetail> lambda = Wrappers.lambdaQuery();
                lambda.eq(ReceiptContainerDetail::getReceiptContainerId, receiptContainerHeader.getId())
游杰 authored
207
                        .eq(ReceiptContainerDetail::getWarehouseCode, warehouseCode);
208
209
210
211
212
                List<ReceiptContainerDetail> receiptContainerDetails = receiptContainerDetailService.list(lambda);
                for (ReceiptContainerDetail receiptContainerDetail2 : receiptContainerDetails) {
                    receiptContainerDetail2.setLocationCode(locationCode);
                    if (!receiptContainerDetailService.updateById(receiptContainerDetail2)) {
                        throw new ServiceException("更新库位编码到入库组盘明细");
213
214
                    }
                }
mahuandong authored
215
216
            }
        }
217
游杰 authored
218
219
220
221
        for (TaskDetail taskDetail : taskDetailList) {
            taskDetail.setToLocation(locationCode);
            if (!taskDetailService.updateById(taskDetail)) {
                throw new ServiceException("更新任务明细目标库位失败");
222
            }
游杰 authored
223
        }
224
游杰 authored
225
226
227
        //修改任务明细目标库位
        LambdaQueryWrapper<Location> locationLambdaQueryWrapper = Wrappers.lambdaQuery();
        locationLambdaQueryWrapper.eq(Location::getCode, locationCode)
游杰 authored
228
                                    .eq(Location::getWarehouseCode, warehouseCode);
游杰 authored
229
230
231
232
233
234
235
236
237
238
239
240
241
242
        Location location = locationService.getOne(locationLambdaQueryWrapper);
        int rowFlag = location.getRowFlag().intValue();
        Integer preTaskNo = 0;
        //如果是外侧库位,那么就要判断该库位对应的内侧库位是不是有托盘
        if (rowFlag == 1) {
            Location insideLocation = locationService.getInsideNear(location);
            if (StringUtils.isNotEmpty(insideLocation.getContainerCode())) {
                Location destinationLocation = locationService.getEmptyLocation(insideLocation);
                AjaxResult ajaxResult = transferTaskService.createTransferTask(insideLocation.getCode(), destinationLocation.getCode());
                preTaskNo = (Integer) ajaxResult.getData();
                if (ajaxResult.hasErr()) {
                    throw new ServiceException("创建移库任务失败");
                }
                taskHeaderService.sendTaskToWcs(Convert.toIntArray(String.valueOf(preTaskNo)));
243
            }
mahuandong authored
244
245
        }
游杰 authored
246
247
248
249
250
251
252
253
254
        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
255
256
    }
mahuandong authored
257
258
    /**
     * 库位筛选
259
260
     *
     * @param locationList     库位列表
261
     * @param locationTypeList 库位类型列表
262
     * @param roadway          巷道
mahuandong authored
263
264
     * @return
     */
265
266
267
268
    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()) {
269
            return null;
270
        } else {
271
272
273
274
275
            return newLocation.get(0).getCode();
        }
    }

    /**
276
     * 定位规则
277
278
     * @return
     */
279
    @Override
280
281
282
    public String taskPositioning() {
        //物料类别中定位规则为空时,查询入库首选项
        LambdaQueryWrapper<ConfigValue> configValueLambda = Wrappers.lambdaQuery();
游杰 authored
283
        configValueLambda.eq(ConfigValue::getWarehouseCode, ShiroUtils.getWarehouseCode())
284
285
286
287
288
                .eq(ConfigValue::getModuleType, "receipt")
                .eq(ConfigValue::getRecordType, "入库首选项");
        ConfigValue configValue = configValueService.getOne(configValueLambda);
        LambdaQueryWrapper<ReceiptPreference> receiptPreferenceLambda = Wrappers.lambdaQuery();
        receiptPreferenceLambda.eq(ReceiptPreference::getCode, configValue.getValue())
游杰 authored
289
                .eq(ReceiptPreference::getWarehouseCode, ShiroUtils.getWarehouseCode());
290
291
292
        ReceiptPreference receiptPreference = receiptPreferenceService.getOne(receiptPreferenceLambda);
        String locatingRule = receiptPreference.getLocationRule();
293
        //通过定位规则查找自定义sql
294
        if (StringUtils.isEmpty(locatingRule)) {
295
296
            throw new ServiceException("未绑定定位规则");
        }
297
298
299
300
301
        LambdaQueryWrapper<FilterConfigDetail> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(FilterConfigDetail::getCode, locatingRule)
                .eq(FilterConfigDetail::getWarehouseCode,ShiroUtils.getWarehouseCode());
        FilterConfigDetail filterConfigDetail = filterConfigDetailService.getOne(lambdaQueryWrapper);
        return filterConfigDetail.getStatement();
pengcheng authored
302
    }
pengcheng authored
303
304
mahuandong authored
305
    /**
306
     * 去向分配
mahuandong authored
307
     */
pengcheng authored
308
309
310
    @Override
    public AjaxResult destinationAllocation(WcsTask wcsTask) {
mahuandong authored
311
        //1、判断非空字段
312
        if (StringUtils.isEmpty(wcsTask.getTaskNo())) {
mahuandong authored
313
314
            return AjaxResult.error("任务号为空");
        }
315
        if (StringUtils.isNull(wcsTask.getLength())) {
mahuandong authored
316
317
            return AjaxResult.error("长为空");
        }
318
        if (StringUtils.isNull(wcsTask.getWidth())) {
mahuandong authored
319
320
            return AjaxResult.error("宽为空");
        }
321
        if (StringUtils.isNull(wcsTask.getHeight())) {
mahuandong authored
322
323
            return AjaxResult.error("高为空");
        }
324
        if (StringUtils.isNull(wcsTask.getWeight())) {
mahuandong authored
325
326
327
328
329
            return AjaxResult.error("重为空");
        }

        //查询满足条件的库位类型
        LambdaQueryWrapper<LocationType> lambdaQueryWrapper = Wrappers.lambdaQuery();
330
        lambdaQueryWrapper.gt(LocationType::getLength, wcsTask.getLength())
mahuandong authored
331
332
333
334
335
                .gt(LocationType::getWidth, wcsTask.getWidth())
                .gt(LocationType::getHeight, wcsTask.getHeight())
                .gt(LocationType::getMaxWeight, wcsTask.getWidth());
        List<LocationType> locationTypeList = locationTypeService.list(lambdaQueryWrapper);
336
        if (locationTypeList.isEmpty()) {
mahuandong authored
337
338
339
            return AjaxResult.error("没有区域可分配");
        }
        List<String> codeList = new ArrayList<>();
340
        for (LocationType locationType : locationTypeList) {
mahuandong authored
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
            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) {
360
            String locatingRule = this.taskPositioning();
mahuandong authored
361
362
363

            LambdaQueryWrapper<FilterConfigDetail> filterConfigDetailLambda = Wrappers.lambdaQuery();
            filterConfigDetailLambda.eq(FilterConfigDetail::getCode, locatingRule)
游杰 authored
364
                    .eq(FilterConfigDetail::getWarehouseCode, ShiroUtils.getWarehouseCode());
mahuandong authored
365
366
367
368
369
370
371
            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);
372
373
374
            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()) {
mahuandong authored
375
376
377
                positioningLocationCodeList.add(newLocation.get(0).getCode());
            }
378
            if (StringUtils.isEmpty(positioningLocationCodeList)) {
mahuandong authored
379
380
381
382
383
384
385
386
387
                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
388
    }
游杰 authored
389
mahuandong authored
390
}