修改成本单价的计算方式为-新成本价 = (剩余商品进货价 × 剩余数量 + 新进商品进货价 × 新进数量) / (剩余数量 + 新进数量)

This commit is contained in:
zjf committed 2025-10-21 18:23:47 +08:00
1 parent fbaf8d150d
commit a3d8df9ad8
1 file changed
+237 -25
@@ -68,7 +68,6 @@ public class SmErpInventoryRecordsServiceImpl extends ServiceImpl<SmErpInventory
private final SmErpSupplierMapper smErpSupplierMapper;
private final RemoteFlowApiFlowService remoteFlowApiFlowService;
@Override
@Transactional
public Object saveInventoryRecord(InventoryRecordSaveDTO inventoryRecordSaveDTO) {
@@ -149,43 +148,116 @@ public class SmErpInventoryRecordsServiceImpl extends ServiceImpl<SmErpInventory
smErpCgDdMapper.update(updateSmErpCgDdEntity,queryWrapper);
//计算库存商品的成本价= 采购金额*采购数量/采购数量
//计算库存商品的成本价 = (剩余商品进货价*剩余数量+新进商品进货价*新进数量)/(剩余数量+新进数量)
if (inventoryRecordSaveDTO.getInventoryType().equals(InventoryTypeEnum.CKRK.getType())){
// 获取当前采购入库的商品ID列表
List<Long> currentSpuIds = cgPlanItemEntities.stream()
.map(SmErpInventoryRecordsItemEntity::getErpSpuId)
.distinct()
.collect(Collectors.toList());
List<SmErpCostPriceVo> itemEntityList = smErpInventoryRecordsItemMapper.getRecordsItemListBySpuIdsAndInventoryType(
currentSpuIds
// 获取当前库存信息和商品信息
List<SmErpStockEntity> stockList = smErpStockService.list(
new LambdaQueryWrapper<SmErpStockEntity>().in(SmErpStockEntity::getErpSpuId, currentSpuIds)
);
Map<Long, List<SmErpCostPriceVo>> costPriceMap = itemEntityList.stream()
.collect(Collectors.groupingBy(SmErpCostPriceVo::getErpSpuId));
Map<Long, SmErpStockEntity> stockMap = stockList.stream()
.collect(Collectors.toMap(SmErpStockEntity::getErpSpuId, stock -> stock));
// 计算并更新成本价
cgPlanItemEntities.forEach(item -> {
Long erpSpuId = item.getErpSpuId();
List<SmErpCostPriceVo> smErpInventoryRecordsItemEntityList = costPriceMap.get(erpSpuId);
Double totalNum = smErpInventoryRecordsItemEntityList.stream().filter(Objects::nonNull).mapToDouble(itemEntity -> itemEntity.getPackageNum() * itemEntity.getQuantity()).sum();
List<SmErpSpuEntity> spuList = smErpSpuMapper.selectList(
new LambdaQueryWrapper<SmErpSpuEntity>().in(SmErpSpuEntity::getId, currentSpuIds)
);
Map<Long, SmErpSpuEntity> 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<Long, List<SmErpInventoryRecordsItemEntity>> 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<SmErpUnitEntity> 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<SmErpInventory
//更新库存
smErpStockService.updateStock(updateStockDTOS);
//计算库存商品的成本价 = (剩余商品进货价*剩余数量+新进商品进货价*新进数量)/(剩余数量+新进数量)
//只有采购入库类型才需要更新成本价
if (smErpInventoryRecordsEntity.getInventoryType() != null &&
smErpInventoryRecordsEntity.getInventoryType().equals(InventoryTypeEnum.CKRK.getType())){
// 获取最终保存的商品列表
List<SmErpInventoryRecordsItemEntity> savedItems = smErpInventoryRecordsItemMapper.selectList(
new LambdaQueryWrapper<SmErpInventoryRecordsItemEntity>()
.eq(SmErpInventoryRecordsItemEntity::getInventoryId, inventoryRecordEditDTO.getId())
);
// 获取涉及的商品ID
List<Long> currentSpuIds = savedItems.stream()
.map(SmErpInventoryRecordsItemEntity::getErpSpuId)
.distinct()
.collect(Collectors.toList());
if (!CollectionUtils.isEmpty(currentSpuIds)) {
// 获取当前库存信息和商品信息
List<SmErpStockEntity> stockList = smErpStockService.list(
new LambdaQueryWrapper<SmErpStockEntity>().in(SmErpStockEntity::getErpSpuId, currentSpuIds)
);
Map<Long, SmErpStockEntity> stockMap = stockList.stream()
.collect(Collectors.toMap(SmErpStockEntity::getErpSpuId, stock -> stock));
List<SmErpSpuEntity> spuList = smErpSpuMapper.selectList(
new LambdaQueryWrapper<SmErpSpuEntity>().in(SmErpSpuEntity::getId, currentSpuIds)
);
Map<Long, SmErpSpuEntity> spuMap = spuList.stream()
.collect(Collectors.toMap(SmErpSpuEntity::getId, spu -> spu));
// 按商品分组,计算每个商品的加权平均成本价
Map<Long, List<SmErpInventoryRecordsItemEntity>> 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<SmErpUnitEntity> 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;
}