diff --git a/pjcloud-supermarket/pjcloud-supermarket-biz/src/main/java/com/bsd/pjcloud/supermarket/service/impl/SmErpInventoryRecordsServiceImpl.java b/pjcloud-supermarket/pjcloud-supermarket-biz/src/main/java/com/bsd/pjcloud/supermarket/service/impl/SmErpInventoryRecordsServiceImpl.java index b1d7c768c..037c9ae79 100644 --- a/pjcloud-supermarket/pjcloud-supermarket-biz/src/main/java/com/bsd/pjcloud/supermarket/service/impl/SmErpInventoryRecordsServiceImpl.java +++ b/pjcloud-supermarket/pjcloud-supermarket-biz/src/main/java/com/bsd/pjcloud/supermarket/service/impl/SmErpInventoryRecordsServiceImpl.java @@ -68,7 +68,6 @@ public class SmErpInventoryRecordsServiceImpl extends ServiceImpl currentSpuIds = cgPlanItemEntities.stream() .map(SmErpInventoryRecordsItemEntity::getErpSpuId) + .distinct() .collect(Collectors.toList()); - List itemEntityList = smErpInventoryRecordsItemMapper.getRecordsItemListBySpuIdsAndInventoryType( - currentSpuIds + // 获取当前库存信息和商品信息 + List stockList = smErpStockService.list( + new LambdaQueryWrapper().in(SmErpStockEntity::getErpSpuId, currentSpuIds) ); - Map> costPriceMap = itemEntityList.stream() - .collect(Collectors.groupingBy(SmErpCostPriceVo::getErpSpuId)); + Map stockMap = stockList.stream() + .collect(Collectors.toMap(SmErpStockEntity::getErpSpuId, stock -> stock)); - // 计算并更新成本价 - cgPlanItemEntities.forEach(item -> { - Long erpSpuId = item.getErpSpuId(); - List smErpInventoryRecordsItemEntityList = costPriceMap.get(erpSpuId); - Double totalNum = smErpInventoryRecordsItemEntityList.stream().filter(Objects::nonNull).mapToDouble(itemEntity -> itemEntity.getPackageNum() * itemEntity.getQuantity()).sum(); + List spuList = smErpSpuMapper.selectList( + new LambdaQueryWrapper().in(SmErpSpuEntity::getId, currentSpuIds) + ); + Map spuMap = spuList.stream() + .collect(Collectors.toMap(SmErpSpuEntity::getId, spu -> spu)); - int totalRealRrice = smErpInventoryRecordsItemEntityList.stream().filter(Objects::nonNull).mapToInt(SmErpCostPriceVo::getTotalAmount).sum(); - double costPrice = totalRealRrice / totalNum; + // 按商品分组,计算每个商品的加权平均成本价 + Map> itemsBySpuId = cgPlanItemEntities.stream() + .collect(Collectors.groupingBy(SmErpInventoryRecordsItemEntity::getErpSpuId)); - SmErpSpuEntity smErpSpuEntity = new SmErpSpuEntity(); - smErpSpuEntity.setCostPrice(costPrice); - smErpSpuEntity.setId(erpSpuId); - // 更新库存成本价 - smErpSpuMapper.updateById(smErpSpuEntity); + itemsBySpuId.forEach((erpSpuId, spuItems) -> { + // 获取剩余库存数量(入库前的库存) + SmErpStockEntity stock = stockMap.get(erpSpuId); + double remainingQuantity = 0; + double remainingPurchasePrice = 0; + + if (stock != null) { + // 获取本次入库数量 + double newInQuantity = spuItems.stream() + .mapToDouble(item -> item.getPackageNum() * item.getQuantity()) + .sum(); + // 剩余数量 = 当前库存(已更新) - 本次入库数量 = 入库前的库存 + remainingQuantity = stock.getCurrentStock() - newInQuantity; + + // 如果剩余数量小于0,说明是新商品或库存异常,设为0 + if (remainingQuantity < 0) { + remainingQuantity = 0; + } + } + // 获取剩余商品的进货价(从基础单位的采购价获取,单位:分) + LambdaQueryWrapper baseUnitWrapper = new LambdaQueryWrapper<>(); + baseUnitWrapper.eq(SmErpUnitEntity::getSpuId, erpSpuId); + baseUnitWrapper.eq(SmErpUnitEntity::getIsBase, true); + SmErpUnitEntity baseUnit = smErpUnitMapper.selectOne(baseUnitWrapper); + if (baseUnit != null && baseUnit.getPurchasePrice() != null) { + remainingPurchasePrice = baseUnit.getPurchasePrice(); + } - //更新实际进价到商品包装单位里 - SmErpUnitEntity smErpUnitEntity = new SmErpUnitEntity(); - smErpUnitEntity.setPurchasePrice(item.getRealPrice()); - smErpUnitEntity.setId(item.getUnitId()); - smErpUnitMapper.updateById(smErpUnitEntity); + // 计算新进商品的总金额和总数量 + double newInTotalAmount = 0; + double newInTotalQuantity = 0; + + for (SmErpInventoryRecordsItemEntity item : spuItems) { + // 新进数量 = 包装数量(箱数) * 内装数(个/箱) + double quantity = item.getPackageNum() * item.getQuantity(); + newInTotalQuantity += quantity; + + // 新进商品总金额 = 实际进价(分/个) * 数量(个) + if (item.getRealPrice() != null) { + newInTotalAmount += item.getRealPrice() * quantity; + } + + //更新实际进价到商品包装单位里 + SmErpUnitEntity smErpUnitEntity = new SmErpUnitEntity(); + smErpUnitEntity.setPurchasePrice(item.getRealPrice()); + smErpUnitEntity.setId(item.getUnitId()); + smErpUnitMapper.updateById(smErpUnitEntity); + } + + // 计算加权平均成本价 = (剩余商品进货价*剩余数量 + 新进商品进货价*新进数量) / (剩余数量 + 新进数量) + double newCostPrice = 0; + double totalQuantity = remainingQuantity + newInTotalQuantity; + + if (totalQuantity > 0) { + double totalAmount = remainingPurchasePrice * remainingQuantity + newInTotalAmount; + newCostPrice = totalAmount / totalQuantity; + + // 调试日志:打印成本价计算过程 +// System.out.println("========== 成本价计算详情 =========="); +// System.out.println("商品ID: " + erpSpuId); +// System.out.println("剩余数量: " + remainingQuantity); +// System.out.println("剩余商品进货价(基础单位采购价): " + remainingPurchasePrice + " 分/个"); +// System.out.println("剩余总金额: " + (remainingPurchasePrice * remainingQuantity) + " 分"); +// System.out.println("新进数量: " + newInTotalQuantity); +// System.out.println("新进商品进货价(realPrice): " + (newInTotalQuantity > 0 ? (newInTotalAmount / newInTotalQuantity) : 0) + " 分/个"); +// System.out.println("新进总金额: " + newInTotalAmount + " 分"); +// System.out.println("总数量: " + totalQuantity); +// System.out.println("总金额: " + totalAmount + " 分"); +// System.out.println("新成本价: " + newCostPrice + " 分/个"); +// System.out.println("新成本价(保留2位): " + String.format("%.2f", newCostPrice) + " 分/个"); +// System.out.println("===================================="); + } else { + // 如果总数量为0,使用新进商品的平均价格 + if (newInTotalQuantity > 0) { + newCostPrice = newInTotalAmount / newInTotalQuantity; + } + } + + // 更新商品成本价(double类型会自动保留精度) + SmErpSpuEntity updateSpu = new SmErpSpuEntity(); + updateSpu.setId(erpSpuId); + updateSpu.setCostPrice(newCostPrice); + smErpSpuMapper.updateById(updateSpu); }); - - } return insert; } @@ -594,6 +666,146 @@ public class SmErpInventoryRecordsServiceImpl extends ServiceImpl savedItems = smErpInventoryRecordsItemMapper.selectList( + new LambdaQueryWrapper() + .eq(SmErpInventoryRecordsItemEntity::getInventoryId, inventoryRecordEditDTO.getId()) + ); + + // 获取涉及的商品ID + List currentSpuIds = savedItems.stream() + .map(SmErpInventoryRecordsItemEntity::getErpSpuId) + .distinct() + .collect(Collectors.toList()); + + if (!CollectionUtils.isEmpty(currentSpuIds)) { + // 获取当前库存信息和商品信息 + List stockList = smErpStockService.list( + new LambdaQueryWrapper().in(SmErpStockEntity::getErpSpuId, currentSpuIds) + ); + Map stockMap = stockList.stream() + .collect(Collectors.toMap(SmErpStockEntity::getErpSpuId, stock -> stock)); + + List spuList = smErpSpuMapper.selectList( + new LambdaQueryWrapper().in(SmErpSpuEntity::getId, currentSpuIds) + ); + Map spuMap = spuList.stream() + .collect(Collectors.toMap(SmErpSpuEntity::getId, spu -> spu)); + + // 按商品分组,计算每个商品的加权平均成本价 + Map> itemsBySpuId = savedItems.stream() + .collect(Collectors.groupingBy(SmErpInventoryRecordsItemEntity::getErpSpuId)); + + itemsBySpuId.forEach((erpSpuId, spuItems) -> { + // 获取当前库存数量(已经更新后的库存) + SmErpStockEntity stock = stockMap.get(erpSpuId); + double currentStockQuantity = 0; + + if (stock != null) { + currentStockQuantity = stock.getCurrentStock(); + } + + // 计算本次编辑的入库数量 + double editInQuantity = spuItems.stream() + .mapToDouble(item -> { + Integer pkgNum = item.getPackageNum(); + if (pkgNum == null) { + SmErpUnitEntity unit = smErpUnitMapper.selectById(item.getUnitId()); + pkgNum = unit != null ? unit.getPackageNum() : 1; + } + return pkgNum * item.getQuantity(); + }) + .sum(); + + // 剩余数量 = 当前库存 - 本次入库数量 + double remainingQuantity = currentStockQuantity - editInQuantity; + if (remainingQuantity < 0) { + remainingQuantity = 0; + } + + // 获取剩余商品的进货价(从基础单位的采购价获取,单位:分) + double remainingPurchasePrice = 0; + LambdaQueryWrapper baseUnitWrapper = new LambdaQueryWrapper<>(); + baseUnitWrapper.eq(SmErpUnitEntity::getSpuId, erpSpuId); + baseUnitWrapper.eq(SmErpUnitEntity::getIsBase, true); + SmErpUnitEntity baseUnit = smErpUnitMapper.selectOne(baseUnitWrapper); + if (baseUnit != null && baseUnit.getPurchasePrice() != null) { + remainingPurchasePrice = baseUnit.getPurchasePrice(); + } + + // 计算新进(编辑后)商品的总金额和总数量 + double newInTotalAmount = 0; + double newInTotalQuantity = 0; + + for (SmErpInventoryRecordsItemEntity item : spuItems) { + // 获取内装数 + Integer pkgNum = item.getPackageNum(); + if (pkgNum == null) { + SmErpUnitEntity unit = smErpUnitMapper.selectById(item.getUnitId()); + pkgNum = unit != null ? unit.getPackageNum() : 1; + } + + // 新进数量 = 包装数量 * 内装数 + double quantity = pkgNum * item.getQuantity(); + newInTotalQuantity += quantity; + + // 新进商品总金额 = 实际进价 * 数量 + if (item.getRealPrice() != null) { + newInTotalAmount += item.getRealPrice() * quantity; + } + + //更新实际进价到商品包装单位里 + if (item.getRealPrice() != null) { + SmErpUnitEntity smErpUnitEntity = new SmErpUnitEntity(); + smErpUnitEntity.setPurchasePrice(item.getRealPrice()); + smErpUnitEntity.setId(item.getUnitId()); + smErpUnitMapper.updateById(smErpUnitEntity); + } + } + + // 计算加权平均成本价 = (剩余商品进货价*剩余数量 + 新进商品进货价*新进数量) / (剩余数量 + 新进数量) + double newCostPrice = 0; + double totalQuantity = remainingQuantity + newInTotalQuantity; + + if (totalQuantity > 0) { + double totalAmount = remainingPurchasePrice * remainingQuantity + newInTotalAmount; + newCostPrice = totalAmount / totalQuantity; + + // 调试日志:打印成本价计算过程(编辑) + System.out.println("========== 成本价计算详情(编辑) =========="); + System.out.println("商品ID: " + erpSpuId); + System.out.println("剩余数量: " + remainingQuantity); + System.out.println("剩余商品进货价(基础单位采购价): " + remainingPurchasePrice + " 分/个"); + System.out.println("剩余总金额: " + (remainingPurchasePrice * remainingQuantity) + " 分"); + System.out.println("新进数量: " + newInTotalQuantity); + System.out.println("新进商品进货价(realPrice): " + (newInTotalQuantity > 0 ? (newInTotalAmount / newInTotalQuantity) : 0) + " 分/个"); + System.out.println("新进总金额: " + newInTotalAmount + " 分"); + System.out.println("总数量: " + totalQuantity); + System.out.println("总金额: " + totalAmount + " 分"); + System.out.println("新成本价: " + newCostPrice + " 分/个"); + System.out.println("新成本价(保留2位): " + String.format("%.2f", newCostPrice) + " 分/个"); + System.out.println("=========================================="); + } else { + // 如果总数量为0,使用新进商品的平均价格 + if (newInTotalQuantity > 0) { + newCostPrice = newInTotalAmount / newInTotalQuantity; + } + } + + // 更新商品成本价 + SmErpSpuEntity updateSpu = new SmErpSpuEntity(); + updateSpu.setId(erpSpuId); + updateSpu.setCostPrice(newCostPrice); + smErpSpuMapper.updateById(updateSpu); + }); + } + } + return i; }