Explorar o código

计算结存单价

24282 %!s(int64=2) %!d(string=hai) anos
pai
achega
b83c7affbc

+ 60 - 0
hx-wms/src/main/java/com/fjhx/wms/utils/CalculatingUnitPriceUtil.java

@@ -0,0 +1,60 @@
+package com.fjhx.wms.utils;
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.extra.spring.SpringUtil;
+import com.fjhx.item.entity.product.po.ProductInfo;
+import com.fjhx.item.service.product.ProductInfoService;
+import com.fjhx.wms.entity.stock.po.Stock;
+import com.fjhx.wms.service.stock.StockService;
+import com.ruoyi.common.exception.ServiceException;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * 计算结存单价
+ */
+public class CalculatingUnitPriceUtil {
+
+    private static final StockService stockService = SpringUtil.getBean(StockService.class);
+    private static final ProductInfoService productInfoService = SpringUtil.getBean(ProductInfoService.class);
+
+    /**
+     * 加权平均值
+     * (库存单价 * 库存数量 + 入库单价 * 入库数量) / (库存数量 + 入库数量)
+     *
+     * @param productId 产品id
+     * @param quantity  入库数量
+     * @param price     入库单价
+     * @return 加权平均值
+     */
+    public static BigDecimal weightedMean(Long productId, BigDecimal quantity, BigDecimal price) {
+        BigDecimal oldUnitPrice = getOldUnitPrice(productId);
+        BigDecimal stockQuantity = getStockQuantity(productId);
+
+        return oldUnitPrice.multiply(stockQuantity).add(price.multiply(quantity))
+                .divide(stockQuantity.add(quantity), 4, RoundingMode.HALF_UP);
+    }
+
+    /**
+     * 获取原结存单价
+     */
+    private static BigDecimal getOldUnitPrice(Long productId) {
+        ProductInfo productInfo = productInfoService.getById(productId);
+        if (productInfo == null) {
+            throw new ServiceException("未找到产品");
+        }
+        return ObjectUtil.defaultIfNull(productInfo.getUnitPrice(), BigDecimal.ZERO);
+    }
+
+    /**
+     * 获取库存数量
+     */
+    private static BigDecimal getStockQuantity(Long productId) {
+        List<Stock> list = stockService.list(q -> q.eq(Stock::getProductId, productId));
+        return list.stream().map(Stock::getQuantity).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
+    }
+
+}