| | |
| | | import com.ruoyi.basic.pojo.Product; |
| | | import com.ruoyi.basic.pojo.ProductModel; |
| | | import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum; |
| | | import com.ruoyi.common.exception.base.BaseException; |
| | | import com.ruoyi.common.utils.poi.ExcelUtil; |
| | | import com.ruoyi.equipmentenergyconsumption.mapper.ElectricityConsumptionAreaMapper; |
| | | import com.ruoyi.framework.web.domain.R; |
| | |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.util.List; |
| | | import java.util.Optional; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | stockInRecordDto.setRecordId(stockInventoryDto.getRecordId()); |
| | | stockInRecordDto.setRecordType(stockInventoryDto.getRecordType()); |
| | | stockInRecordDto.setWeighingOperator(stockInventoryDto.getWeighingOperator()); |
| | | stockInRecordDto.setUnit(stockInventoryDto.getUnit()); |
| | | Long modelId; |
| | | if (stockInventoryDto.getProductId() != null) { |
| | | stockInRecordDto.setProductId(stockInventoryDto.getProductId()); |
| | |
| | | stockInRecordDto.setGrossWeight(stockInventoryDto.getGrossWeight()); |
| | | stockInRecordDto.setTareWeight(stockInventoryDto.getTareWeight()); |
| | | stockInRecordDto.setLicensePlateNo(stockInventoryDto.getLicensePlateNo()); |
| | | stockInRecordDto.setUnit(stockInventoryDto.getUnit()); |
| | | // 生成磅单 |
| | | String absoluteDocPath = weighbridgeDocGenerator.generateWeighbridgeDoc(stockInRecordDto); |
| | | stockInRecordDto.setWeighbridgeDocPath(absoluteDocPath); |
| | |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Boolean subtractStockInventory(StockInventoryDto stockInventoryDto) { |
| | | |
| | | // 1. 查询产品型号和库存信息 |
| | | ProductModel productModel = productModelMapper.selectById(stockInventoryDto.getProductModelId()); |
| | | BigDecimal weight = compareUnit(stockInventoryDto, productModel); |
| | | // 新增出库记录 |
| | | StockOutRecordDto stockOutRecordDto = new StockOutRecordDto(); |
| | | stockOutRecordDto.setRecordId(stockInventoryDto.getRecordId()); |
| | | stockOutRecordDto.setRecordType(stockInventoryDto.getRecordType()); |
| | | stockOutRecordDto.setWeighingDate(stockInventoryDto.getWeighingDate()); |
| | | stockOutRecordDto.setStockOutNum(stockInventoryDto.getNetWeight()); |
| | | stockOutRecordDto.setNetWeight(stockInventoryDto.getNetWeight()); |
| | | stockOutRecordDto.setGrossWeight(stockInventoryDto.getGrossWeight()); |
| | | stockOutRecordDto.setTareWeight(stockInventoryDto.getTareWeight()); |
| | | stockOutRecordDto.setWeighingOperator(stockInventoryDto.getWeighingOperator()); |
| | | stockOutRecordDto.setProductModelId(stockInventoryDto.getProductModelId()); |
| | | stockOutRecordDto.setLicensePlateNo(stockInventoryDto.getLicensePlateNo()); |
| | | stockOutRecordDto.setProductId(stockInventoryDto.getProductId()); |
| | | stockOutRecordDto.setRemark(stockInventoryDto.getRemark()); |
| | | stockOutRecordDto.setType("0"); |
| | | //生成磅单 |
| | | StockInRecordDto stockInRecordDto = new StockInRecordDto(); |
| | | BeanUtils.copyProperties(stockOutRecordDto, stockInRecordDto); |
| | | String absoluteDocPath = weighbridgeDocGenerator.generateWeighbridgeDoc(stockInRecordDto); |
| | | stockOutRecordDto.setWeighbridgeDocPath(absoluteDocPath); |
| | | stockOutRecordService.add(stockOutRecordDto); |
| | | StockInventory oldStockInventory = stockInventoryMapper.selectOne(new QueryWrapper<StockInventory>().lambda().eq(StockInventory::getProductModelId, stockInventoryDto.getProductModelId())); |
| | | if (ObjectUtils.isEmpty(oldStockInventory)) { |
| | | throw new RuntimeException("产品库存不存在"); |
| | | } |
| | | BigDecimal lockedQty = oldStockInventory.getLockedQuantity(); |
| | | if (lockedQty == null) { |
| | | lockedQty = BigDecimal.ZERO; |
| | | } |
| | | stockInventoryDto.setQualitity(weight); |
| | | if (stockInventoryDto.getQualitity().compareTo(oldStockInventory.getQualitity().subtract(lockedQty)) > 0) { |
| | | throw new RuntimeException("库存不足无法出库"); |
| | | if (productModel == null) { |
| | | throw new BaseException("产品型号不存在"); |
| | | } |
| | | |
| | | stockInventoryMapper.updateSubtractStockInventory(stockInventoryDto); |
| | | StockInventory oldStockInventory = stockInventoryMapper.selectOne( |
| | | new QueryWrapper<StockInventory>().lambda() |
| | | .eq(StockInventory::getProductModelId, stockInventoryDto.getProductModelId()) |
| | | ); |
| | | if (oldStockInventory == null) { |
| | | throw new BaseException("产品库存不存在"); |
| | | } |
| | | |
| | | // 2. 计算并转换出库数量 |
| | | BigDecimal outQuantity = compareUnit(stockInventoryDto, productModel); |
| | | |
| | | // 3. 检查库存是否充足(考虑锁定库存) |
| | | BigDecimal availableQuantity = oldStockInventory.getQualitity() |
| | | .subtract(Optional.ofNullable(oldStockInventory.getLockedQuantity()).orElse(BigDecimal.ZERO)); |
| | | if (outQuantity.compareTo(availableQuantity) > 0) { |
| | | throw new BaseException("库存不足,当前可用库存:" + availableQuantity); |
| | | } |
| | | |
| | | // 4. 扣减库存 |
| | | stockInventoryDto.setQualitity(outQuantity); |
| | | int affectedRows = stockInventoryMapper.updateSubtractStockInventory(stockInventoryDto); |
| | | if (affectedRows == 0) { |
| | | throw new BaseException("扣减库存失败,可能库存不足或数据已被修改"); |
| | | } |
| | | |
| | | // 5. 创建并保存出库记录 |
| | | createAndSaveStockOutRecord(stockInventoryDto, productModel); |
| | | |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * 计算并转换出库数量(统一转换为库存单位) |
| | | */ |
| | | private BigDecimal compareUnit(StockInventoryDto stockInventoryDto, ProductModel productModel) { |
| | | String unit = ""; |
| | | if (productModel != null) { |
| | | unit = productModel.getUnit(); |
| | | // 获取原始出库数量(根据产品类型选择净重或数量) |
| | | BigDecimal originalQuantity = (stockInventoryDto.getProductType() != null && stockInventoryDto.getProductType() == 0) |
| | | ? stockInventoryDto.getNetWeight() |
| | | : stockInventoryDto.getQualitity(); |
| | | |
| | | String sourceUnit = stockInventoryDto.getUnit(); |
| | | String targetUnit = productModel.getUnit(); |
| | | |
| | | // 单位相同,直接返回 |
| | | if (sourceUnit.equals(targetUnit)) { |
| | | return originalQuantity; |
| | | } |
| | | BigDecimal weight; |
| | | if (stockInventoryDto.getUnit().equals(unit)) { |
| | | weight = stockInventoryDto.getProductType() != null && stockInventoryDto.getProductType() == 0 ? |
| | | stockInventoryDto.getNetWeight() : stockInventoryDto.getQualitity(); |
| | | |
| | | // 单位转换 |
| | | if ("吨".equals(targetUnit)) { |
| | | // 转换为吨 |
| | | return originalQuantity.divide(BigDecimal.valueOf(1000), 2, RoundingMode.HALF_UP); |
| | | } else if ("公斤".equals(targetUnit)) { |
| | | // 转换为公斤 |
| | | return originalQuantity.multiply(BigDecimal.valueOf(1000)); |
| | | } else { |
| | | if ("吨".equals(unit)) { |
| | | weight =stockInventoryDto.getProductType() != null && stockInventoryDto.getProductType() == 0 ? |
| | | stockInventoryDto.getNetWeight().divide(BigDecimal.valueOf(1000),2, RoundingMode.HALF_UP) : stockInventoryDto.getQualitity().divide(BigDecimal.valueOf(1000),2,RoundingMode.HALF_UP); |
| | | } else if ("公斤".equals(unit)) { |
| | | weight = stockInventoryDto.getProductType() != null && stockInventoryDto.getProductType() == 0 ? |
| | | stockInventoryDto.getNetWeight().multiply(BigDecimal.valueOf(1000)) : stockInventoryDto.getQualitity().multiply(BigDecimal.valueOf(1000)); |
| | | }else { |
| | | weight =stockInventoryDto.getProductType() != null && stockInventoryDto.getProductType() == 0 ? |
| | | stockInventoryDto.getNetWeight() : stockInventoryDto.getQualitity(); |
| | | } |
| | | // 单位不匹配时,返回原值 |
| | | return originalQuantity; |
| | | } |
| | | return weight; |
| | | } |
| | | |
| | | /** |
| | | * 创建并保存出库记录 |
| | | */ |
| | | private void createAndSaveStockOutRecord(StockInventoryDto stockInventoryDto, ProductModel productModel) { |
| | | // 创建出库记录DTO |
| | | StockOutRecordDto stockOutRecordDto = new StockOutRecordDto(); |
| | | if (stockInventoryDto.getProductType() != null && stockInventoryDto.getProductType() == 0) { |
| | | stockOutRecordDto.setRecordId(stockInventoryDto.getRecordId()); |
| | | stockOutRecordDto.setRecordType(stockInventoryDto.getRecordType()); |
| | | stockOutRecordDto.setWeighingDate(stockInventoryDto.getWeighingDate()); |
| | | stockOutRecordDto.setStockOutNum(stockInventoryDto.getNetWeight()); |
| | | stockOutRecordDto.setNetWeight(stockInventoryDto.getNetWeight()); |
| | | stockOutRecordDto.setGrossWeight(stockInventoryDto.getGrossWeight()); |
| | | stockOutRecordDto.setTareWeight(stockInventoryDto.getTareWeight()); |
| | | stockOutRecordDto.setWeighingOperator(stockInventoryDto.getWeighingOperator()); |
| | | stockOutRecordDto.setProductModelId(stockInventoryDto.getProductModelId()); |
| | | stockOutRecordDto.setLicensePlateNo(stockInventoryDto.getLicensePlateNo()); |
| | | stockOutRecordDto.setProductId(stockInventoryDto.getProductId()); |
| | | stockOutRecordDto.setRemark(stockInventoryDto.getRemark()); |
| | | stockOutRecordDto.setUnit(stockInventoryDto.getUnit()); |
| | | stockOutRecordDto.setType("0"); |
| | | // 生成磅单 |
| | | StockInRecordDto stockInRecordDto = new StockInRecordDto(); |
| | | BeanUtils.copyProperties(stockOutRecordDto, stockInRecordDto); |
| | | String absoluteDocPath = weighbridgeDocGenerator.generateWeighbridgeDoc(stockInRecordDto); |
| | | stockOutRecordDto.setWeighbridgeDocPath(absoluteDocPath); |
| | | } else { |
| | | stockOutRecordDto.setRecordId(stockInventoryDto.getRecordId()); |
| | | stockOutRecordDto.setRecordType(stockInventoryDto.getRecordType()); |
| | | stockOutRecordDto.setStockOutNum(stockInventoryDto.getQualitity()); |
| | | stockOutRecordDto.setNetWeight(stockInventoryDto.getQualitity()); |
| | | stockOutRecordDto.setProductModelId(stockInventoryDto.getProductModelId()); |
| | | stockOutRecordDto.setProductId(stockInventoryDto.getProductId()); |
| | | stockOutRecordDto.setRemark(stockInventoryDto.getRemark()); |
| | | stockOutRecordDto.setUnit(stockInventoryDto.getUnit()); |
| | | stockOutRecordDto.setType("0"); |
| | | } |
| | | stockOutRecordService.add(stockOutRecordDto); |
| | | } |
| | | |
| | | @Override |