From c67e3d0295858a61122354a15dec8835044bac0d Mon Sep 17 00:00:00 2001
From: chen.lin <1442464845@qq.com>
Date: 星期二, 24 二月 2026 15:54:53 +0800
Subject: [PATCH] 库位拣料出库数量调整
---
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java | 134 ++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 132 insertions(+), 2 deletions(-)
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java
index 2e999d3..e2cf9c4 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java
@@ -8,12 +8,16 @@
import com.vincent.rsf.framework.exception.CoolException;
import com.vincent.rsf.server.api.utils.LocUtils;
import com.vincent.rsf.server.common.constant.Constants;
+import com.vincent.rsf.server.common.domain.BaseParam;
+import com.vincent.rsf.server.common.domain.PageParam;
import com.vincent.rsf.server.manager.controller.dto.ExistDto;
import com.vincent.rsf.server.manager.controller.dto.OrderOutItemDto;
import com.vincent.rsf.server.manager.controller.params.*;
import com.vincent.rsf.server.manager.enums.*;
+import com.vincent.rsf.server.manager.entity.Matnr;
import com.vincent.rsf.server.manager.entity.*;
import com.vincent.rsf.server.manager.mapper.AsnOrderMapper;
+import com.vincent.rsf.server.manager.mapper.LocItemMapper;
import com.vincent.rsf.server.manager.service.*;
import com.vincent.rsf.server.manager.utils.LocManageUtil;
import com.vincent.rsf.server.manager.utils.OptimalAlgorithmUtil;
@@ -83,7 +87,123 @@
private WaveOrderRelaServiceImpl waveOrderRelaService;
@Autowired
private TaskItemService taskItemService;
+ @Autowired
+ private LocItemMapper locItemMapper;
+ @Override
+ public PageParam<Matnr, BaseParam> pageMatnrForOutStock(PageParam<Matnr, BaseParam> pageParam, Map<String, Object> params) {
+ // 鍦� getMatnrPage 涔嬪墠鍙栧嚭 locUseStatus锛歡etMatnrPage 浼氫粠 where.map 涓� remove 鎺夎閿紙涓� params 鍚屽紩鐢級锛屽鑷村悗缁彇涓嶅埌
+ String locUseStatus = params.get("locUseStatus") != null ? params.get("locUseStatus").toString().trim() : null;
+ if (locUseStatus != null && locUseStatus.isEmpty()) locUseStatus = null;
+
+ PageParam<Matnr, BaseParam> page = matnrService.getMatnrPage(pageParam, params);
+ List<Matnr> records = page.getRecords();
+ if (records == null || records.isEmpty()) {
+ return page;
+ }
+ List<Long> matnrIds = records.stream().map(Matnr::getId).collect(Collectors.toList());
+ List<Map<String, Object>> stockByLocList = locItemMapper.listStockByMatnrIdsGroupByStatusAndLoc(matnrIds, locUseStatus);
+ Map<Long, List<Map<String, Object>>> rowsByMatnr = buildRowsByMatnrFromPerLoc(stockByLocList);
+ List<Matnr> expanded = new ArrayList<>();
+ for (Matnr record : records) {
+ List<Map<String, Object>> statusRows = rowsByMatnr.get(record.getId());
+ if (statusRows == null || statusRows.isEmpty()) {
+ record.setStockQty(0d);
+ record.setLocUseStatus$(null);
+ record.setLocCodes$(null);
+ expanded.add(record);
+ continue;
+ }
+ for (Map<String, Object> row : statusRows) {
+ double v = row.get("stockQty") instanceof Number ? ((Number) row.get("stockQty")).doubleValue() : 0d;
+ String useStatus = getStr(row, "useStatus", "usestatus");
+ String statusDesc = useStatus != null ? LocStsType.getDescByType(useStatus) : null;
+ String locCodesWithQty = getStr(row, "locCodes$", "loccodes$");
+ Matnr copy = cloneMatnrForRow(record);
+ copy.setStockQty(v);
+ copy.setLocUseStatus$(statusDesc);
+ copy.setLocCodes$(locCodesWithQty);
+ expanded.add(copy);
+ }
+ }
+ page.setRecords(expanded);
+ return page;
+ }
+
+ /** 澶嶅埗鐗╂枡鐢ㄤ簬鎸夌姸鎬佸睍寮�琛岋紙浠呭鍒跺睍绀虹敤瀛楁锛宨d 淇濇寔鍘熸牱渚涘墠绔�夎鐢級 */
+ private static Matnr cloneMatnrForRow(Matnr source) {
+ Matnr copy = new Matnr();
+ BeanUtils.copyProperties(source, copy, "stockQty", "locUseStatus$", "locCodes$");
+ return copy;
+ }
+
+ /**
+ * 浠呯敤銆屾寜搴撲綅鏄庣粏銆嶆煡璇㈢粨鏋滃湪鍐呭瓨涓垎缁勬眹鎬伙細鎸� (matnrId, useStatus) 鑱氬悎锛�
+ * 寰楀埌 stockQty銆乴ocCodes$锛堝簱浣�(鏁伴噺),...锛夛紝鍑忚交鏁版嵁搴撳帇鍔涖��
+ */
+ private static Map<Long, List<Map<String, Object>>> buildRowsByMatnrFromPerLoc(List<Map<String, Object>> stockByLocList) {
+ Map<String, List<Map<String, Object>>> perLocByMatnrAndStatus = new HashMap<>();
+ for (Map<String, Object> locRow : stockByLocList) {
+ Long mid = getLong(locRow, "matnrId", "matnrid");
+ String us = getStr(locRow, "useStatus", "usestatus");
+ if (mid == null || us == null) continue;
+ String key = mid + ":" + us;
+ perLocByMatnrAndStatus.computeIfAbsent(key, k -> new ArrayList<>()).add(locRow);
+ }
+ Map<Long, List<Map<String, Object>>> rowsByMatnr = new HashMap<>();
+ for (Map.Entry<String, List<Map<String, Object>>> e : perLocByMatnrAndStatus.entrySet()) {
+ String[] parts = e.getKey().split(":", 2);
+ if (parts.length != 2) continue;
+ Long matnrId;
+ try { matnrId = Long.parseLong(parts[0]); } catch (NumberFormatException ex) { continue; }
+ String useStatus = parts[1];
+ List<Map<String, Object>> locs = e.getValue();
+ double stockQty = 0d;
+ StringBuilder sb = new StringBuilder();
+ for (Map<String, Object> locRow : locs) {
+ Object q = getAny(locRow, "locQty", "locqty");
+ double qty = q instanceof Number ? ((Number) q).doubleValue() : 0d;
+ stockQty += qty;
+ String code = getStr(locRow, "locCode", "loccode");
+ if (sb.length() > 0) sb.append(",");
+ sb.append(code != null ? code : "").append("(").append(formatQtyForLoc(qty)).append(")");
+ }
+ Map<String, Object> statusRow = new HashMap<>();
+ statusRow.put("matnrId", matnrId);
+ statusRow.put("useStatus", useStatus);
+ statusRow.put("stockQty", stockQty);
+ statusRow.put("locCodes$", sb.toString());
+ rowsByMatnr.computeIfAbsent(matnrId, k -> new ArrayList<>()).add(statusRow);
+ }
+ return rowsByMatnr;
+ }
+
+ private static String formatQtyForLoc(double qty) {
+ if (qty == (long) qty) return String.valueOf((long) qty);
+ String s = BigDecimal.valueOf(qty).setScale(6, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString();
+ return s;
+ }
+
+ private static Long getLong(Map<String, Object> map, String... keys) {
+ Object v = getAny(map, keys);
+ if (v == null) return null;
+ if (v instanceof Long) return (Long) v;
+ if (v instanceof Number) return ((Number) v).longValue();
+ try { return Long.parseLong(v.toString()); } catch (NumberFormatException e) { return null; }
+ }
+
+ private static String getStr(Map<String, Object> map, String... keys) {
+ Object v = getAny(map, keys);
+ return v != null ? v.toString() : null;
+ }
+
+ private static Object getAny(Map<String, Object> map, String... keys) {
+ for (String key : keys) {
+ Object v = map.get(key);
+ if (v != null) return v;
+ }
+ return null;
+ }
/**
* @param
@@ -680,11 +800,13 @@
locItems.add(locItem);
LocToTaskParams taskParams = new LocToTaskParams();
+ // 鍑哄簱鍗曚笅鍙戜换鍔℃椂锛屽嚭搴撳彛鏈紶鍒欓粯璁� 1001
+ String siteNo = StringUtils.isNotBlank(param.getSiteNo()) ? param.getSiteNo() : "1001";
taskParams.setType(Constants.TASK_TYPE_ORDER_OUT_STOCK)
.setOrgLoc(loc.getCode())
.setItems(locItems)
.setSourceId(outId)
- .setSiteNo(param.getSiteNo());
+ .setSiteNo(siteNo);
try {
//鐢熸垚鍑哄簱浠诲姟
locItemService.generateTask(TaskResouceType.TASK_RESOUCE_ORDER_TYPE.val, taskParams, loginUserId);
@@ -824,6 +946,14 @@
.eq(DeviceSite::getChannel, loc.getChannel())
.eq(DeviceSite::getType, issued.doubleValue() >= locItem.getAnfme() && itemList.size() == 1 ? TaskType.TASK_TYPE_OUT.type : TaskType.TASK_TYPE_PICK_AGAIN_OUT.type)
);
+ // 鍑哄簱鍙e垪琛ㄦ帓搴忥細1001 鎺掔涓�锛屼綔涓洪粯璁�
+ deviceSites.sort((a, b) -> {
+ boolean a1001 = "1001".equals(a.getSite());
+ boolean b1001 = "1001".equals(b.getSite());
+ if (a1001 && !b1001) return -1;
+ if (!a1001 && b1001) return 1;
+ return 0;
+ });
if (!deviceSites.isEmpty()) {
List<OrderOutItemDto.staListDto> maps = new ArrayList<>();
@@ -836,7 +966,7 @@
orderOutItemDto.setStaNos(maps);
//榛樿鑾峰彇绗竴绔欑偣
DeviceSite deviceSite = deviceSites.stream().findFirst().get();
- orderOutItemDto.setSiteNo(deviceSite.getSite());
+ orderOutItemDto.setSitesNo(deviceSite.getSite());
}
list.add(orderOutItemDto);
--
Gitblit v1.9.1