| | |
| | | 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.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ruoyi.basic.mapper.ProductModelMapper; |
| | | import com.ruoyi.basic.pojo.ProductModel; |
| | | import com.ruoyi.common.exception.ServiceException; |
| | | import com.ruoyi.common.exception.base.BaseException; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import com.ruoyi.common.utils.poi.ExcelUtil; |
| | |
| | | import com.ruoyi.stock.dto.StockOutRecordDto; |
| | | import com.ruoyi.stock.dto.StockUninventoryDto; |
| | | import com.ruoyi.stock.execl.StockUnInventoryExportData; |
| | | import com.ruoyi.stock.mapper.StockInventoryMapper; |
| | | import com.ruoyi.stock.mapper.StockUninventoryMapper; |
| | | import com.ruoyi.stock.pojo.StockInRecord; |
| | | import com.ruoyi.stock.pojo.StockInventory; |
| | | import com.ruoyi.stock.pojo.StockUninventory; |
| | | import com.ruoyi.stock.service.StockInRecordService; |
| | | import com.ruoyi.stock.service.StockOutRecordService; |
| | | import com.ruoyi.stock.service.StockUninventoryService; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDate; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.List; |
| | | |
| | | /** |
| | |
| | | * @since 2026-01-22 10:17:45 |
| | | */ |
| | | @Service |
| | | @RequiredArgsConstructor |
| | | public class StockUninventoryServiceImpl extends ServiceImpl<StockUninventoryMapper, StockUninventory> implements StockUninventoryService { |
| | | |
| | | @Autowired |
| | | private StockUninventoryMapper stockUninventoryMapper; |
| | | @Autowired |
| | | private StockOutRecordService stockOutRecordService; |
| | | @Autowired |
| | | private StockInRecordService stockInRecordService; |
| | | |
| | | private final StockUninventoryMapper stockUninventoryMapper; |
| | | private final StockOutRecordService stockOutRecordService; |
| | | private final StockInRecordService stockInRecordService; |
| | | private final ProductModelMapper productModelMapper; |
| | | private final StockInventoryMapper stockInventoryMapper; |
| | | |
| | | @Override |
| | | public IPage<StockUninventoryDto> pageStockUninventory(Page page, StockUninventoryDto stockUninventoryDto) { |
| | |
| | | stockInRecordDto.setRecordId(stockUninventoryDto.getRecordId()); |
| | | stockInRecordDto.setRecordType(stockUninventoryDto.getRecordType()); |
| | | stockInRecordDto.setStockInNum(stockUninventoryDto.getQualitity()); |
| | | stockInRecordDto.setBatchNo(stockUninventoryDto.getBatchNo()); |
| | | String batchNo = StringUtils.trim(stockUninventoryDto.getBatchNo()); |
| | | if (StringUtils.isEmpty(batchNo)) { |
| | | batchNo = generateAutoBatchNo(stockUninventoryDto.getProductModelId()); |
| | | } |
| | | stockInRecordDto.setBatchNo(batchNo); |
| | | stockInRecordDto.setProductModelId(stockUninventoryDto.getProductModelId()); |
| | | stockInRecordDto.setType("1"); |
| | | stockInRecordDto.setRemark(stockUninventoryDto.getRemark()); |
| | |
| | | stockUninventory.setLockedQuantity(stockUninventory.getLockedQuantity().subtract(stockInventoryDto.getLockedQuantity())); |
| | | return this.updateById(stockUninventory); |
| | | } |
| | | |
| | | //规则生成:20260424-产品编号-001 |
| | | private String generateAutoBatchNo(Long productModelId) { |
| | | if (productModelId == null) { |
| | | throw new ServiceException("产品规格ID不能为空"); |
| | | } |
| | | ProductModel productModel = productModelMapper.selectById(productModelId); |
| | | if (productModel == null) { |
| | | throw new ServiceException("产品规格不存在,ID=" + productModelId); |
| | | } |
| | | String productCode = StringUtils.trim(productModel.getProductCode()); |
| | | if (StringUtils.isEmpty(productCode)) { |
| | | throw new ServiceException("产品规格未维护产品编码,ID=" + productModelId); |
| | | } |
| | | |
| | | String dateText = LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE); |
| | | String prefix = dateText + "-" + productCode + "-"; |
| | | int maxSequence = resolveMaxSequence(prefix); |
| | | int sequence = maxSequence + 1; |
| | | while (sequence < 1_000_000) { |
| | | String batchNo = prefix + String.format("%03d", sequence); |
| | | if (!isBatchNoExists(batchNo)) { |
| | | return batchNo; |
| | | } |
| | | sequence++; |
| | | } |
| | | throw new ServiceException("批号序号超出范围,请检查批号数据"); |
| | | } |
| | | |
| | | private int resolveMaxSequence(String prefix) { |
| | | int maxSequence = 0; |
| | | List<StockInventory> stockInventoryList = stockInventoryMapper.selectList( |
| | | Wrappers.<StockInventory>lambdaQuery() |
| | | .select(StockInventory::getBatchNo) |
| | | .likeRight(StockInventory::getBatchNo, prefix)); |
| | | for (StockInventory stockInventory : stockInventoryList) { |
| | | maxSequence = Math.max(maxSequence, parseSequence(stockInventory.getBatchNo(), prefix)); |
| | | } |
| | | |
| | | List<StockInRecord> stockInRecordList = stockInRecordService.list( |
| | | Wrappers.<StockInRecord>lambdaQuery() |
| | | .select(StockInRecord::getBatchNo) |
| | | .likeRight(StockInRecord::getBatchNo, prefix)); |
| | | for (StockInRecord stockInRecord : stockInRecordList) { |
| | | maxSequence = Math.max(maxSequence, parseSequence(stockInRecord.getBatchNo(), prefix)); |
| | | } |
| | | return maxSequence; |
| | | } |
| | | |
| | | private int parseSequence(String batchNo, String prefix) { |
| | | if (StringUtils.isEmpty(batchNo) || StringUtils.isEmpty(prefix) || !batchNo.startsWith(prefix)) { |
| | | return 0; |
| | | } |
| | | String sequenceText = batchNo.substring(prefix.length()); |
| | | if (StringUtils.isEmpty(sequenceText) || !sequenceText.matches("\\d+")) { |
| | | return 0; |
| | | } |
| | | try { |
| | | return Integer.parseInt(sequenceText); |
| | | } catch (NumberFormatException ignored) { |
| | | return 0; |
| | | } |
| | | } |
| | | |
| | | private boolean isBatchNoExists(String batchNo) { |
| | | if (StringUtils.isEmpty(batchNo)) { |
| | | return false; |
| | | } |
| | | Long inventoryCount = stockInventoryMapper.selectCount( |
| | | Wrappers.<StockInventory>lambdaQuery().eq(StockInventory::getBatchNo, batchNo)); |
| | | if (inventoryCount != null && inventoryCount > 0) { |
| | | return true; |
| | | } |
| | | return stockInRecordService.count( |
| | | Wrappers.<StockInRecord>lambdaQuery().eq(StockInRecord::getBatchNo, batchNo)) > 0; |
| | | } |
| | | } |