| | |
| | | import com.vincent.rsf.server.manager.entity.*; |
| | | import com.vincent.rsf.server.manager.mapper.AsnOrderMapper; |
| | | import com.vincent.rsf.server.manager.service.*; |
| | | 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; |
| | |
| | | * @time 2025/3/7 08:02 |
| | | */ |
| | | @Service("outStockServiceImpl") |
| | | public class OutStockServiceImpl extends ServiceImpl<AsnOrderMapper, AsnOrder> implements OutStockService { |
| | | public class OutStockServiceImpl extends ServiceImpl<AsnOrderMapper, WkOrder> implements OutStockService { |
| | | |
| | | public Logger logger = LoggerFactory.getLogger(this.getClass()); |
| | | |
| | |
| | | private DeviceSiteService deviceSiteService; |
| | | @Autowired |
| | | private LocService locService; |
| | | @Autowired |
| | | private WaveOrderRelaServiceImpl waveOrderRelaService; |
| | | |
| | | |
| | | /** |
| | |
| | | */ |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void svaeOrUpdateOrderItem(AsnOrderAndItemsParams params, Long loginUserId) throws Exception { |
| | | AsnOrder orders = params.getOrders(); |
| | | WkOrder orders = params.getOrders(); |
| | | params.getItems().forEach(item -> { |
| | | item.put("asnId", orders.getId()); |
| | | item.put("asnCode", orders.getCode()); |
| | |
| | | throw new CoolException("明细保存失败!!"); |
| | | } |
| | | }); |
| | | List<AsnOrderItem> orderItems = asnOrderItemService.list(new LambdaQueryWrapper<AsnOrderItem>() |
| | | .eq(AsnOrderItem::getAsnId, params.getOrders().getId())); |
| | | Double sum = orderItems.stream().mapToDouble(AsnOrderItem::getAnfme).sum(); |
| | | List<WkOrderItem> orderItems = asnOrderItemService.list(new LambdaQueryWrapper<WkOrderItem>() |
| | | .eq(WkOrderItem::getAsnId, params.getOrders().getId())); |
| | | Double sum = orderItems.stream().mapToDouble(WkOrderItem::getAnfme).sum(); |
| | | orders.setAnfme(sum); |
| | | if (!this.updateById(orders)) { |
| | | throw new CoolException("计划收货数量修改失败!!"); |
| | |
| | | if (Cools.isEmpty(id)) { |
| | | throw new CoolException("参数不能为空!!"); |
| | | } |
| | | AsnOrder order = this.getById(id); |
| | | WkOrder order = this.getById(id); |
| | | if (Objects.isNull(order)) { |
| | | throw new CoolException("单据不存在!!"); |
| | | } |
| | |
| | | throw new CoolException("当前单据状态为" + AsnExceStatus.getExceStatus(order.getExceStatus()) + ", 不可执行取消操作!!"); |
| | | } |
| | | |
| | | List<AsnOrderItem> orderItems = outStockItemService.list(new LambdaQueryWrapper<AsnOrderItem>().eq(AsnOrderItem::getAsnId, id)); |
| | | List<WkOrderItem> orderItems = outStockItemService.list(new LambdaQueryWrapper<WkOrderItem>().eq(WkOrderItem::getAsnId, id)); |
| | | if (!orderItems.isEmpty()) { |
| | | for (AsnOrderItem orderItem : orderItems) { |
| | | for (WkOrderItem orderItem : orderItems) { |
| | | if (!Objects.isNull(orderItem.getPoDetlId())) { |
| | | DeliveryItem deliveryItem = deliveryItemService.getById(orderItem.getPoDetlId()); |
| | | Double workQty = Math.round((deliveryItem.getWorkQty() - orderItem.getAnfme()) * 10000) / 10000.0; |
| | |
| | | } |
| | | } |
| | | |
| | | if (!this.remove(new LambdaQueryWrapper<AsnOrder>().eq(AsnOrder::getId, id))) { |
| | | if (!this.remove(new LambdaQueryWrapper<WkOrder>().eq(WkOrder::getId, id))) { |
| | | throw new CoolException("主单删除失败!!"); |
| | | } |
| | | if (!outStockItemService.remove(new LambdaQueryWrapper<AsnOrderItem>().eq(AsnOrderItem::getAsnId, id))) { |
| | | if (!outStockItemService.remove(new LambdaQueryWrapper<WkOrderItem>().eq(WkOrderItem::getAsnId, id))) { |
| | | throw new CoolException("单据明细删除失败!!"); |
| | | } |
| | | return R.ok("操作成功"); |
| | |
| | | if (Objects.isNull(delivery)) { |
| | | throw new CoolException("单据不存在!!"); |
| | | } |
| | | AsnOrder order = new AsnOrder(); |
| | | WkOrder order = new WkOrder(); |
| | | BeanUtils.copyProperties(delivery, order); |
| | | String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_OUT_STOCK_CODE, order); |
| | | if (StringUtils.isBlank(ruleCode)) { |
| | |
| | | .setId(null) |
| | | .setUpdateBy(loginUserId) |
| | | .setCreateBy(loginUserId) |
| | | .setCreateTime(new Date()) |
| | | .setUpdateTime(new Date()) |
| | | .setPoCode(delivery.getCode()); |
| | | if (!this.save(order)) { |
| | | throw new CoolException("主单保存失败!!"); |
| | | } |
| | | List<AsnOrderItem> orderItems = new ArrayList<>(); |
| | | List<WkOrderItem> orderItems = new ArrayList<>(); |
| | | listMap.get(key).forEach(item -> { |
| | | DeliveryItem deliveryItem = deliveryItemService.getById(item.getId()); |
| | | AsnOrderItem orderItem = new AsnOrderItem(); |
| | | WkOrderItem orderItem = new WkOrderItem(); |
| | | if (item.getAnfme().compareTo(0.0) <= 0) { |
| | | throw new CoolException("出库数量不能小于或等于零!!"); |
| | | } |
| | |
| | | } |
| | | }); |
| | | |
| | | Double sum = orderItems.stream().mapToDouble(AsnOrderItem::getAnfme).sum(); |
| | | Double sum = orderItems.stream().mapToDouble(WkOrderItem::getAnfme).sum(); |
| | | //修改计划数量 |
| | | order.setAnfme(sum).setWorkQty(0.0); |
| | | if (!this.saveOrUpdate(order)) { |
| | |
| | | if (Objects.isNull(params.getIds()) || params.getIds().isEmpty()) { |
| | | throw new CoolException("参数不能为空!!"); |
| | | } |
| | | List<AsnOrder> orders = this.list(new LambdaQueryWrapper<AsnOrder>().in(AsnOrder::getId, params.getIds())); |
| | | List<WkOrder> orders = this.list(new LambdaQueryWrapper<WkOrder>() |
| | | .eq(WkOrder::getExceStatus, AsnExceStatus.OUT_STOCK_STATUS_TASK_INIT.val) |
| | | .in(WkOrder::getId, params.getIds())); |
| | | if (orders.isEmpty()) { |
| | | throw new CoolException("当前单据状态不能执行波次生成操作!!"); |
| | | } |
| | | Double sum = orders.stream().mapToDouble(AsnOrder::getAnfme).sum(); |
| | | Double workQty = orders.stream().mapToDouble(AsnOrder::getWorkQty).sum(); |
| | | Double sum = orders.stream().mapToDouble(WkOrder::getAnfme).sum(); |
| | | Double workQty = orders.stream().mapToDouble(WkOrder::getWorkQty).sum(); |
| | | Double anfme = Math.round((sum - workQty) * 10000) / 10000.0; |
| | | Wave wave = new Wave(); |
| | | String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_WAVE_TYPE, null); |
| | |
| | | throw new CoolException("波次保存失败!!"); |
| | | } |
| | | |
| | | List<Long> list = orders.stream().map(AsnOrder::getId).collect(Collectors.toList()); |
| | | List<AsnOrderItem> orderItems = asnOrderItemService |
| | | .list(new LambdaQueryWrapper<AsnOrderItem>() |
| | | .in(AsnOrderItem::getAsnId, list).apply("anfme > work_qty")); |
| | | List<Long> list = orders.stream().map(WkOrder::getId).collect(Collectors.toList()); |
| | | List<WkOrderItem> orderItems = asnOrderItemService |
| | | .list(new LambdaQueryWrapper<WkOrderItem>() |
| | | .in(WkOrderItem::getAsnId, list).apply("anfme > work_qty")); |
| | | if (orderItems.isEmpty()) { |
| | | throw new CoolException("单据不存在!!"); |
| | | } |
| | | |
| | | //合并物料,生成波次明细 |
| | | List<WaveItem> waveItems = mergeWave(orderItems, wave); |
| | | |
| | | if (!waveItemService.saveBatch(waveItems)) { |
| | | throw new CoolException("波次明细保存失败!!"); |
| | | } |
| | |
| | | for (int i = 0; i < orderItems.size(); i++) { |
| | | orderItems.get(i).setWorkQty(orderItems.get(i).getAnfme()); |
| | | } |
| | | |
| | | /** |
| | | *订单信息存储至逻辑关联表 |
| | | */ |
| | | for (WaveItem item : waveItems) { |
| | | List<WkOrderItem> items = orderItems.stream() |
| | | .filter(orderItem -> item.getMatnrId() |
| | | .equals(orderItem.getMatnrId())) |
| | | .collect(Collectors.toList()); |
| | | |
| | | items.forEach(orderItem -> { |
| | | WaveOrderRela orderRela = new WaveOrderRela(); |
| | | orderRela.setId(null) |
| | | .setOrderId(orderItem.getAsnId()) |
| | | .setOrderItemId(orderItem.getId()) |
| | | .setWaveId(wave.getId()) |
| | | .setWaveItemId(item.getId()); |
| | | if (!waveOrderRelaService.saveOrUpdate(orderRela)) { |
| | | throw new CoolException("<UNK>"); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | |
| | | if (!asnOrderItemService.saveOrUpdateBatch(orderItems)) { |
| | | throw new CoolException("出库单执行数量修改失败!!"); |
| | | } |
| | | for (AsnOrder order : orders) { |
| | | for (WkOrder order : orders) { |
| | | Double wkQty = Math.round((order.getWorkQty() + order.getAnfme()) * 10000) / 10000.0; |
| | | if (!this.update(new LambdaUpdateWrapper<AsnOrder>() |
| | | .set(AsnOrder::getWaveId, wave.getId()) |
| | | .set(AsnOrder::getWorkQty, wkQty) |
| | | .set(AsnOrder::getExceStatus, AsnExceStatus.OUT_STOCK_STATUS_TASK_WAVE.val) |
| | | .eq(AsnOrder::getId, order.getId()))) { |
| | | if (!this.update(new LambdaUpdateWrapper<WkOrder>() |
| | | .set(WkOrder::getWaveId, wave.getId()) |
| | | .set(WkOrder::getWorkQty, wkQty) |
| | | .set(WkOrder::getExceStatus, AsnExceStatus.OUT_STOCK_STATUS_TASK_WAVE.val) |
| | | .eq(WkOrder::getId, order.getId()))) { |
| | | throw new CoolException("执行状态修改修改失败!!"); |
| | | } |
| | | } |
| | |
| | | if (Objects.isNull(params.getOrders())) { |
| | | throw new CoolException("主单信息不能为空"); |
| | | } |
| | | AsnOrder orders = params.getOrders(); |
| | | WkOrder orders = params.getOrders(); |
| | | if (StringUtils.isBlank(orders.getWkType())) { |
| | | throw new CoolException("业务类型不能为空!!"); |
| | | } |
| | |
| | | */ |
| | | @Override |
| | | public R updateOrderItem(AsnOrderAndItemsParams params, Long loginUserId) { |
| | | AsnOrder orders = params.getOrders(); |
| | | WkOrder orders = params.getOrders(); |
| | | if (Objects.isNull(orders)) { |
| | | throw new CoolException("主单信息不能为空!!"); |
| | | } |
| | |
| | | if (Cools.isEmpty(param.getOrderId())) { |
| | | throw new CoolException("单据ID为空"); |
| | | } |
| | | WaveRule waveRule = waveRuleService.getOne(new LambdaQueryWrapper<WaveRule>().eq(WaveRule::getId, param.getWaveId())); |
| | | WaveRule waveRule = waveRuleService.getOne(new LambdaQueryWrapper<WaveRule>() |
| | | .eq(WaveRule::getId, param.getWaveId())); |
| | | if (Cools.isEmpty(waveRule)) { |
| | | throw new CoolException("未找到当前策略"); |
| | | } |
| | |
| | | List<LocItem> locItems = new ArrayList<>(); |
| | | LocItem locItem = locItemService.getById(param.getId()); |
| | | |
| | | AsnOrderItem orderItem = outStockItemService.getOne(new LambdaQueryWrapper<AsnOrderItem>() |
| | | .eq(AsnOrderItem::getAsnId, outId) |
| | | .eq(StringUtils.isNotBlank(locItem.getBatch()), AsnOrderItem::getSplrBatch, locItem.getBatch()) |
| | | .eq(StringUtils.isNotBlank(locItem.getFieldsIndex()), AsnOrderItem::getFieldsIndex, locItem.getFieldsIndex()) |
| | | .eq(AsnOrderItem::getMatnrId, locItem.getMatnrId())); |
| | | WkOrderItem orderItem = outStockItemService.getOne(new LambdaQueryWrapper<WkOrderItem>() |
| | | .eq(WkOrderItem::getAsnId, outId) |
| | | .eq(StringUtils.isNotBlank(locItem.getBatch()), WkOrderItem::getSplrBatch, locItem.getBatch()) |
| | | .eq(StringUtils.isNotBlank(locItem.getFieldsIndex()), WkOrderItem::getFieldsIndex, locItem.getFieldsIndex()) |
| | | .eq(WkOrderItem::getMatnrId, locItem.getMatnrId())); |
| | | |
| | | if (Objects.isNull(orderItem)) { |
| | | throw new CoolException("单据明细不存在!!"); |
| | |
| | | |
| | | Double sum = Items.stream().mapToDouble(OutStockToTaskParams::getOutQty).sum(); |
| | | //更新出库单明细及主单 |
| | | AsnOrder outOrder = outStockService.getById(outId); |
| | | WkOrder outOrder = outStockService.getById(outId); |
| | | if (Objects.isNull(outOrder)) { |
| | | throw new CoolException("出库单据不存在!!"); |
| | | } |
| | |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public R cancelOutOrderByItems(List<AsnOrderItem> orderItems) { |
| | | Map<Long, List<AsnOrderItem>> listMap = orderItems.stream().collect(Collectors.groupingBy(AsnOrderItem::getAsnId)); |
| | | public R cancelOutOrderByItems(List<WkOrderItem> orderItems) { |
| | | Map<Long, List<WkOrderItem>> listMap = orderItems.stream().collect(Collectors.groupingBy(WkOrderItem::getAsnId)); |
| | | for (Long key : listMap.keySet()) { |
| | | AsnOrder order = this.getById(key); |
| | | WkOrder order = this.getById(key); |
| | | if (Objects.isNull(order)) { |
| | | throw new CoolException("单据不存在!!"); |
| | | } |
| | | List<AsnOrderItem> items = listMap.get(key); |
| | | List<WkOrderItem> items = listMap.get(key); |
| | | if (!items.isEmpty()) { |
| | | for (AsnOrderItem orderItem : items) { |
| | | for (WkOrderItem orderItem : items) { |
| | | DeliveryItem deliveryItem = deliveryItemService.getById(orderItem.getPoDetlId()); |
| | | Double workQty = Math.round((deliveryItem.getWorkQty() - orderItem.getAnfme()) * 10000) / 10000.0; |
| | | deliveryItem.setWorkQty(workQty.compareTo(0.0) >= 0 ? workQty : 0); |
| | |
| | | } |
| | | } |
| | | |
| | | if (!this.remove(new LambdaQueryWrapper<AsnOrder>().eq(AsnOrder::getId, key))) { |
| | | if (!this.remove(new LambdaQueryWrapper<WkOrder>().eq(WkOrder::getId, key))) { |
| | | throw new CoolException("主单删除失败!!"); |
| | | } |
| | | if (!outStockItemService.remove(new LambdaQueryWrapper<AsnOrderItem>() |
| | | .eq(AsnOrderItem::getAsnId, key))) { |
| | | if (!outStockItemService.remove(new LambdaQueryWrapper<WkOrderItem>() |
| | | .eq(WkOrderItem::getAsnId, key))) { |
| | | throw new CoolException("单据明细删除失败!!"); |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | |
| | | private List<LocItem> getEfficiencyFirstItemList(AsnOrderItem asnOrderItem) { |
| | | LambdaQueryWrapper<LocItem> locItemQueryWrapper = new LambdaQueryWrapper<>(); |
| | | locItemQueryWrapper.eq(LocItem::getMatnrCode, asnOrderItem.getMatnrCode()); |
| | | locItemQueryWrapper.eq(LocItem::getBatch, asnOrderItem.getSplrBatch()); |
| | | 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); |
| | | List<LocItem> locItems = locItemService.list(locItemQueryWrapper); |
| | | locItems.sort(Comparator.comparing((LocItem item) -> !LocUtils.isShallowLoc(item.getLocCode()))); |
| | | List<LocItem> locsSet = locItems.stream().filter(locItem -> locItem.getAnfme().compareTo(asnOrderItem.getAnfme()) == 0.0).collect(Collectors.toList()); |
| | | if (!locsSet.isEmpty()) { |
| | | return locsSet; |
| | | } |
| | | return locItems; |
| | | } |
| | | |
| | | private List<LocItem> getFirstInFirstOutItemList(AsnOrderItem asnOrderItem) { |
| | | LambdaQueryWrapper<LocItem> locItemQueryWrapper = new LambdaQueryWrapper<>(); |
| | | locItemQueryWrapper.eq(LocItem::getMatnrCode, asnOrderItem.getMatnrCode()); |
| | | locItemQueryWrapper.eq(LocItem::getBatch, asnOrderItem.getSplrBatch()); |
| | | 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); |
| | | List<LocItem> locItems = locItemService.list(locItemQueryWrapper); |
| | | return locItems; |
| | | } |
| | | |
| | | private List<OrderOutItemDto> getOutOrderList(Long orderId, WaveRule waveRule) { |
| | | List<AsnOrderItem> asnOrderItems = asnOrderItemService.list(new LambdaQueryWrapper<AsnOrderItem>() |
| | | .eq(AsnOrderItem::getAsnId, orderId)); |
| | | List<WkOrderItem> wkOrderItems = asnOrderItemService.list(new LambdaQueryWrapper<WkOrderItem>() |
| | | .eq(WkOrderItem::getAsnId, orderId)); |
| | | List<OrderOutItemDto> list = new ArrayList<>(); |
| | | Set<ExistDto> existDtos = new HashSet<>(); |
| | | |
| | | for (AsnOrderItem asnOrderItem : asnOrderItems) { |
| | | BigDecimal issued = new BigDecimal(asnOrderItem.getAnfme().toString()) |
| | | .subtract(new BigDecimal(asnOrderItem.getWorkQty().toString()) |
| | | for (WkOrderItem wkOrderItem : wkOrderItems) { |
| | | BigDecimal issued = new BigDecimal(wkOrderItem.getAnfme().toString()) |
| | | .subtract(new BigDecimal(wkOrderItem.getWorkQty().toString()) |
| | | ); |
| | | if (issued.doubleValue() <= 0) { |
| | | continue; |
| | | } |
| | | List<LocItem> locItems = new ArrayList<>(); |
| | | if (WaveRuleType.Efficiency_First.type.equals(waveRule.getType())) { |
| | | locItems = getEfficiencyFirstItemList(asnOrderItem); |
| | | locItems = LocManageUtil.getEfficiencyFirstItemList(wkOrderItem.getMatnrCode(), wkOrderItem.getSplrBatch(), wkOrderItem.getAnfme()); |
| | | } else if (WaveRuleType.First_In_First_Out.type.equals(waveRule.getType())) { |
| | | locItems = getFirstInFirstOutItemList(asnOrderItem); |
| | | locItems = LocManageUtil.getFirstInFirstOutItemList(wkOrderItem.getMatnrCode(), wkOrderItem.getSplrBatch(), wkOrderItem.getAnfme()); |
| | | } else { |
| | | locItems = getFirstInFirstOutItemList(asnOrderItem); |
| | | locItems = LocManageUtil.getFirstInFirstOutItemList(wkOrderItem.getMatnrCode(), wkOrderItem.getSplrBatch(), wkOrderItem.getAnfme()); |
| | | } |
| | | for (LocItem locItem : locItems) { |
| | | Loc loc = locService.getById(locItem.getLocId()); |
| | |
| | | if (issued.doubleValue() > 0) { |
| | | LocItem locItem = new LocItem() |
| | | .setId(new Random().nextLong()) |
| | | .setMatnrCode(asnOrderItem.getMatnrCode()) |
| | | .setMaktx(asnOrderItem.getMaktx()) |
| | | .setMatnrCode(wkOrderItem.getMatnrCode()) |
| | | .setMaktx(wkOrderItem.getMaktx()) |
| | | .setAnfme(0.00) |
| | | .setWorkQty(issued.doubleValue()) |
| | | .setOutQty(issued.doubleValue()) |
| | | .setUnit(asnOrderItem.getStockUnit()) |
| | | .setBatch(asnOrderItem.getSplrBatch()); |
| | | .setUnit(wkOrderItem.getStockUnit()) |
| | | .setBatch(wkOrderItem.getSplrBatch()); |
| | | OrderOutItemDto orderOutItemDto = new OrderOutItemDto(); |
| | | orderOutItemDto.setLocItem(locItem); |
| | | list.add(orderOutItemDto); |
| | |
| | | * @description 合并生成波次 |
| | | * @time 2025/4/25 10:07 |
| | | */ |
| | | private List<WaveItem> mergeWave(List<AsnOrderItem> orderItems, Wave wave) { |
| | | private List<WaveItem> mergeWave(List<WkOrderItem> orderItems, Wave wave) { |
| | | List<WaveItem> items = new ArrayList<>(); |
| | | orderItems.forEach(order -> { |
| | | Double anfme = Math.round((order.getAnfme() - order.getWorkQty()) * 10000) / 10000.0; |