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 | 258 +++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 217 insertions(+), 41 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 111ac2f..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,32 +1,38 @@ 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; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Objects; +import java.util.*; import java.util.stream.Collectors; +@Slf4j @Service("waveService") public class WaveServiceImpl extends ServiceImpl<WaveMapper, Wave> implements WaveService { @@ -42,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 娉㈡浠诲姟涓嬪彂 @@ -52,43 +67,176 @@ */ @Override @Transactional(rollbackFor = Exception.class) - public R publicTask(Map<String, Object> map) { - List<Long> ids = (List<Long>) map.get("ids"); - if (Objects.isNull(ids) || ids.isEmpty()) { + 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<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))) { + 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("鍑哄簱鍗曟嵁鐘舵�佷慨鏀瑰け璐ワ紒锛�"); } - if (!this.update(new LambdaUpdateWrapper<Wave>().set(Wave::getExceStatus, WaveExceStatus.WAVE_EXCE_STATUS_TASK).in(Wave::getId, ids))) { + 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); + } } /** @@ -120,31 +268,59 @@ /** * @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()) .eq(StringUtils.isNotBlank(waveItem.getFieldsIndex()), LocItem::getFieldsIndex, waveItem.getFieldsIndex()) .groupBy(LocItem::getMatnrCode, LocItem::getSplrBatch, LocItem::getFieldsIndex, LocItem::getId)); + List<Double> doubles1 = locItems.stream().map(LocItem::getAnfme).collect(Collectors.toList()); + double[] doubles = doubles1.stream().mapToDouble(Double::doubleValue).toArray(); - Double[] doubles = locItems.stream().map(LocItem::getAnfme).toArray(Double[]::new); - List<Double> result = OptimalAlgorithmUtil.findBestCombination(doubles, waveItem.getAnfme()); - String locs = JSONArray.toJSONString(new ArrayList<>()); - if (!locItems.isEmpty()) { - List<String> codes = locItems.stream().map(LocItem::getLocCode).collect(Collectors.toList()); - locs = JSONArray.toJSONString(codes); + /**浣跨敤鍥炴函绠楁硶璁$畻锛岃幏鍙栫鍚堝嚭搴撻噺鐨勬渶绠�缁勫悎*/ + List<Integer> result = OptimalAlgorithmUtil.findCombination(doubles, waveItem.getAnfme()); + + String locs = "[]"; + 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 = 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); } - waveItem.setStockLocs(locs); }); return waveItems; } -- Gitblit v1.9.1