| | |
| | | import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ruoyi.basic.entity.CoalInfo; |
| | | import com.ruoyi.basic.mapper.CoalInfoMapper; |
| | | import com.ruoyi.business.dto.ProductionMasterDto; |
| | | import com.ruoyi.business.entity.OfficialInventory; |
| | | import com.ruoyi.business.entity.Production; |
| | | import com.ruoyi.business.entity.ProductionInventory; |
| | | import com.ruoyi.business.entity.ProductionMaster; |
| | | import com.ruoyi.business.mapper.OfficialInventoryMapper; |
| | | import com.ruoyi.business.mapper.ProductionInventoryMapper; |
| | | import com.ruoyi.business.mapper.ProductionMapper; |
| | | import com.ruoyi.business.mapper.ProductionMasterMapper; |
| | | import com.ruoyi.business.entity.*; |
| | | import com.ruoyi.business.mapper.*; |
| | | import com.ruoyi.business.service.ProductionMasterService; |
| | | import com.ruoyi.common.core.domain.entity.SysUser; |
| | | import com.ruoyi.common.exception.base.BaseException; |
| | | import com.ruoyi.common.utils.bean.BeanUtils; |
| | | import com.ruoyi.system.mapper.SysUserMapper; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | |
| | | |
| | | private final OfficialInventoryMapper officialInventoryMapper; |
| | | |
| | | private final SysUserMapper sysUserMapper; |
| | | private final CoalInfoMapper coalInfoMapper; |
| | | |
| | | private final PendingInventoryMapper pendingInventoryMapper; |
| | | |
| | | @Override |
| | | public IPage<ProductionMasterDto> selectPMList(Page page, ProductionMasterDto productionMasterDto) { |
| | |
| | | |
| | | @Override |
| | | @Transactional |
| | | public int addOrEditPM(ProductionMasterDto productionMasterDto) { |
| | | // 1. 直接计算聚合值,避免创建多余列表 |
| | | BigDecimal totalPurchasePrice = BigDecimal.ZERO; |
| | | BigDecimal totalLaborCost = BigDecimal.ZERO; |
| | | BigDecimal totalEnergyConsumptionCost = BigDecimal.ZERO; |
| | | BigDecimal totalTotalCost = BigDecimal.ZERO; |
| | | BigDecimal totalEquipmentDepreciation = BigDecimal.ZERO; |
| | | int totalProductionQuantity = 0; |
| | | StringBuilder coalBuilder = new StringBuilder(); |
| | | public int addOrEditPM(ProductionMasterDto dto) { |
| | | Long masterId = dto.getId(); |
| | | |
| | | for (Production production : productionMasterDto.getProductionList()) { |
| | | totalPurchasePrice = totalPurchasePrice.add(production.getPurchasePrice()); |
| | | totalLaborCost = totalLaborCost.add(production.getLaborCost()); |
| | | totalEnergyConsumptionCost = totalEnergyConsumptionCost.add(production.getEnergyConsumptionCost()); |
| | | totalTotalCost = totalTotalCost.add(production.getTotalCost()); |
| | | totalEquipmentDepreciation = totalEquipmentDepreciation.add(production.getEquipmentDepreciation()); |
| | | totalProductionQuantity += production.getProductionQuantity(); |
| | | if (coalBuilder.length() > 0) { |
| | | coalBuilder.append(","); // 在元素之间添加逗号 |
| | | } |
| | | coalBuilder.append(production.getCoal()); |
| | | // 编辑场景:回滚旧库存并删除旧记录 |
| | | if (masterId != null) { |
| | | rollbackOldInventory(masterId); |
| | | deleteChildRecords(masterId); |
| | | } |
| | | String coalStr = coalBuilder.toString(); // 直接获取拼接结果 |
| | | |
| | | // 2. 创建主表对象 |
| | | ProductionMaster productionMaster = new ProductionMaster(); |
| | | productionMaster.setProductionQuantity(totalProductionQuantity); |
| | | productionMaster.setTotalCost(totalTotalCost); |
| | | productionMaster.setEquipmentDepreciation(totalEquipmentDepreciation); |
| | | productionMaster.setEnergyConsumptionCost(totalEnergyConsumptionCost); |
| | | productionMaster.setLaborCost(totalLaborCost); |
| | | productionMaster.setCoal(coalStr); |
| | | // 校验使用量并减少库存 |
| | | validateAndReduceInventory(dto.getProductionInventoryList()); |
| | | |
| | | Long masterId = productionMasterDto.getId(); |
| | | productionMaster.setId(masterId); |
| | | // 构造主表实体对象 |
| | | ProductionMaster master = buildProductionMaster(dto); |
| | | |
| | | // 3. 统一子表处理逻辑 |
| | | Long producerId = productionMasterDto.getProducerId(); |
| | | if (producerId == null) { |
| | | throw new BaseException("请选择生产者"); |
| | | } |
| | | SysUser sysUser = sysUserMapper.selectUserById(producerId); |
| | | productionMaster.setProducer(sysUser.getUserName()); |
| | | // 插入或更新主表 |
| | | if (masterId == null) { |
| | | productionMasterMapper.insert(productionMaster); |
| | | masterId = productionMaster.getId(); // 获取新生成的ID |
| | | productionMasterMapper.insert(master); |
| | | masterId = master.getId(); |
| | | } else { |
| | | // 删除关联子表数据 |
| | | productionMapper.delete(new LambdaQueryWrapper<Production>() |
| | | .eq(Production::getProductionMasterId, masterId)); |
| | | |
| | | productionInventoryMapper.delete(new LambdaQueryWrapper<ProductionInventory>() |
| | | .eq(ProductionInventory::getProductionMasterId, masterId)); |
| | | |
| | | productionMasterMapper.updateById(productionMaster); |
| | | master.setId(masterId); |
| | | productionMasterMapper.updateById(master); |
| | | } |
| | | //库存更新 |
| | | for (ProductionInventory productionInventory : productionMasterDto.getProductionInventoryList()) { |
| | | OfficialInventory officialInventory = officialInventoryMapper.selectById(productionInventory.getOfficialId()); |
| | | BigDecimal subtract = officialInventory.getInventoryQuantity().subtract(new BigDecimal(productionInventory.getUsedQuantity())); |
| | | if (subtract.compareTo(BigDecimal.ZERO) < 0) { |
| | | throw new BaseException("库存不足"); |
| | | } |
| | | officialInventory.setInventoryQuantity(subtract); |
| | | officialInventoryMapper.updateById(officialInventory); |
| | | } |
| | | |
| | | // 4. 批量插入子表数据 |
| | | batchInsertProductions(masterId, productionMasterDto.getProductionList()); |
| | | batchInsertInventories(masterId, productionMasterDto.getProductionInventoryList()); |
| | | |
| | | // 批量插入生产记录与库存记录 |
| | | batchInsertProductions(masterId, dto.getProductionList()); |
| | | batchInsertInventories(masterId, dto.getProductionInventoryList()); |
| | | |
| | | // 插入待入库数据 |
| | | insertPendingInventory(dto.getProductionList()); |
| | | |
| | | return 1; |
| | | } |
| | | |
| | | // 批量插入生产数据 |
| | | private void batchInsertProductions(Long masterId, List<Production> productions) { |
| | | List<Production> insertList = productions.stream() |
| | | .peek(p -> { |
| | | p.setId(null); |
| | | p.setProductionMasterId(masterId); |
| | | }) |
| | | .collect(Collectors.toList()); |
| | | /** |
| | | * 回滚旧的库存数据(将库存数量还原) |
| | | */ |
| | | private void rollbackOldInventory(Long masterId) { |
| | | List<ProductionInventory> oldInventories = productionInventoryMapper.selectList( |
| | | new LambdaQueryWrapper<ProductionInventory>().eq(ProductionInventory::getProductionMasterId, masterId)); |
| | | |
| | | if (!insertList.isEmpty()) { |
| | | for (Production production : productions) { |
| | | production.setId(null); |
| | | production.setProductionMasterId(masterId); |
| | | productionMapper.insert(production); |
| | | for (ProductionInventory oldInv : oldInventories) { |
| | | OfficialInventory inv = officialInventoryMapper.selectById(oldInv.getOfficialId()); |
| | | if (inv != null) { |
| | | inv.setInventoryQuantity(inv.getInventoryQuantity().add(new BigDecimal(oldInv.getUsedQuantity()))); |
| | | officialInventoryMapper.updateById(inv); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 批量插入库存数据 |
| | | private void batchInsertInventories(Long masterId, List<ProductionInventory> inventories) { |
| | | List<ProductionInventory> insertList = inventories.stream() |
| | | .peek(inv -> { |
| | | inv.setId(null); |
| | | inv.setProductionMasterId(masterId); |
| | | }) |
| | | .collect(Collectors.toList()); |
| | | /** |
| | | * 删除旧的子表数据及待入库数据 |
| | | */ |
| | | private void deleteChildRecords(Long masterId) { |
| | | productionMapper.delete(new LambdaQueryWrapper<Production>().eq(Production::getProductionMasterId, masterId)); |
| | | productionInventoryMapper.delete(new LambdaQueryWrapper<ProductionInventory>().eq(ProductionInventory::getProductionMasterId, masterId)); |
| | | pendingInventoryMapper.delete(new LambdaQueryWrapper<PendingInventory>().eq(PendingInventory::getMasterId, masterId)); |
| | | } |
| | | |
| | | if (!insertList.isEmpty()) { |
| | | for (ProductionInventory inventory : inventories) { |
| | | inventory.setId(null); |
| | | inventory.setProductionMasterId(masterId); |
| | | productionInventoryMapper.insert(inventory); |
| | | /** |
| | | * 校验每条使用量是否足够,并减少正式库存数量 |
| | | */ |
| | | private void validateAndReduceInventory(List<ProductionInventory> inventoryList) { |
| | | for (ProductionInventory inv : inventoryList) { |
| | | OfficialInventory official = officialInventoryMapper.selectById(inv.getOfficialId()); |
| | | BigDecimal used = new BigDecimal(inv.getUsedQuantity()); |
| | | if (official.getInventoryQuantity().compareTo(used) < 0) { |
| | | throw new BaseException("库存不足"); |
| | | } |
| | | official.setInventoryQuantity(official.getInventoryQuantity().subtract(used)); |
| | | officialInventoryMapper.updateById(official); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 构造主表对象并聚合字段值(如总成本、煤种等) |
| | | */ |
| | | private ProductionMaster buildProductionMaster(ProductionMasterDto dto) { |
| | | BigDecimal totalPurchase = BigDecimal.ZERO; |
| | | BigDecimal totalLabor = BigDecimal.ZERO; |
| | | BigDecimal totalEnergy = BigDecimal.ZERO; |
| | | BigDecimal totalCost = BigDecimal.ZERO; |
| | | BigDecimal totalDepreciation = BigDecimal.ZERO; |
| | | BigDecimal totalQuantity = BigDecimal.ZERO; |
| | | |
| | | List<Long> coalIds = new ArrayList<>(); |
| | | |
| | | for (Production p : dto.getProductionList()) { |
| | | totalPurchase = totalPurchase.add(p.getPurchasePrice()); |
| | | totalLabor = totalLabor.add(p.getLaborCost()); |
| | | totalEnergy = totalEnergy.add(p.getEnergyConsumptionCost()); |
| | | totalCost = totalCost.add(p.getTotalCost()); |
| | | totalDepreciation = totalDepreciation.add(p.getEquipmentDepreciation()); |
| | | totalQuantity = totalQuantity.add(p.getProductionQuantity()); |
| | | coalIds.add(p.getCoalId()); |
| | | } |
| | | |
| | | List<CoalInfo> coalInfos = coalInfoMapper.selectList(new LambdaQueryWrapper<CoalInfo>().in(CoalInfo::getId, coalIds)); |
| | | |
| | | ProductionMaster master = new ProductionMaster(); |
| | | master.setProductionQuantity(totalQuantity); |
| | | master.setTotalCost(totalCost); |
| | | master.setLaborCost(totalLabor); |
| | | master.setEnergyConsumptionCost(totalEnergy); |
| | | master.setEquipmentDepreciation(totalDepreciation); |
| | | master.setCoal(coalInfos.stream().map(CoalInfo::getCoal).collect(Collectors.joining(","))); |
| | | master.setCoalId(coalIds.stream().map(String::valueOf).collect(Collectors.joining(","))); |
| | | |
| | | return master; |
| | | } |
| | | |
| | | /** |
| | | * 批量插入生产子表数据 |
| | | */ |
| | | private void batchInsertProductions(Long masterId, List<Production> list) { |
| | | if (list.isEmpty()) return; |
| | | |
| | | for (Production p : list) { |
| | | Production copy = new Production(); |
| | | BeanUtils.copyProperties(p, copy); |
| | | copy.setId(null); |
| | | copy.setProductionMasterId(masterId); |
| | | productionMapper.insert(copy); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 批量插入库存使用子表数据 |
| | | */ |
| | | private void batchInsertInventories(Long masterId, List<ProductionInventory> list) { |
| | | if (list.isEmpty()) return; |
| | | |
| | | for (ProductionInventory p : list) { |
| | | p.setId(null); |
| | | p.setProductionMasterId(masterId); |
| | | productionInventoryMapper.insert(p); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 将加工产生的产品记录到待入库表 |
| | | */ |
| | | private void insertPendingInventory(List<Production> list) { |
| | | for (Production p : list) { |
| | | PendingInventory pending = new PendingInventory(); |
| | | pending.setCoalId(p.getCoalId()); |
| | | pending.setInventoryQuantity(p.getProductionQuantity()); |
| | | pending.setSupplierName("生产加工入库"); |
| | | pending.setTotalPriceIncludingTax(p.getTotalCost()); |
| | | pending.setPriceIncludingTax(p.getPurchasePrice()); |
| | | pending.setPriceIncludingTax(p.getPurchasePrice()); |
| | | pendingInventoryMapper.insert(pending); |
| | | } |
| | | } |
| | | |