|
1
2
|
package com.huaheng.api.wcs.service.warecellAllocation;
|
|
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;
|
|
6
|
import com.huaheng.common.constant.QuantityConstant;
|
|
7
|
import com.huaheng.common.exception.service.ServiceException;
|
|
8
|
import com.huaheng.common.support.Convert;
|
|
9
|
import com.huaheng.common.utils.StringUtils;
|
|
10
|
import com.huaheng.common.utils.security.ShiroUtils;
|
|
11
|
import com.huaheng.framework.web.domain.AjaxResult;
|
|
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;
|
|
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;
|
|
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;
|
|
41
|
import org.springframework.stereotype.Service;
|
|
42
43
|
import org.springframework.transaction.annotation.Transactional;
import com.huaheng.api.wcs.domain.WcsTask;
|
|
44
|
|
|
45
46
47
48
49
|
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
|
|
50
51
52
|
@Service
public class WarecellAllocationServiceImpl implements WarecellAllocationService {
|
|
53
54
55
56
57
|
@Resource
private LocationTypeService locationTypeService;
@Resource
private LocationService locationService;
@Resource
|
|
58
59
60
61
|
private ContainerService containerService;
@Resource
private ContainerTypeService containerTypeService;
@Resource
|
|
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;
|
|
85
86
|
@Resource
private LocationAllocationService locationAllocationService;
|
|
87
|
|
|
88
|
/**
|
|
89
|
* 立库仓位分配
|
|
90
91
|
* 1、判断非空字段
* 2、实体转换
|
|
92
|
* 3、查询满足条件的库位类型
|
|
93
|
*
|
|
94
95
96
97
|
* @param wcsTask
* @return
*/
@Override
|
|
98
99
|
@Transactional(rollbackFor = Exception.class)
public AjaxResult warecellAllocation(WcsTask wcsTask) {
|
|
100
|
//1、判断非空字段
|
|
101
|
if (StringUtils.isEmpty(wcsTask.getTaskNo())) {
|
|
102
103
|
return AjaxResult.error("任务号为空");
}
|
|
104
|
if (StringUtils.isEmpty(wcsTask.getDestination())) {
|
|
105
|
return AjaxResult.error("目的区域为空");
|
|
106
|
}
|
|
107
|
if (StringUtils.isNull(wcsTask.getLength())) {
|
|
108
109
|
return AjaxResult.error("长为空");
}
|
|
110
|
if (StringUtils.isNull(wcsTask.getWidth())) {
|
|
111
112
|
return AjaxResult.error("宽为空");
}
|
|
113
|
if (StringUtils.isNull(wcsTask.getHeight())) {
|
|
114
115
|
return AjaxResult.error("高为空");
}
|
|
116
|
if (StringUtils.isNull(wcsTask.getWeight())) {
|
|
117
118
|
return AjaxResult.error("重为空");
}
|
|
119
|
return verticalWarehouseAllocation(wcsTask);
|
|
120
|
}
|
|
121
|
|
|
122
|
public AjaxResult verticalWarehouseAllocation(WcsTask wcsTask) {
|
|
123
|
String warehouseCode = wcsTask.getWarehouseCode();
|
|
124
125
|
//查询满足条件的库位类型
LambdaQueryWrapper<LocationType> lambdaQueryWrapper = Wrappers.lambdaQuery();
|
|
126
|
lambdaQueryWrapper.gt(LocationType::getLength, wcsTask.getLength())
|
|
127
128
|
.gt(LocationType::getWidth, wcsTask.getWidth())
.gt(LocationType::getHeight, wcsTask.getHeight())
|
|
129
|
.gt(LocationType::getMaxWeight, wcsTask.getWidth())
|
|
130
|
.eq(LocationType::getWarehouseCode, warehouseCode);
|
|
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("任务已经完成,不能再分库位");
}
|
|
143
|
String containerCode = taskHeader.getContainerCode();
|
|
144
|
|
|
145
|
/* 循环查询入库组盘明细*/
|
|
146
147
|
List<ReceiptContainerDetail> receiptContainerDetailList = new ArrayList<>();
for (TaskDetail taskDetail : taskDetailList) {
|
|
148
149
150
151
|
ReceiptContainerDetail receiptContainerDetail = receiptContainerDetailService.getById(taskDetail.getAllocationId());
if (receiptContainerDetail != null) {
receiptContainerDetailList.add(receiptContainerDetail);
}
|
|
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();
|
|
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())
|
|
167
|
.eq(ReceiptPreference::getWarehouseCode, warehouseCode);
|
|
168
|
ReceiptPreference receiptPreference = receiptPreferenceService.getOne(receiptPreferenceLambda);
|
|
169
|
locatingRule = receiptPreference.getLocationRule();
|
|
170
|
}
|
|
171
|
|
|
172
173
174
|
if (StringUtils.isEmpty(locatingRule)){
throw new ServiceException("未绑定定位规则");
}
|
|
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)) {
|
|
183
|
return AjaxResult.error("没有库位可分配");
|
|
184
|
}
|
|
185
|
|
|
186
|
if (StringUtils.isNotEmpty(locationCode)) {
|
|
187
|
locationService.updateStatus(locationCode, QuantityConstant.STATUS_LOCATION_LOCK, warehouseCode);
|
|
188
|
if (StringUtils.isNotEmpty(taskHeader.getToLocation()) && !locationCode.equals(taskHeader.getToLocation())) {
|
|
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())
|
|
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
|
}
}
|
|
215
216
|
}
}
|
|
217
|
|
|
218
219
220
221
|
for (TaskDetail taskDetail : taskDetailList) {
taskDetail.setToLocation(locationCode);
if (!taskDetailService.updateById(taskDetail)) {
throw new ServiceException("更新任务明细目标库位失败");
|
|
222
|
}
|
|
223
|
}
|
|
224
|
|
|
225
226
227
|
//修改任务明细目标库位
LambdaQueryWrapper<Location> locationLambdaQueryWrapper = Wrappers.lambdaQuery();
locationLambdaQueryWrapper.eq(Location::getCode, locationCode)
|
|
228
|
.eq(Location::getWarehouseCode, warehouseCode);
|
|
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
|
}
|
|
244
245
|
}
|
|
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);
|
|
255
256
|
}
|
|
257
258
|
/**
* 库位筛选
|
|
259
260
|
*
* @param locationList 库位列表
|
|
261
|
* @param locationTypeList 库位类型列表
|
|
262
|
* @param roadway 巷道
|
|
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();
|
|
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())
|
|
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();
|
|
302
|
}
|
|
303
304
|
|
|
305
|
/**
|
|
306
|
* 去向分配
|
|
307
|
*/
|
|
308
309
310
|
@Override
public AjaxResult destinationAllocation(WcsTask wcsTask) {
|
|
311
|
//1、判断非空字段
|
|
312
|
if (StringUtils.isEmpty(wcsTask.getTaskNo())) {
|
|
313
314
|
return AjaxResult.error("任务号为空");
}
|
|
315
|
if (StringUtils.isNull(wcsTask.getLength())) {
|
|
316
317
|
return AjaxResult.error("长为空");
}
|
|
318
|
if (StringUtils.isNull(wcsTask.getWidth())) {
|
|
319
320
|
return AjaxResult.error("宽为空");
}
|
|
321
|
if (StringUtils.isNull(wcsTask.getHeight())) {
|
|
322
323
|
return AjaxResult.error("高为空");
}
|
|
324
|
if (StringUtils.isNull(wcsTask.getWeight())) {
|
|
325
326
327
328
329
|
return AjaxResult.error("重为空");
}
//查询满足条件的库位类型
LambdaQueryWrapper<LocationType> lambdaQueryWrapper = Wrappers.lambdaQuery();
|
|
330
|
lambdaQueryWrapper.gt(LocationType::getLength, wcsTask.getLength())
|
|
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()) {
|
|
337
338
339
|
return AjaxResult.error("没有区域可分配");
}
List<String> codeList = new ArrayList<>();
|
|
340
|
for (LocationType locationType : locationTypeList) {
|
|
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();
|
|
361
362
363
|
LambdaQueryWrapper<FilterConfigDetail> filterConfigDetailLambda = Wrappers.lambdaQuery();
filterConfigDetailLambda.eq(FilterConfigDetail::getCode, locatingRule)
|
|
364
|
.eq(FilterConfigDetail::getWarehouseCode, ShiroUtils.getWarehouseCode());
|
|
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()) {
|
|
375
376
377
|
positioningLocationCodeList.add(newLocation.get(0).getCode());
}
|
|
378
|
if (StringUtils.isEmpty(positioningLocationCodeList)) {
|
|
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);
|
|
388
|
}
|
|
389
|
|
|
390
|
}
|