package com.vincent.rsf.server.manager.service.impl; 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.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.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.OptimalAlgorithmUtil; import org.apache.commons.lang3.StringUtils; 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.stream.Collectors; @Service("waveService") public class WaveServiceImpl extends ServiceImpl implements WaveService { @Autowired private AsnOrderItemService asnOrderItemService; @Autowired private AsnOrderService asnOrderService; @Autowired private WaveItemService waveItemService; @Autowired private TaskService taskService; @Autowired private TaskItemService taskItemService; @Autowired private LocItemService locItemService; /** * @param * @return * @author Ryan * @description 波次任务下发 * @time 2025/4/25 16:24 */ @Override @Transactional(rollbackFor = Exception.class) public R publicTask(Map map) { List ids = (List) map.get("ids"); if (Objects.isNull(ids) || ids.isEmpty()) { throw new CoolException("参数不能为空!!"); } List waves = this.list(new LambdaQueryWrapper().in(Wave::getId, ids)); if (Objects.isNull(waves) || waves.isEmpty()) { throw new CoolException("波次数据不存在!!"); } List list = waves.stream().map(Wave::getId).collect(Collectors.toList()); List waveItems = waveItemService.list(new LambdaQueryWrapper().in(WaveItem::getWaveId, list)); if (waveItems.isEmpty()) { throw new CoolException("波次明细不存在!!"); } List orderIds = waveItems.stream().map(WaveItem::getOrderId).collect(Collectors.toList()); /**查询每条明细匹配的库位*/ try { List items = getLocs(waveItems); } catch (Exception e) { throw new CoolException("库位获取失败!!!"); } //TODO 1. 根据波次明细生成出库任务 // 2. 根据物料SKU寻找符合物料库位 {1. 根据物料编码,批次,动态字段 查询符合的库位,再根据库位中物料的数量选择最适合的库位 2. 判断当前订单是全拖出库还是拣料入库} // 3. 修改主单、波次执行数量 // 4. 判断全仓出库或拣料出库 List orders = asnOrderService.list(new LambdaQueryWrapper().in(AsnOrder::getId, orderIds)); /**修改原出库单状态*/ if (!asnOrderService.update(new LambdaQueryWrapper() .eq(AsnOrder::getExceStatus, AsnExceStatus.OUT_STOCK_STATUS_TASK_WORKING.val) .in(AsnOrder::getId, orders))) { throw new CoolException("出库单据状态修改失败!!"); } if (!this.update(new LambdaUpdateWrapper().set(Wave::getExceStatus, WaveExceStatus.WAVE_EXCE_STATUS_TASK).in(Wave::getId, ids))) { throw new CoolException("波次状态修改失败!!"); } return R.ok(); } /** * @param * @return * @author Ryan * @description 预览波次下发任务 * @time 2025/4/27 11:09 */ @Override @Transactional(rollbackFor = Exception.class) public List mergeWavePreview(Long waveId) { Wave wave = this.getById(waveId); if (Objects.isNull(wave)) { throw new CoolException("波次不能存在!!"); } List waveItems = waveItemService.list(new LambdaQueryWrapper().eq(WaveItem::getWaveId, waveId)); if (waveItems.isEmpty()) { throw new CoolException("波次明细不存在!!"); } List itemPreview = null; try { itemPreview = getLocs(waveItems); } catch (Exception e) { throw new CoolException("库位获取失败!!!!"); } return itemPreview; } /** * @param * @param waveItems * @return * @author Ryan * @description 根据物料编码,批次,动态字段 查询符合的库位,再根据库位中物料的数量选择最适合的库位 * @time 2025/4/27 09:26 */ private synchronized List getLocs(List waveItems) throws Exception { //TODO 根据物料编码,批次,动态字段 查询符合的库位,再根据库位中物料的数量选择最适合的库位 waveItems.forEach(waveItem -> { List locItems = locItemService.list(new QueryWrapper() .select("id", "loc_id", "loc_code", "order_id", "SUM(anfme) anfme", "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)); Double[] doubles = locItems.stream().map(LocItem::getAnfme).toArray(Double[]::new); List result = OptimalAlgorithmUtil.findBestCombination(doubles, waveItem.getAnfme()); String locs = JSONArray.toJSONString(new ArrayList<>()); if (!locItems.isEmpty()) { List codes = locItems.stream().map(LocItem::getLocCode).collect(Collectors.toList()); locs = JSONArray.toJSONString(codes); } waveItem.setStockLocs(locs); }); return waveItems; } }