| | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; |
| | | |
| | | 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.account.service.AccountIncomeService; |
| | | import com.ruoyi.approve.service.IApproveProcessService; |
| | | import com.ruoyi.approve.vo.ApproveProcessVO; |
| | | import com.fasterxml.jackson.databind.JsonNode; |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import com.fasterxml.jackson.databind.node.ObjectNode; |
| | | import com.ruoyi.account.service.AccountIncomeService; |
| | | import com.ruoyi.approve.pojo.ApproveProcess; |
| | | import com.ruoyi.common.enums.ApproveTypeEnum; |
| | | import com.ruoyi.approve.service.IApproveProcessService; |
| | | import com.ruoyi.approve.vo.ApproveProcessVO; |
| | | import com.ruoyi.basic.mapper.CustomerMapper; |
| | | import com.ruoyi.basic.mapper.ProductMapper; |
| | | import com.ruoyi.basic.mapper.ProductModelMapper; |
| | |
| | | import com.ruoyi.basic.pojo.Product; |
| | | import com.ruoyi.basic.pojo.ProductModel; |
| | | import com.ruoyi.basic.service.ICustomerRegionsService; |
| | | import com.ruoyi.common.enums.FileNameType; |
| | | import com.ruoyi.common.enums.SaleEnum; |
| | | import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum; |
| | | import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum; |
| | | import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum; |
| | | import com.ruoyi.common.enums.StockOutUnQualifiedRecordTypeEnum; |
| | | import com.ruoyi.common.enums.*; |
| | | import com.ruoyi.common.exception.ServiceException; |
| | | import com.ruoyi.common.exception.base.BaseException; |
| | | import com.ruoyi.common.utils.DateUtils; |
| | | import com.ruoyi.common.utils.EnumUtil; |
| | | import com.ruoyi.common.utils.OrderUtils; |
| | | import com.ruoyi.common.utils.SecurityUtils; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import com.ruoyi.common.utils.*; |
| | | import com.ruoyi.common.utils.poi.ExcelUtil; |
| | | import com.ruoyi.framework.security.LoginUser; |
| | | import com.ruoyi.other.mapper.TempFileMapper; |
| | | import com.ruoyi.other.pojo.TempFile; |
| | | import com.ruoyi.procurementrecord.utils.StockUtils; |
| | | import com.ruoyi.production.mapper.*; |
| | | import com.ruoyi.production.pojo.ProcessRoute; |
| | | import com.ruoyi.production.pojo.ProcessRouteItem; |
| | | import com.ruoyi.production.service.ProductionProductMainService; |
| | | |
| | | import com.ruoyi.project.system.domain.SysUser; |
| | | import com.ruoyi.project.system.mapper.SysDeptMapper; |
| | | import com.ruoyi.project.system.mapper.SysUserMapper; |
| | | import com.ruoyi.procurementrecord.utils.StockUtils; |
| | | import com.ruoyi.purchase.dto.SimpleReturnOrderGroupDto; |
| | | import com.ruoyi.purchase.mapper.PurchaseReturnOrderProductsMapper; |
| | | import com.ruoyi.quality.mapper.QualityInspectMapper; |
| | |
| | | import com.ruoyi.sales.service.ISalesLedgerService; |
| | | import com.ruoyi.stock.dto.StockInventoryDto; |
| | | import com.ruoyi.stock.mapper.StockInRecordMapper; |
| | | import com.ruoyi.stock.mapper.StockInventoryMapper; |
| | | import com.ruoyi.stock.mapper.StockOutRecordMapper; |
| | | import com.ruoyi.stock.pojo.StockInRecord; |
| | | import com.ruoyi.stock.pojo.StockOutRecord; |
| | |
| | | import java.nio.file.StandardCopyOption; |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | import java.time.ZoneId; |
| | | import java.time.YearMonth; |
| | | import java.time.ZoneId; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.*; |
| | | import java.util.concurrent.TimeUnit; |
| | |
| | | private final StockInventoryService stockInventoryService; |
| | | private final StockInRecordMapper stockInRecordMapper; |
| | | private final StockOutRecordMapper stockOutRecordMapper; |
| | | private final StockInventoryMapper stockInventoryMapper; |
| | | private final StockInRecordService stockInRecordService; |
| | | private final StockOutRecordService stockOutRecordService; |
| | | private final StockUtils stockUtils; |
| | |
| | | |
| | | @Override |
| | | public IPage<SalesLedger> selectSalesLedgerListPage(Page page, SalesLedgerDto salesLedgerDto) { |
| | | // 添加 reviewStatus 的筛选条件 |
| | | IPage<SalesLedger> iPage = salesLedgerMapper.selectSalesLedgerListPage(page, salesLedgerDto); |
| | | |
| | | if (CollectionUtils.isEmpty(iPage.getRecords())) { |
| | |
| | | salesLedger.setIsFh(isFh); |
| | | |
| | | salesLedger.setIsEdit(!isFh); |
| | | |
| | | // 根据 reviewStatus 控制反审相关字段的显示 |
| | | if (salesLedger.getReviewStatus() != null && salesLedger.getReviewStatus() != 2) { |
| | | // 当 reviewStatus 不为 2 时,隐藏反审时间、反审人和反审人ID |
| | | salesLedger.setCounterReviewTime(null); |
| | | salesLedger.setCounterReviewPerson(null); |
| | | salesLedger.setCounterReviewPersonId(null); |
| | | } |
| | | } |
| | | |
| | | if (salesLedgerDto.getStatus() != null && salesLedgerDto.getStatus()) { |
| | |
| | | } else { |
| | | if (salesLedger.getDeliveryStatus() == 5) { |
| | | throw new ServiceException("订单已发货,禁止编辑"); |
| | | } |
| | | if (salesLedger.getReviewStatus() != null && salesLedger.getReviewStatus() == 1) { |
| | | salesLedger.setReviewStatus(salesLedgerDto.getReviewStatus()); |
| | | } else if (salesLedger.getReviewStatus() != null && salesLedger.getReviewStatus() == 2) { |
| | | handleCounterReview(salesLedger); |
| | | } else { |
| | | salesLedger.setReviewStatus(0); |
| | | } |
| | | salesLedgerMapper.updateById(salesLedger); |
| | | } |
| | |
| | | } |
| | | baseMapper.updateById(salesLedger); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 处理销售台账反审逻辑 |
| | | * 1. 设置反审相关信息(时间、人员) |
| | | * 2. 复制原销售台账及产品数据,生成新的台账 |
| | | * 3. 对原台账的库存数据进行反向操作 |
| | | */ |
| | | private void handleCounterReview(SalesLedger salesLedger) { |
| | | // 1. 设置反审相关信息 |
| | | LoginUser loginUser = SecurityUtils.getLoginUser(); |
| | | salesLedger.setCounterReviewTime(LocalDateTime.now()); |
| | | salesLedger.setCounterReviewPerson(loginUser.getUser().getNickName()); |
| | | salesLedger.setCounterReviewPersonId(loginUser.getUserId()); |
| | | salesLedger.setReviewStatus(2); |
| | | |
| | | Long originalSalesLedgerId = salesLedger.getId(); |
| | | |
| | | // 2. 查询原销售台账数据 |
| | | SalesLedger originalLedger = salesLedgerMapper.selectById(originalSalesLedgerId); |
| | | if (originalLedger == null) { |
| | | throw new ServiceException("原订单不存在,无法反审"); |
| | | } |
| | | |
| | | // 3. 创建新的销售台账,复制原台账数据 |
| | | SalesLedger newLedger = new SalesLedger(); |
| | | BeanUtils.copyProperties(originalLedger, newLedger); |
| | | newLedger.setId(null); // 清空ID,准备插入新记录 |
| | | newLedger.setSalesContractNo(generateSalesContractNo()); // 生成新合同号 |
| | | newLedger.setDeliveryStatus(1); // 设置为未发货状态 |
| | | newLedger.setStockStatus(0); // 设置为未入库状态 |
| | | newLedger.setReviewStatus(0); // 设置为未审核状态 |
| | | newLedger.setCounterReviewTime(null); // 清空反审时间 |
| | | newLedger.setCounterReviewPerson(null); // 清空反审人 |
| | | newLedger.setCounterReviewPersonId(null); // 清空反审人ID |
| | | |
| | | // 4. 插入新的销售台账 |
| | | salesLedgerMapper.insert(newLedger); |
| | | |
| | | // 5. 查询并复制原台账的所有产品数据 |
| | | List<SalesLedgerProduct> originalProducts = salesLedgerProductMapper.selectList( |
| | | Wrappers.<SalesLedgerProduct>lambdaQuery() |
| | | .eq(SalesLedgerProduct::getSalesLedgerId, originalSalesLedgerId) |
| | | ); |
| | | |
| | | for (SalesLedgerProduct originalProduct : originalProducts) { |
| | | // 5.1 创建新产品记录,复制原产品数据 |
| | | SalesLedgerProduct newProduct = new SalesLedgerProduct(); |
| | | BeanUtils.copyProperties(originalProduct, newProduct); |
| | | newProduct.setId(null); // 清空ID,准备插入新记录 |
| | | newProduct.setSalesLedgerId(newLedger.getId()); // 关联到新的台账ID |
| | | newProduct.setStockedQuantity(BigDecimal.ZERO); // 已入库数量重置为0 |
| | | newProduct.setShippedQuantity(BigDecimal.ZERO); // 已出库数量重置为0 |
| | | newProduct.setUnqualifiedStockedQuantity(BigDecimal.ZERO); // 不合格入库数量重置为0 |
| | | newProduct.setUnqualifiedShippedQuantity(BigDecimal.ZERO); // 不合格出库数量重置为0 |
| | | newProduct.setReturnQuality(BigDecimal.ZERO); // 退货数量重置为0 |
| | | newProduct.setAvailableQuality(newProduct.getQuantity().subtract(newProduct.getReturnQuality())); // 重新计算可用数量 |
| | | newProduct.setProductStockStatus(0); // 产品库存状态重置为0 |
| | | newProduct.fillRemainingQuantity(); // 重新计算剩余数量 |
| | | |
| | | // 5.2 插入新产品记录 |
| | | salesLedgerProductMapper.insert(newProduct); |
| | | } |
| | | |
| | | // 6. 处理原订单的库存数据(生成反审出入库记录) |
| | | processOriginalOrderStock(originalSalesLedgerId); |
| | | } |
| | | |
| | | /** |
| | | * 处理原订单的库存数据 |
| | | * 1. 对原订单的入库数据生成反审出库记录(销售-反审出库) |
| | | * 2. 对原订单的出库数据生成反审入库记录(销售-反审入库) |
| | | * 3. 更新库存表数据 |
| | | */ |
| | | private void processOriginalOrderStock(Long originalSalesLedgerId) { |
| | | // 1. 查询原订单的所有入库记录 |
| | | List<StockInRecord> stockInRecords = stockInRecordMapper.selectList( |
| | | Wrappers.<StockInRecord>lambdaQuery() |
| | | .eq(StockInRecord::getSalesLedgerId, originalSalesLedgerId) |
| | | ); |
| | | |
| | | // 2. 对每条入库记录生成对应的反审出库记录 |
| | | for (StockInRecord stockInRecord : stockInRecords) { |
| | | // 2.1 创建反审出库记录 |
| | | StockOutRecord stockOutRecord = new StockOutRecord(); |
| | | stockOutRecord.setOutboundBatches(OrderUtils.countTodayByCreateTime(stockOutRecordMapper, "CK")); // 生成出库批次号 |
| | | stockOutRecord.setStockOutNum(stockInRecord.getStockInNum()); // 出库数量等于原入库数量 |
| | | stockOutRecord.setRecordId(stockInRecord.getId()); // 记录原入库记录ID |
| | | stockOutRecord.setRecordType(StockOutQualifiedRecordTypeEnum.SALE_COUNTER_REVIEW_STOCK_OUT.getCode()); // 设置为销售反审出库类型 |
| | | stockOutRecord.setProductModelId(stockInRecord.getProductModelId()); // 产品规格ID |
| | | stockOutRecord.setRemark("销售-反审出库"); // 备注 |
| | | stockOutRecord.setType(stockInRecord.getType()); // 类型(合格/不合格) |
| | | stockOutRecord.setSalesLedgerId(stockInRecord.getSalesLedgerId()); // 销售订单ID |
| | | stockOutRecord.setSalesLedgerProductId(stockInRecord.getSalesLedgerProductId()); // 销售订单产品ID |
| | | |
| | | // 2.2 插入反审出库记录 |
| | | stockOutRecordMapper.insert(stockOutRecord); |
| | | |
| | | // 2.3 从库存表中扣减相应数量 |
| | | StockInventoryDto stockInventoryDto = new StockInventoryDto(); |
| | | stockInventoryDto.setProductModelId(stockOutRecord.getProductModelId()); |
| | | stockInventoryDto.setQualitity(stockOutRecord.getStockOutNum()); |
| | | stockInventoryMapper.updateSubtractStockInventory(stockInventoryDto); |
| | | } |
| | | |
| | | // 3. 查询原订单的所有出库记录 |
| | | List<StockOutRecord> stockOutRecords = stockOutRecordMapper.selectList( |
| | | Wrappers.<StockOutRecord>lambdaQuery() |
| | | .eq(StockOutRecord::getSalesLedgerId, originalSalesLedgerId) |
| | | ); |
| | | |
| | | // 4. 对每条出库记录生成对应的反审入库记录 |
| | | for (StockOutRecord stockOutRecord : stockOutRecords) { |
| | | // 4.1 创建反审入库记录 |
| | | StockInRecord stockInRecord = new StockInRecord(); |
| | | stockInRecord.setInboundBatches(OrderUtils.countTodayByCreateTime(stockInRecordMapper, "RK")); // 生成入库批次号 |
| | | stockInRecord.setStockInNum(stockOutRecord.getStockOutNum()); // 入库数量等于原出库数量 |
| | | stockInRecord.setRecordId(stockOutRecord.getId()); // 记录原出库记录ID |
| | | stockInRecord.setRecordType(StockInQualifiedRecordTypeEnum.SALE_COUNTER_REVIEW_STOCK_IN.getCode()); // 设置为销售反审入库类型 |
| | | stockInRecord.setProductModelId(stockOutRecord.getProductModelId()); // 产品规格ID |
| | | stockInRecord.setRemark("销售-反审入库"); // 备注 |
| | | stockInRecord.setType(stockOutRecord.getType()); // 类型(合格/不合格) |
| | | stockInRecord.setSalesLedgerId(stockOutRecord.getSalesLedgerId()); // 销售订单ID |
| | | stockInRecord.setSalesLedgerProductId(stockOutRecord.getSalesLedgerProductId()); // 销售订单产品ID |
| | | |
| | | // 4.2 插入反审入库记录 |
| | | stockInRecordMapper.insert(stockInRecord); |
| | | |
| | | // 4.3 向库存表中增加相应数量 |
| | | StockInventoryDto stockInventoryDto = new StockInventoryDto(); |
| | | stockInventoryDto.setProductModelId(stockInRecord.getProductModelId()); |
| | | stockInventoryDto.setQualitity(stockInRecord.getStockInNum()); |
| | | stockInventoryMapper.updateAddStockInventory(stockInventoryDto); |
| | | } |
| | | } |
| | | } |