liding
8 天以前 5e99b5312dd1560214719252d07fa4cc2b48082a
feat:1.订单调整
2.领料提示
3.退料添加入库记录
已修改11个文件
149 ■■■■ 文件已修改
src/main/java/com/ruoyi/common/enums/StockInQualifiedRecordTypeEnum.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/bean/vo/ProductionOperationTaskVo.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/controller/ProductionOrderController.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/pojo/ProductionOrder.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/ProductionOrderService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductionOperationTaskServiceImpl.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductionOrderPickServiceImpl.java 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductionOrderServiceImpl.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductionOperationTaskMapper.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductionOrderMapper.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/common/enums/StockInQualifiedRecordTypeEnum.java
@@ -12,7 +12,8 @@
    PURCHASE_STOCK_IN("7", "采购-入库"),
    QUALITYINSPECT_STOCK_IN("6", "质检-合格入库"),
    DEFECTIVE_PASS("11", "不合格-让步放行"),
    RETURN_HE_IN("14", "销售退货-合格入库");
    RETURN_HE_IN("14", "销售退货-合格入库"),
    PICK_RETURN_IN("20", "销售退货-合格入库");
    private final String code;
src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java
@@ -32,12 +32,13 @@
    /**
     * 不合格入库
     *
     * @param productModelId
     * @param quantity
     * @param recordType
     * @param recordId
     */
    public void addUnStock(Long productModelId, BigDecimal quantity, String recordType,Long recordId) {
    public void addUnStock(Long productModelId, BigDecimal quantity, String recordType, Long recordId) {
        StockUninventoryDto stockUninventoryDto = new StockUninventoryDto();
        stockUninventoryDto.setRecordId(recordId);
        stockUninventoryDto.setRecordType(String.valueOf(recordType));
@@ -48,12 +49,13 @@
    /**
     * 不合格出库
     *
     * @param productModelId
     * @param quantity
     * @param recordType
     * @param recordId
     */
    public void subtractUnStock(Long productModelId, BigDecimal quantity, Integer recordType,Long recordId) {
    public void subtractUnStock(Long productModelId, BigDecimal quantity, Integer recordType, Long recordId) {
        StockUninventoryDto stockUninventoryDto = new StockUninventoryDto();
        stockUninventoryDto.setRecordId(recordId);
        stockUninventoryDto.setRecordType(String.valueOf(recordType));
@@ -80,12 +82,13 @@
    /**
     * 合格出库
     *
     * @param productModelId
     * @param quantity
     * @param recordType
     * @param recordId
     */
    public void substractStock(Long productModelId, BigDecimal quantity, String recordType,Long recordId) {
    public void substractStock(Long productModelId, BigDecimal quantity, String recordType, Long recordId) {
        StockInventoryDto stockInventoryDto = new StockInventoryDto();
        stockInventoryDto.setRecordId(recordId);
        stockInventoryDto.setRecordType(String.valueOf(recordType));
@@ -110,6 +113,7 @@
        }
    }
    public void deleteStockOutRecord(Long recordId, String recordType) {
        StockOutRecord one = stockOutRecordService.getOne(new QueryWrapper<StockOutRecord>()
                .lambda().eq(StockOutRecord::getRecordId, recordId)
src/main/java/com/ruoyi/production/bean/vo/ProductionOperationTaskVo.java
@@ -34,4 +34,7 @@
    @Schema(description = "报工人员名称,多个使用逗号分隔")
    private String userNames;
    @Schema(description = "是否结束)")
    private Boolean endOrder;
}
src/main/java/com/ruoyi/production/controller/ProductionOrderController.java
@@ -89,4 +89,10 @@
    public R<ProductionOrderWorkOrderDetailVo> getWorkOrderReportInspectDetail(@PathVariable Long productionOrderId) {
        return R.ok(productionOrderService.getWorkOrderReportInspectDetail(productionOrderId));
    }
    @Operation(summary = "更新订单状态")
    @PostMapping("/updateOrder")
    public R updateOrder(@RequestBody ProductionOrderDto productionOrderDto) {
        return R.ok(productionOrderService.updateOrder(productionOrderDto));
    }
}
src/main/java/com/ruoyi/production/pojo/ProductionOrder.java
@@ -74,6 +74,10 @@
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate planCompleteTime;
    @Schema(description = "状态(1.待开始 2.进行中 3.已完成 4.已取消)")
    @Schema(description = "状态(1.待开始 2.进行中 3.已完成 4.已取消 5.已结束)")
    private Integer status;
    @Schema(description = "是否结束)")
    @TableField("is_end_order")
    private Boolean endOrder;
}
src/main/java/com/ruoyi/production/service/ProductionOrderService.java
@@ -33,4 +33,6 @@
    List<ProductionOrderPickVo> pick(Long productionOrderId);
    ProductionOrderWorkOrderDetailVo getWorkOrderReportInspectDetail(Long productionOrderId);
    int updateOrder(ProductionOrderDto productionOrderDto);
}
src/main/java/com/ruoyi/production/service/impl/ProductionOperationTaskServiceImpl.java
@@ -22,7 +22,9 @@
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.production.bean.dto.ProductionOperationTaskDto;
import com.ruoyi.production.bean.vo.ProductionOperationTaskVo;
import com.ruoyi.production.mapper.ProductionOrderMapper;
import com.ruoyi.production.mapper.ProductionOperationTaskMapper;
import com.ruoyi.production.pojo.ProductionOrder;
import com.ruoyi.production.pojo.ProductionOperationTask;
import com.ruoyi.production.service.ProductionOperationTaskService;
import com.ruoyi.project.system.domain.SysUser;
@@ -45,6 +47,7 @@
public class ProductionOperationTaskServiceImpl extends ServiceImpl<ProductionOperationTaskMapper, ProductionOperationTask> implements ProductionOperationTaskService {
    private final SysUserMapper sysUserMapper;
    private final ProductionOrderMapper productionOrderMapper;
    private final FileUtil fileUtil;
@@ -75,6 +78,12 @@
            return null;
        }
        ProductionOperationTaskVo vo = BeanUtil.copyProperties(item, ProductionOperationTaskVo.class);
        if (item.getProductionOrderId() != null) {
            ProductionOrder productionOrder = productionOrderMapper.selectById(item.getProductionOrderId());
            if (productionOrder != null) {
                vo.setEndOrder(productionOrder.getEndOrder());
            }
        }
        fillUserNames(Collections.singletonList(vo));
        return vo;
    }
src/main/java/com/ruoyi/production/service/impl/ProductionOrderPickServiceImpl.java
@@ -3,6 +3,7 @@
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.StockInQualifiedRecordTypeEnum;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.production.bean.dto.ProductionOrderPickDto;
@@ -18,6 +19,7 @@
import com.ruoyi.stock.dto.StockInventoryDto;
import com.ruoyi.stock.mapper.StockInventoryMapper;
import com.ruoyi.stock.pojo.StockInventory;
import com.ruoyi.stock.service.StockInventoryService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -46,6 +48,7 @@
    private final ProductionOperationTaskMapper productionOperationTaskMapper;
    private final ProductionOrderPickRecordMapper productionOrderPickRecordMapper;
    private final StockInventoryMapper stockInventoryMapper;
    private final StockInventoryService stockInventoryService;
    @Override
    @Transactional(rollbackFor = Exception.class)
@@ -59,7 +62,7 @@
            List<String> batchNoList = resolveBatchNoList(resolvedDto);
            String inventoryBatchNo = pickInventoryBatchNo(batchNoList);
            String storedBatchNo = formatBatchNoStorage(batchNoList);
            subtractInventory(resolvedDto.getProductModelId(), inventoryBatchNo, resolvedDto.getPickQuantity(), rowNo);
            subtractInventory(resolvedDto.getProductModelId(), storedBatchNo, resolvedDto.getPickQuantity(), rowNo);
            ProductionOrderPick orderPick = new ProductionOrderPick();
            orderPick.setProductionOrderId(resolvedDto.getProductionOrderId());
@@ -234,7 +237,7 @@
        List<String> batchNoList = resolveBatchNoList(dto);
        String inventoryBatchNo = pickInventoryBatchNo(batchNoList);
        String storedBatchNo = formatBatchNoStorage(batchNoList);
        subtractInventory(dto.getProductModelId(), inventoryBatchNo, dto.getPickQuantity(), rowNo);
        subtractInventory(dto.getProductModelId(), storedBatchNo, dto.getPickQuantity(), rowNo);
        ProductionOrderPick orderPick = new ProductionOrderPick();
        orderPick.setProductionOrderId(dto.getProductionOrderId());
@@ -296,7 +299,7 @@
        List<String> batchNoList = resolveBatchNoList(dto);
        String inventoryBatchNo = batchNoList.isEmpty()
                ? resolveInventoryBatchNoFromStored(oldPick.getBatchNo())
                : pickInventoryBatchNo(batchNoList);
                : formatBatchNoStorage(batchNoList);
        BigDecimal feedingQuantity = dto.getFeedingQuantity();
        subtractInventory(productModelId, inventoryBatchNo, feedingQuantity, rowNo);
@@ -388,13 +391,13 @@
        if (sameStockKey) {
            BigDecimal delta = newQuantity.subtract(oldQuantity);
            if (delta.compareTo(BigDecimal.ZERO) > 0) {
                subtractInventory(newProductModelId, newBatchNo, delta, rowNo);
                subtractInventory(newProductModelId, newStoredBatchNo, delta, rowNo);
            } else if (delta.compareTo(BigDecimal.ZERO) < 0) {
                addInventory(oldProductModelId, oldBatchNo, delta.abs());
            }
        } else {
            addInventory(oldProductModelId, oldBatchNo, oldQuantity);
            subtractInventory(newProductModelId, newBatchNo, newQuantity, rowNo);
            subtractInventory(newProductModelId, newStoredBatchNo, newQuantity, rowNo);
        }
        oldPick.setProductModelId(newProductModelId);
@@ -457,22 +460,61 @@
    }
    private void subtractInventory(Long productModelId, String batchNo, BigDecimal quantity, int rowNo) {
        StockInventory stockInventory = stockInventoryMapper.selectOne(buildStockWrapper(productModelId, batchNo));
        if (stockInventory == null) {
            throw new ServiceException("第" + rowNo + "条领料对应库存不存在");
        BigDecimal deductQuantity = defaultDecimal(quantity);
        if (deductQuantity.compareTo(BigDecimal.ZERO) <= 0) {
            return;
        }
        BigDecimal availableQuantity = defaultDecimal(stockInventory.getQualitity())
                .subtract(defaultDecimal(stockInventory.getLockedQuantity()));
        if (quantity.compareTo(availableQuantity) > 0) {
            throw new ServiceException("第" + rowNo + "条领料可用库存不足");
        List<String> batchNoList = parseBatchNoValue(batchNo);
        if (batchNoList.isEmpty()) {
            batchNoList = Collections.singletonList(null);
        }
        StockInventoryDto stockInventoryDto = new StockInventoryDto();
        stockInventoryDto.setProductModelId(productModelId);
        stockInventoryDto.setBatchNo(batchNo);
        stockInventoryDto.setQualitity(quantity);
        int affected = stockInventoryMapper.updateSubtractStockInventory(stockInventoryDto);
        if (affected <= 0) {
            throw new ServiceException("第" + rowNo + "条领料扣减库存失败");
        Map<String, BigDecimal> availableQuantityMap = new LinkedHashMap<>();
        BigDecimal totalAvailableQuantity = BigDecimal.ZERO;
        for (String currentBatchNo : batchNoList) {
            StockInventory stockInventory = stockInventoryMapper.selectOne(buildStockWrapper(productModelId, currentBatchNo));
            BigDecimal availableQuantity = BigDecimal.ZERO;
            if (stockInventory != null) {
                availableQuantity = defaultDecimal(stockInventory.getQualitity())
                        .subtract(defaultDecimal(stockInventory.getLockedQuantity()));
                if (availableQuantity.compareTo(BigDecimal.ZERO) < 0) {
                    availableQuantity = BigDecimal.ZERO;
                }
            }
            availableQuantityMap.put(currentBatchNo, availableQuantity);
            totalAvailableQuantity = totalAvailableQuantity.add(availableQuantity);
        }
        if (deductQuantity.compareTo(totalAvailableQuantity) > 0) {
            BigDecimal shortQuantity = deductQuantity.subtract(totalAvailableQuantity);
            throw new ServiceException("领料可用库存不足,可用库存为" + formatQuantity(totalAvailableQuantity)
                    + ",还差" + formatQuantity(shortQuantity));
        }
        BigDecimal remainingQuantity = deductQuantity;
        for (Map.Entry<String, BigDecimal> entry : availableQuantityMap.entrySet()) {
            if (remainingQuantity.compareTo(BigDecimal.ZERO) <= 0) {
                break;
            }
            BigDecimal availableQuantity = defaultDecimal(entry.getValue());
            if (availableQuantity.compareTo(BigDecimal.ZERO) <= 0) {
                continue;
            }
            BigDecimal currentDeductQuantity = remainingQuantity.min(availableQuantity);
            StockInventoryDto stockInventoryDto = new StockInventoryDto();
            stockInventoryDto.setProductModelId(productModelId);
            stockInventoryDto.setBatchNo(entry.getKey());
            stockInventoryDto.setQualitity(currentDeductQuantity);
            int affected = stockInventoryMapper.updateSubtractStockInventory(stockInventoryDto);
            if (affected <= 0) {
                throw new ServiceException("第" + rowNo + "条领料扣减库存失败");
            }
            remainingQuantity = remainingQuantity.subtract(currentDeductQuantity);
        }
        if (remainingQuantity.compareTo(BigDecimal.ZERO) > 0) {
            throw new ServiceException("第" + rowNo + "条领料扣减库存失败,剩余待扣减数量为" + formatQuantity(remainingQuantity));
        }
    }
@@ -481,25 +523,13 @@
        if (addQuantity.compareTo(BigDecimal.ZERO) <= 0) {
            return;
        }
        StockInventory stockInventory = stockInventoryMapper.selectOne(buildStockWrapper(productModelId, batchNo));
        if (stockInventory == null) {
            StockInventory newStockInventory = new StockInventory();
            newStockInventory.setProductModelId(productModelId);
            newStockInventory.setBatchNo(batchNo);
            newStockInventory.setQualitity(addQuantity);
            newStockInventory.setLockedQuantity(BigDecimal.ZERO);
            newStockInventory.setVersion(1);
            stockInventoryMapper.insert(newStockInventory);
            return;
        }
        StockInventoryDto stockInventoryDto = new StockInventoryDto();
        stockInventoryDto.setProductModelId(productModelId);
        stockInventoryDto.setBatchNo(batchNo);
        stockInventoryDto.setQualitity(addQuantity);
        int affected = stockInventoryMapper.updateAddStockInventory(stockInventoryDto);
        if (affected <= 0) {
            throw new ServiceException("库存回退失败,产品规格ID=" + productModelId);
        }
        stockInventoryDto.setRecordType(String.valueOf(StockInQualifiedRecordTypeEnum.PICK_RETURN_IN.getCode()));
        stockInventoryDto.setRecordId(0L);
        stockInventoryService.addStockInRecordOnly(stockInventoryDto);
    }
    private List<ProductionOrderPickDto> resolvePickItems(ProductionOrderPickDto dto) {
@@ -882,4 +912,8 @@
    private BigDecimal defaultDecimal(BigDecimal value) {
        return value == null ? BigDecimal.ZERO : value;
    }
    private String formatQuantity(BigDecimal value) {
        return defaultDecimal(value).stripTrailingZeros().toPlainString();
    }
}
src/main/java/com/ruoyi/production/service/impl/ProductionOrderServiceImpl.java
@@ -915,4 +915,10 @@
        }
        return new ArrayList<>(mergedPickMap.values());
    }
    @Override
    public int updateOrder(ProductionOrderDto productionOrderDto) {
        productionOrderDto.setStatus(5);
        return baseMapper.updateById(productionOrderDto);
    }
}
src/main/resources/mapper/production/ProductionOperationTaskMapper.xml
@@ -24,6 +24,7 @@
    <select id="pageProductionOperationTask" resultType="com.ruoyi.production.bean.vo.ProductionOperationTaskVo">
        select pot.*,
               po.nps_no as npsNo,
               po.is_end_order as endOrder,
               p.product_name as productName,
               pm.model as model,
               pm.unit as unit,
src/main/resources/mapper/production/ProductionOrderMapper.xml
@@ -49,6 +49,7 @@
        po_sales.customerName,
        p.product_name as productName,
        pm.model as model,
        po.is_end_order as endOrder,
        tr.process_route_code as processRouteCode,
        ROUND(po.complete_quantity / po.quantity * 100, 2) AS completionStatus,
        tb.bom_no as bomNo