src/main/java/com/ruoyi/approve/controller/ApproveNodeController.java
@@ -49,7 +49,7 @@ */ @PostMapping("/init") public AjaxResult init(String id) { approveNodeService.initApproveNodes("",id,1L); approveNodeService.initApproveNodes("",id,1L,null); return AjaxResult.success(); } src/main/java/com/ruoyi/approve/pojo/ApproveNode.java
@@ -40,6 +40,10 @@ * 审批编号 */ private String approveProcessId; /** * 审批id */ private Long processId; /** * 审批节点顺序 src/main/java/com/ruoyi/approve/pojo/ApproveProcess.java
@@ -188,4 +188,10 @@ * 入库id */ private Long recordId; /** * 采购id */ @ApiModelProperty(value = "采购id") private Long purchaseLedgerId; } src/main/java/com/ruoyi/approve/service/IApproveNodeService.java
@@ -8,7 +8,7 @@ public interface IApproveNodeService extends IService<ApproveNode> { void initApproveNodes(String approveUserIds,String approveID,Long tenantId); void initApproveNodes(String approveUserIds,String approveID,Long tenantId,Long approveProcessId); /** * 详情 * @param id src/main/java/com/ruoyi/approve/service/impl/ApproveNodeServiceImpl.java
@@ -95,7 +95,6 @@ private StockInventoryService stockInventoryService; public ApproveProcess getApproveById(String id) { LambdaQueryWrapper<ApproveProcess> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(ApproveProcess::getApproveId, id); @@ -107,7 +106,7 @@ } @Override public void initApproveNodes(String approveUserIds, String approveID, Long tenantId) { public void initApproveNodes(String approveUserIds, String approveID, Long tenantId, Long approveProcessId) { Long userId = SecurityUtils.getLoginUser().getUser().getUserId(); String[] names = approveUserIds.split(","); for (int i = 0; i < names.length; i++) { @@ -126,6 +125,9 @@ approveNode.setUpdateUser(userId); approveNode.setCreateTime(LocalDateTime.now()); approveNode.setUpdateTime(LocalDateTime.now()); if (approveProcessId != null) { approveNode.setProcessId(approveProcessId); } approveNodeMapper.insert(approveNode); } } @@ -314,6 +316,20 @@ stockInRecordService.updateById(stockInRecord); } } if (approveProcess.getApproveType() == 5) { //采购入库 ApproveProcess process = approveProcessMapper.selectById(approveNode.getProcessId()); List<SalesLedgerProduct> salesLedgerProductList = salesLedgerProductMapper.selectList(new LambdaQueryWrapper<SalesLedgerProduct>().in(SalesLedgerProduct::getSalesLedgerId, process.getPurchaseLedgerId()) .eq(SalesLedgerProduct::getType, 2)); for (SalesLedgerProduct salesLedgerProduct : salesLedgerProductList) { StockInRecord stockInRecord = new StockInRecord(); stockInRecord.setStockInNum(salesLedgerProduct.getQuantity()); stockInRecord.setProductModelId(salesLedgerProduct.getProductModelId()); stockInRecord.setWarnNum(salesLedgerProduct.getWarnNum()); stockInRecord.setBatchNo(salesLedgerProduct.getBatchNo()); stockInventoryService.updateOrCreateStockInventory(stockInRecord); } } } break; case 2: src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java
@@ -120,8 +120,8 @@ .getNickName()); approveProcess.setStorageType(approveProcessVO.getStorageType()); approveProcess.setInventoryReview(approveProcessVO.isInventoryReview()); approveProcess.setInventoryReview(approveProcessVO.isInventoryReview()); approveProcess.setRecordId(approveProcessVO.getRecordId()); approveProcess.setPurchaseLedgerId(approveProcessVO.getPurchaseLedgerId()); // 设置状态为重新提交 if (approveProcessVO.getId() != null) { ApproveProcess approveProcess1 = approveProcessMapper.selectById(approveProcessVO.getId()); @@ -130,7 +130,7 @@ } save(approveProcess); //初始化审批节点 approveNodeService.initApproveNodes(approveProcessVO.getApproveUserIds(), approveID, approveProcessVO.getApproveDeptId()); approveNodeService.initApproveNodes(approveProcessVO.getApproveUserIds(), approveID, approveProcessVO.getApproveDeptId(),approveProcess.getId()); // 附件绑定 tempFileService.migrateTempFilesToFormal(approveProcess.getId(), approveProcessVO.getTempFileIds(), FileNameType.ApproveProcess.getValue()); /*消息通知*/ @@ -336,7 +336,7 @@ // .eq(ApproveNode::getTenantId, SecurityUtils.getLoginUser().getTenantId()) .orderByAsc(ApproveNode::getApproveNodeOrder); approveNodeMapper.delete(approveNodeLambdaQueryWrapper); approveNodeService.initApproveNodes(approveGetAndUpdateVo.getApproveUserIds(), approveProcess.getApproveId(), approveProcess.getTenantId()); approveNodeService.initApproveNodes(approveGetAndUpdateVo.getApproveUserIds(), approveProcess.getApproveId(), approveProcess.getTenantId(),null); /*消息通知*/ String id = approveProcess.getApproveUserIds().split(",")[0]; if (approveProcess.getApproveType() == 8) { @@ -383,7 +383,7 @@ // .eq(ApproveNode::getTenantId, SecurityUtils.getLoginUser().getTenantId()) .orderByAsc(ApproveNode::getApproveNodeOrder); approveNodeMapper.delete(approveNodeLambdaQueryWrapper); approveNodeService.initApproveNodes(approveGetAndUpdateVo.getApproveUserIds(), approve.getApproveId(), approve.getTenantId()); approveNodeService.initApproveNodes(approveGetAndUpdateVo.getApproveUserIds(), approve.getApproveId(), approve.getTenantId(),approve.getId()); // int i = 0; // for (ApproveNode approveNode : list) { src/main/java/com/ruoyi/approve/vo/ApproveProcessVO.java
@@ -90,4 +90,10 @@ */ @ApiModelProperty(value = "入库id") private Long recordId; /** * 采购id */ @ApiModelProperty(value = "采购id") private Long purchaseLedgerId; } src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java
@@ -1,29 +1,23 @@ package com.ruoyi.purchase.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.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.account.pojo.AccountExpense; import com.ruoyi.account.pojo.AccountIncome; import com.ruoyi.account.service.AccountExpenseService; import com.ruoyi.account.service.AccountIncomeService; import com.ruoyi.approve.pojo.ApproveProcess; import com.ruoyi.approve.service.impl.ApproveProcessServiceImpl; import com.ruoyi.approve.vo.ApproveProcessVO; import com.ruoyi.basic.mapper.ProductMapper; import com.ruoyi.basic.mapper.ProductModelMapper; import com.ruoyi.basic.mapper.SupplierManageMapper; import com.ruoyi.basic.pojo.Customer; import com.ruoyi.basic.pojo.Product; import com.ruoyi.basic.pojo.ProductModel; import com.ruoyi.basic.pojo.SupplierManage; import com.ruoyi.common.enums.FileNameType; import com.ruoyi.common.exception.base.BaseException; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.poi.ExcelUtil; @@ -39,19 +33,27 @@ import com.ruoyi.purchase.dto.PurchaseLedgerImportDto; import com.ruoyi.purchase.dto.PurchaseLedgerProductImportDto; import com.ruoyi.purchase.mapper.*; import com.ruoyi.purchase.pojo.*; import com.ruoyi.purchase.pojo.PaymentRegistration; import com.ruoyi.purchase.pojo.ProductRecord; import com.ruoyi.purchase.pojo.PurchaseLedger; import com.ruoyi.purchase.pojo.TicketRegistration; import com.ruoyi.purchase.service.IPurchaseLedgerService; import com.ruoyi.quality.mapper.*; import com.ruoyi.quality.pojo.*; import com.ruoyi.sales.dto.SalesLedgerImportDto; import com.ruoyi.sales.dto.SalesLedgerProductImportDto; import com.ruoyi.sales.mapper.*; import com.ruoyi.quality.pojo.QualityInspect; import com.ruoyi.quality.pojo.QualityInspectParam; import com.ruoyi.quality.pojo.QualityTestStandard; import com.ruoyi.quality.pojo.QualityTestStandardParam; import com.ruoyi.sales.mapper.CommonFileMapper; import com.ruoyi.sales.mapper.InvoiceRegistrationProductMapper; import com.ruoyi.sales.mapper.SalesLedgerMapper; import com.ruoyi.sales.mapper.SalesLedgerProductMapper; import com.ruoyi.sales.pojo.CommonFile; import com.ruoyi.sales.pojo.InvoiceRegistrationProduct; import com.ruoyi.sales.pojo.SalesLedger; import com.ruoyi.sales.pojo.SalesLedgerProduct; import com.ruoyi.sales.service.impl.CommonFileServiceImpl; import lombok.RequiredArgsConstructor; import com.ruoyi.stock.mapper.StockInventoryMapper; import com.ruoyi.stock.pojo.StockInventory; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FilenameUtils; import org.springframework.beans.BeanUtils; @@ -76,6 +78,8 @@ import java.time.format.DateTimeFormatter; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; /** @@ -150,6 +154,8 @@ private PurchaseLedgerTemplateMapper purchaseLedgerTemplateMapper; @Autowired private SalesLedgerProductTemplateMapper salesLedgerProductTemplateMapper; @Autowired private StockInventoryMapper stockInventoryMapper; @Value("${file.upload-dir}") private String uploadDir; @@ -284,9 +290,21 @@ } // 设置字段 List<StockInventory> stockInventoryList = stockInventoryMapper.selectList(null); for (SalesLedgerProduct product : products) { product.setSalesLedgerId(salesLedgerId); // 获取当前月份(两位) LocalDate now = LocalDate.now(); String monthFlag = now.format(DateTimeFormatter.ofPattern("MM")); // 获取当前月份的最大流水号 int maxSeq = getCurrentMonthMaxSeq(product.getMaterialCode(), product.getSpecificationModel(), monthFlag, stockInventoryList); // 新流水号 = 最大流水号 + 1 int newSeq = maxSeq + 1; String seqStr = String.format("%03d", newSeq); // 组装batchNo String batchNo = product.getMaterialCode() + product.getSpecificationModel() + "P" + monthFlag + seqStr; product.setSalesLedgerId(salesLedgerId); product.setBatchNo(batchNo); Long productId = product.getProductId(); if (productId != null && productMap.containsKey(productId)) { product.setProductCategory(productMap.get(productId)); @@ -341,6 +359,33 @@ // 直接更新指定ID的记录的contractAmount字段为totalTaxInclusiveAmount purchaseLedgerMapper.updateContractAmountById(salesLedgerId, totalTaxInclusiveAmount); } } /** * 查询当前月份已存在的最大流水号 */ 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; } /** @@ -808,6 +853,7 @@ approveProcessVO.setApproveUserIds(purchaseLedger.getApproveUserIds()); approveProcessVO.setApproveUser(loginUser.getUserId()); approveProcessVO.setApproveTime(LocalDate.now().toString()); approveProcessVO.setPurchaseLedgerId(purchaseLedger.getId()); approveProcessService.addApprove(approveProcessVO); } src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java
@@ -78,8 +78,13 @@ */ @Excel(name = "数量") private BigDecimal quantity; /** * 最低库存数量 */ @Excel(name = "最低库存数量") private BigDecimal minStock; /** * 税率 */ @@ -242,4 +247,7 @@ @TableField(exist = false) private Integer hasSufficientStock; @ApiModelProperty("批号") private String batchNo; } src/main/java/com/ruoyi/stock/pojo/StockInRecord.java
@@ -75,4 +75,7 @@ @ApiModelProperty(value = "审批状态:0待审核,1审核中,2审核完成 3审核未通过 4已重新提交") @Excel(name = "审批状态", readConverterExp = "0=待审核,1=审核中,2=审核完成,3=审核未通过,4=已重新提交") private Integer approveStatus; @ApiModelProperty("批号") private String batchNo; } src/main/java/com/ruoyi/stock/pojo/StockInventory.java
@@ -63,4 +63,7 @@ @ApiModelProperty("备注") private String remark; @ApiModelProperty("批号") private String batchNo; } src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
@@ -37,9 +37,12 @@ import javax.servlet.http.HttpServletResponse; import java.math.BigDecimal; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * <p> @@ -76,6 +79,7 @@ @Override @Transactional(rollbackFor = Exception.class) public Boolean addstockInventory(StockInventoryDto stockInventoryDto) { List<StockInventory> stockInventoryList = stockInventoryMapper.selectList(null); //新增入库记录再添加库存 StockInRecordDto stockInRecordDto = new StockInRecordDto(); stockInRecordDto.setRecordId(stockInventoryDto.getRecordId()); @@ -87,16 +91,62 @@ stockInRecordDto.setLockedQuantity(stockInventoryDto.getLockedQuantity()); stockInRecordDto.setApproveStatus(0); stockInRecordDto.setType("0"); if (stockInventoryDto.getBatchNo() == null || stockInventoryDto.getBatchNo().isEmpty()) { String batchNo; // 获取当前月份(两位) LocalDate now = LocalDate.now(); String monthFlag = now.format(DateTimeFormatter.ofPattern("MM")); // 获取当前月份的最大流水号 int maxSeq = getCurrentMonthMaxSeq(stockInventoryDto, monthFlag, stockInventoryList); // 新流水号 = 最大流水号 + 1 int newSeq = maxSeq + 1; String seqStr = String.format("%03d", newSeq); // 组装batchNo batchNo = stockInventoryDto.getMaterialCode() + stockInventoryDto.getModel() + "P" + monthFlag + seqStr; stockInRecordDto.setBatchNo(batchNo); } else { stockInRecordDto.setBatchNo(stockInventoryDto.getBatchNo()); } Long id = stockInRecordService.add(stockInRecordDto); LoginUser loginUser = SecurityUtils.getLoginUser(); if (id != null) { try { addApproveByPurchase(loginUser, stockInRecordDto,id); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e.getMessage()); } } return true; } /** * 查询当前月份已存在的最大流水号 */ private static int getCurrentMonthMaxSeq(StockInventoryDto dto, String monthFlag, List<StockInventory> existingList) { int maxSeq = 0; String prefix = dto.getMaterialCode() + dto.getModel() + "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; } public void addApproveByPurchase(LoginUser loginUser, StockInRecordDto stockInRecordDto,Long id) throws Exception { @@ -123,6 +173,7 @@ StockInventory oldStockInventory = stockInventoryMapper.selectOne( new QueryWrapper<StockInventory>().lambda() .eq(StockInventory::getProductModelId, stockInRecord.getProductModelId()) .eq(StockInventory::getBatchNo, stockInRecord.getBatchNo()) ); if (ObjectUtils.isEmpty(oldStockInventory)) { @@ -134,12 +185,14 @@ newStockInventory.setRemark(stockInRecord.getRemark()); newStockInventory.setLockedQuantity(stockInRecord.getLockedQuantity()); newStockInventory.setWarnNum(stockInRecord.getWarnNum()); newStockInventory.setBatchNo(stockInRecord.getBatchNo()); stockInventoryMapper.insert(newStockInventory); } else { // 存在则更新 LambdaUpdateWrapper<StockInventory> updateWrapper = new LambdaUpdateWrapper<>(); updateWrapper .eq(StockInventory::getProductModelId, stockInRecord.getProductModelId()) .eq(StockInventory::getBatchNo, stockInRecord.getBatchNo()) .setSql(stockInRecord.getStockInNum() != null, "qualitity = qualitity + " + stockInRecord.getStockInNum()) .setSql(true, "version = version + 1") src/main/resources/mapper/stock/StockInventoryMapper.xml
@@ -68,7 +68,8 @@ pm.material_code as materialCode, p.product_name, p.parent_id, p2.product_name AS parent_name p2.product_name AS parent_name, si.batch_no FROM stock_inventory si LEFT JOIN product_model pm ON si.product_model_id = pm.id LEFT JOIN product p ON pm.product_id = p.id