| | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ruoyi.common.enums.ReviewStatusEnum; |
| | | import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum; |
| | | import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum; |
| | | import com.ruoyi.common.exception.ServiceException; |
| | |
| | | import com.ruoyi.stock.pojo.StockInRecord; |
| | | import com.ruoyi.stock.pojo.StockInventory; |
| | | import com.ruoyi.stock.pojo.StockOutRecord; |
| | | import com.ruoyi.stock.service.StockInventoryService; |
| | | import com.ruoyi.stock.service.StockInRecordService; |
| | | import com.ruoyi.stock.service.StockInventoryService; |
| | | import com.ruoyi.stock.service.StockOutRecordService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.stereotype.Service; |
| | |
| | | baseMapper.insert(orderPick); |
| | | |
| | | // 先新增出库申请,再审批通过,完成库存扣减。 |
| | | subtractInventory(orderPick.getId(), resolvedDto.getProductModelId(), storedBatchNo, resolvedDto.getPickQuantity(), rowNo, PICK_STOCK_OUT_RECORD_TYPE); |
| | | // subtractInventory(orderPick.getId(), resolvedDto.getProductModelId(), storedBatchNo, resolvedDto.getPickQuantity(), rowNo, PICK_STOCK_OUT_RECORD_TYPE); |
| | | |
| | | // 记录本次领料流水(before=0,after=本次领料量)。 |
| | | insertPickRecord(orderPick.getId(), |
| | |
| | | } |
| | | String oldBatchNo = resolveInventoryBatchNoFromStored(existingPick.getBatchNo()); |
| | | BigDecimal oldQuantity = defaultDecimal(existingPick.getQuantity()); |
| | | addInventory(existingPick.getId(), existingPick.getProductModelId(), oldBatchNo, oldQuantity, PICK_RETURN_IN_RECORD_TYPE); |
| | | // addInventory(existingPick.getId(), existingPick.getProductModelId(), oldBatchNo, oldQuantity, PICK_RETURN_IN_RECORD_TYPE); |
| | | // 删除关联领料流水,避免遗留无主记录。 |
| | | productionOrderPickRecordMapper.delete( |
| | | Wrappers.<ProductionOrderPickRecord>lambdaQuery() |
| | |
| | | for (ProductionOrderPick missingPick : missingPickList) { |
| | | String oldBatchNo = resolveInventoryBatchNoFromStored(missingPick.getBatchNo()); |
| | | BigDecimal oldQuantity = defaultDecimal(missingPick.getQuantity()); |
| | | addInventory(missingPick.getId(), missingPick.getProductModelId(), oldBatchNo, oldQuantity, PICK_RETURN_IN_RECORD_TYPE); |
| | | // addInventory(missingPick.getId(), missingPick.getProductModelId(), oldBatchNo, oldQuantity, PICK_RETURN_IN_RECORD_TYPE); |
| | | // 删除关联领料流水,避免遗留无主记录。 |
| | | productionOrderPickRecordMapper.delete( |
| | | Wrappers.<ProductionOrderPickRecord>lambdaQuery() |
| | |
| | | baseMapper.insert(orderPick); |
| | | |
| | | // 先新增出库申请,再审批通过,完成库存扣减。 |
| | | subtractInventory(orderPick.getId(), dto.getProductModelId(), storedBatchNo, dto.getPickQuantity(), rowNo, PICK_STOCK_OUT_RECORD_TYPE); |
| | | // subtractInventory(orderPick.getId(), dto.getProductModelId(), storedBatchNo, dto.getPickQuantity(), rowNo, PICK_STOCK_OUT_RECORD_TYPE); |
| | | |
| | | insertPickRecord(orderPick.getId(), |
| | | dto.getProductionOrderId(), |
| | |
| | | : formatBatchNoStorage(batchNoList); |
| | | BigDecimal feedingQuantity = dto.getFeedingQuantity(); |
| | | |
| | | subtractInventory(oldPick.getId(), productModelId, inventoryBatchNo, feedingQuantity, rowNo, FEED_STOCK_OUT_RECORD_TYPE); |
| | | // subtractInventory(oldPick.getId(), productModelId, inventoryBatchNo, feedingQuantity, rowNo, FEED_STOCK_OUT_RECORD_TYPE); |
| | | |
| | | // 计算补料前后数量并写补料流水。 |
| | | BigDecimal beforeFeedingQty = sumFeedingQuantity(dto.getProductionOrderId(), oldPick.getId()); |
| | |
| | | BigDecimal totalReturnQty = oldReturnQty.add(currentReturnQty); |
| | | if (currentReturnQty.compareTo(BigDecimal.ZERO) > 0) { |
| | | String returnBatchNo = resolveInventoryBatchNoFromStored(oldPick.getBatchNo()); |
| | | addInventory(oldPick.getId(), oldPick.getProductModelId(), returnBatchNo, currentReturnQty, FEED_RETURN_IN_RECORD_TYPE); |
| | | // addInventoryRecordOnly(oldPick.getId(), oldPick.getProductModelId(), returnBatchNo, currentReturnQty, FEED_RETURN_IN_RECORD_TYPE); |
| | | } |
| | | |
| | | BigDecimal actualQty = defaultDecimal(oldPick.getQuantity()) |
| | |
| | | BigDecimal deltaQuantity = newQuantity.subtract(oldQuantity); |
| | | if (deltaQuantity.compareTo(BigDecimal.ZERO) > 0) { |
| | | // 数量增加,只扣减新增部分。 |
| | | subtractInventory(oldPick.getId(), newProductModelId, newStoredBatchNo, deltaQuantity, rowNo, PICK_STOCK_OUT_RECORD_TYPE); |
| | | // subtractInventory(oldPick.getId(), newProductModelId, newStoredBatchNo, deltaQuantity, rowNo, PICK_STOCK_OUT_RECORD_TYPE); |
| | | } else if (deltaQuantity.compareTo(BigDecimal.ZERO) < 0) { |
| | | // 数量减少,只回退差值部分。 |
| | | addInventory(oldPick.getId(), oldProductModelId, oldBatchNo, deltaQuantity.abs(), PICK_RETURN_IN_RECORD_TYPE); |
| | | // addInventory(oldPick.getId(), oldProductModelId, oldBatchNo, deltaQuantity.abs(), PICK_RETURN_IN_RECORD_TYPE); |
| | | } |
| | | } else { |
| | | // 规格或批次变化:先全量回退旧领料,再全量扣减新领料。 |
| | | addInventory(oldPick.getId(), oldProductModelId, oldBatchNo, oldQuantity, PICK_RETURN_IN_RECORD_TYPE); |
| | | subtractInventory(oldPick.getId(), newProductModelId, newStoredBatchNo, newQuantity, rowNo, PICK_STOCK_OUT_RECORD_TYPE); |
| | | // addInventory(oldPick.getId(), oldProductModelId, oldBatchNo, oldQuantity, PICK_RETURN_IN_RECORD_TYPE); |
| | | // subtractInventory(oldPick.getId(), newProductModelId, newStoredBatchNo, newQuantity, rowNo, PICK_STOCK_OUT_RECORD_TYPE); |
| | | } |
| | | if (needReissuePickRecord) { |
| | | // 正常领料流水按“最新领料量”重建,避免保留历史旧值。 |
| | |
| | | continue; |
| | | } |
| | | BigDecimal currentDeductQuantity = remainingQuantity.min(availableQuantity); |
| | | createAndApproveStockOutRecord(recordId, productModelId, entry.getKey(), currentDeductQuantity, rowNo, stockOutRecordType); |
| | | // createAndApproveStockOutRecord(recordId, productModelId, entry.getKey(), currentDeductQuantity, rowNo, stockOutRecordType); |
| | | remainingQuantity = remainingQuantity.subtract(currentDeductQuantity); |
| | | } |
| | | |
| | |
| | | } else { |
| | | recordWrapper.eq(StockOutRecord::getBatchNo, batchNo); |
| | | } |
| | | StockOutRecord stockOutRecord = stockOutRecordService.getOne(recordWrapper, false); |
| | | if (stockOutRecord == null || stockOutRecord.getId() == null) { |
| | | throw new ServiceException("第" + rowNo + "行扣减库存失败:未找到对应出库申请记录"); |
| | | } |
| | | stockOutRecordService.batchApprove( |
| | | Collections.singletonList(stockOutRecord.getId()), |
| | | ReviewStatusEnum.APPROVED.getCode() |
| | | ); |
| | | // StockOutRecord stockOutRecord = stockOutRecordService.getOne(recordWrapper, false); |
| | | // if (stockOutRecord == null || stockOutRecord.getId() == null) { |
| | | // throw new ServiceException("第" + rowNo + "行扣减库存失败:未找到对应出库申请记录"); |
| | | // } |
| | | // stockOutRecordService.batchApprove( |
| | | // Collections.singletonList(stockOutRecord.getId()), |
| | | // ReviewStatusEnum.APPROVED.getCode() |
| | | // ); |
| | | } catch (ServiceException ex) { |
| | | throw ex; |
| | | } catch (Exception ex) { |
| | |
| | | if (stockInRecord == null || stockInRecord.getId() == null) { |
| | | throw new ServiceException("回补库存失败:未找到对应入库申请记录"); |
| | | } |
| | | stockInRecordService.batchApprove( |
| | | Collections.singletonList(stockInRecord.getId()), |
| | | ReviewStatusEnum.APPROVED.getCode() |
| | | ); |
| | | // stockInRecordService.batchApprove( |
| | | // Collections.singletonList(stockInRecord.getId()), |
| | | // ReviewStatusEnum.APPROVED.getCode(),stockInRecord.getWarehouseInfoId() |
| | | // ); |
| | | } catch (ServiceException ex) { |
| | | throw ex; |
| | | } catch (Exception ex) { |
| | |
| | | } |
| | | } |
| | | |
| | | private void addInventoryRecordOnly(Long recordId, |
| | | Long productModelId, |
| | | String batchNo, |
| | | BigDecimal quantity, |
| | | String stockInRecordType) { |
| | | // 仅记录入库申请,不做审核通过。 |
| | | BigDecimal addQuantity = defaultDecimal(quantity); |
| | | if (addQuantity.compareTo(BigDecimal.ZERO) <= 0) { |
| | | return; |
| | | } |
| | | try { |
| | | StockInventoryDto stockInventoryDto = new StockInventoryDto(); |
| | | stockInventoryDto.setProductModelId(productModelId); |
| | | stockInventoryDto.setBatchNo(batchNo); |
| | | stockInventoryDto.setQualitity(addQuantity); |
| | | stockInventoryDto.setRecordType(stockInRecordType); |
| | | stockInventoryDto.setRecordId(recordId == null ? 0L : recordId); |
| | | stockInventoryService.addStockInRecordOnly(stockInventoryDto); |
| | | } catch (ServiceException ex) { |
| | | throw ex; |
| | | } catch (Exception ex) { |
| | | throw new ServiceException("退料入库记录保存失败:" + ex.getMessage()); |
| | | } |
| | | } |
| | | |
| | | private List<ProductionOrderPickDto> resolvePickItems(ProductionOrderPickDto dto) { |
| | | // 解析新增场景的领料明细集合。 |
| | | if (dto == null) { |