From 98d88ac8caf7f0991d741079474c262f1e252927 Mon Sep 17 00:00:00 2001
From: chen.lin <1442464845@qq.com>
Date: 星期五, 06 三月 2026 08:14:54 +0800
Subject: [PATCH] 拣货过程中的出库库存匹配
---
rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/TaskSchedules.java | 56 +
rsf-open-api/src/main/java/com/vincent/rsf/openApi/service/impl/WmsRcsServiceImpl.java | 1
rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/ReportMsgServiceImpl.java | 29
rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/LocManageUtil.java | 20
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/dto/OrderOutItemDto.java | 3
rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/MaterialAutoSchedules.java | 1
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TaskServiceImpl.java | 181 ++++++++
rsf-server/src/main/java/com/vincent/rsf/server/api/entity/dto/QuickPickOrderModuleDto.java | 27 +
rsf-server/src/main/java/com/vincent/rsf/server/common/constant/Constants.java | 5
rsf-admin/src/i18n/zh.js | 1
rsf-admin/src/i18n/en.js | 1
rsf-admin/src/page/ResourceContent.js | 3
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/params/LocToTaskParams.java | 2
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/TaskService.java | 5
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/LocItemServiceImpl.java | 159 ++++++-
rsf-admin/src/page/orders/outStock/OutStockPublic.jsx | 18
rsf-server/src/main/java/com/vincent/rsf/server/api/entity/dto/ContainerWaveItemDto.java | 22 +
rsf-server/src/main/java/com/vincent/rsf/server/api/service/WcsService.java | 2
rsf-server/src/main/java/com/vincent/rsf/server/api/controller/WcsController.java | 64 +++
rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/AutoRunSchedules.java | 66 +-
rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/WcsServiceImpl.java | 96 ++++
rsf-open-api/src/main/java/com/vincent/rsf/openApi/entity/params/LocationAllocateParams.java | 2
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/RcsTestServiceImpl.java | 4
rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/PdaOutStockServiceImpl.java | 371 ++++++++++--------
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/LocItemService.java | 5
25 files changed, 869 insertions(+), 275 deletions(-)
diff --git a/rsf-admin/src/i18n/en.js b/rsf-admin/src/i18n/en.js
index fe7fc7b..11e16ef 100644
--- a/rsf-admin/src/i18n/en.js
+++ b/rsf-admin/src/i18n/en.js
@@ -211,6 +211,7 @@
wave: 'Wave Manage',
basStation: 'BasStation',
basContainer: 'BasContainer',
+ emptyOutbound: 'Empty Pallet Outbound',
waveRule: 'Wave Rules',
checkDiff: 'Check Diff',
transfer: 'Transfer',
diff --git a/rsf-admin/src/i18n/zh.js b/rsf-admin/src/i18n/zh.js
index 25670f2..76d166f 100644
--- a/rsf-admin/src/i18n/zh.js
+++ b/rsf-admin/src/i18n/zh.js
@@ -219,6 +219,7 @@
outBound: '鍑哄簱浣滀笟',
checkOutBound: '鐩樼偣鍑哄簱',
stockTransfer: '搴撲綅杞Щ',
+ emptyOutbound: '绌烘澘鍑哄簱',
waveRule: '娉㈡绛栫暐',
checkOrder: '鐩樼偣鍗�',
checkDiff: '鐩樼偣宸紓鍗�',
diff --git a/rsf-admin/src/page/ResourceContent.js b/rsf-admin/src/page/ResourceContent.js
index 9be9260..969a2e6 100644
--- a/rsf-admin/src/page/ResourceContent.js
+++ b/rsf-admin/src/page/ResourceContent.js
@@ -53,6 +53,7 @@
import outBound from "./work/outBound";
import checkOutBound from "./work/checkOutBound";
import stockTransfer from "./work/stockTransfer";
+import emptyOutbound from "./work/emptyOutbound";
import waveRule from "./waveRule";
import check from "./orders/check";
import checkDiff from "./orders/check/checkDiff";
@@ -170,6 +171,8 @@
return checkOutBound;
case "stockTransfer":
return stockTransfer;
+ case "emptyOutbound":
+ return emptyOutbound;
case "waveRule":
return waveRule;
case "check":
diff --git a/rsf-admin/src/page/orders/outStock/OutStockPublic.jsx b/rsf-admin/src/page/orders/outStock/OutStockPublic.jsx
index 1b4061d..ea6c111 100644
--- a/rsf-admin/src/page/orders/outStock/OutStockPublic.jsx
+++ b/rsf-admin/src/page/orders/outStock/OutStockPublic.jsx
@@ -238,7 +238,8 @@
siteNo: defaultSiteNo,
staNos: item.staNos || [],
sourceId: item.sourceId,
- source: item.source
+ source: item.source,
+ pickingStatus: item.pickingStatus || null
};
}
// 濡傛灉鏁版嵁宸茬粡鏄墎骞崇粨鏋勶紝鐩存帴杩斿洖
@@ -399,9 +400,9 @@
{ field: 'unit', headerName: '鍗曚綅', width: 60 },
{ field: 'outQty', headerName: '鍑哄簱鏁伴噺', width: 110, valueFormatter: (v) => formatQuantity(v) },
{
- field: 'anfme', headerName: '搴撳瓨鏁伴噺', width: 110,
+ field: 'anfme', headerName: '搴撳瓨鏁伴噺', width: 160,
renderCell: (params) => (
- <OutStockAnfme value={params.value} />
+ <OutStockAnfme value={params.value} row={params.row} />
)
},
{
@@ -447,9 +448,18 @@
}
const OutStockAnfme = React.memo(function OutStockAnfme(props) {
- const { value } = props;
+ const { value, row } = props;
+ const pickingStatus = row?.pickingStatus;
const num = Number(value);
const hasStock = typeof num === 'number' && !Number.isNaN(num) && num > 1e-6;
+ if (pickingStatus) {
+ return (
+ <Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-start', justifyContent: 'center' }}>
+ <span style={{ color: '#1976d2' }}>{pickingStatus}</span>
+ {!hasStock && <span style={{ color: 'red', fontSize: '0.85em' }}>{translate('common.edit.title.insuffInventory')}</span>}
+ </Box>
+ );
+ }
return (
hasStock ? (
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
diff --git a/rsf-open-api/src/main/java/com/vincent/rsf/openApi/entity/params/LocationAllocateParams.java b/rsf-open-api/src/main/java/com/vincent/rsf/openApi/entity/params/LocationAllocateParams.java
index 1e7dd08..c5c2bf3 100644
--- a/rsf-open-api/src/main/java/com/vincent/rsf/openApi/entity/params/LocationAllocateParams.java
+++ b/rsf-open-api/src/main/java/com/vincent/rsf/openApi/entity/params/LocationAllocateParams.java
@@ -19,6 +19,8 @@
@ApiModelProperty(value = "鍏ュ簱绔欑偣", required = true)
private String staNo;
+ @ApiModelProperty(value = "鏄惁绌烘澘锛歵rue=绌烘澘鍏ュ簱锛岀┖/false=鏅�氬叆搴擄紙闇�缁勬墭锛�")
+ private Boolean full;
@ApiModelProperty(value = "鍏ュ簱绫诲瀷", required = true)
private Integer type;
diff --git a/rsf-open-api/src/main/java/com/vincent/rsf/openApi/service/impl/WmsRcsServiceImpl.java b/rsf-open-api/src/main/java/com/vincent/rsf/openApi/service/impl/WmsRcsServiceImpl.java
index 1a0bb6e..5154b7d 100644
--- a/rsf-open-api/src/main/java/com/vincent/rsf/openApi/service/impl/WmsRcsServiceImpl.java
+++ b/rsf-open-api/src/main/java/com/vincent/rsf/openApi/service/impl/WmsRcsServiceImpl.java
@@ -437,6 +437,7 @@
requestParams.put("barcode", params.getBarcode());
requestParams.put("staNo", params.getStaNo());
requestParams.put("type", params.getType());
+ requestParams.put("full", params.getFull());
log.info("璇锋眰鍙傛暟锛歿}", requestParams.toJSONString());
HttpHeaders headers = new HttpHeaders();
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/api/controller/WcsController.java b/rsf-server/src/main/java/com/vincent/rsf/server/api/controller/WcsController.java
index f8be5e6..68408c0 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/api/controller/WcsController.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/api/controller/WcsController.java
@@ -7,12 +7,22 @@
import com.vincent.rsf.server.api.entity.params.ExMsgParams;
import com.vincent.rsf.server.api.entity.params.WcsTaskParams;
import com.vincent.rsf.server.common.annotation.OperationLog;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.vincent.rsf.server.common.domain.BaseParam;
+import com.vincent.rsf.server.common.domain.PageParam;
+import com.vincent.rsf.server.manager.controller.params.LocToTaskParams;
+import com.vincent.rsf.server.manager.entity.Loc;
+import com.vincent.rsf.server.manager.enums.LocStsType;
import com.vincent.rsf.server.manager.enums.TaskType;
+import com.vincent.rsf.server.manager.service.LocItemService;
+import com.vincent.rsf.server.manager.service.LocService;
import com.vincent.rsf.server.api.service.WcsService;
+import com.vincent.rsf.server.common.constant.Constants;
import com.vincent.rsf.server.system.controller.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -27,7 +37,23 @@
@Autowired
private WcsService wcsService;
+ @Autowired
+ private LocItemService locItemService;
+ @Autowired
+ private LocService locService;
+
+ @ApiOperation("绌烘澘搴撲綅鍒楄〃锛堝垎椤碉級锛屼粎杩斿洖 useStatus=D 鐨勫簱浣嶏紝鐢ㄤ簬绌烘澘鍑哄簱椤靛嬀閫�")
+ @PreAuthorize("hasAuthority('manager:emptyOutbound:list')")
+ @PostMapping("/empty/locs/page")
+ public R emptyLocsPage(@RequestBody Map<String, Object> map) {
+ BaseParam baseParam = buildParam(map, BaseParam.class);
+ PageParam<Loc, BaseParam> pageParam = new PageParam<>(baseParam, Loc.class);
+ LambdaQueryWrapper<Loc> qw = new LambdaQueryWrapper<Loc>()
+ .eq(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_D.type)
+ .orderByAsc(Loc::getId);
+ return R.ok().add(locService.page(pageParam, qw));
+ }
@ApiOperation(value = "wcs鐢熸垚鍏ュ簱浠诲姟鎺ュ彛")
@PostMapping("/create/in/task")
@@ -138,7 +164,14 @@
String barcode = (String) params.get("barcode");
String staNo = (String) params.get("staNo");
Integer type = params.get("type") != null ? Integer.valueOf(params.get("type").toString()) : null;
-
+ Boolean full = null;
+ if (params.get("full") != null) {
+ if (params.get("full") instanceof Boolean) {
+ full = (Boolean) params.get("full");
+ } else {
+ full = Boolean.parseBoolean(params.get("full").toString());
+ }
+ }
if (Cools.isEmpty(barcode)) {
return R.error("鏂欑鐮佷笉鑳戒负绌猴紒锛�");
}
@@ -148,8 +181,33 @@
if (type == null) {
return R.error("鍏ュ簱绫诲瀷涓嶈兘涓虹┖锛侊紒");
}
-
- return wcsService.allocateLocation(barcode, staNo, type);
+ return wcsService.allocateLocation(barcode, staNo, type, full);
+ }
+
+ @ApiOperation("绌烘澘鍑哄簱锛氫粠鎸囧畾绌烘澘搴撲綅鐢熸垚鍑哄簱浠诲姟鑷崇洰鏍囩珯鐐�")
+ @PreAuthorize("hasAuthority('manager:emptyOutbound:list')")
+ @PostMapping("/empty/outbound")
+ public R emptyOutbound(@RequestBody Map<String, Object> params) {
+ if (Cools.isEmpty(params)) {
+ return R.error("鍙傛暟涓嶈兘涓虹┖锛侊紒");
+ }
+ String staNo = (String) params.get("staNo");
+ String orgLoc = (String) params.get("orgLoc");
+ if (Cools.isEmpty(staNo)) {
+ return R.error("鐩爣绔欑偣 staNo 涓嶈兘涓虹┖锛侊紒");
+ }
+ if (Cools.isEmpty(orgLoc)) {
+ return R.error("婧愬簱浣� orgLoc 涓嶈兘涓虹┖锛侊紒");
+ }
+ LocToTaskParams map = new LocToTaskParams();
+ map.setSiteNo(staNo);
+ map.setOrgLoc(orgLoc);
+ map.setType(Constants.TASK_TYPE_OUT_STOCK_EMPTY);
+ Long userId = getLoginUserId();
+ if (userId == null) {
+ userId = 1L;
+ }
+ return R.ok("绌烘澘鍑哄簱浠诲姟鍒涘缓鎴愬姛").add(locItemService.generateTaskEmpty(map, userId));
}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/api/entity/dto/ContainerWaveItemDto.java b/rsf-server/src/main/java/com/vincent/rsf/server/api/entity/dto/ContainerWaveItemDto.java
new file mode 100644
index 0000000..09b9fce
--- /dev/null
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/api/entity/dto/ContainerWaveItemDto.java
@@ -0,0 +1,22 @@
+package com.vincent.rsf.server.api.entity.dto;
+
+import com.vincent.rsf.server.manager.entity.WkOrderItem;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+/**
+ * PDA 娉㈡鎷h揣鍒楄〃椤癸細鏀寔鍗曞彿鍖哄垎涓庡彲杩藉姞鏍囪瘑
+ */
+@Data
+@Accessors(chain = true)
+@ApiModel(value = "ContainerWaveItemDto", description = "娉㈡鎷h揣鏄庣粏锛堝惈鍗曞彿銆佸彲杩藉姞锛�")
+public class ContainerWaveItemDto {
+
+ @ApiModelProperty("鍑哄簱鍗曟槑缁嗭紙鍚崟鍙风瓑锛�")
+ private WkOrderItem orderItem;
+
+ @ApiModelProperty("鏄惁鍙拷鍔犺鍗曪紙鍚庣画鍒嗛厤鐨勫悓鐗╂枡璁㈠崟锛屾湭鎷h揣纭锛�")
+ private Boolean appendable;
+}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/api/entity/dto/QuickPickOrderModuleDto.java b/rsf-server/src/main/java/com/vincent/rsf/server/api/entity/dto/QuickPickOrderModuleDto.java
new file mode 100644
index 0000000..d90faff
--- /dev/null
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/api/entity/dto/QuickPickOrderModuleDto.java
@@ -0,0 +1,27 @@
+package com.vincent.rsf.server.api.entity.dto;
+
+import com.vincent.rsf.server.manager.entity.TaskItem;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.List;
+
+/**
+ * 蹇�熸嫞璐ф寜鍑哄簱鍗曞垎妯″潡锛氫竴涓嚭搴撳崟瀵瑰簲涓�涓ā鍧楋紝灞曠ず璇ュ崟鐨勬嫞璐ф暟閲�
+ */
+@Data
+@Accessors(chain = true)
+@ApiModel(value = "QuickPickOrderModuleDto", description = "蹇�熸嫞璐�-鎸夎鍗曟ā鍧�")
+public class QuickPickOrderModuleDto {
+
+ @ApiModelProperty("鍑哄簱鍗旾D")
+ private Long orderId;
+
+ @ApiModelProperty("鍑哄簱鍗曞彿")
+ private String orderCode;
+
+ @ApiModelProperty("璇ヨ鍗曚笅鐨勬嫞璐ф槑缁�")
+ private List<TaskItem> items;
+}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/api/service/WcsService.java b/rsf-server/src/main/java/com/vincent/rsf/server/api/service/WcsService.java
index 74f0d72..707562d 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/api/service/WcsService.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/api/service/WcsService.java
@@ -19,5 +19,5 @@
R pubWcsTask(WcsTaskParams params);
- R allocateLocation(String barcode, String staNo, Integer type);
+ R allocateLocation(String barcode, String staNo, Integer type, Boolean full);
}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/PdaOutStockServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/PdaOutStockServiceImpl.java
index 8de29f8..fb2e32f 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/PdaOutStockServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/PdaOutStockServiceImpl.java
@@ -5,6 +5,8 @@
import com.vincent.rsf.framework.common.R;
import com.vincent.rsf.framework.exception.CoolException;
import com.vincent.rsf.server.api.entity.dto.ContainerWaveDto;
+import com.vincent.rsf.server.api.entity.dto.ContainerWaveItemDto;
+import com.vincent.rsf.server.api.entity.dto.QuickPickOrderModuleDto;
import com.vincent.rsf.server.api.entity.params.ContainerWaveParam;
import com.vincent.rsf.server.api.entity.params.WavePickItemsParams;
import com.vincent.rsf.server.api.service.PdaOutStockService;
@@ -76,70 +78,132 @@
@Autowired
private ConfigServiceImpl configService;
+ /**
+ * 蹇�熸嫞璐ф煡璇細鍚屼竴绠辩爜鍙兘鏈夊鏉′换鍔★紝浠� RCS 鍑哄簱鍥炶皟鍚庡彉涓� 199 鐨勬墠灞曠ず锛涜绠辩爜涓嬩粛涓嶆槸 199 鐨� PDA 涓嶆樉绀恒��
+ * 杩斿洖锛歰rders 鎸夊嚭搴撳崟鍒嗘ā鍧椼�乴ist/taskItems 璇ョ鐮佷笅 199 浠诲姟鏄庣粏銆�
+ */
@Override
public R getOutStockTaskItem(String barcode) {
- LambdaQueryWrapper<Task> lambdaQueryWrapper = new LambdaQueryWrapper<>();
- lambdaQueryWrapper.eq(Task::getBarcode, barcode)
- .orderByDesc(Task::getId)
- .last("limit 1");
- Task task = taskService.getOne(lambdaQueryWrapper);
- if (null == task) {
- return R.error("鏈煡璇㈠埌鐩稿叧浠诲姟");
+ // 鍙煡 199锛圵AVE_SEED锛�/AWAIT锛氬凡纭鍙樻垚 200 鐨勭粷涓嶈兘鎵嚭鏉ワ紝鏄庣‘鎺掗櫎 200 閬垮厤绗簩娆℃壂鍒�
+ List<Task> tasks = taskService.list(new LambdaQueryWrapper<Task>()
+ .eq(Task::getBarcode, barcode)
+ .in(Task::getTaskStatus, Arrays.asList(TaskStsType.WAVE_SEED.id, TaskStsType.AWAIT.id))
+ .ne(Task::getTaskStatus, TaskStsType.UPDATED_OUT.id)
+ .orderByAsc(Task::getId));
+ if (tasks == null || tasks.isEmpty()) {
+ return R.error("鏈煡璇㈠埌寰呯‘璁や换鍔�");
}
- List<TaskItem> taskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, task.getId()));
- if (null == taskItems || taskItems.size() <= 0) {
+ List<Long> taskIds = tasks.stream().map(Task::getId).collect(Collectors.toList());
+ List<TaskItem> taskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().in(TaskItem::getTaskId, taskIds));
+ if (taskItems == null || taskItems.isEmpty()) {
return R.error("浠诲姟鍑洪敊锛屾湭鏌ヨ鍒扮浉鍏充换鍔℃槑缁�");
}
-
- return R.ok(taskItems);
+ // 鍚屼竴绠辩爜涓嬪彲鑳芥湁澶氭潯锛堝涓嚭搴撳崟锛夛紝鎸夊嚭搴撳崟鍒嗙粍锛涗粎杩斿洖灏氭湭鎷e畬鐨勮鍗曟ā鍧�
+ String nullKey = "__none__";
+ Map<String, List<TaskItem>> byOrder = taskItems.stream()
+ .collect(Collectors.groupingBy(ti -> ti.getOrderId() != null ? "o_" + ti.getOrderId() : (StringUtils.isNotBlank(ti.getSourceCode()) ? "s_" + ti.getSourceCode() : nullKey)));
+ List<QuickPickOrderModuleDto> orders = new ArrayList<>();
+ for (Map.Entry<String, List<TaskItem>> e : byOrder.entrySet()) {
+ List<TaskItem> items = e.getValue();
+ boolean allPicked = items.stream().allMatch(ti -> ti.getQty() != null && ti.getAnfme() != null && ti.getQty().compareTo(ti.getAnfme()) >= 0);
+ if (allPicked) continue;
+ TaskItem first = items.get(0);
+ orders.add(new QuickPickOrderModuleDto()
+ .setOrderId(first.getOrderId())
+ .setOrderCode(StringUtils.isNotBlank(first.getSourceCode()) ? first.getSourceCode() : ("鍗曞彿:" + (first.getOrderId() != null ? first.getOrderId() : "鈥�")))
+ .setItems(items));
+ }
+ R r = orders.isEmpty() ? R.ok("鍏ㄩ儴鎷h揣宸插畬鎴�") : R.ok();
+ r.put("orders", orders);
+ r.put("taskItems", taskItems);
+ r.put("list", taskItems); // 鍚屼竴绠辩爜涓嬪鏉℃槑缁嗭紝渚夸簬鐩存帴灞曠ず
+ return r;
}
@Override
@Transactional(rollbackFor = Exception.class)
@Synchronized
public R saveOutTaskSts(String barcode) {
- LambdaQueryWrapper<Task> lambdaQueryWrapper = new LambdaQueryWrapper<>();
- lambdaQueryWrapper.eq(Task::getBarcode, barcode)
- .orderByDesc(Task::getId)
- .last("limit 1");
- Task task = taskService.getOne(lambdaQueryWrapper);
- if (null == task) {
- throw new CoolException("鏈壘鍒版枡绠辩爜瀵瑰簲浠诲姟");
+ // 鍙粺璁″綋鍓嶃�屽緟纭銆嶄换鍔★細鍑哄簱鍗曟湁3鍗曚絾鍙笅鍙戜簡2涓换鍔℃椂锛�2涓换鍔¢兘鎷e畬鍗冲彲纭骞剁敓鎴愭嫞鏂欏叆搴擄紱鏈変换鍔¤鍙栨秷鍒欏彧澶勭悊鍓╀綑浠诲姟
+ List<Task> tasks = taskService.list(new LambdaQueryWrapper<Task>()
+ .eq(Task::getBarcode, barcode)
+ .in(Task::getTaskStatus, Arrays.asList(TaskStsType.WAVE_SEED.id, TaskStsType.AWAIT.id))
+ .orderByAsc(Task::getId));
+ if (tasks == null || tasks.isEmpty()) {
+ throw new CoolException("鏈壘鍒版枡绠辩爜瀵瑰簲浠诲姟鎴栦换鍔$姸鎬佷笉鏄瓑寰呯‘璁�");
}
- // 鍏佽 199锛圵AVE_SEED 鎾涓�/寰呯‘璁わ級鎴� 196锛圓WAIT 绛夊緟纭锛夛紝涓庣洏鐐� PDA 閫昏緫涓�鑷�
- if (!task.getTaskStatus().equals(TaskStsType.WAVE_SEED.id)
- && !task.getTaskStatus().equals(TaskStsType.AWAIT.id)) {
- return R.error("浠诲姟鐘舵�佷笉鏄瓑寰呯‘璁�");
- }
-
Long loginUserId = SystemAuthUtils.getLoginUserId();
if (loginUserId == null) {
- loginUserId = 1L; // 浣跨敤榛樿鍊�
+ loginUserId = 1L;
}
-
try {
- if (task.getTaskType().equals(TaskType.TASK_TYPE_PICK_AGAIN_OUT.type)) {
- // 鎷f枡鍑哄簱锛氬垱寤烘嫞鏂欏叆搴撲换鍔★紙褰㈡垚闂幆锛�
- taskService.pickOrCheckTask(task.getId(), "");
- return R.ok("纭鎴愬姛锛屽凡鍒涘缓鎷f枡鍏ュ簱浠诲姟");
- } else if (task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_OUT.type)) {
- // 鐩樼偣鍑哄簱锛氬垱寤虹洏鐐瑰叆搴撲换鍔★紙褰㈡垚闂幆锛�
- taskService.pickOrCheckTask(task.getId(), Constants.TASK_TYPE_OUT_CHECK);
+ Task first = tasks.get(0);
+ if (first.getTaskType().equals(TaskType.TASK_TYPE_PICK_AGAIN_OUT.type)) {
+ // 纭鍓嶈绠辩爜涓嬪凡鏈� 200 鐨勶紙渚嬪绗竴娆″凡纭鐨勶級锛氭湰娆″彧鎶婂綋鍓� 199 缃负 200锛屼笉鐢熸垚鎷f枡鍏ュ簱锛岄伩鍏嶁�滅浜屾璇‘璁も�濆鑷撮敊璇墸鍑忓拰鐢熸垚鍏ュ簱
+ long already200 = taskService.count(new LambdaQueryWrapper<Task>()
+ .eq(Task::getBarcode, barcode)
+ .eq(Task::getTaskType, TaskType.TASK_TYPE_PICK_AGAIN_OUT.type)
+ .eq(Task::getTaskStatus, TaskStsType.UPDATED_OUT.id));
+ // 纭鍗冲凡纭锛氬綋鍓� 199 浠诲姟鍏ㄩ儴缃负 200锛屽苟鍥炲啓宸叉嫞鏁伴噺(qty)锛涗粎褰撴湰娆$‘璁ゅ墠娌℃湁浠讳綍 200 涓旂‘璁ゅ悗鍏ㄩ儴 200 鏃舵墠缁熶竴鎵e噺骞剁敓鎴愭嫞鏂欏叆搴�
+ for (Task task : tasks) {
+ task.setTaskStatus(TaskStsType.UPDATED_OUT.id)
+ .setUpdateBy(loginUserId)
+ .setUpdateTime(new Date());
+ if (!taskService.updateById(task)) {
+ return R.error("鏇存柊浠诲姟鐘舵�佸け璐�");
+ }
+ List<TaskItem> items = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, task.getId()));
+ for (TaskItem ti : items) {
+ if (ti.getQty() == null || ti.getQty().compareTo(0.0) <= 0) {
+ ti.setQty(ti.getAnfme() != null ? ti.getAnfme() : 0.0);
+ ti.setUpdateBy(loginUserId);
+ ti.setUpdateTime(new Date());
+ taskItemService.updateById(ti);
+ }
+ }
+ }
+ long not200 = taskService.count(new LambdaQueryWrapper<Task>()
+ .eq(Task::getBarcode, barcode)
+ .ne(Task::getTaskStatus, TaskStsType.UPDATED_OUT.id));
+ if (not200 > 0) {
+ return R.ok("纭鎴愬姛");
+ }
+ // 鏈纭鍓嶈绠辩爜涓嬪凡鏈� 200 鐨勶紝涓嶅湪姝ゅ鐢熸垚鎷f枡鍏ュ簱锛岀敱瀹氭椂浠诲姟鍦ㄢ�滃叏閮� 200鈥濇椂缁熶竴澶勭悊
+ if (already200 > 0) {
+ return R.ok("纭鎴愬姛锛涘悓绠卞凡鏈夎繃纭浠诲姟锛屾墸鍑忎笌鎷f枡鍏ュ簱鐢辩郴缁熷湪鍏ㄩ儴200鍚庣粺涓�澶勭悊");
+ }
+ // 鏈纭鍓嶆病鏈変换浣� 200锛屼笖纭鍚庡悓绠辩爜宸插叏閮� 200锛氱粺涓�鎵e噺銆佹湁浣欓噺鎵嶇敓鎴愭嫞鏂欏叆搴撳崟
+ List<Task> all200 = taskService.list(new LambdaQueryWrapper<Task>()
+ .eq(Task::getBarcode, barcode)
+ .eq(Task::getTaskType, TaskType.TASK_TYPE_PICK_AGAIN_OUT.type)
+ .eq(Task::getTaskStatus, TaskStsType.UPDATED_OUT.id)
+ .orderByAsc(Task::getId));
+ for (Task task : all200) {
+ taskService.pickOrCheckTask(task.getId(), "");
+ }
+ return R.ok("纭鎴愬姛锛屽凡缁熶竴鎵e噺骞剁敓鎴愭嫞鏂欏叆搴撲换鍔★紙鏈変綑閲忔椂锛�");
+ }
+ if (first.getTaskType().equals(TaskType.TASK_TYPE_CHECK_OUT.type)) {
+ for (Task task : tasks) {
+ taskService.pickOrCheckTask(task.getId(), Constants.TASK_TYPE_OUT_CHECK);
+ }
return R.ok("纭鎴愬姛锛屽凡鍒涘缓鐩樼偣鍏ュ簱浠诲姟");
- } else if (task.getTaskType().equals(TaskType.TASK_TYPE_OUT.type)) {
- // 鍏ㄧ増鍑哄簱锛氭洿鏂颁负200锛堟渶缁堝畬鎴愶紝涓嶉棴鐜級
- taskService.completeFullOutStock(task.getId(), loginUserId);
+ }
+ if (first.getTaskType().equals(TaskType.TASK_TYPE_OUT.type)) {
+ for (Task task : tasks) {
+ taskService.completeFullOutStock(task.getId(), loginUserId);
+ }
return R.ok("纭鎴愬姛锛屽叏鐗堝嚭搴撳凡瀹屾垚");
- } else {
- // 鍏朵粬鍑哄簱绫诲瀷锛氱洿鎺ユ洿鏂颁负200
+ }
+ for (Task task : tasks) {
task.setTaskStatus(TaskStsType.UPDATED_OUT.id)
.setUpdateBy(loginUserId)
.setUpdateTime(new Date());
if (!taskService.updateById(task)) {
return R.error("鏇存柊浠诲姟鐘舵�佸け璐�");
}
- return R.ok("纭鎴愬姛");
}
+ return R.ok("纭鎴愬姛");
} catch (Exception e) {
throw new CoolException("蹇�熸嫞璐х‘璁ゅけ璐ワ細" + e.getMessage());
}
@@ -168,24 +232,47 @@
if (!task.getTaskStatus().equals(TaskStsType.WAVE_SEED.id)) {
return R.error("浠诲姟鐘舵�佷笉鏄弨鏂欑媭鎱�");
}
- List<TaskItem> taskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, task.getId()));
- Set<Long> longSet = taskItems.stream().map(TaskItem::getSourceId).collect(Collectors.toSet());
- List<WaveOrderRela> waveOrderRelas = waveOrderRelaService.list(new LambdaQueryWrapper<WaveOrderRela>()
- .in(WaveOrderRela::getWaveId, longSet));
- if (Cools.isEmpty(waveOrderRelas)) {
+ // 褰撳墠鏂欑瀵瑰簲搴撲綅涓嬫墍鏈夊浜庛�岄绾﹀嚭搴�/鎷h揣涓�嶇殑浠诲姟锛堝惈鍙拷鍔犵殑鍚庣画璁㈠崟锛�
+ String orgLoc = task.getOrgLoc();
+ List<Integer> pickingStatuses = Arrays.asList(TaskStsType.GENERATE_OUT.id, TaskStsType.WAVE_SEED.id);
+ List<Task> sameLocTasks = taskService.list(new LambdaQueryWrapper<Task>()
+ .eq(Task::getOrgLoc, orgLoc)
+ .in(Task::getTaskStatus, pickingStatuses));
+ Set<Long> waveIds = new java.util.HashSet<>();
+ Set<String> matnrCodes = new java.util.HashSet<>();
+ for (Task t : sameLocTasks) {
+ List<TaskItem> items = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, t.getId()));
+ for (TaskItem ti : items) {
+ if (ti.getSourceId() != null) waveIds.add(ti.getSourceId());
+ if (StringUtils.isNotBlank(ti.getMatnrCode())) matnrCodes.add(ti.getMatnrCode());
+ }
+ }
+ if (waveIds.isEmpty()) {
throw new CoolException("娉㈡瀵瑰簲鍏宠仈鍗曟湭鎵惧埌");
}
+ List<WaveOrderRela> waveOrderRelas = waveOrderRelaService.list(new LambdaQueryWrapper<WaveOrderRela>()
+ .in(WaveOrderRela::getWaveId, waveIds));
Set<Long> orderIds = waveOrderRelas.stream().map(WaveOrderRela::getOrderId).collect(Collectors.toSet());
List<WkOrder> wkOrders = asnOrderService.listByIds(orderIds);
if (wkOrders.isEmpty()) {
throw new CoolException("鍗曟嵁涓嶅瓨鍦紒锛�");
}
- Set<String> codes = taskItems.stream().map(TaskItem::getMatnrCode).collect(Collectors.toSet());
+ // 鎸夎鍗曞垱寤烘椂闂存帓搴忥紝鍏堝垱寤虹殑涓轰富璁㈠崟锛屽悗缁负鍙拷鍔�
+ wkOrders.sort(Comparator.comparing(WkOrder::getCreateTime, Comparator.nullsLast(Comparator.naturalOrder())));
+ Set<String> codes = matnrCodes.isEmpty() ? taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, task.getId()))
+ .stream().map(TaskItem::getMatnrCode).filter(StringUtils::isNotBlank).collect(Collectors.toSet()) : matnrCodes;
List<WkOrderItem> orderItems = asnOrderItemService.list(new LambdaQueryWrapper<WkOrderItem>()
.in(WkOrderItem::getMatnrCode, codes)
.in(WkOrderItem::getOrderId, orderIds));
-
- return R.ok("鏌ヨ鎴愬姛").add(orderItems);
+ List<ContainerWaveItemDto> result = new ArrayList<>();
+ Long firstOrderId = wkOrders.isEmpty() ? null : wkOrders.get(0).getId();
+ for (WkOrderItem item : orderItems) {
+ boolean appendable = firstOrderId != null && !firstOrderId.equals(item.getOrderId());
+ result.add(new ContainerWaveItemDto().setOrderItem(item).setAppendable(appendable));
+ }
+ R r = R.ok("鏌ヨ鎴愬姛");
+ r.put("list", result);
+ return r;
// ArrayList<ContainerWaveDto> containerWaveDtos = new ArrayList<>();
//// List<TaskItem> taskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, task.getId()));
@@ -320,109 +407,52 @@
}
List<TaskItem> taskItems = params.getTaskItems();
Map<String, List<TaskItem>> listMap = taskItems.stream().collect(Collectors.groupingBy(TaskItem::getMatnrCode));
+ // 鎷h揣瀹屾垚浠呮墸鍑忓簱浣嶆暟閲忓苟绱姞 TaskItem.qty锛屼笉鏇存柊鍑哄簱鍗�/璁㈠崟锛涘緟鎵樼洏鍏ㄩ儴鎷e畬鍦� saveWavePick 鍐嶆寜椤哄簭鏇存柊搴撳瓨骞舵牎楠�
+ Config config = configService.getOne(new LambdaQueryWrapper<Config>().eq(Config::getFlag, GlobalConfigCode.ALLOW_OVER_CHANGE));
listMap.keySet().forEach(code -> {
List<TaskItem> items = listMap.get(code);
- //涓�寮犲嚭搴撳崟锛岀浉鍚岀殑鍝佺涓嶄細鍑虹幇涓ゆ
WkOrderItem orderItem = asnOrderItemService.getOne(new LambdaQueryWrapper<WkOrderItem>()
.eq(WkOrderItem::getMatnrCode, code)
.eq(WkOrderItem::getOrderId, order.getId()));
if (Objects.isNull(orderItem)) {
throw new CoolException("鏁版嵁閿欒锛屾嫞鏂欎笉鍦ㄥ崟鎹渶姹備腑锛侊紒");
}
- //taskItems涓烘嫞璐ф槑缁嗭紝浣滃弬鏁颁笂鎶�
- Double summed = items.stream().mapToDouble(TaskItem::getAnfme).sum();
- //鍔犱笂鍘嗗彶鎷f枡鏁伴噺
- Double pickQty = Math.round((orderItem.getQty() + summed) * 1000000) / 1000000.0;
- Config config = configService.getOne(new LambdaQueryWrapper<Config>().eq(Config::getFlag, GlobalConfigCode.ALLOW_OVER_CHANGE));
- //鍒ゆ柇鏄惁鍏佽瓒呮敹锛屼笉鍏佽瓒呮敹娣诲姞鎷掓敹鍒ゆ柇
- if (!Objects.isNull(config)) {
- if (!Boolean.parseBoolean(config.getVal())) {
- if (pickQty.compareTo(orderItem.getAnfme()) > 0.0) {
- throw new CoolException("鎾鏁伴噺涓嶈兘瓒呭嚭璁㈠崟闇�姹傛暟閲�");
- }
+ Double summed = items.stream().mapToDouble(ti -> ti.getAnfme() != null ? ti.getAnfme() : 0.0).sum();
+ Double pickQty = Math.round((orderItem.getQty() != null ? orderItem.getQty() : 0.0) + summed) * 1000000.0 / 1000000.0;
+ if (!Objects.isNull(config) && !Boolean.parseBoolean(config.getVal())) {
+ if (pickQty.compareTo(orderItem.getAnfme()) > 0.0) {
+ throw new CoolException("鎾鏁伴噺涓嶈兘瓒呭嚭璁㈠崟闇�姹傛暟閲�");
}
}
- orderItem.setQty(pickQty);
-
- if (!asnOrderItemService.updateById(orderItem)) {
- throw new CoolException("鍑哄簱鍗曟槑缁嗘洿鏂板け璐ワ紒锛�");
- }
-
- Stock stock = new Stock();
- String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_STOCK_CODE, null);
- if (StringUtils.isBlank(ruleCode)) {
- throw new CoolException("褰撳墠涓氬姟锛�" + SerialRuleCode.SYS_STOCK_CODE + "锛岀紪鐮佽鍒欎笉瀛樺湪锛侊紒");
- }
- Double sum = taskItems.stream().mapToDouble(TaskItem::getAnfme).sum();
- stock.setCode(ruleCode)
- .setUpdateBy(SystemAuthUtils.getLoginUserId())
- .setBarcode(task.getBarcode())
- .setLocCode(task.getOrgLoc())
- .setType(order.getType())
- .setWkType(Short.parseShort(order.getWkType()))
- .setSourceId(orderItem.getOrderId())
- .setSourceCode(orderItem.getOrderCode())
- .setUpdateTime(new Date())
- .setAnfme(sum);
-
- if (!stockService.save(stock)) {
- throw new CoolException("鍑哄叆搴撳巻鍙蹭繚瀛樺け璐ワ紒锛�");
- }
-
- List<StockItem> stockItems = new ArrayList<>();
items.forEach(taskItem -> {
TaskItem item = taskItemService.getById(taskItem.getId());
- //鍒ゆ柇鏄惁鍏佽瓒呮敹锛屼笉鍏佽瓒呮敹娣诲姞鎷掓敹鍒ゆ柇
- if (!Objects.isNull(config)) {
- TaskItem serviceOne = taskItemService.getOne(new LambdaQueryWrapper<TaskItem>()
- .eq(TaskItem::getTaskId, task.getId())
- .eq(TaskItem::getFieldsIndex, item.getFieldsIndex()));
- if (Objects.isNull(serviceOne)) {
- throw new CoolException("缂撳瓨鏁版嵁涓㈠け锛侊紒");
- }
- LocItemWorking workItem = locItemWorkingService.getOne(new LambdaQueryWrapper<LocItemWorking>()
- .eq(LocItemWorking::getTaskId, task.getId())
- .eq(LocItemWorking::getFieldsIndex, item.getFieldsIndex()));
- if (Objects.isNull(workItem)) {
- throw new CoolException("缂撳瓨鏁版嵁涓㈠け锛侊紒");
- }
- Double v1 = Math.round((workItem.getAnfme() - serviceOne.getQty()) * 1000000) / 1000000.0;
- //涓嶇鏄惁鍏佽瓒呮敹锛岄兘闇�鍒ゆ柇鏄惁瓒呭嚭搴撳瓨鑼冨洿锛堢エ鍙锋殏涓嶄娇鐢紝璇ュ垽鏂敞閲婏級
- // if (taskItem.getAnfme().compareTo(v1) > 0) {
- // throw new CoolException("鎷h揣鏁伴噺瓒呭嚭褰撳墠绁ㄥ彿搴撳瓨鏁伴噺锛侊紒");
- // }
- if (!Boolean.parseBoolean(config.getVal())) {
- Double v = Math.round((item.getQty() + taskItem.getAnfme()) * 1000000) / 1000000.0;
- if (item.getAnfme().compareTo(v) < 0.0) {
- throw new CoolException("鍓嶅綋鐗╂枡宸茶秴鍑哄彲鎷h寖鍥达紝璇锋牳瀵瑰悗鍐嶆搷浣滐紒锛�");
- }
+ if (Objects.isNull(item)) {
+ throw new CoolException("浠诲姟鏄庣粏涓嶅瓨鍦紒锛�");
+ }
+ if (!Objects.isNull(config) && !Boolean.parseBoolean(config.getVal())) {
+ Double v = Math.round(((item.getQty() != null ? item.getQty() : 0.0) + (taskItem.getAnfme() != null ? taskItem.getAnfme() : 0.0)) * 1000000.0) / 1000000.0;
+ if (item.getAnfme() != null && item.getAnfme().compareTo(v) < 0.0) {
+ throw new CoolException("褰撳墠鐗╂枡宸茶秴鍑哄彲鎷h寖鍥达紝璇锋牳瀵瑰悗鍐嶆搷浣滐紒锛�");
}
}
-
- Double picQty = Math.round((item.getQty() + taskItem.getAnfme()) * 1000000) / 1000000.0;
+ Double picQty = Math.round(((item.getQty() != null ? item.getQty() : 0.0) + (taskItem.getAnfme() != null ? taskItem.getAnfme() : 0.0)) * 1000000.0) / 1000000.0;
item.setQty(picQty).setOrderId(order.getId()).setOrderItemId(orderItem.getId());
if (!taskItemService.updateById(item)) {
- throw new CoolException("鐘舵�佸畬鎴愬け璐ワ紒锛�");
+ throw new CoolException("鎷h揣鏁伴噺鏇存柊澶辫触锛侊紒");
}
-
- // 鎵e噺搴撲綅鏄庣粏搴撳瓨锛堜笌鍑哄簱瀹屾垚閫昏緫淇濇寔涓�鑷达級
if (StringUtils.isNotBlank(task.getOrgLoc())) {
LocItem locItem = locItemService.getOne(new LambdaQueryWrapper<LocItem>()
.eq(LocItem::getLocCode, task.getOrgLoc())
.eq(LocItem::getMatnrId, item.getMatnrId())
.eq(StringUtils.isNotBlank(item.getBatch()), LocItem::getBatch, item.getBatch())
.eq(StringUtils.isNotBlank(item.getFieldsIndex()), LocItem::getFieldsIndex, item.getFieldsIndex()));
-
if (Objects.nonNull(locItem)) {
- // 浣跨敤瀹為檯鎷h揣鏁伴噺锛坱askItem.getAnfme()锛夋墸鍑忓簱浣嶆槑缁�
- Double newAnfme = Math.round((locItem.getAnfme() - taskItem.getAnfme()) * 1000000) / 1000000.0;
-
+ Double pickAmt = taskItem.getAnfme() != null ? taskItem.getAnfme() : 0.0;
+ Double newAnfme = Math.round((locItem.getAnfme() - pickAmt) * 1000000.0) / 1000000.0;
if (newAnfme.compareTo(0.0) <= 0) {
- // 鏁伴噺灏忎簬绛変簬0锛屽垹闄ゅ簱浣嶆槑缁�
locItemService.removeById(locItem.getId());
} else {
- // 鏇存柊搴撲綅鏄庣粏鏁伴噺
locItem.setAnfme(newAnfme)
.setUpdateBy(SystemAuthUtils.getLoginUserId())
.setUpdateTime(new Date());
@@ -432,33 +462,8 @@
}
}
}
-
- StockItem stockItem = new StockItem();
- BeanUtils.copyProperties(item, stockItem);
- //taskItem涓轰笂鎶ユ暟鎹�
- stockItem.setStockId(stock.getId()).setAnfme(taskItem.getAnfme()).setStockCode(stock.getCode()).setSourceItemId(orderItem.getId());
- stockItems.add(stockItem);
});
- if (!stockItemService.saveBatch(stockItems)) {
- throw new CoolException("鍑哄叆搴撳巻鍙叉槑缁嗕繚瀛樺け璐ワ紒锛�");
- }
});
-
- List<WkOrderItem> orderItems = asnOrderItemService.list(new LambdaQueryWrapper<WkOrderItem>().eq(WkOrderItem::getOrderId, params.getOrderId()));
- Double total = orderItems.stream().mapToDouble(WkOrderItem::getQty).sum();
- Double wkQty = orderItems.stream().mapToDouble(WkOrderItem::getWorkQty).sum();
- double v = order.getWorkQty().compareTo(wkQty) < 0 ? 0.0 : Math.round((total - wkQty) * 1000000) / 1000000.0;
- order.setQty(total).setWorkQty(v);
- if (!asnOrderService.updateById(order)) {
- throw new CoolException("璁㈠崟鏁伴噺鏇存柊澶辫触锛侊紒");
- }
-// //妫�鏌ュ崟鎹槸鍚﹀畬鎴�
-// if (order.getAnfme().compareTo(order.getQty()) == 0) {
-// order.setExceStatus(AsnExceStatus.OUT_STOCK_STATUS_TASK_DONE.val);
-// if (!asnOrderService.updateById(order)) {
-// throw new CoolException("鍑哄簱鍗曟洿鏂扮姸鎬佸け璐�");
-// }
-// }
return R.ok();
}
@@ -582,36 +587,80 @@
return R.error("浠诲姟鐘舵�佷笉鏄緟鎻�鐙�鎱�");
}
- Config config = configService.getOne(new LambdaQueryWrapper<Config>().eq(Config::getFlag, GlobalConfigCode.ALLOW_OVER_CHANGE));
- //鍒ゆ柇鏄惁鍏佽瓒呮敹锛屼笉鍏佽瓒呮敹娣诲姞鎷掓敹鍒ゆ柇
- if (!Objects.isNull(config)) {
- if (!Boolean.parseBoolean(config.getVal())) {
- List<TaskItem> taskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, task.getId()));
- taskItems.forEach(taskItem -> {
- if ((taskItem.getQty().compareTo(taskItem.getAnfme()) < 0)) {
- throw new CoolException("鏈夊崟鎹墿鏂欐湭鎷o紝璇锋嫞瀹屽悗鍐嶇‘璁わ紒锛�");
- }
- });
+ List<TaskItem> taskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, task.getId()));
+ // 蹇呴』褰撳墠鎵樼洏鍏宠仈鍑哄簱鍗曞叏閮ㄦ嫞璐у畬鎴愭墠鍏佽纭
+ for (TaskItem ti : taskItems) {
+ Double q = ti.getQty() != null ? ti.getQty() : 0.0;
+ Double a = ti.getAnfme() != null ? ti.getAnfme() : 0.0;
+ if (q.compareTo(a) < 0) {
+ throw new CoolException("鏈夊崟鎹墿鏂欐湭鎷e畬锛岃瀹屾垚璇ユ墭鐩樹笅鎵�鏈夎鍗曟嫞璐у悗鍐嶇‘璁わ紒锛�");
}
}
+ // 鎸夐『搴忔洿鏂板嚭搴撳崟鏄庣粏銆佽鍗曞強搴撳瓨娴佹按锛堜笌 wavePickItems 鍘熼�昏緫涓�鑷达紝鍦ㄥ叏閮ㄦ嫞瀹屽悗缁熶竴鎵ц锛�
+ Map<Long, List<TaskItem>> byOrder = taskItems.stream()
+ .filter(ti -> ti.getOrderId() != null)
+ .collect(Collectors.groupingBy(TaskItem::getOrderId));
+ List<Long> orderIds = new ArrayList<>(byOrder.keySet());
+ orderIds.sort(Long::compareTo);
+ for (Long orderId : orderIds) {
+ WkOrder order = asnOrderService.getById(orderId);
+ if (order == null) continue;
+ List<TaskItem> items = byOrder.get(orderId);
+ Map<String, List<TaskItem>> byMatnr = items.stream().collect(Collectors.groupingBy(TaskItem::getMatnrCode));
+ for (String code : byMatnr.keySet()) {
+ List<TaskItem> matItems = byMatnr.get(code);
+ WkOrderItem orderItem = asnOrderItemService.getOne(new LambdaQueryWrapper<WkOrderItem>()
+ .eq(WkOrderItem::getMatnrCode, code)
+ .eq(WkOrderItem::getOrderId, orderId));
+ if (orderItem == null) continue;
+ Double summed = matItems.stream().mapToDouble(t -> t.getQty() != null ? t.getQty() : 0.0).sum();
+ orderItem.setQty(summed);
+ asnOrderItemService.updateById(orderItem);
+ String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_STOCK_CODE, null);
+ if (StringUtils.isBlank(ruleCode)) continue;
+ Stock stock = new Stock();
+ stock.setCode(ruleCode)
+ .setUpdateBy(loginUserId)
+ .setBarcode(task.getBarcode())
+ .setLocCode(task.getOrgLoc())
+ .setType(order.getType())
+ .setWkType(Short.parseShort(order.getWkType()))
+ .setSourceId(orderItem.getOrderId())
+ .setSourceCode(orderItem.getOrderCode())
+ .setUpdateTime(new Date())
+ .setAnfme(summed);
+ if (!stockService.save(stock)) continue;
+ List<StockItem> stockItems = new ArrayList<>();
+ for (TaskItem ti : matItems) {
+ StockItem si = new StockItem();
+ BeanUtils.copyProperties(ti, si);
+ si.setStockId(stock.getId()).setAnfme(ti.getQty()).setStockCode(stock.getCode()).setSourceItemId(orderItem.getId());
+ stockItems.add(si);
+ }
+ stockItemService.saveBatch(stockItems);
+ }
+ List<WkOrderItem> ois = asnOrderItemService.list(new LambdaQueryWrapper<WkOrderItem>().eq(WkOrderItem::getOrderId, orderId));
+ Double total = ois.stream().mapToDouble(oi -> oi.getQty() != null ? oi.getQty() : 0.0).sum();
+ Double wkQty = ois.stream().mapToDouble(oi -> oi.getWorkQty() != null ? oi.getWorkQty() : 0.0).sum();
+ double v = (order.getWorkQty() != null && order.getWorkQty().compareTo(wkQty) < 0) ? 0.0 : Math.round((total - wkQty) * 1000000.0) / 1000000.0;
+ order.setQty(total).setWorkQty(v);
+ asnOrderService.updateById(order);
+ }
try {
if (task.getTaskType().equals(TaskType.TASK_TYPE_PICK_AGAIN_OUT.type)) {
- // 鎷f枡鍑哄簱锛氬垱寤烘嫞鏂欏叆搴撲换鍔�
taskService.pickOrCheckTask(task.getId(), "");
} else if (task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_OUT.type)) {
- // 鐩樼偣鍑哄簱锛氬垱寤虹洏鐐瑰叆搴撲换鍔�
taskService.pickOrCheckTask(task.getId(), Constants.TASK_TYPE_OUT_CHECK);
} else {
- // 鍏朵粬鍑哄簱绫诲瀷锛氱洿鎺ユ洿鏂颁负200
task.setTaskStatus(TaskStsType.UPDATED_OUT.id);
if (!taskService.updateById(task)) {
throw new CoolException("浠诲姟鐘舵�佹洿鏂板け璐�");
}
}
} catch (Exception e) {
- throw new CoolException("鍒嗘嫞澶辫触");
+ throw new CoolException("鍒嗘嫞澶辫触锛�" + e.getMessage());
}
return R.ok();
}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/ReportMsgServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/ReportMsgServiceImpl.java
index b107cee..a1c7793 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/ReportMsgServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/ReportMsgServiceImpl.java
@@ -302,10 +302,13 @@
//鑾峰彇搴撳瓨涓鍗曞簱浣�
Set<Long> longSet = stockItems.stream().map(StockItem::getStockId).collect(Collectors.toSet());
- Stock stocks = stockService.getOne(new LambdaQueryWrapper<Stock>()
- .in(Stock::getId, longSet)
- .eq(Stock::getType, OrderType.ORDER_IN.type)
- .eq(Stock::getSourceCode, order.getCode()));
+ Stock stocks = null;
+ if (!longSet.isEmpty()) {
+ stocks = stockService.getOne(new LambdaQueryWrapper<Stock>()
+ .in(Stock::getId, longSet)
+ .eq(Stock::getType, OrderType.ORDER_IN.type)
+ .eq(Stock::getSourceCode, order.getCode()));
+ }
if (!Objects.isNull(stocks)) {
param.setZone(stocks.getLocCode());
}
@@ -319,7 +322,7 @@
.setItemCode(orderItem.getMatnrCode())
.setEditUser(nickName)
.setEditDate(order.getUpdateTime())
- .setZone(stocks.getLocCode())
+ .setZone(stocks != null ? stocks.getLocCode() : null)
// .setGoodsNO(fields.get("crushNo")) // 绁ㄥ彿鏆備笉浣跨敤
.setMemoDtl(order.getMemo());
@@ -393,6 +396,9 @@
//杩囨护鎷h揣鍏ュ簱鏄庣粏锛岄伩鍏嶄笂鎶�
List<Stock> stockList = stocks.stream().filter(stock -> stock.getType().equals(OrderType.ORDER_OUT.type) && !Objects.isNull(stock.getSourceCode())).collect(Collectors.toList());
List<Long> list = stockList.stream().map(Stock::getId).collect(Collectors.toList());
+ if (list.isEmpty()) {
+ return;
+ }
List<StockItem> stockItems1 = stockItemService.list(new LambdaQueryWrapper<StockItem>().in(StockItem::getStockId, list));
String finalNickName = nickName;
stockItems1.forEach(stockItem -> {
@@ -500,11 +506,14 @@
.eq(StockItem::getFieldsIndex, orderItem.getFieldsIndex()));
//鑾峰彇搴撳瓨涓鍗曞簱浣�
List<Long> longSet = stockItems.stream().map(StockItem::getStockId).collect(Collectors.toList());
- //鑾峰彇搴撳瓨搴撲綅淇℃伅
- Stock stocks = stockService.getOne(new LambdaQueryWrapper<Stock>()
- .in(Stock::getId, longSet)
- .eq(Stock::getType, OrderType.ORDER_IN.type)
- .eq(Stock::getSourceCode, order.getCode()));
+ //鑾峰彇搴撳瓨搴撲綅淇℃伅锛堥伩鍏� longSet 涓虹┖鏃剁敓鎴� stock_id IN () 瀵艰嚧 SQL 寮傚父锛�
+ Stock stocks = null;
+ if (!longSet.isEmpty()) {
+ stocks = stockService.getOne(new LambdaQueryWrapper<Stock>()
+ .in(Stock::getId, longSet)
+ .eq(Stock::getType, OrderType.ORDER_IN.type)
+ .eq(Stock::getSourceCode, order.getCode()));
+ }
if (!Objects.isNull(stocks)) {
param.setZone(stocks.getLocCode());
}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/WcsServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/WcsServiceImpl.java
index d2d1fc1..f1dd469 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/WcsServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/WcsServiceImpl.java
@@ -39,6 +39,7 @@
import com.vincent.rsf.server.manager.enums.LocStsType;
import com.vincent.rsf.server.system.utils.SerialRuleUtils;
import lombok.extern.slf4j.Slf4j;
+import lombok.val;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
@@ -497,6 +498,8 @@
log.warn("[RCS鍏ュ簱鐢宠-鑷姩缁勬墭] 鍏ュ簱鍗曠紪鐮佽鍒欐湭閰嶇疆");
return;
}
+// val orderWorkTypeOtherIn = OrderWorkType.ORDER_WORK_TYPE_OTHER_IN.type;
+ // .setWkType(orderWorkTypeOtherIn)
WkOrder order = new WkOrder();
order.setCode(ruleCode)
.setType(OrderType.ORDER_IN.type)
@@ -578,10 +581,18 @@
*/
private Task createTask(String ruleCode, String targetLoc, String barcode,
String targetSite, String sourceSiteNo, Long loginUserId) {
+ return createTask(ruleCode, targetLoc, barcode, targetSite, sourceSiteNo, loginUserId, TaskType.TASK_TYPE_IN.type);
+ }
+
+ /**
+ * 鍒涘缓骞朵繚瀛樹换鍔★紙鏀寔鎸囧畾浠诲姟绫诲瀷锛屽绌烘澘鍏ュ簱锛�
+ */
+ private Task createTask(String ruleCode, String targetLoc, String barcode,
+ String targetSite, String sourceSiteNo, Long loginUserId, Integer taskType) {
Task task = new Task();
task.setTaskCode(ruleCode)
.setTaskStatus(TaskStsType.GENERATE_IN.id)
- .setTaskType(TaskType.TASK_TYPE_IN.type)
+ .setTaskType(taskType != null ? taskType : TaskType.TASK_TYPE_IN.type)
.setWarehType(WarehType.WAREHOUSE_TYPE_CRN.val)
.setTargLoc(targetLoc)
.setBarcode(barcode)
@@ -607,6 +618,75 @@
if (!updated) {
throw new CoolException("搴撲綅棰勭害澶辫触锛侊紒");
}
+ }
+
+ /**
+ * 绌烘澘鍏ュ簱锛歊CS 鐢宠鏃� full=true锛屾棤闇�缁勬墭锛屽垎閰嶅簱浣嶅苟鍒涘缓 TASK_TYPE_EMPITY_IN 浠诲姟銆�
+ * 闇�鍦ㄨ澶囩珯鐐逛腑閰嶇疆 type=10锛堢┖鏉垮叆搴擄級鐨勭珯鐐硅矾寰勩��
+ */
+ private InTaskMsgDto createInTaskForEmptyPallet(String barcode, String staNo, Integer type) {
+ TaskInParam param = new TaskInParam();
+ param.setBarcode(barcode);
+ param.setSourceStaNo(staNo);
+ param.setLocType1(type != null ? type : 1);
+ param.setIoType(TaskType.TASK_TYPE_EMPITY_IN.type);
+ param.setUser(1L);
+
+ // 鏍¢獙璁惧绔欑偣锛堥渶閰嶇疆 type=10 绌烘澘鍏ュ簱鐨勭珯鐐癸級
+ DeviceSite deviceSite = validateDeviceSite(param);
+
+ // 妫�鏌ヨ鎵樼洏鍙锋槸鍚﹀凡鏈夌┖鏉垮叆搴撲换鍔★紝鏈夊垯澶嶇敤
+ Task existingInTask = taskService.getOne(new LambdaQueryWrapper<Task>()
+ .eq(Task::getBarcode, barcode)
+ .eq(Task::getTaskType, TaskType.TASK_TYPE_EMPITY_IN.type)
+ .orderByDesc(Task::getCreateTime)
+ .last("LIMIT 1"));
+ if (existingInTask != null) {
+ log.info("鎵惧埌璇ユ墭鐩樺彿宸叉湁绌烘澘鍏ュ簱浠诲姟锛屽鐢� - 浠诲姟缂栫爜锛歿}锛岀鍙凤細{}", existingInTask.getTaskCode(), barcode);
+ if (StringUtils.isNotBlank(staNo) && !staNo.equals(existingInTask.getOrgSite())) {
+ existingInTask.setOrgSite(staNo);
+ taskService.updateById(existingInTask);
+ }
+ InTaskMsgDto msgDto = new InTaskMsgDto();
+ msgDto.setWorkNo(existingInTask.getTaskCode());
+ msgDto.setTaskId(existingInTask.getId());
+ msgDto.setLocNo(existingInTask.getTargLoc());
+ msgDto.setSourceStaNo(existingInTask.getOrgSite());
+ msgDto.setStaNo(existingInTask.getTargSite());
+ return msgDto;
+ }
+
+ // 璇ユ墭鐩樺凡鍦ㄥ簱鎴栧嚭搴撲腑锛屼笉鍙噸澶嶇敵璇风┖鏉垮叆搴�
+ List<Loc> inStock = locService.list(new LambdaQueryWrapper<Loc>().eq(Loc::getBarcode, barcode));
+ if (!inStock.isEmpty()) {
+ throw new CoolException("barcode=" + barcode + ": 璇ユ墭鐩樺凡鍦ㄥ簱锛屼笉鍙噸澶嶇敵璇峰叆搴�");
+ }
+ Task outboundTask = taskService.getOne(new LambdaQueryWrapper<Task>()
+ .eq(Task::getBarcode, barcode)
+ .in(Task::getTaskType, Arrays.asList(TaskType.TASK_TYPE_OUT.type, TaskType.TASK_TYPE_EMPITY_OUT.type,
+ TaskType.TASK_TYPE_PICK_AGAIN_OUT.type, TaskType.TASK_TYPE_CHECK_OUT.type))
+ .lt(Task::getTaskStatus, TaskStsType.COMPLETE_OUT.id));
+ if (outboundTask != null) {
+ throw new CoolException("barcode=" + barcode + ": 璇ユ墭鐩樺嚭搴撲腑鏈畬鎴愶紝涓嶅彲鐢宠鍏ュ簱");
+ }
+
+ InTaskMsgDto locNo;
+ try {
+ locNo = getLocNo(param);
+ } catch (Exception e) {
+ throw new CoolException("鑾峰彇绌烘澘鍏ュ簱搴撲綅澶辫触锛�" + e.getMessage());
+ }
+ if (locNo == null || StringUtils.isBlank(locNo.getLocNo())) {
+ throw new CoolException("鏈壘鍒板彲鐢ㄧ殑绌哄簱浣嶏紝璇锋鏌ュ簱鍖轰笌璁惧绔欑偣閰嶇疆锛堢┖鏉垮叆搴撻渶閰嶇疆 type=10 鐨勭珯鐐癸級");
+ }
+ String ruleCode = generateTaskCode();
+ String targetSite = StringUtils.isNotBlank(deviceSite.getDeviceSite()) ? deviceSite.getDeviceSite() : staNo;
+ Task task = createTask(ruleCode, locNo.getLocNo(), barcode, targetSite, staNo, param.getUser(), TaskType.TASK_TYPE_EMPITY_IN.type);
+ updateLocStatus(task.getTargLoc(), barcode);
+ locNo.setWorkNo(ruleCode);
+ locNo.setTaskId(task.getId());
+ log.info("[绌烘澘鍏ュ簱] 宸插垱寤轰换鍔�: {}, 搴撲綅: {}, 鏂欑: {}", ruleCode, locNo.getLocNo(), barcode);
+ return locNo;
}
/**
@@ -1476,9 +1556,19 @@
*/
@Override
@Transactional(rollbackFor = Exception.class)
- public R allocateLocation(String barcode, String staNo, Integer type) {
+ public R allocateLocation(String barcode, String staNo, Integer type, Boolean full) {
log.info("========== 寮�濮嬬敵璇峰叆搴撲换鍔★紝鍒嗛厤搴撲綅 ==========");
- log.info("鏂欑鐮侊細{}锛屽叆搴撶珯鐐癸細{}锛屽叆搴撶被鍨嬶細{}", barcode, staNo, type);
+ log.info("鏂欑鐮侊細{}锛屽叆搴撶珯鐐癸細{}锛屽叆搴撶被鍨嬶細{}锛岀┖鏉匡細{}", barcode, staNo, type, full);
+
+ // full=true 鏃惰蛋绌烘澘鍏ュ簱锛堟棤闇�缁勬墭锛夛紱鍚﹀垯璧版櫘閫氬叆搴擄紙闇�缁勬墭鎴栬嚜鍔ㄧ粍鎵橈級
+ if (Boolean.TRUE.equals(full)) {
+ InTaskMsgDto msgDto = createInTaskForEmptyPallet(barcode, staNo, type);
+ JSONObject result = new JSONObject();
+ result.put("locNo", msgDto.getLocNo());
+ result.put("batchNo", msgDto.getWorkNo());
+ result.put("taskNo", msgDto.getWorkNo());
+ return R.ok(result);
+ }
// 鏋勫缓 TaskInParam 鍙傛暟锛屼笌 /wcs/create/in/task 鎺ュ彛鍙傛暟涓�鑷�
TaskInParam param = new TaskInParam();
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/common/constant/Constants.java b/rsf-server/src/main/java/com/vincent/rsf/server/common/constant/Constants.java
index 8b6e00e..8389b66 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/common/constant/Constants.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/common/constant/Constants.java
@@ -119,6 +119,11 @@
public static final String TASK_TYPE_OUT_PICK = "pick";
/**
+ * 绌烘澘鍑哄簱
+ */
+ public static final String TASK_TYPE_OUT_STOCK_EMPTY = "empty";
+
+ /**
* 鎺掑簭榛樿鍊�
*/
public static final Integer TASK_SORT_DEFAULT_VALUE = 49;
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/dto/OrderOutItemDto.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/dto/OrderOutItemDto.java
index cf4b173..991fd0b 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/dto/OrderOutItemDto.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/dto/OrderOutItemDto.java
@@ -20,6 +20,9 @@
private String sitesNo;
+ /** 鎷f枡鍑哄簱鏈‘璁ゆ椂锛氬睍绀恒�屾鍦ㄦ嫞鏂欎腑锛屽墿浣� X 鍙敤銆嶏紱浠呭綋鍓╀綑涓嶅彲鐢ㄦ椂涓哄簱瀛樹笉瓒� */
+ private String pickingStatus;
+
private String sourceId;
private String source;
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/params/LocToTaskParams.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/params/LocToTaskParams.java
index 6f4700d..9231589 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/params/LocToTaskParams.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/params/LocToTaskParams.java
@@ -14,7 +14,7 @@
@ApiModel(value = "LocToTaskParams", description = "搴撳瓨鍑哄簱鍙傛暟")
public class LocToTaskParams {
- @ApiModelProperty("绫诲瀷锛� check:鐩樼偣鍑哄簱锛� outStock: 搴撳瓨鍑哄簱")
+ @ApiModelProperty("绫诲瀷锛� check:鐩樼偣鍑哄簱锛� outStock: 搴撳瓨鍑哄簱锛� empty: 绌烘澘鍑哄簱")
private String type;
@ApiModelProperty("鍘熷崟鎹甀D (鐢ㄦ埛鍗曟嵁鍑哄簱鏌ユ壘涓氬姟绫诲瀷")
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/AutoRunSchedules.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/AutoRunSchedules.java
index b6526ed..2be0b04 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/AutoRunSchedules.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/AutoRunSchedules.java
@@ -96,45 +96,55 @@
// }
/**
- * @author Ryan
- * @date 2025/9/1
- * @description: 鑷姩瀹屾垚鐩樼偣鍔熻兘
- * @version 1.0
+ * 鑷姩瀹屾垚鐩樼偣/鎷f枡锛氱洏鐐瑰嚭搴撻�愭潯澶勭悊锛涙嫞鏂欏嚭搴撴寜绠辩爜鍒嗙粍锛屽悓涓�绠辩爜涓嬪叏閮ㄤ换鍔℃嫞瀹屾墠鎵e噺骞剁敓鎴愭嫞鏂欏叆搴擄紙涓嶱DA纭閫昏緫涓�鑷达級銆�
*/
// @Scheduled(cron = "0/25 * * * * ?")
@Transactional(rollbackFor = Exception.class)
public void autoCheckComplete() {
- //鑾峰彇浠诲姟鍒楄〃涓紝涓虹洏鐐瑰嚭搴撶殑浠诲姟
List<Task> tasks = taskService.list(new LambdaQueryWrapper<Task>()
.in(Task::getTaskType, Arrays.asList(TaskType.TASK_TYPE_CHECK_OUT.type,
TaskType.TASK_TYPE_PICK_IN.type,
TaskType.TASK_TYPE_PICK_AGAIN_OUT.type,
TaskType.TASK_TYPE_CHECK_IN.type)));
- if (!tasks.isEmpty()) {
- tasks.forEach(task -> {
- if (task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_IN.type)) {
- if (task.getTaskStatus().equals(TaskStsType.COMPLETE_IN.id)) {
-
- }
- } else {
- if (task.getTaskStatus().equals(TaskStsType.WAVE_SEED.id)) {
- if (!stationService.update(new LambdaUpdateWrapper<BasStation>()
- .eq(BasStation::getStationName, task.getTargSite())
- .set(BasStation::getUseStatus, LocStsType.LOC_STS_TYPE_R.type))) {
- log.error("绔欑偣鐘舵�佷慨鏀瑰畬鎴愬け璐�,褰撳墠浠诲姟鐘舵�侊細", task.getTaskStatus());
-// throw new CoolException("绔欑偣鐘舵�佷慨鏀瑰け璐ワ紒锛�");
- }
- try {
- taskService.pickOrCheckTask(task.getId(), task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_OUT.type) ? Constants.TASK_TYPE_OUT_CHECK : "");
-
- } catch (Exception e) {
- log.error("error====>", e);
- }
- }
- }
- });
+ if (tasks.isEmpty()) {
+ return;
}
+ // 鎷f枡鍑哄簱锛氭寜绠辩爜鍒嗙粍锛屼粎褰撹绠辩爜涓嬫墍鏈変换鍔¢兘鎷e畬鎵嶅鐞嗭紙鎵e噺骞剁敓鎴愭嫞鏂欏叆搴撴垨搴撳瓨鎵e畬涓嶇敓鎴愶級
+ Map<String, List<Task>> pickOutByBarcode = tasks.stream()
+ .filter(t -> TaskType.TASK_TYPE_PICK_AGAIN_OUT.type.equals(t.getTaskType()) && TaskStsType.WAVE_SEED.id.equals(t.getTaskStatus()))
+ .collect(Collectors.groupingBy(t -> t.getBarcode() != null ? t.getBarcode() : ""));
+ for (Map.Entry<String, List<Task>> e : pickOutByBarcode.entrySet()) {
+ if (e.getKey().isEmpty()) continue;
+ List<Task> barcodeTasks = e.getValue();
+ List<Long> taskIds = barcodeTasks.stream().map(Task::getId).collect(Collectors.toList());
+ List<TaskItem> items = taskItemService.list(new LambdaQueryWrapper<TaskItem>().in(TaskItem::getTaskId, taskIds));
+ boolean allPicked = items.stream().allMatch(ti ->
+ ti.getQty() != null && ti.getAnfme() != null && ti.getQty().compareTo(ti.getAnfme()) >= 0);
+ if (!allPicked) continue;
+ for (Task task : barcodeTasks) {
+ try {
+ taskService.pickOrCheckTask(task.getId(), "");
+ } catch (Exception ex) {
+ log.error("autoCheckComplete 鎷f枡鍑哄簱 taskId={} error", task.getId(), ex);
+ }
+ }
+ }
+ // 鐩樼偣鍑哄簱锛氶�愭潯澶勭悊锛堜笉鎸夌鐮佽仛鍚堬級
+ tasks.stream()
+ .filter(t -> TaskType.TASK_TYPE_CHECK_OUT.type.equals(t.getTaskType()) && TaskStsType.WAVE_SEED.id.equals(t.getTaskStatus()))
+ .forEach(task -> {
+ if (!stationService.update(new LambdaUpdateWrapper<BasStation>()
+ .eq(BasStation::getStationName, task.getTargSite())
+ .set(BasStation::getUseStatus, LocStsType.LOC_STS_TYPE_R.type))) {
+ log.error("绔欑偣鐘舵�佷慨鏀瑰畬鎴愬け璐�,褰撳墠浠诲姟鐘舵�侊細", task.getTaskStatus());
+ }
+ try {
+ taskService.pickOrCheckTask(task.getId(), Constants.TASK_TYPE_OUT_CHECK);
+ } catch (Exception e) {
+ log.error("autoCheckComplete 鐩樼偣鍑哄簱 taskId={} error", task.getId(), e);
+ }
+ });
}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/MaterialAutoSchedules.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/MaterialAutoSchedules.java
index 14cdc65..8ed7634 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/MaterialAutoSchedules.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/MaterialAutoSchedules.java
@@ -20,6 +20,7 @@
import com.vincent.rsf.server.system.service.ConfigService;
import com.vincent.rsf.server.system.utils.SerialRuleUtils;
import lombok.extern.slf4j.Slf4j;
+import lombok.val;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/TaskSchedules.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/TaskSchedules.java
index 84c2299..371527f 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/TaskSchedules.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/TaskSchedules.java
@@ -590,13 +590,34 @@
}
tasks.forEach(task -> {
- TaskLog taskLog = new TaskLog();
- BeanUtils.copyProperties(task, taskLog);
- taskLog.setTaskId(task.getId()).setId(null);
- if (!taskLogService.save(taskLog)) {
- throw new CoolException("浠诲姟鍘嗗彶妗d繚瀛樺け璐ワ紒锛�");
+ // 鍙鍑哄簱 200 鍋氬悓绠辩爜妫�鏌ワ細鍚岀鐮佷笅鑻ユ湁 101/196/198/199 绛夛紙鏈埌 200锛夊垯璺宠繃锛岀瓑鍏ㄩ儴 200 鎵嶄竴娆″鐞嗭紱鎷f枡鍏ュ簱 100 涓嶅彈褰卞搷
+ List<Task> toProcess = Collections.singletonList(task);
+ if (TaskStsType.UPDATED_OUT.id.equals(task.getTaskStatus()) && TaskType.TASK_TYPE_PICK_AGAIN_OUT.type.equals(task.getTaskType()) && StringUtils.isNotBlank(task.getBarcode())) {
+ long not200 = taskService.count(new LambdaQueryWrapper<Task>()
+ .eq(Task::getBarcode, task.getBarcode())
+ .ne(Task::getTaskStatus, TaskStsType.UPDATED_OUT.id));
+ if (not200 > 0) {
+ return; // 鍚岀鐮佸皻鏈� 101/196/198/199 绛夐潪 200 浠诲姟锛屼笉澶勭悊锛岀户缁瓑寰�
+ }
+ // 鍚岀鐮佸凡鍏ㄩ儴 200锛氫竴娆℃�у鐞嗚绠辩爜涓嬫墍鏈� 200 鎷f枡鍑哄簱锛堝悎璁℃墸鍑忋�佹洿鏂板簱瀛樸�佺敓鎴愪竴寮犳嫞鏂欏叆搴撳崟銆佹洿鏂板簱浣嶇姸鎬侊級
+ List<Task> all200 = taskService.list(new LambdaQueryWrapper<Task>()
+ .eq(Task::getBarcode, task.getBarcode())
+ .eq(Task::getTaskType, TaskType.TASK_TYPE_PICK_AGAIN_OUT.type)
+ .eq(Task::getTaskStatus, TaskStsType.UPDATED_OUT.id)
+ .orderByAsc(Task::getId));
+ if (!all200.isEmpty()) {
+ taskService.processPickOutBarcodeAll200(all200);
+ toProcess = all200;
+ }
}
- List<TaskItem> taskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, task.getId()));
+ for (Task t : toProcess) {
+ TaskLog taskLog = new TaskLog();
+ BeanUtils.copyProperties(t, taskLog);
+ taskLog.setTaskId(t.getId()).setId(null);
+ if (!taskLogService.save(taskLog)) {
+ throw new CoolException("浠诲姟鍘嗗彶妗d繚瀛樺け璐ワ紒锛�");
+ }
+ List<TaskItem> taskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, t.getId()));
// 涓婃姤ERP鏆傛椂娉ㄩ噴锛�/rsf-open-api/erp/report/order锛�
// if (task.getTaskType().equals(TaskType.TASK_TYPE_IN.type)) {
@@ -630,13 +651,13 @@
// reportMsgService.reportOrderItem(wkOrderItem);
// }
// } else
- if (task.getTaskType().equals(TaskType.TASK_TYPE_IN.type)) {
+ if (t.getTaskType().equals(TaskType.TASK_TYPE_IN.type)) {
// 鍏ュ簱绫诲瀷浠呰浆鍘嗗彶锛屼笉涓婃姤ERP锛堝凡娉ㄩ噴锛�
- } else if ((task.getTaskType() >= TaskType.TASK_TYPE_OUT.type && task.getTaskType() <= TaskType.TASK_TYPE_EMPITY_OUT.type)
- || task.getTaskType().equals(TaskType.TASK_TYPE_PICK_IN.type)) {
+ } else if ((t.getTaskType() >= TaskType.TASK_TYPE_OUT.type && t.getTaskType() <= TaskType.TASK_TYPE_EMPITY_OUT.type)
+ || t.getTaskType().equals(TaskType.TASK_TYPE_PICK_IN.type)) {
/**鍒ゆ柇鍗曟嵁鏄惁瀹屾垚锛氭尝娆′笅鍙戙�佹寜鍗曚笅鍙戯紙鐐瑰嚮涓嬪彂浠诲姟锛夊畬鎴愬悗鍧囧皢鍑哄簱鍗曠疆涓哄畬缁�*/
Set<Long> orderIdsToDone = new HashSet<>();
- if (task.getResource() != null && task.getResource().equals(TaskResouceType.TASK_RESOUCE_WAVE_TYPE.val)) {
+ if (t.getResource() != null && t.getResource().equals(TaskResouceType.TASK_RESOUCE_WAVE_TYPE.val)) {
Set<Long> longSet = taskItems.stream()
.map(TaskItem::getSourceId)
.filter(Objects::nonNull)
@@ -648,7 +669,7 @@
orderIdsToDone.addAll(waveOrderRelas.stream().map(WaveOrderRela::getOrderId).collect(Collectors.toSet()));
}
}
- } else if (task.getResource() != null && task.getResource().equals(TaskResouceType.TASK_RESOUCE_ORDER_TYPE.val)) {
+ } else if (t.getResource() != null && t.getResource().equals(TaskResouceType.TASK_RESOUCE_ORDER_TYPE.val)) {
// 鎸夊崟涓嬪彂锛氫换鍔℃槑缁� sourceId 涓哄嚭搴撳崟ID
Set<Long> ids = taskItems.stream()
.map(TaskItem::getSourceId)
@@ -680,9 +701,9 @@
//鍑哄簱鍗曚笂鎶CS淇敼搴撲綅鐘舵��
try {
- reportStationStatus(task);
+ reportStationStatus(t);
} catch (Exception e) {
- logger.error("浠诲姟{}涓婃姤RCS淇敼搴撲綅鐘舵�佸け璐ャ�備换鍔$紪鐮侊細{}", task.getId(), task.getTaskCode(), e);
+ logger.error("浠诲姟{}涓婃姤RCS淇敼搴撲綅鐘舵�佸け璐ャ�備换鍔$紪鐮侊細{}", t.getId(), t.getTaskCode(), e);
// 涓嶆姏鍑哄紓甯革紝閬垮厤涓柇瀹氭椂浠诲姟
}
}
@@ -692,16 +713,16 @@
TaskItemLog itemLog = new TaskItemLog();
BeanUtils.copyProperties(item, itemLog);
itemLog.setId(null)
- .setTaskId(task.getId())
+ .setTaskId(t.getId())
.setLogId(taskLog.getId())
.setTaskItemId(item.getId());
itemLogs.add(itemLog);
}
- locItemWorkingService.remove(new LambdaQueryWrapper<LocItemWorking>().eq(LocItemWorking::getTaskId, task.getId()));
+ locItemWorkingService.remove(new LambdaQueryWrapper<LocItemWorking>().eq(LocItemWorking::getTaskId, t.getId()));
- if (!taskService.removeById(task.getId())) {
+ if (!taskService.removeById(t.getId())) {
throw new CoolException("鍘熷浠诲姟鍒犻櫎澶辫触锛侊紒");
}
@@ -709,11 +730,12 @@
if (!taskItemLogService.saveBatch(itemLogs)) {
throw new CoolException("浠诲姟鏄庣粏鍘嗗彶妗d繚瀛樺け璐ワ紒锛�");
}
- if (!taskItemService.remove(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, task.getId()))) {
+ if (!taskItemService.remove(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, t.getId()))) {
throw new CoolException("鍘熷浠诲姟鏄庣粏鍒犻櫎澶辫触锛侊紒");
}
}
+ }
});
}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/LocItemService.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/LocItemService.java
index 544c3e2..236415c 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/LocItemService.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/LocItemService.java
@@ -14,5 +14,10 @@
Task genMoveTask(LocToTaskParams map, Long loginUserId);
+ /**
+ * 绌烘澘鍑哄簱锛氫粠鎸囧畾绌烘澘搴撲綅锛坲seStatus=D锛夌敓鎴� TASK_TYPE_EMPITY_OUT 浠诲姟鑷崇洰鏍囩珯鐐�
+ */
+ Task generateTaskEmpty(LocToTaskParams map, Long loginUserId);
+
List<LocItem> listByMatnr(CheckLocQueryParams matnrs);
}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/TaskService.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/TaskService.java
index 4a63743..dc8eecd 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/TaskService.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/TaskService.java
@@ -37,4 +37,9 @@
R menualExceTask(List<Long> ids);
void pubTaskToWcs(List<Task> tasks);
+
+ /**
+ * 鍚岀鐮佷笅澶氭潯 200 鎷f枡鍑哄簱涓�娆℃�у鐞嗭細鎸夌浉鍚岀墿鏂欏悎璁℃墸鍑忓簱浣嶃�佹洿鏂板嚭搴撳崟/搴撳瓨鏄庣粏銆佺敓鎴愪竴寮犳嫞鏂欏叆搴撳崟锛堟湁浣欓噺鏃讹級銆佹洿鏂板簱浣嶇姸鎬�
+ */
+ void processPickOutBarcodeAll200(List<Task> all200Tasks);
}
\ No newline at end of file
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/LocItemServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/LocItemServiceImpl.java
index 61531c0..0b19e52 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/LocItemServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/LocItemServiceImpl.java
@@ -1,6 +1,7 @@
package com.vincent.rsf.server.manager.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.vincent.rsf.framework.exception.CoolException;
import com.vincent.rsf.server.api.controller.erp.params.TaskInParam;
import com.vincent.rsf.server.api.entity.dto.InTaskMsgDto;
@@ -95,14 +96,53 @@
if (Objects.isNull(loc)) {
throw new CoolException("鏁版嵁閿欒锛氭墍閫夊簱瀛樹俊鎭笉瀛樺湪锛侊紒");
}
- if (!loc.getUseStatus().equals(LocStsType.LOC_STS_TYPE_F.type)) {
- throw new CoolException("搴撲綅:" + loc.getCode() + ",涓嶅浜嶧.鍦ㄥ簱鐘舵�侊紝涓嶅彲鎵цR.鍑哄簱棰勭害鎿嶄綔锛侊紒");
+ // 鏀寔 F.鍦ㄥ簱 鎴� R.鍑哄簱棰勭害/鎷h揣涓� 鐘舵�佷笅鍒嗛厤锛堟嫞璐т腑鍙拷鍔犲悓搴撲綅璁㈠崟锛屽垎閰嶉噺涓嶈秴杩囧凡鍒嗛厤鍓╀綑锛�
+ if (!loc.getUseStatus().equals(LocStsType.LOC_STS_TYPE_F.type)
+ && !loc.getUseStatus().equals(LocStsType.LOC_STS_TYPE_R.type)) {
+ throw new CoolException("搴撲綅:" + loc.getCode() + ",涓嶅浜嶧.鍦ㄥ簱鎴朢.鍑哄簱棰勭害鐘舵�侊紝涓嶅彲鎵ц鍑哄簱鍒嗛厤锛侊紒");
}
-
- loc.setUseStatus(LocStsType.LOC_STS_TYPE_R.type);
-
- if (!locService.updateById(loc)) {
- throw new CoolException("搴撲綅鐘舵�佹洿鏂板け璐ワ紒锛�");
+ if (loc.getUseStatus().equals(LocStsType.LOC_STS_TYPE_F.type)) {
+ loc.setUseStatus(LocStsType.LOC_STS_TYPE_R.type);
+ if (!locService.updateById(loc)) {
+ throw new CoolException("搴撲綅鐘舵�佹洿鏂板け璐ワ紒锛�");
+ }
+ }
+ // 搴撲綅宸蹭负 R 鏃讹細璁$畻璇ュ簱浣嶅綋鍓嶄换鍔″凡鍒嗛厤閲忥紝鏂板垎閰嶄笉鑳借秴杩� (搴撲綅鏁伴噺 - 宸插垎閰�)
+ Map<String, Double> allocatedByKey = new HashMap<>();
+ List<Task> existTasks = new ArrayList<>();
+ if (loc.getUseStatus().equals(LocStsType.LOC_STS_TYPE_R.type)) {
+ existTasks = taskService.list(new LambdaQueryWrapper<Task>()
+ .eq(Task::getOrgLoc, loc.getCode())
+ .in(Task::getTaskStatus, Arrays.asList(TaskStsType.GENERATE_OUT.id, TaskStsType.WAVE_SEED.id)));
+ for (Task t : existTasks) {
+ List<TaskItem> existItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, t.getId()));
+ for (TaskItem ti : existItems) {
+ String k = buildAllocKey(ti.getMatnrId(), ti.getBatch(), ti.getFieldsIndex());
+ allocatedByKey.put(k, allocatedByKey.getOrDefault(k, 0.0) + (ti.getAnfme() != null ? ti.getAnfme() : 0.0));
+ }
+ }
+ }
+ // 鏂欑鐮侊細浼樺厛鐢ㄥ簱浣嶏紱棰勭害鍑哄簱(R) 鏃惰嫢搴撲綅鏈粦瀹氬垯浠庡悓搴撲綅宸叉湁浠诲姟甯﹀嚭骞跺洖鍐欏簱浣嶏紱鍐嶅惁鍒欎粠鏈鍒嗛厤鏄庣粏甯﹀嚭
+ String barcodeToUse = StringUtils.isNotBlank(loc.getBarcode()) ? loc.getBarcode() : null;
+ if (barcodeToUse == null && !existTasks.isEmpty()) {
+ barcodeToUse = existTasks.get(0).getBarcode();
+ if (StringUtils.isNotBlank(barcodeToUse)) {
+ locService.update(new LambdaUpdateWrapper<Loc>().eq(Loc::getId, loc.getId())
+ .set(Loc::getBarcode, barcodeToUse).set(Loc::getUpdateBy, loginUserId).set(Loc::getUpdateTime, new Date()));
+ }
+ }
+ if (barcodeToUse == null) {
+ List<LocItem> allocItems = listMap.get(key);
+ if (allocItems != null) {
+ barcodeToUse = allocItems.stream()
+ .map(LocItem::getBarcode)
+ .filter(StringUtils::isNotBlank)
+ .findFirst()
+ .orElse(null);
+ }
+ }
+ if (barcodeToUse == null) {
+ barcodeToUse = loc.getBarcode();
}
Task moveTask = new Task();
String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_TASK_CODE, null);
@@ -116,7 +156,7 @@
.setCreateTime(new Date())
.setUpdateTime(new Date())
.setTaskStatus(TaskStsType.GENERATE_OUT.id)
- .setBarcode(loc.getBarcode())
+ .setBarcode(barcodeToUse)
.setMemo(map.getMemo());
List<LocItem> locItems = this.list(new LambdaQueryWrapper<LocItem>().eq(LocItem::getLocId, key));
@@ -203,10 +243,33 @@
List<TaskItem> taskItems = new ArrayList<>();
listMap.get(key).forEach(item -> {
+ LocItem locItem = locItemService.getById(item.getId());
+ if (Objects.isNull(locItem)) {
+ throw new CoolException("搴撳瓨淇℃伅涓嶅瓨鍦紒");
+ }
+ if (item.getOutQty().compareTo(0.0) < 0) {
+ throw new CoolException("鍑哄簱鏁伴噷涓嶈兘灏忎簬0锛侊紒");
+ }
+ // 棰勭害鍑哄簱/鎷h揣涓拷鍔狅細鏂板垎閰嶉噺涓嶈兘瓒呰繃 (搴撲綅鏁伴噺 - 璇ョ墿鏂欏凡鍒嗛厤閲�)
+ Double allocQty = item.getOutQty();
+ if (!allocatedByKey.isEmpty()) {
+ String allocKey = buildAllocKey(locItem.getMatnrId(), locItem.getBatch(), locItem.getFieldsIndex());
+ Double already = allocatedByKey.getOrDefault(allocKey, 0.0);
+ Double available = Math.round((locItem.getAnfme() - already) * 1000000) / 1000000.0;
+ if (available.compareTo(0.0) <= 0) {
+ throw new CoolException("搴撲綅:" + loc.getCode() + " 璇ョ墿鏂欏凡鏃犲墿浣欏彲鍒嗛厤鏁伴噺锛屼笉鍙啀杩藉姞璁㈠崟锛�");
+ }
+ if (allocQty.compareTo(available) > 0) {
+ allocQty = available;
+ item.setOutQty(allocQty);
+ }
+ allocatedByKey.put(allocKey, already + allocQty);
+ }
+
TaskItem taskItem = new TaskItem();
BeanUtils.copyProperties(item, taskItem);
taskItem.setTaskId(task.getId())
- .setAnfme(item.getOutQty())
+ .setAnfme(allocQty)
.setBatch(item.getBatch())
.setUpdateBy(loginUserId)
.setCreateBy(loginUserId)
@@ -231,18 +294,9 @@
}
taskItems.add(taskItem);
- Double qty = Math.round((item.getWorkQty() + item.getOutQty()) * 1000000) / 1000000.0;
- LocItem locItem = locItemService.getById(item.getId());
- if (Objects.isNull(locItem)) {
- throw new CoolException("搴撳瓨淇℃伅涓嶅瓨鍦紒");
- }
-
- if (item.getOutQty().compareTo(0.0) < 0) {
- throw new CoolException("鍑哄簱鏁伴噷涓嶈兘灏忎簬0锛侊紒");
- }
-
+ Double qty = Math.round((item.getWorkQty() != null ? item.getWorkQty() : 0.0) + allocQty) * 1000000.0 / 1000000.0;
if (locItem.getAnfme().compareTo(qty) < 0) {
- Double minusQty = Math.round((locItem.getAnfme() - locItem.getWorkQty()) * 1000000) / 1000000.0;
+ Double minusQty = Math.round((locItem.getAnfme() - (locItem.getWorkQty() != null ? locItem.getWorkQty() : 0.0)) * 1000000) / 1000000.0;
item.setWorkQty(minusQty);
} else {
item.setWorkQty(qty);
@@ -368,6 +422,66 @@
}
/**
+ * 绌烘澘鍑哄簱锛氫粠鎸囧畾绌烘澘搴撲綅锛坲seStatus=D锛夌敓鎴� TASK_TYPE_EMPITY_OUT 浠诲姟鑷崇洰鏍囩珯鐐广��
+ * 闇�鍦ㄨ澶囩珯鐐逛腑閰嶇疆 type=110锛堢┖鏉垮嚭搴擄級鐨勭珯鐐硅矾寰勩��
+ */
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public Task generateTaskEmpty(LocToTaskParams map, Long loginUserId) {
+ if (StringUtils.isBlank(map.getSiteNo())) {
+ throw new CoolException("鐩爣绔欑偣涓嶈兘涓虹┖锛�");
+ }
+ if (StringUtils.isBlank(map.getOrgLoc())) {
+ throw new CoolException("婧愬簱浣嶄笉鑳戒负绌猴紒");
+ }
+ if (!Constants.TASK_TYPE_OUT_STOCK_EMPTY.equals(map.getType())) {
+ throw new CoolException("绫诲瀷蹇呴』涓� empty锛堢┖鏉垮嚭搴擄級锛�");
+ }
+ Loc loc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getCode, map.getOrgLoc()));
+ if (loc == null) {
+ throw new CoolException("婧愬簱浣嶄笉瀛樺湪锛�");
+ }
+ if (!LocStsType.LOC_STS_TYPE_D.type.equals(loc.getUseStatus())) {
+ throw new CoolException("搴撲綅 " + loc.getCode() + " 涓嶅浜庣┖鏉跨姸鎬侊紙D锛夛紝涓嶅彲鎵ц绌烘澘鍑哄簱锛�");
+ }
+ DeviceSite deviceSite = deviceSiteService.getOne(new LambdaQueryWrapper<DeviceSite>()
+ .eq(DeviceSite::getSite, map.getSiteNo())
+ .eq(DeviceSite::getType, TaskType.TASK_TYPE_EMPITY_OUT.type)
+ .last("limit 1"));
+ if (deviceSite == null) {
+ throw new CoolException("绔欑偣涓嶆敮鎸佺┖鏉垮嚭搴撴垨鏈厤缃┖鏉垮嚭搴撹矾寰勶紒");
+ }
+ if (!locService.update(new LambdaUpdateWrapper<Loc>()
+ .eq(Loc::getId, loc.getId())
+ .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_R.type))) {
+ throw new CoolException("搴撲綅鍑哄簱棰勭害澶辫触锛�");
+ }
+ String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_TASK_CODE, null);
+ if (StringUtils.isBlank(ruleCode)) {
+ throw new CoolException("缂栫爜閿欒锛氳纭鏄惁宸茬敓鎴愶紒");
+ }
+ Task task = new Task();
+ task.setTaskCode(ruleCode)
+ .setTaskStatus(TaskStsType.GENERATE_OUT.id)
+ .setTaskType(TaskType.TASK_TYPE_EMPITY_OUT.type)
+ .setWarehType(WarehType.WAREHOUSE_TYPE_CRN.val)
+ .setOrgLoc(loc.getCode())
+ .setTargSite(map.getSiteNo())
+ .setBarcode(loc.getBarcode())
+ .setSort(Constants.TASK_SORT_DEFAULT_VALUE)
+ .setCreateBy(loginUserId)
+ .setUpdateBy(loginUserId)
+ .setCreateTime(new Date())
+ .setUpdateTime(new Date())
+ .setMemo(map.getMemo());
+ if (!taskService.save(task)) {
+ throw new CoolException("绌烘澘鍑哄簱浠诲姟鍒涘缓澶辫触锛�");
+ }
+ logger.info("[绌烘澘鍑哄簱] 宸插垱寤轰换鍔�: {}, 婧愬簱浣�: {}, 鐩爣绔欑偣: {}", ruleCode, loc.getCode(), map.getSiteNo());
+ return task;
+ }
+
+ /**
* @author Ryan
* @date 2025/7/16
* @description: 鑾峰彇褰撳墠鐗╂枡鎵�鏈夊簱瀛樹俊鎭�
@@ -381,4 +495,9 @@
.in(!matnr.getMatnrCode().isEmpty(), LocItem::getMatnrCode, matnr.getMatnrCode());
return this.baseMapper.listByMatnr(LocStsType.LOC_STS_TYPE_F.type, matnr.getChannel(), wrapper);
}
+
+ /** 搴撲綅宸插垎閰嶉噺鎸夌墿鏂�+鎵规+绁ㄥ彿鑱氬悎鐨� key */
+ private static String buildAllocKey(Long matnrId, String batch, String fieldsIndex) {
+ return (matnrId != null ? matnrId : "") + "|" + (batch != null ? batch : "") + "|" + (fieldsIndex != null ? fieldsIndex : "");
+ }
}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/RcsTestServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/RcsTestServiceImpl.java
index ffe81ce..3afff4b 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/RcsTestServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/RcsTestServiceImpl.java
@@ -221,8 +221,8 @@
}
if ("location_allocate".equals(params.getInboundApiType())) {
- // 浣跨敤 location_allocate 鎺ュ彛锛堝唴閮ㄨ皟鐢╟reateInTask锛�
- R allocateResult = wcsService.allocateLocation(barcode, inboundStation, 1);
+ // 浣跨敤 location_allocate 鎺ュ彛锛堝唴閮ㄨ皟鐢╟reateInTask锛夛紱full=null 琛ㄧず鏅�氬叆搴�
+ R allocateResult = wcsService.allocateLocation(barcode, inboundStation, 1, null);
if (allocateResult != null) {
Object dataObj = allocateResult.get("data");
if (dataObj != null) {
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TaskServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TaskServiceImpl.java
index 7c3e65e..7ebc3ce 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TaskServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TaskServiceImpl.java
@@ -1383,6 +1383,15 @@
});
log.debug("[鎷f枡鍏ュ簱] 鍗冲皢鎵e噺搴撲綅 locId={}, locCode={}", loc.getId(), loc.getCode());
subtractLocItemByTaskItems(loc, taskItems, SystemAuthUtils.getLoginUserId());
+ // 鏂欑宸插叏閮ㄧ敤瀹屽垯涓嶇敓鎴愭嫞璐у叆搴撳崟锛屼粎瀹岀粨鍑哄簱
+ double totalRemaining = taskItems.stream().mapToDouble(ti -> ti.getAnfme() != null && ti.getAnfme().compareTo(0.0) > 0 ? ti.getAnfme() : 0.0).sum();
+ if (totalRemaining <= 0.0) {
+ task.setTaskType(TaskType.TASK_TYPE_PICK_AGAIN_OUT.type);
+ task.setTaskStatus(TaskStsType.UPDATED_OUT.id);
+ this.updateById(task);
+ locItemWorkingService.remove(new LambdaQueryWrapper<LocItemWorking>().eq(LocItemWorking::getTaskId, task.getId()));
+ return task;
+ }
}
tempLocs.forEach(working -> {
@@ -1478,6 +1487,137 @@
}
/**
+ * 鍚岀鐮佷笅澶氭潯 200 鎷f枡鍑哄簱涓�娆℃�у鐞嗭細鎸夌浉鍚岀墿鏂欏悎璁℃墸鍑忓簱浣嶃�佹洿鏂板嚭搴撳崟/搴撳瓨鏄庣粏銆佺敓鎴愪竴寮犳嫞鏂欏叆搴撳崟锛堟湁浣欓噺鏃讹級銆佹洿鏂板簱浣嶇姸鎬�
+ */
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void processPickOutBarcodeAll200(List<Task> all200Tasks) {
+ if (all200Tasks == null || all200Tasks.isEmpty()) {
+ return;
+ }
+ Task first = all200Tasks.get(0);
+ if (!TaskType.TASK_TYPE_PICK_AGAIN_OUT.type.equals(first.getTaskType()) || !TaskStsType.UPDATED_OUT.id.equals(first.getTaskStatus())) {
+ throw new CoolException("闈炴嫞鏂欏嚭搴�200浠诲姟锛屼笉鍙壒閲忓鐞�");
+ }
+ List<Long> taskIds = all200Tasks.stream().map(Task::getId).collect(Collectors.toList());
+ List<TaskItem> allItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().in(TaskItem::getTaskId, taskIds));
+ if (allItems.isEmpty()) {
+ throw new CoolException("浠诲姟鏄庣粏涓虹┖");
+ }
+ Long loginUserId = SystemAuthUtils.getLoginUserId();
+ if (loginUserId == null) {
+ loginUserId = 1L;
+ }
+ String orgLoc = first.getOrgLoc();
+ Loc loc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getCode, orgLoc));
+ if (loc == null) {
+ throw new CoolException("搴撲綅涓嶅瓨鍦細" + orgLoc);
+ }
+ // 鎸夌墿鏂�+鎵规+绁ㄥ彿姹囨�诲凡鎷f暟閲�
+ Map<String, List<TaskItem>> byKey = allItems.stream().collect(Collectors.groupingBy(ti ->
+ (ti.getMatnrId() != null ? ti.getMatnrId() : "") + "_" + (ti.getBatch() != null ? ti.getBatch() : "") + "_" + (ti.getFieldsIndex() != null ? ti.getFieldsIndex() : "")));
+ List<TaskItem> aggregatedForDeduct = new ArrayList<>();
+ Map<String, Double> remainderByKey = new LinkedHashMap<>();
+ for (Map.Entry<String, List<TaskItem>> e : byKey.entrySet()) {
+ List<TaskItem> group = e.getValue();
+ double totalQty = group.stream().mapToDouble(ti -> ti.getQty() != null && ti.getQty() > 0 ? ti.getQty() : (ti.getAnfme() != null ? ti.getAnfme() : 0)).sum();
+ TaskItem rep = group.get(0);
+ TaskItem forDeduct = new TaskItem();
+ forDeduct.setMatnrId(rep.getMatnrId()).setBatch(rep.getBatch()).setFieldsIndex(rep.getFieldsIndex()).setQty(totalQty);
+ aggregatedForDeduct.add(forDeduct);
+ LambdaQueryWrapper<LocItem> qw = new LambdaQueryWrapper<LocItem>().eq(LocItem::getLocId, loc.getId()).eq(LocItem::getMatnrId, rep.getMatnrId());
+ if (StringUtils.isNotBlank(rep.getBatch())) qw.eq(LocItem::getBatch, rep.getBatch());
+ else qw.and(w -> w.isNull(LocItem::getBatch).or().eq(LocItem::getBatch, ""));
+ if (StringUtils.isNotBlank(rep.getFieldsIndex())) qw.eq(LocItem::getFieldsIndex, rep.getFieldsIndex());
+ else qw.and(w -> w.isNull(LocItem::getFieldsIndex).or().eq(LocItem::getFieldsIndex, ""));
+ LocItem li = locItemService.getOne(qw);
+ double remainder = (li != null && li.getAnfme() != null ? li.getAnfme() : 0) - totalQty;
+ if (remainder > 0) {
+ remainderByKey.put(e.getKey(), remainder);
+ }
+ }
+ subtractLocItemByTaskItems(loc, aggregatedForDeduct, loginUserId);
+ // 鎸� source 鍒嗙粍鏇存柊鍑哄簱鍗曞苟鍐欏簱瀛樻祦姘�
+ Map<Long, List<TaskItem>> bySource = allItems.stream().collect(Collectors.groupingBy(TaskItem::getSource));
+ for (Map.Entry<Long, List<TaskItem>> e : bySource.entrySet()) {
+ Long key = e.getKey();
+ List<TaskItem> items = e.getValue();
+ if (first.getResource() != null && first.getResource().equals(TaskResouceType.TASK_RESOUCE_WAVE_TYPE.val)) {
+ WaveItem waveItem = waveItemService.getById(key);
+ if (waveItem != null) {
+ try {
+ saveOutStockItem(items, null, waveItem, null, loginUserId);
+ } catch (Exception ex) {
+ throw new CoolException(ex.getMessage());
+ }
+ }
+ } else if (first.getResource() != null && first.getResource().equals(TaskResouceType.TASK_RESOUCE_ORDER_TYPE.val)) {
+ WkOrderItem orderItem = asnOrderItemService.getById(key);
+ if (orderItem != null) {
+ try {
+ saveOutStockItem(items, orderItem, null, null, loginUserId);
+ } catch (Exception ex) {
+ throw new CoolException(ex.getMessage());
+ }
+ }
+ }
+ }
+ // 鏈変綑閲忓垯鐢熸垚涓�寮犳嫞鏂欏叆搴撳崟
+ if (!remainderByKey.isEmpty()) {
+ Task pickInTask = new Task();
+ pickInTask.setTaskCode(SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_TASK_CODE, first));
+ pickInTask.setTaskType(TaskType.TASK_TYPE_PICK_IN.type);
+ pickInTask.setTaskStatus(TaskStsType.GENERATE_IN.id);
+ pickInTask.setBarcode(first.getBarcode());
+ pickInTask.setOrgLoc(orgLoc);
+ pickInTask.setTargLoc(orgLoc);
+ pickInTask.setOrgSite(first.getTargSite());
+ pickInTask.setTargSite(first.getTargSite());
+ pickInTask.setResource(first.getResource());
+ if (!this.save(pickInTask)) {
+ throw new CoolException("鎷f枡鍏ュ簱浠诲姟鍒涘缓澶辫触");
+ }
+ List<LocItemWorking> workings = new ArrayList<>();
+ for (Map.Entry<String, Double> re : remainderByKey.entrySet()) {
+ String k = re.getKey();
+ Double rem = re.getValue();
+ if (rem == null || rem <= 0) continue;
+ List<TaskItem> group = byKey.get(k);
+ if (group == null || group.isEmpty()) continue;
+ TaskItem rep = group.get(0);
+ TaskItem ti = new TaskItem();
+ ti.setTaskId(pickInTask.getId());
+ ti.setMatnrId(rep.getMatnrId()).setMaktx(rep.getMaktx()).setMatnrCode(rep.getMatnrCode());
+ ti.setBatch(rep.getBatch()).setFieldsIndex(rep.getFieldsIndex()).setUnit(rep.getUnit()).setSpec(rep.getSpec()).setModel(rep.getModel());
+ ti.setAnfme(rem).setQty(0.0);
+ taskItemService.save(ti);
+ LocItemWorking w = new LocItemWorking();
+ w.setTaskId(pickInTask.getId());
+ w.setLocId(loc.getId());
+ w.setLocCode(loc.getCode());
+ w.setMatnrId(rep.getMatnrId()).setMaktx(rep.getMaktx()).setMatnrCode(rep.getMatnrCode());
+ w.setBatch(rep.getBatch()).setFieldsIndex(rep.getFieldsIndex()).setUnit(rep.getUnit());
+ w.setAnfme(rem);
+ workings.add(w);
+ }
+ if (!workings.isEmpty()) {
+ locItemWorkingService.saveBatch(workings);
+ }
+ loc.setUseStatus(LocStsType.LOC_STS_TYPE_S.type);
+ locService.updateById(loc);
+ } else {
+ loc.setUseStatus(LocStsType.LOC_STS_TYPE_O.type);
+ loc.setBarcode(null);
+ loc.setUpdateBy(loginUserId);
+ loc.setUpdateTime(new Date());
+ locService.updateById(loc);
+ }
+ for (Long tid : taskIds) {
+ locItemWorkingService.remove(new LambdaQueryWrapper<LocItemWorking>().eq(LocItemWorking::getTaskId, tid));
+ }
+ }
+
+ /**
* @author Ryan
* @date 2025/5/20
* @description: 瀹屾垚鍑哄簱浠诲姟锛屾洿鏂板嚭搴撳簱瀛樹俊鎭�
@@ -1493,7 +1633,35 @@
if (Objects.isNull(loc)) {
throw new CoolException("搴撲綅涓嶅瓨鍦紒锛�");
}
-
+
+ // 绌烘澘鍑哄簱锛氭棤浠诲姟鏄庣粏锛屼笉闇�瑕� PDA 鎷h揣纭锛孯CS 鍥炶皟鍚庣洿鎺ュ畬鎴愬簱浣嶆洿鏂板苟缃负 UPDATED_OUT
+ if (task.getTaskType().equals(TaskType.TASK_TYPE_EMPITY_OUT.type)) {
+ List<TaskItem> emptyItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, task.getId()));
+ if (emptyItems.isEmpty()) {
+ if (!LocStsType.LOC_STS_TYPE_R.type.equals(loc.getUseStatus())) {
+ log.warn("绌烘澘鍑哄簱浠诲姟{}鐨勫簱浣峽}鐘舵�佷笉鏄疪.鍑哄簱棰勭害锛岃烦杩�", task.getId(), loc.getCode());
+ return;
+ }
+ if (!locService.update(new LambdaUpdateWrapper<Loc>()
+ .eq(Loc::getId, loc.getId())
+ .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_O.type)
+ .set(Loc::getBarcode, null)
+ .set(Loc::getUpdateBy, loginUserId)
+ .set(Loc::getUpdateTime, new Date()))) {
+ throw new CoolException("绌烘澘鍑哄簱搴撲綅鐘舵�佹洿鏂板け璐ワ紒锛�");
+ }
+ if (!this.update(new LambdaUpdateWrapper<Task>()
+ .eq(Task::getId, task.getId())
+ .set(Task::getUpdateBy, loginUserId)
+ .set(Task::getUpdateTime, new Date())
+ .set(Task::getTaskStatus, TaskStsType.UPDATED_OUT.id))) {
+ throw new CoolException("绌烘澘鍑哄簱浠诲姟鐘舵�佹洿鏂板け璐ワ紒锛�");
+ }
+ log.info("[绌烘澘鍑哄簱] 浠诲姟{} RCS鍥炶皟鍚庡凡鐩存帴瀹屾垚搴撲綅鏇存柊锛屾棤闇�PDA纭", task.getTaskCode());
+ return;
+ }
+ }
+
List<TaskItem> taskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, task.getId()));
if (taskItems.isEmpty()) {
throw new CoolException("浠诲姟鏄庣粏涓嶅瓨鍦紒锛�");
@@ -1610,15 +1778,8 @@
// 鏍规嵁浠诲姟绫诲瀷鏇存柊搴撲綅鐘舵��
if (task.getTaskType().equals(TaskType.TASK_TYPE_PICK_AGAIN_OUT.type) || task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_OUT.type)) {
- /**淇敼涓哄簱浣嶇姸鎬佷负S.棰勭害鍏ュ簱锛屼繚鐣欏師鏈夊簱浣�*/
- if (!locService.update(new LambdaUpdateWrapper<Loc>()
- .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_S.type)
- .set(Loc::getBarcode, null)
- .set(Loc::getUpdateBy, loginUserId)
- .set(Loc::getUpdateTime, new Date())
- .eq(Loc::getId, loc.getId()))) {
- throw new CoolException("搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�");
- }
+ // 鎷f枡鍑哄簱/鐩樼偣鍑哄簱锛氬湪鏈敓鎴愭嫞鏂欏叆搴撳崟涔嬪墠淇濇寔 R.棰勭害鍑哄簱锛屽惁鍒欎笅鍙戜换鍔℃椂鏌ヤ笉鍒拌搴撲綅锛堝彧鏌� F+R锛夊鑷粹�滃簱瀛樹笉瓒斥��
+ // 绛� PDA 纭骞剁敓鎴愭嫞鏂欏叆搴撲换鍔℃椂锛屽啀鍦� pickOrCheckTask 涓皢鐩爣搴撲綅鏀逛负 S.棰勭害鍏ュ簱
} else if (task.getTaskType().equals(TaskType.TASK_TYPE_OUT.type)) {
// 鍏ㄧ増鍑哄簱锛氫笉鏇存柊搴撲綅鐘舵�佷负O锛岀瓑寰匬DA蹇�熸嫞璐х‘璁ゆ椂鍐嶆洿鏂�
// 搴撲綅鐘舵�佷繚鎸佸師鏍凤紙R.鍑哄簱棰勭害鐘舵�侊級
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/LocManageUtil.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/LocManageUtil.java
index ac3d112..d4b8a60 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/LocManageUtil.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/LocManageUtil.java
@@ -100,13 +100,8 @@
if (StringUtils.isNotBlank(splrBatch)) {
locItemQueryWrapper.and(w -> w.eq(LocItem::getBatch, splrBatch).or().isNull(LocItem::getBatch));
}
- String applySql = String.format(
- "EXISTS (SELECT 1 FROM man_loc ml " +
- "WHERE ml.use_status = '%s'" +
- "AND ml.id = man_loc_item.loc_id " +
- ")",
- LocStsType.LOC_STS_TYPE_F.type
- );
+ // 鍚� F.鍦ㄥ簱 涓� R.鍑哄簱棰勭害锛堟嫞鏂欏嚭搴撴湭纭鍓嶅彲鍐嶄笅鍙戯紝浣跨敤鍓╀綑鍙敤锛�
+ String applySql = "EXISTS (SELECT 1 FROM man_loc ml WHERE ml.use_status IN ('" + LocStsType.LOC_STS_TYPE_F.type + "','" + LocStsType.LOC_STS_TYPE_R.type + "') AND ml.id = man_loc_item.loc_id)";
locItemQueryWrapper.apply(applySql);
LocItemService locItemService = SpringUtils.getBean(LocItemService.class);
List<LocItem> locItems = locItemService.list(locItemQueryWrapper);
@@ -140,14 +135,9 @@
} else {
locItemQueryWrapper.orderByAsc(LocItem::getCreateTime);
}
- String applySql = String.format(
- "EXISTS (SELECT 1 FROM man_loc ml " +
- "WHERE ml.use_status = '%s'" +
- "AND ml.id = man_loc_item.loc_id " +
- ")",
- LocStsType.LOC_STS_TYPE_F.type
- );
- locItemQueryWrapper.apply(applySql);
+ // 鍚� F.鍦ㄥ簱 涓� R.鍑哄簱棰勭害锛堟嫞鏂欏嚭搴撴湭纭鍓嶅彲鍐嶄笅鍙戯紝浣跨敤鍓╀綑鍙敤锛�
+ String applySqlR = "EXISTS (SELECT 1 FROM man_loc ml WHERE ml.use_status IN ('" + LocStsType.LOC_STS_TYPE_F.type + "','" + LocStsType.LOC_STS_TYPE_R.type + "') AND ml.id = man_loc_item.loc_id)";
+ locItemQueryWrapper.apply(applySqlR);
LocItemService locItemService = SpringUtils.getBean(LocItemService.class);
List<LocItem> locItems = locItemService.list(locItemQueryWrapper);
return locItems;
--
Gitblit v1.9.1