src/main/java/com/ruoyi/production/controller/ProductOrderController.java
@@ -87,4 +87,15 @@ } @ApiOperation("新增生产订单") @PostMapping("addProductOrder") public R addProductOrder(@RequestBody ProductOrder productOrder) { return R.ok(productOrderService.addProductOrder(productOrder)); } @ApiOperation("删除生产订单") @DeleteMapping("/{ids}") public R delete(@PathVariable("ids") Long[] ids) { return R.ok(productOrderService.delete(ids)); } } src/main/java/com/ruoyi/production/mapper/ProductWorkOrderMapper.java
@@ -20,4 +20,6 @@ ProductWorkOrderDto getProductWorkOrderFlowCard(@Param("id") Long id); List<ProductWorkOrderDto> selectWorkOrderStartStats(@Param("startDate") String startDate, @Param("endDate") String endDate); ProductWorkOrder selectMax(@Param("datePrefix") String datePrefix); } src/main/java/com/ruoyi/production/service/ProductOrderService.java
@@ -21,4 +21,8 @@ List<ProcessRoute> listProcessRoute(Long productModelId); List<ProductStructureDto> listProcessBom(Long orderId); Boolean addProductOrder(ProductOrder productOrder); Boolean delete(Long[] id); } src/main/java/com/ruoyi/production/service/impl/ProductOrderServiceImpl.java
@@ -1,9 +1,14 @@ package com.ruoyi.production.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.common.enums.StockQualifiedRecordTypeEnum; import com.ruoyi.common.enums.StockUnQualifiedRecordTypeEnum; import com.ruoyi.procurementrecord.utils.StockUtils; import com.ruoyi.production.dto.ProductBomDto; import com.ruoyi.production.dto.ProductOrderDto; import com.ruoyi.production.dto.ProductStructureDto; @@ -11,12 +16,16 @@ import com.ruoyi.production.pojo.*; import com.ruoyi.production.service.ProcessRouteService; import com.ruoyi.production.service.ProductOrderService; import com.ruoyi.quality.mapper.QualityInspectMapper; import com.ruoyi.quality.pojo.QualityInspect; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.List; import java.util.stream.Collectors; @Service public class ProductOrderServiceImpl extends ServiceImpl<ProductOrderMapper, ProductOrder> implements ProductOrderService { @@ -39,6 +48,23 @@ @Autowired private ProductWorkOrderMapper productWorkOrderMapper; @Autowired private ProductionProductMainMapper productionProductMainMapper; @Autowired private ProductionProductOutputMapper productionProductOutputMapper; @Autowired private ProductionProductInputMapper productionProductInputMapper; @Autowired private QualityInspectMapper qualityInspectMapper; @Autowired private SalesLedgerProductionAccountingMapper salesLedgerProductionAccountingMapper; @Autowired private StockUtils stockUtils; @Override public IPage<ProductOrderDto> pageProductOrder(Page page, ProductOrderDto productOrder) { @@ -69,11 +95,7 @@ int insert = productProcessRouteItemMapper.insert(productProcessRouteItem); if (insert > 0) { // 查询今日已存在的最大工单号 QueryWrapper<ProductWorkOrder> queryWrapper = new QueryWrapper<>(); queryWrapper.likeRight("work_order_no", datePrefix) .orderByDesc("work_order_no") .last("LIMIT 1"); ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectOne(queryWrapper); ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectMax(datePrefix); int sequenceNumber = 1; // 默认序号 if (lastWorkOrder != null && lastWorkOrder.getWorkOrderNo() != null) { String lastNo = lastWorkOrder.getWorkOrderNo().toString(); @@ -110,4 +132,139 @@ public List<ProductStructureDto> listProcessBom(Long orderId) { return productOrderMapper.listProcessBom(orderId); } @Override public Boolean addProductOrder(ProductOrder productOrder) { String string = generateNextOrderNo(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"))); productOrder.setNpsNo(string); productOrder.setCompleteQuantity(BigDecimal.ZERO); this.save(productOrder); if (ObjectUtils.isNotEmpty(productOrder.getRouteId())) { this.bindingRoute(productOrder); } return true; } @Override public Boolean delete(Long[] ids) { //批量查询productOrder List<ProductOrder> productOrders = productOrderMapper.selectList( new LambdaQueryWrapper<ProductOrder>() .in(ProductOrder::getId, ids) ); if (!org.springframework.util.CollectionUtils.isEmpty(productOrders)) { // 批量查询processRouteItems List<ProductProcessRouteItem> allRouteItems = productProcessRouteItemMapper.selectList( new LambdaQueryWrapper<ProductProcessRouteItem>() .in(ProductProcessRouteItem::getProductOrderId, ids) ); if (!com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(allRouteItems)) { // 获取要删除的工序项ID List<Long> routeItemIds = allRouteItems.stream() .map(ProductProcessRouteItem::getId) .collect(Collectors.toList()); // 查询关联的工单ID List<ProductWorkOrder> workOrders = productWorkOrderMapper.selectList( new LambdaQueryWrapper<ProductWorkOrder>() .in(ProductWorkOrder::getProductProcessRouteItemId, routeItemIds) ); if (!com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(workOrders)) { List<Long> workOrderIds = workOrders.stream() .map(ProductWorkOrder::getId) .collect(Collectors.toList()); // 查询关联的生产主表ID List<ProductionProductMain> productMains = productionProductMainMapper.selectList( new LambdaQueryWrapper<ProductionProductMain>() .in(ProductionProductMain::getWorkOrderId, workOrderIds) ); List<Long> productMainIds = productMains.stream() .map(ProductionProductMain::getId) .collect(Collectors.toList()); // 删除产出表、投入表数据 if (!com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(productMainIds)) { productionProductOutputMapper.deleteByProductMainIds(productMainIds); productionProductInputMapper.deleteByProductMainIds(productMainIds); List<QualityInspect> qualityInspects = qualityInspectMapper.selectList( new LambdaQueryWrapper<QualityInspect>() .in(QualityInspect::getProductMainId, productMainIds) ); //删除出库记录 for (Long productMainId : productMainIds) { //删除生产出库记录 stockUtils.deleteStockOutRecord(productMainId, StockQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode()); //删除报废的入库记录 stockUtils.deleteStockInRecord(productMainId, StockUnQualifiedRecordTypeEnum.PRODUCTION_SCRAP.getCode()); } qualityInspects.forEach(qualityInspect -> { //inspectState=1 已提交 不能删除 if (qualityInspect.getInspectState() == 1) { throw new RuntimeException("已提交的检验单不能删除"); } }); qualityInspectMapper.deleteByProductMainIds(productMainIds); salesLedgerProductionAccountingMapper.delete(new LambdaQueryWrapper<SalesLedgerProductionAccounting>() .in(SalesLedgerProductionAccounting::getProductMainId, productMainIds)); } // 删除生产主表数据 productionProductMainMapper.deleteByWorkOrderIds(workOrderIds); // 删除工单数据 productWorkOrderMapper.delete(new LambdaQueryWrapper<ProductWorkOrder>() .in(ProductWorkOrder::getProductProcessRouteItemId, routeItemIds)); } } // 批量删除processRouteItem productProcessRouteItemMapper.delete(new LambdaQueryWrapper<ProductProcessRouteItem>() .in(ProductProcessRouteItem::getProductOrderId, ids)); // 批量删除productProcessRoute productProcessRouteMapper.delete(new LambdaQueryWrapper<ProductProcessRoute>() .in(ProductProcessRoute::getProductOrderId, ids)); // 批量删除productOrder productOrderMapper.delete(new LambdaQueryWrapper<ProductOrder>() .in(ProductOrder::getId, ids)); } return true; } //获取当前生产订单号 public String getMaxOrderNoByDate(String datePrefix) { QueryWrapper<ProductOrder> queryWrapper = new QueryWrapper<>(); // 匹配以 SC + 日期开头的订单号 queryWrapper.likeRight("nps_no", "SC" + datePrefix); // 按订单号倒序排列 queryWrapper.orderByDesc("nps_no"); queryWrapper.last("LIMIT 1"); ProductOrder latestOrder = this.getOne(queryWrapper); return latestOrder != null ? latestOrder.getNpsNo() : null; } public String generateNextOrderNo(String datePrefix) { String maxOrderNo = getMaxOrderNoByDate(datePrefix); int sequence = 1; // 默认起始序号 if (maxOrderNo != null && !maxOrderNo.isEmpty()) { // 提取流水号部分(假设格式为 SC + 日期 + 流水号) String sequenceStr = maxOrderNo.substring(("SC" + datePrefix).length()); try { sequence = Integer.parseInt(sequenceStr) + 1; } catch (NumberFormatException e) { // 异常情况下重置为1 sequence = 1; } } // 生成新订单号 return "SC" + datePrefix + String.format("%04d", sequence); } } src/main/java/com/ruoyi/production/service/impl/ProductProcessRouteItemServiceImpl.java
@@ -142,11 +142,7 @@ String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")); if (insert > 0) { // 查询今日已存在的最大工单号 QueryWrapper<ProductWorkOrder> queryWrapper = new QueryWrapper<>(); queryWrapper.likeRight("work_order_no", datePrefix) .orderByDesc("work_order_no") .last("LIMIT 1"); ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectOne(queryWrapper); ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectMax(datePrefix); int sequenceNumber = 1; // 默认序号 if (lastWorkOrder != null && lastWorkOrder.getWorkOrderNo() != null) { String lastNo = lastWorkOrder.getWorkOrderNo().toString(); src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
@@ -24,6 +24,8 @@ import com.ruoyi.project.system.mapper.SysUserMapper; import com.ruoyi.quality.mapper.*; import com.ruoyi.quality.pojo.*; import com.ruoyi.quality.service.IQualityInspectService; import com.ruoyi.quality.service.impl.QualityInspectFileServiceImpl; import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -42,6 +44,7 @@ @Transactional(rollbackFor = Exception.class) public class ProductionProductMainServiceImpl extends ServiceImpl<ProductionProductMainMapper, ProductionProductMain> implements ProductionProductMainService { private IQualityInspectService qualityInspectService; private ProductionProductMainMapper productionProductMainMapper; @@ -283,7 +286,9 @@ new LambdaQueryWrapper<QualityInspectParam>() .eq(QualityInspectParam::getInspectId, q.getId())); qualityInspectMapper.deleteById(q.getId()); stockUtils.deleteStockInRecord(q.getId(), StockQualifiedRecordTypeEnum.QUALITYINSPECT_STOCK_IN.getCode()); }); // 删除产出记录 productionProductOutputMapper.delete(new LambdaQueryWrapper<ProductionProductOutput>() .eq(ProductionProductOutput::getProductMainId, productionProductMain.getId())); src/main/java/com/ruoyi/quality/service/impl/QualityUnqualifiedServiceImpl.java
@@ -98,11 +98,7 @@ int insert = productProcessRouteItemMapper.insert(productProcessRouteItem); if (insert > 0) { // 查询今日已存在的最大工单号 QueryWrapper<ProductWorkOrder> queryWrapper = new QueryWrapper<>(); queryWrapper.likeRight("work_order_no", datePrefix) .orderByDesc("work_order_no") .last("LIMIT 1"); ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectOne(queryWrapper); ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectMax(datePrefix); int sequenceNumber = 1; // 默认序号 if (lastWorkOrder != null && lastWorkOrder.getWorkOrderNo() != null) { String lastNo = lastWorkOrder.getWorkOrderNo().toString(); src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
@@ -15,6 +15,7 @@ import com.ruoyi.production.dto.ProductStructureDto; import com.ruoyi.production.mapper.*; import com.ruoyi.production.pojo.*; import com.ruoyi.production.service.impl.ProductOrderServiceImpl; import com.ruoyi.production.service.impl.SalesLedgerProductionAccountingServiceImpl; import com.ruoyi.purchase.mapper.PurchaseLedgerMapper; import com.ruoyi.purchase.pojo.PurchaseLedger; @@ -94,7 +95,7 @@ @Autowired private StockInventoryMapper stockInventoryMapper; @Autowired private SalesLedgerProductionAccountingServiceImpl salesLedgerProductionAccountingServiceImpl; private ProductOrderServiceImpl productOrderServiceImpl; @Override public SalesLedgerProduct selectSalesLedgerProductById(Long id) { @@ -273,7 +274,8 @@ productOrder.setSalesLedgerId(salesLedgerProduct.getSalesLedgerId()); productOrder.setProductModelId(salesLedgerProduct.getProductModelId()); productOrder.setSaleLedgerProductId(salesLedgerProduct.getId()); productOrder.setNpsNo("SC" + String.format("%08d", salesLedgerProduct.getId())); String string = productOrderServiceImpl.generateNextOrderNo(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"))); productOrder.setNpsNo(string); productOrder.setQuantity(salesLedgerProduct.getQuantity());//需求数量 productOrder.setCompleteQuantity(BigDecimal.ZERO);//完成数量 productOrderMapper.insert(productOrder); @@ -304,13 +306,7 @@ int insert = productProcessRouteItemMapper.insert(productProcessRouteItem); if (insert > 0) { // 查询今日已存在的最大工单号 QueryWrapper<ProductWorkOrder> queryWrapper = new QueryWrapper<>(); queryWrapper.likeRight("work_order_no", datePrefix) .orderByDesc("work_order_no") .last("LIMIT 1"); ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectOne(queryWrapper); ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectMax(datePrefix); int sequenceNumber = 1; // 默认序号 if (lastWorkOrder != null && lastWorkOrder.getWorkOrderNo() != null) { String lastNo = lastWorkOrder.getWorkOrderNo().toString(); src/main/resources/mapper/production/ProductOrderMapper.xml
@@ -17,8 +17,9 @@ select po.*, sl.sales_contract_no, sl.customer_name, slp.product_category, slp.specification_model, p.product_name as product_category, pm.model as specification_model, pm.unit, ppr.process_route_code, pb.bom_no, ROUND(po.complete_quantity / po.quantity * 100, 2) AS completionStatus, @@ -38,6 +39,8 @@ FROM shipping_info GROUP BY sales_ledger_id ) shipping_status_counts ON sl.id = shipping_status_counts.sales_ledger_id left join product_model pm on po.product_model_id = pm.id left join product p on pm.product_id = p.id left join sales_ledger_product slp on po.sale_ledger_product_id = slp.id left join product_process_route ppr on po.id = ppr.product_order_id left join product_bom pb on pb.id = ppr.bom_id src/main/resources/mapper/production/ProductWorkOrderMapper.xml
@@ -87,4 +87,12 @@ actual_start_time >= #{startDate} AND actual_start_time <= #{endDate} </select> <select id="selectMax" resultType="com.ruoyi.production.pojo.ProductWorkOrder"> SELECT SUBSTRING(work_order_no, 3) as work_order_no FROM product_work_order WHERE SUBSTRING(work_order_no, 3) like concat(#{datePrefix},'%') order by work_order_no desc limit 1 ; </select> </mapper>