From f2833c7f3e01c997e94a66bd5dd9be738b5c6cc7 Mon Sep 17 00:00:00 2001 From: skyouc Date: 星期四, 26 六月 2025 13:31:08 +0800 Subject: [PATCH] 波次任务下发功能优化 --- rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaveServiceImpl.java | 244 +++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 205 insertions(+), 39 deletions(-) diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaveServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaveServiceImpl.java index 96355b3..96dcb4b 100644 --- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaveServiceImpl.java +++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaveServiceImpl.java @@ -1,21 +1,28 @@ package com.vincent.rsf.server.manager.service.impl; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.vincent.rsf.framework.common.Cools; import com.vincent.rsf.framework.common.R; import com.vincent.rsf.framework.exception.CoolException; -import com.vincent.rsf.server.manager.entity.AsnOrder; -import com.vincent.rsf.server.manager.entity.LocItem; -import com.vincent.rsf.server.manager.entity.WaveItem; -import com.vincent.rsf.server.manager.enums.AsnExceStatus; -import com.vincent.rsf.server.manager.enums.WaveExceStatus; +import com.vincent.rsf.server.common.constant.Constants; +import com.vincent.rsf.server.manager.controller.dto.OrderOutItemDto; +import com.vincent.rsf.server.manager.controller.params.LocToTaskParams; +import com.vincent.rsf.server.manager.controller.params.WaveToLocParams; +import com.vincent.rsf.server.manager.enums.*; +import com.vincent.rsf.server.manager.entity.*; import com.vincent.rsf.server.manager.mapper.WaveMapper; -import com.vincent.rsf.server.manager.entity.Wave; import com.vincent.rsf.server.manager.service.*; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.vincent.rsf.server.manager.utils.LocManageUtil; import com.vincent.rsf.server.manager.utils.OptimalAlgorithmUtil; +import com.vincent.rsf.server.system.constant.SerialRuleCode; +import com.vincent.rsf.server.system.utils.SerialRuleUtils; +import lombok.Synchronized; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -24,8 +31,8 @@ import java.util.*; import java.util.stream.Collectors; -import java.util.stream.IntStream; +@Slf4j @Service("waveService") public class WaveServiceImpl extends ServiceImpl<WaveMapper, Wave> implements WaveService { @@ -41,9 +48,18 @@ private TaskItemService taskItemService; @Autowired private LocItemService locItemService; + @Autowired + private LocService locService; + @Autowired + private OutStockService outStockService; + @Autowired + private WaveService waveService; + @Autowired + private WaveRuleServiceImpl waveRuleService; /** * @param + * @param loginUserId * @return * @author Ryan * @description 娉㈡浠诲姟涓嬪彂 @@ -51,43 +67,176 @@ */ @Override @Transactional(rollbackFor = Exception.class) - public R publicTask(Map<String, Object> map) { - List<WaveItem> itemParams = (List<WaveItem>) map.get("wave"); + public R publicTask(Map<String, Object> map, Long loginUserId) { + List<WaveItem> itemParams = JSONArray.parseArray(JSON.toJSONString(map.get("waveItem")), WaveItem.class); if (Objects.isNull(itemParams) || itemParams.isEmpty()) { throw new CoolException("鍙傛暟涓嶈兘涓虹┖锛侊紒"); } - List<Long> ids = itemParams.stream().map(WaveItem::getWaveId).collect(Collectors.toList()); - List<Wave> waves = this.list(new LambdaQueryWrapper<Wave>().in(Wave::getId, ids)); - if (Objects.isNull(waves) || waves.isEmpty()) { + String waveId = map.get("wave").toString(); + Wave waves = this.getById(Long.parseLong(waveId)); + if (Objects.isNull(waves)) { throw new CoolException("娉㈡鏁版嵁涓嶅瓨鍦紒锛�"); } - List<Long> list = waves.stream().map(Wave::getId).collect(Collectors.toList()); - List<WaveItem> waveItems = waveItemService.list(new LambdaQueryWrapper<WaveItem>().in(WaveItem::getWaveId, list)); + List<WaveItem> waveItems = waveItemService.list(new LambdaQueryWrapper<WaveItem>() + .eq(WaveItem::getWaveId, waves.getId()) + .apply("anfme > work_qty")); if (waveItems.isEmpty()) { throw new CoolException("娉㈡鏄庣粏涓嶅瓨鍦紒锛�"); } - List<Long> orderIds = waveItems.stream().map(WaveItem::getOrderId).collect(Collectors.toList()); - /**鏌ヨ姣忔潯鏄庣粏鍖归厤鐨勫簱浣�*/ + /**鐢熸垚鍑哄簱浠诲姟*/ try { -// List<WaveItem> items = getLocs(waveItems); + List<WaveToLocParams> params = new ArrayList<>(); + for (WaveItem item : waveItems) { + WaveToLocParams locParams = new WaveToLocParams(); + BeanUtils.copyProperties(item, locParams); + locParams.setBatch(item.getSplrBatch()) + .setItemId(item.getId()) + .setWaveId(item.getWaveId()); + params.add(locParams); + } + List<OrderOutItemDto> results = LocManageUtil.getOutOrderList(params, null); + generateOutTask(results, loginUserId, waves); } catch (Exception e) { - throw new CoolException("搴撲綅鑾峰彇澶辫触锛侊紒锛�"); + log.error(e.getMessage()); + throw new CoolException("鍑哄簱浠诲姟鐢熸垚澶辫触锛侊紒锛�"); } - //TODO 1. 鏍规嵁娉㈡鏄庣粏鐢熸垚鍑哄簱浠诲姟 - // 2. 鏍规嵁鐗╂枡SKU瀵绘壘绗﹀悎鐗╂枡搴撲綅 {1. 鏍规嵁鐗╂枡缂栫爜锛屾壒娆★紝鍔ㄦ�佸瓧娈� 鏌ヨ绗﹀悎鐨勫簱浣嶏紝鍐嶆牴鎹簱浣嶄腑鐗╂枡鐨勬暟閲忛�夋嫨鏈�閫傚悎鐨勫簱浣� 2. 鍒ゆ柇褰撳墠璁㈠崟鏄叏鎷栧嚭搴撹繕鏄嫞鏂欏叆搴搣 - // 3. 淇敼涓诲崟銆佹尝娆℃墽琛屾暟閲� - // 4. 鍒ゆ柇鍏ㄤ粨鍑哄簱鎴栨嫞鏂欏嚭搴� -// List<AsnOrder> orders = asnOrderService.list(new LambdaQueryWrapper<AsnOrder>().in(AsnOrder::getId, orderIds)); -// /**淇敼鍘熷嚭搴撳崟鐘舵��*/ -// if (!asnOrderService.update(new LambdaQueryWrapper<AsnOrder>() -// .eq(AsnOrder::getExceStatus, AsnExceStatus.OUT_STOCK_STATUS_TASK_WORKING.val) -// .in(AsnOrder::getId, orders))) { -// throw new CoolException("鍑哄簱鍗曟嵁鐘舵�佷慨鏀瑰け璐ワ紒锛�"); -// } -// if (!this.update(new LambdaUpdateWrapper<Wave>().set(Wave::getExceStatus, WaveExceStatus.WAVE_EXCE_STATUS_TASK).in(Wave::getId, ids))) { -// throw new CoolException("娉㈡鐘舵�佷慨鏀瑰け璐ワ紒锛�"); -// } + List<Long> orderIds = waveItems.stream().map(WaveItem::getOrderId).collect(Collectors.toList()); + /**淇敼鍑哄簱鍗曠姸鎬�*/ + if (!asnOrderService.update(new LambdaUpdateWrapper<AsnOrder>() + .set(AsnOrder::getExceStatus, AsnExceStatus.OUT_STOCK_STATUS_TASK_WORKING.val) + .in(AsnOrder::getId, orderIds))) { + throw new CoolException("鍑哄簱鍗曟嵁鐘舵�佷慨鏀瑰け璐ワ紒锛�"); + } return R.ok(); + } + + + /** + * 閫夋嫨娉㈡鏄庣粏涓嬪彂浠诲姟 + * + * @param map + * @param loginUserId + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public R waveToTask(Map<String, Object> map, Long loginUserId) { + if (Objects.isNull(map.get("waveItem"))) { + throw new CoolException("鍙傛暟涓嶈兘涓虹┖锛侊紒"); + } + String waveId = map.get("wave").toString(); + Wave waves = this.getById(Long.parseLong(waveId)); + if (Objects.isNull(waves)) { + throw new CoolException("娉㈡鏁版嵁涓嶅瓨鍦紒锛�"); + } + List<Long> waveItems = JSONArray.parseArray(JSON.toJSONString(map.get("waveItem")), Long.class); + if (waveItems.isEmpty()) { + throw new CoolException("娉㈡鏄庣粏涓嶈兘涓虹┖锛侊紒"); + } + List<WaveItem> items = waveItemService.listByIds(waveItems); + if (items.isEmpty()) { + throw new CoolException("娉㈡鏄庣粏涓嶅瓨鍦紒锛�"); + } + + if (!waveItemService.update(new LambdaUpdateWrapper<WaveItem>() + .set(WaveItem::getExceStatus, WaveItemExceStatus.WAVE_EXCE_STATUS_ING.val) + .in(WaveItem::getId, waveItems))) { + throw new CoolException("鎵ц鐘舵�佷慨鏀瑰け璐ワ紒锛�"); + } + + WaveRule waveRule = waveRuleService.getOne(new LambdaQueryWrapper<WaveRule>() + .eq(WaveRule::getType, WaveRuleType.First_In_First_Out.type)); + if (Cools.isEmpty(waveRule)) { + throw new CoolException("鏈壘鍒板綋鍓嶇瓥鐣�"); + } + + List<WaveToLocParams> params = new ArrayList<>(); + for (WaveItem item : items) { + WaveToLocParams locParams = new WaveToLocParams(); + BeanUtils.copyProperties(item, locParams); + locParams.setBatch(item.getSplrBatch()) + .setItemId(item.getId()) + .setWaveId(item.getWaveId()); + params.add(locParams); + } + List<OrderOutItemDto> results = LocManageUtil.getOutOrderList(params, waveRule); + if (results.isEmpty()) { + waveService.update(new LambdaUpdateWrapper<Wave>() + .set(Wave::getExceStatus, WaveExceStatus.WAVE_EXCE_STATUS_EXCING.val) + .set(Wave::getUpdateBy, loginUserId) + .set(Wave::getUpdateTime, new Date()) + .eq(Wave::getId, waveId)); + return R.ok(); + } + /**鐢熸垚鍑哄簱浠诲姟*/ + try { + generateOutTask(results, loginUserId, waves); + } catch (Exception e) { + log.error("UNK", e); + throw new CoolException(e.getMessage()); + } + + List<TaskItem> taskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>() + .in(TaskItem::getSource, waveItems)); + if (Cools.isEmpty(taskItems)) { + throw new CoolException("鏆傛棤鍚堥�傚簱瀛樹俊鎭紒锛�"); + } + for (TaskItem item : taskItems) { + WaveItem waveItem = waveItemService.getById(item.getSource()); + + Double workQty = Math.round((waveItem.getWorkQty() + item.getAnfme()) * 10000) / 10000.0; + waveItem.setWorkQty(workQty); + if (workQty.compareTo(waveItem.getAnfme()) < 0) { + waveItem.setExceStatus(WaveItemExceStatus.WAVE_EXCE_STATUS_ING.val); + } else { + waveItem.setExceStatus(WaveItemExceStatus.WAVE_EXCE_STATUS_PUBD.val); + } + + if (!waveItemService.update(new LambdaUpdateWrapper<WaveItem>() + .set(WaveItem::getExceStatus, WaveItemExceStatus.WAVE_EXCE_STATUS_PUBD.val) + .setSql("work_qty = work_qty + " + item.getAnfme()) + .set(WaveItem::getUpdateBy, loginUserId) + .set(WaveItem::getUpdateTime, new Date()) + .eq(WaveItem::getId, item.getSource()))) { + throw new CoolException("涓嬪彂鎵ц寮傚父锛岃绋嶅�欓噸璇曪紒"); + } + } + if (!waveService.update(new LambdaUpdateWrapper<Wave>() + .set(Wave::getExceStatus, WaveExceStatus.WAVE_EXCE_STATUS_TASK.val) + .set(Wave::getWorkQty, taskItems.stream().mapToDouble(TaskItem::getAnfme).sum()) + .set(Wave::getUpdateBy, loginUserId) + .set(Wave::getUpdateTime, new Date()) + .eq(Wave::getId, waveId))) { + throw new CoolException("娉㈡鐘舵�佷慨鏀瑰け璐ワ紒锛�"); + } + return R.ok(); + } + + /** + * @param + * @param loginUserId + * @param wave + * @return + * @author Ryan + * @description 鐢熸垚鍑哄簱浠诲姟 + * @time 2025/4/28 14:01 + */ + @Synchronized + @Transactional(rollbackFor = Exception.class) + public void generateOutTask(List<OrderOutItemDto> itemParams, Long loginUserId, Wave wave) throws Exception { + for (OrderOutItemDto itemDto : itemParams) { + LocToTaskParams taskParams = new LocToTaskParams(); + Loc loc = locService.getById(itemDto.getLocId()); + if (Objects.isNull(loc)) { + continue; + } + taskParams.setItems(Arrays.asList(itemDto.getLocItem())) + .setSiteNo(itemDto.getSiteNo()) + .setType(Constants.TASK_TYPE_WAVE_OUT_STOCK) + .setSourceId(wave.getId()) + .setTarLoc(loc.getCode()); + locItemService.generateTask(TaskResouceType.TASK_RESOUCE_WAVE_TYPE.val, taskParams, loginUserId); + } } /** @@ -119,17 +268,32 @@ /** * @param + * @return + * @author Ryan + * @description 鍙栨秷娉㈡ + * @time 2025/6/17 10:04 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public R cancelWave(List<Long> ids) { + + return null; + } + + /** + * @param * @param waveItems * @return * @author Ryan * @description 鏍规嵁鐗╂枡缂栫爜锛屾壒娆★紝鍔ㄦ�佸瓧娈� 鏌ヨ绗﹀悎鐨勫簱浣嶏紝鍐嶆牴鎹簱浣嶄腑鐗╂枡鐨勬暟閲忛�夋嫨鏈�閫傚悎鐨勫簱浣� * @time 2025/4/27 09:26 */ - private synchronized List<WaveItem> getLocs(List<WaveItem> waveItems) throws Exception { + @Synchronized + private List<WaveItem> getLocs(List<WaveItem> waveItems) throws Exception { //TODO 鏍规嵁鐗╂枡缂栫爜锛屾壒娆★紝鍔ㄦ�佸瓧娈� 鏌ヨ绗﹀悎鐨勫簱浣嶏紝鍐嶆牴鎹簱浣嶄腑鐗╂枡鐨勬暟閲忛�夋嫨鏈�閫傚悎鐨勫簱浣� waveItems.forEach(waveItem -> { List<LocItem> locItems = locItemService.list(new QueryWrapper<LocItem>() - .select("id", "loc_id", "loc_code", "order_id", "SUM(anfme) anfme", "SUM(work_qty) work_qty", "splr_batch", "fields_index", "matnr_code") + .select("id", "loc_id", "loc_code", "order_id", "SUM(anfme) anfme", "SUM(qty) qty", "SUM(work_qty) work_qty", "splr_batch", "fields_index", "matnr_code") .lambda() .eq(LocItem::getMatnrCode, waveItem.getMatnrCode()) .eq(LocItem::getSplrBatch, waveItem.getSplrBatch()) @@ -140,19 +304,21 @@ /**浣跨敤鍥炴函绠楁硶璁$畻锛岃幏鍙栫鍚堝嚭搴撻噺鐨勬渶绠�缁勫悎*/ List<Integer> result = OptimalAlgorithmUtil.findCombination(doubles, waveItem.getAnfme()); + String locs = "[]"; - if (Objects.isNull(result)) { + if (Objects.isNull(result) || result.isEmpty()) { waveItem.setStockLocs(locs).setStockQty(0.0); } else { /**杩囨护闆嗗悎涓渶绠�鐭殑缁勫悎*/ List<LocItem> locsInfo = result.stream() .filter(i -> i >= 0 && i < locItems.size()) .map(locItems::get).collect(Collectors.toList()); + locs = JSONArray.toJSONString(locsInfo); - double sumQty = locItems.stream().mapToDouble(LocItem::getAnfme).sum(); - double surQty = locItems.stream().mapToDouble(LocItem::getWorkQty).sum(); - double qty = locItems.stream().mapToDouble(LocItem::getQty).sum(); - double v = sumQty - surQty - qty; + Double sumQty = locsInfo.stream().mapToDouble(LocItem::getAnfme).sum(); + Double surQty = locsInfo.stream().mapToDouble(LocItem::getWorkQty).sum(); + Double qty = locsInfo.stream().mapToDouble(LocItem::getQty).sum(); + Double v = sumQty - surQty - qty; waveItem.setStockLocs(locs).setStockQty(v); } }); -- Gitblit v1.9.1