src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java
@@ -126,12 +126,15 @@ * @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,String batchNo) { StockInventoryDto stockInventoryDto = new StockInventoryDto(); stockInventoryDto.setRecordId(recordId); stockInventoryDto.setRecordType(String.valueOf(recordType)); stockInventoryDto.setQualitity(quantity); stockInventoryDto.setProductModelId(productModelId); if (batchNo !=null && !batchNo.isEmpty()) { stockInventoryDto.setBatchNo(batchNo); } stockInventoryService.subtractStockInventory(stockInventoryDto); } src/main/java/com/ruoyi/production/controller/ProductOrderController.java
@@ -1,13 +1,11 @@ package com.ruoyi.production.controller; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.basic.pojo.Customer; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.framework.aspectj.lang.annotation.Log; import com.ruoyi.framework.aspectj.lang.enums.BusinessType; import com.ruoyi.framework.web.domain.R; import com.ruoyi.production.dto.ProductOrderDto; import com.ruoyi.production.pojo.ProcessRoute; import com.ruoyi.production.pojo.ProductOrder; import com.ruoyi.production.service.ProductOrderService; import io.swagger.annotations.Api; @@ -16,7 +14,6 @@ import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletResponse; import java.math.BigDecimal; import java.util.List; @RequestMapping("productOrder") @@ -65,9 +62,9 @@ @ApiOperation("新增生产订单") @PostMapping("addProductOrder") public R addProductOrder(@RequestBody ProductOrder productOrder) { return R.ok(productOrderService.addProductOrder(productOrder)); @PostMapping("/addProductOrder") public R addProductOrder(@RequestBody ProductOrderDto productOrderDto) { return R.ok(productOrderService.addProductOrder(productOrderDto)); } @ApiOperation("删除生产订单") src/main/java/com/ruoyi/production/dto/ProductOrderDto.java
@@ -62,4 +62,7 @@ //是否发货(台账页面颜色控制) private Boolean isFh; @ApiModelProperty(value = "型号") private String productModelName; } src/main/java/com/ruoyi/production/dto/ProductionProductMainDto.java
@@ -83,4 +83,7 @@ // 不合格处理结果 @ApiModelProperty(value = "不合格处理结果") private String dealResult; @ApiModelProperty(value = "生产批号") private String batchNo; } src/main/java/com/ruoyi/production/pojo/ProductOrder.java
@@ -3,7 +3,6 @@ import com.baomidou.mybatisplus.annotation.*; import com.fasterxml.jackson.annotation.JsonFormat; import com.ruoyi.framework.aspectj.lang.annotation.Excel; import io.swagger.annotations.Api; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; @@ -52,7 +51,7 @@ private String priority; /** * 优先级 * 生产批号 */ @ApiModelProperty(value = "生产批号") private String batchNo; src/main/java/com/ruoyi/production/service/ProductOrderService.java
@@ -3,7 +3,6 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.production.dto.ProductBomDto; import com.ruoyi.production.dto.ProductOrderDto; import com.ruoyi.production.dto.ProductStructureDto; import com.ruoyi.production.pojo.ProcessRoute; @@ -22,7 +21,7 @@ List<ProductStructureDto> listProcessBom(Long orderId); Boolean addProductOrder(ProductOrder productOrder); Boolean addProductOrder(ProductOrderDto productOrderDto); Boolean delete(Long[] id); } src/main/java/com/ruoyi/production/service/impl/ProductOrderServiceImpl.java
@@ -7,8 +7,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum; import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum; import com.ruoyi.common.utils.bean.BeanUtils; import com.ruoyi.procurementrecord.utils.StockUtils; import com.ruoyi.production.dto.ProductOrderDto; import com.ruoyi.production.dto.ProductStructureDto; @@ -16,7 +15,8 @@ import com.ruoyi.production.pojo.*; import com.ruoyi.production.service.ProductOrderService; import com.ruoyi.quality.mapper.QualityInspectMapper; import com.ruoyi.quality.pojo.QualityInspect; import com.ruoyi.stock.mapper.StockInventoryMapper; import com.ruoyi.stock.pojo.StockInventory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -24,6 +24,8 @@ import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @Service @@ -64,6 +66,9 @@ @Autowired private StockUtils stockUtils; @Autowired private StockInventoryMapper stockInventoryMapper; @Override public IPage<ProductOrderDto> pageProductOrder(Page page, ProductOrderDto productOrder) { @@ -135,10 +140,33 @@ } @Override public Boolean addProductOrder(ProductOrder productOrder) { public Boolean addProductOrder(ProductOrderDto productOrderDto) { String string = generateNextOrderNo(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"))); ProductOrder productOrder = new ProductOrder(); BeanUtils.copyProperties(productOrderDto, productOrder); productOrder.setNpsNo(string); productOrder.setCompleteQuantity(BigDecimal.ZERO); List<StockInventory> stockInventoryList = stockInventoryMapper.selectList(null); if (productOrder.getBatchNo() == null || productOrder.getBatchNo().isEmpty()) { String batchNo; // 获取当前月份(两位) LocalDate now = LocalDate.now(); String monthFlag = now.format(DateTimeFormatter.ofPattern("MM")); // 获取当前月份的最大流水号 int maxSeq = getCurrentMonthMaxSeq(productOrderDto.getMaterialCode(), productOrderDto.getProductModelName(), monthFlag, stockInventoryList); // 新流水号 = 最大流水号 + 1 int newSeq = maxSeq + 1; String seqStr = String.format("%03d", newSeq); // 组装batchNo batchNo = productOrderDto.getMaterialCode() + productOrderDto.getProductModelName() + "P" + monthFlag + seqStr; productOrder.setBatchNo(batchNo); } else { productOrder.setBatchNo(productOrder.getBatchNo()); } this.save(productOrder); if (ObjectUtils.isNotEmpty(productOrder.getRouteId())) { this.bindingRoute(productOrder); @@ -146,16 +174,38 @@ return true; } /** * 查询当前月份已存在的最大流水号 */ private static int getCurrentMonthMaxSeq(String materialCode, String model, String monthFlag, List<StockInventory> existingList) { int maxSeq = 0; String prefix = materialCode + model + "P" + monthFlag; // 正则匹配:前缀 + 3位数字 Pattern pattern = Pattern.compile(Pattern.quote(prefix) + "(\\d{3})"); for (StockInventory item : existingList) { String batchNo = item.getBatchNo(); if (batchNo == null) continue; Matcher matcher = pattern.matcher(batchNo); if (matcher.find()) { int seq = Integer.parseInt(matcher.group(1)); if (seq > maxSeq) { maxSeq = seq; } } } return maxSeq; } @Override public Boolean delete(Long[] ids) { //如果已经开始生产,不能删除 //查询生产订单下的工单 List<ProductWorkOrder> productWorkOrders = productWorkOrderMapper.selectList(Wrappers.<ProductWorkOrder>lambdaQuery().in(ProductWorkOrder::getProductOrderId, ids)); if (productWorkOrders.size()>0){ if (productWorkOrders.size() > 0) { //判断是否有报工数据 List<ProductionProductMain> productionProductMains = productionProductMainMapper.selectList(Wrappers.<ProductionProductMain>lambdaQuery() .in(ProductionProductMain::getWorkOrderId, productWorkOrders.stream().map(ProductWorkOrder::getId).collect(Collectors.toList()))); if (productionProductMains.size()>0){ if (productionProductMains.size() > 0) { throw new RuntimeException("生产订单已经开始生产,不能删除"); } //删除工单 src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
@@ -13,8 +13,8 @@ import com.ruoyi.basic.pojo.Product; import com.ruoyi.basic.pojo.ProductModel; import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum; import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum; import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum; import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.bean.BeanUtils; import com.ruoyi.procurementrecord.utils.StockUtils; @@ -32,14 +32,14 @@ import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.ruoyi.production.mapper.ProductionProductMainMapper; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @Service @@ -177,7 +177,7 @@ productionProductMainMapper.insert(productionProductMain); /*新增报工投入表*/ List<ProductStructureDto> productStructureDtos = productStructureMapper.listBybomAndProcess(productProcessRoute.getBomId(), productProcess.getId()); if (productStructureDtos.size() == 0) { if (productStructureDtos.isEmpty()) { //如果该工序没有产品结构的投入品,那这个投入品和产出品是同一个 ProductStructureDto productStructureDto = new ProductStructureDto(); productStructureDto.setProductModelId(productProcessRouteItem.getProductModelId()); @@ -191,8 +191,7 @@ productionProductInput.setQuantity(productStructureDto.getUnitQuantity().multiply(dto.getQuantity())); productionProductInput.setProductMainId(productionProductMain.getId()); productionProductInputMapper.insert(productionProductInput); stockUtils.substractStock(productStructureDto.getProductModelId(), productionProductInput.getQuantity(), StockOutQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode(), productionProductMain.getId()); stockUtils.substractStock(productStructureDto.getProductModelId(), productionProductInput.getQuantity(), StockOutQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode(), productionProductMain.getId(),dto.getBatchNo()); } /*新增报工产出表*/ ProductionProductOutput productionProductOutput = new ProductionProductOutput(); src/main/java/com/ruoyi/sales/service/impl/ShippingInfoServiceImpl.java
@@ -66,7 +66,7 @@ //扣减库存 if(!"已发货".equals(byId.getStatus())){ SalesLedgerProduct salesLedgerProduct = salesLedgerProductMapper.selectById(byId.getSalesLedgerProductId()); stockUtils.substractStock(salesLedgerProduct.getProductModelId(), salesLedgerProduct.getQuantity(), StockOutQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode(), req.getId()); stockUtils.substractStock(salesLedgerProduct.getProductModelId(), salesLedgerProduct.getQuantity(), StockOutQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode(), req.getId(),null); } byId.setExpressNumber(req.getExpressNumber()); byId.setExpressCompany(req.getExpressCompany()); src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
@@ -250,7 +250,8 @@ stockOutRecordDto.setProductModelId(stockInventoryDto.getProductModelId()); stockOutRecordDto.setType("0"); stockOutRecordService.add(stockOutRecordDto); StockInventory oldStockInventory = stockInventoryMapper.selectOne(new QueryWrapper<StockInventory>().lambda().eq(StockInventory::getProductModelId, stockInventoryDto.getProductModelId())); StockInventory oldStockInventory = stockInventoryMapper.selectOne(new QueryWrapper<StockInventory>().lambda().eq(StockInventory::getProductModelId, stockInventoryDto.getProductModelId()) .eq(StockInventory::getBatchNo, stockInventoryDto.getBatchNo())); if (ObjectUtils.isEmpty(oldStockInventory)) { throw new RuntimeException("产品库存不存在"); } src/main/resources/application-dev.yml
@@ -28,7 +28,7 @@ # 开发环境配置 server: # 服务器的HTTP端口,默认为8080 port: 7003 port: 8888 servlet: # 应用的访问路径 context-path: / @@ -42,13 +42,6 @@ max: 800 # Tomcat启动初始化的线程数,默认值10 min-spare: 100 # 日志配置 logging: level: org.quartz: DEBUG com.ruoyi: warn org.springframework: warn minio: endpoint: http://114.132.189.42/ @@ -74,8 +67,10 @@ druid: # 主库数据源 master: url: jdbc:mysql://localhost:3306/product-inventory-management-new?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 # url: jdbc:mysql://1.15.17.182:9999/product-inventory-management-new?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 url: jdbc:mysql://localhost:3307/product-inventory-management-pcdz?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 username: root # password: xd@123456.. password: 123456 # 从库数据源 slave: @@ -154,7 +149,7 @@ database: 0 # 密码 # password: root2022! password: password: 123456 # 连接超时时间 timeout: 10s @@ -205,16 +200,30 @@ # MyBatis Plus配置 mybatis-plus: # 搜索指定包别名 根据自己的项目来 typeAliasesPackage: com.ruoyi.**.pojo # 配置mapper的扫描,找到所有的mapper.xml映射文件 mapperLocations: classpath*:mapper/**/*Mapper.xml # 加载全局的配置文件 configLocation: classpath:mybatis/mybatis-config.xml configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl map-underscore-to-camel-case: true type-aliases-package: com.ruoyi.**.pojo mapper-locations: classpath*:mapper/**/*Mapper.xml global-config: enable-sql-runner: true banner: false db-config: id-type: auto # 日志配置 logging: level: root: INFO com.ruoyi.production.mapper: DEBUG org.apache.ibatis: DEBUG org.mybatis: DEBUG java.sql: DEBUG java.sql.Connection: DEBUG java.sql.Statement: DEBUG java.sql.PreparedStatement: DEBUG java.sql.ResultSet: DEBUG com.baomidou.mybatisplus: DEBUG com.baomidou.mybatisplus.core: DEBUG # PageHelper分页插件 pagehelper: @@ -253,4 +262,4 @@ file: temp-dir: D:/ruoyi/temp/uploads # 临时目录 upload-dir: D:/ruoyi/prod/uploads # 正式目录 upload-dir: D:/ruoyi/prod/uploads # 正式目录 src/main/resources/mapper/production/ProductWorkOrderMapper.xml
@@ -21,6 +21,7 @@ <select id="pageProductWorkOrder" resultType="com.ruoyi.production.dto.ProductWorkOrderDto"> SELECT pwo.*, po.batch_no as batchNo, pp.id as processId, pp.NAME as processName, pp.qualified_rate as processQualifiedRate,