| | |
| | | |
| | | private final PendingInventoryMapper pendingInventoryMapper; |
| | | |
| | | private final ProductionSchedulingMapper productionSchedulingMapper; |
| | | |
| | | @Override |
| | | public IPage<ProductionMasterDto> selectPMList(Page page, ProductionMasterDto productionMasterDto) { |
| | | // 1. 构建主表查询条件 |
| | |
| | | batchInsertInventories(masterId, dto.getProductionInventoryList()); |
| | | |
| | | // 插入待入库数据 |
| | | insertPendingInventory(dto.getProductionList()); |
| | | // insertPendingInventory(dto.getProductionList()); |
| | | |
| | | return 1; |
| | | } |
| | |
| | | BeanUtils.copyProperties(p, copy); |
| | | copy.setId(null); |
| | | copy.setProductionMasterId(masterId); |
| | | copy.setStatus(1); |
| | | productionMapper.insert(copy); |
| | | } |
| | | } |
| | |
| | | /** |
| | | * 将加工产生的产品记录到待入库表 |
| | | */ |
| | | private void insertPendingInventory(List<Production> list) { |
| | | public void insertPendingInventory(List<Production> list) { |
| | | LocalDate currentDate = LocalDate.now(); |
| | | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); |
| | | String formattedDate = currentDate.format(formatter); |
| | | // 常量定义:保留2位小数,四舍五入模式 |
| | | final int SCALE = 2; |
| | | final RoundingMode ROUNDING_MODE = RoundingMode.HALF_UP; |
| | | // 税率13%,用字符串构造BigDecimal避免精度误差 |
| | | final BigDecimal TAX_RATE = new BigDecimal("1.13"); |
| | | |
| | | for (Production p : list) { |
| | | PendingInventory pending = new PendingInventory(); |
| | | pending.setCoalId(p.getCoalId()); |
| | | pending.setInventoryQuantity(p.getProductionQuantity()); |
| | | pending.setUnit("t"); |
| | | pending.setUnit("吨"); |
| | | pending.setSupplierName(formattedDate + " - " + "生产加工入库"); |
| | | |
| | | // 1. 非空处理:避免null导致的运算异常 |
| | | // 非空处理 |
| | | BigDecimal totalCost = p.getTotalCost() == null ? BigDecimal.ZERO : p.getTotalCost(); |
| | | BigDecimal productionQuantity = p.getProductionQuantity() == null ? BigDecimal.ZERO : p.getProductionQuantity(); |
| | | |
| | | // 2. 含税总价 = 含税单价 * 产量 → 保留2位小数 |
| | | // 含税总价 |
| | | BigDecimal totalPriceIncludingTax = totalCost.multiply(productionQuantity) |
| | | .setScale(SCALE, ROUNDING_MODE); |
| | | pending.setTotalPriceIncludingTax(totalPriceIncludingTax); |
| | | |
| | | // 3. 含税单价 → 直接保留2位小数 |
| | | // 含税单价 |
| | | pending.setPriceIncludingTax(totalCost.setScale(SCALE, ROUNDING_MODE)); |
| | | |
| | | // 4. 不含税单价 = 含税单价 / 1.13 → 先高精度计算,再保留2位 |
| | | BigDecimal priceExcludingTax = totalCost.divide(TAX_RATE, 10, ROUNDING_MODE) // 中间保留10位防误差 |
| | | .setScale(SCALE, ROUNDING_MODE); // 最终保留2位 |
| | | // 不含税单价(直接保留2位小数) |
| | | BigDecimal priceExcludingTax = totalCost.divide(TAX_RATE, SCALE, ROUNDING_MODE); |
| | | pending.setPriceExcludingTax(priceExcludingTax); |
| | | |
| | | // 5. 不含税总价 = 不含税单价 * 产量 → 保留2位小数 |
| | | // 不含税总价 |
| | | BigDecimal totalPriceExcludingTax = priceExcludingTax.multiply(productionQuantity) |
| | | .setScale(SCALE, ROUNDING_MODE); |
| | | pending.setTotalPriceExcludingTax(totalPriceExcludingTax); |
| | | |
| | | pending.setRegistrantId(p.getProducerId()); |
| | | pending.setRegistrationDate(LocalDate.now()); |
| | | |
| | | pending.setCode(generateCode(p.getType())); |
| | | pending.setType(p.getType()); |
| | | pendingInventoryMapper.insert(pending); |
| | | } |
| | | } |
| | | |
| | | private String generateCode(Integer type) { |
| | | LocalDate now = LocalDate.now(); |
| | | String year = now.format(DateTimeFormatter.ofPattern("yyyyMMdd")); |
| | | String s = ""; |
| | | //生成编码 |
| | | switch (type){ |
| | | case 1: |
| | | s = "CP"; |
| | | break; |
| | | case 2: |
| | | s = "YL"; |
| | | break; |
| | | } |
| | | // 查询当天待入库新增条数 |
| | | Long count = pendingInventoryMapper.selectCount(new LambdaQueryWrapper<PendingInventory>() |
| | | .apply("date_trunc('day', create_time) = date_trunc('day', now())")); |
| | | return s + year + String.format("%03d", count + 1); |
| | | } |
| | | |
| | | @Override |
| | |
| | | .collect(Collectors.toList()); |
| | | productionInventoryMapper.deleteBatchIds(inventoryIds); |
| | | } |
| | | List<Production> productions = productionMapper.selectList(new LambdaQueryWrapper<Production>() |
| | | .in(Production::getProductionMasterId, idList)); |
| | | |
| | | // 删除生产报工记录 |
| | | productionSchedulingMapper.delete( |
| | | new LambdaQueryWrapper<ProductionScheduling>() |
| | | .in(ProductionScheduling::getProductionId, productions.stream().map(Production::getId).collect(Collectors.toList())) |
| | | ); |
| | | |
| | | // 删除生产明细 |
| | | productionMapper.delete( |
| | | new LambdaQueryWrapper<Production>() |
| | | .in(Production::getProductionMasterId, idList) |
| | | ); |
| | | |
| | | |
| | | // 5. 删除主记录 |
| | | return productionMasterMapper.deleteBatchIds(idList); |
| | |
| | | } |
| | | |
| | | // 批量更新官方库存 |
| | | for (Map.Entry<Long, BigDecimal> entry : inventoryAdjustMap.entrySet()) { |
| | | OfficialInventory official = officialInventoryMapper.selectById(entry.getKey()); |
| | | if (official == null) { |
| | | throw new BaseException("官方库存不存在,ID: " + entry.getKey()); |
| | | } |
| | | |
| | | // 使用线程安全的BigDecimal操作 |
| | | official.setInventoryQuantity( |
| | | Optional.ofNullable(official.getInventoryQuantity()) |
| | | .orElse(BigDecimal.ZERO) |
| | | .add(entry.getValue()) |
| | | ); |
| | | officialInventoryMapper.updateById(official); |
| | | } |
| | | // for (Map.Entry<Long, BigDecimal> entry : inventoryAdjustMap.entrySet()) { |
| | | // OfficialInventory official = officialInventoryMapper.selectById(entry.getKey()); |
| | | // if (official == null) { |
| | | // throw new BaseException("官方库存不存在,ID: " + entry.getKey()); |
| | | // } |
| | | // |
| | | // // 使用线程安全的BigDecimal操作 |
| | | // official.setInventoryQuantity( |
| | | // Optional.ofNullable(official.getInventoryQuantity()) |
| | | // .orElse(BigDecimal.ZERO) |
| | | // .add(entry.getValue()) |
| | | // ); |
| | | // officialInventoryMapper.updateById(official); |
| | | // } |
| | | |
| | | // 批量删除生产库存 |
| | | if (!productionIdsToDelete.isEmpty()) { |