瀏覽代碼

签移结存单价算法代码块

yzc 1 年之前
父節點
當前提交
ce752b4d86

+ 4 - 4
hx-item/src/main/java/com/fjhx/item/entity/product/po/ProductInfo.java

@@ -165,10 +165,10 @@ public class ProductInfo extends BasePo {
      */
     private String barCode;
 
-    /**
-     * 结存单价
-     */
-    private BigDecimal unitPrice;
+//    /**
+//     * 结存单价
+//     */
+//    private BigDecimal unitPrice;
 
     /**
      * 归属公司Id

+ 11 - 0
hx-item/src/main/java/com/fjhx/item/entity/product/po/ProductStockInfo.java

@@ -35,4 +35,15 @@ public class ProductStockInfo extends BasePo {
      */
     private Long companyId;
 
+    /**
+     * 结存单价(在库库存单价)
+     */
+    private BigDecimal unitPrice;
+
+    /**
+     * 不在库库存单价(不在库库存结存单价)
+     */
+    private BigDecimal outUnitPrice;
+
+
 }

+ 5 - 0
hx-wms/src/main/java/com/fjhx/wms/entity/stock/po/Stock.java

@@ -50,4 +50,9 @@ public class Stock extends BasePo {
      */
     private Long companyId;
 
+    /**
+     * 不在库库存数量
+     */
+    private BigDecimal outQuantity;
+
 }

+ 14 - 0
hx-wms/src/main/java/com/fjhx/wms/entity/stock/po/StockJournalDetails.java

@@ -40,4 +40,18 @@ public class StockJournalDetails extends BasePo {
      */
     private Long businessDetailsId;
 
+    /**
+     * 产品单价
+     */
+    private BigDecimal price;
+    /**
+     * 当时库存单价
+     */
+    private BigDecimal stockPrice;
+    /**
+     * 当时出库库存单价
+     */
+    private BigDecimal outStockPrice;
+
+
 }

+ 8 - 0
hx-wms/src/main/java/com/fjhx/wms/service/stock/StockService.java

@@ -2,13 +2,16 @@ package com.fjhx.wms.service.stock;
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.fjhx.common.entity.InOutBo;
+import com.fjhx.common.enums.InOutType;
 import com.fjhx.wms.entity.stock.dto.StockDto;
 import com.fjhx.wms.entity.stock.dto.StockSelectDto;
 import com.fjhx.wms.entity.stock.emums.JournalType;
 import com.fjhx.wms.entity.stock.po.Stock;
+import com.fjhx.wms.entity.stock.po.StockJournalDetails;
 import com.fjhx.wms.entity.stock.vo.StockVo;
 import com.ruoyi.common.core.service.BaseService;
 
+import java.math.BigDecimal;
 import java.util.List;
 
 
@@ -48,4 +51,9 @@ public interface StockService extends BaseService<Stock> {
     void delete(Long id);
 
     void changeStock(List<? extends InOutBo> list, Long warehouseId, JournalType journalType);
+
+    /**
+     * 计算结存单价(在操作库存之前计算)
+     */
+    StockJournalDetails calculateUnitPrice(InOutType inOutType, Long productId, Long warehouseId, BigDecimal inOutQuantity, Integer purchaseArrival, BigDecimal price);
 }

+ 139 - 9
hx-wms/src/main/java/com/fjhx/wms/service/stock/impl/StockServiceImpl.java

@@ -10,9 +10,11 @@ import com.fjhx.common.entity.InOutBo;
 import com.fjhx.common.enums.InOutType;
 import com.fjhx.item.entity.product.po.ProductClassify;
 import com.fjhx.item.entity.product.po.ProductInfo;
+import com.fjhx.item.entity.product.po.ProductStockInfo;
 import com.fjhx.item.enums.ProductAvailableRecordType;
 import com.fjhx.item.service.product.ProductClassifyService;
 import com.fjhx.item.service.product.ProductInfoService;
+import com.fjhx.item.service.product.ProductStockInfoService;
 import com.fjhx.wms.entity.stock.dto.StockDto;
 import com.fjhx.wms.entity.stock.dto.StockJournalDetailsDto;
 import com.fjhx.wms.entity.stock.dto.StockSelectDto;
@@ -29,6 +31,7 @@ import com.fjhx.wms.service.stock.StockService;
 import com.fjhx.wms.service.warehouse.WarehouseService;
 import com.fjhx.wms.utils.CodeEnum;
 import com.ruoyi.common.core.domain.BaseIdPo;
+import com.ruoyi.common.core.domain.BasePo;
 import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.wrapper.IWrapper;
@@ -36,10 +39,8 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
+import java.math.RoundingMode;
+import java.util.*;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 
@@ -55,15 +56,17 @@ import java.util.stream.Collectors;
 @Service
 public class StockServiceImpl extends ServiceImpl<StockMapper, Stock> implements StockService {
     @Autowired
-    StockJournalService stockJournalService;
+    private StockJournalService stockJournalService;
     @Autowired
-    StockJournalDetailsService stockJournalDetailsService;
+    private StockJournalDetailsService stockJournalDetailsService;
     @Autowired
-    ProductInfoService productInfoService;
+    private ProductInfoService productInfoService;
     @Autowired
-    ProductClassifyService productClassifyService;
+    private ProductClassifyService productClassifyService;
     @Autowired
-    WarehouseService warehouseService;
+    private WarehouseService warehouseService;
+    @Autowired
+    private ProductStockInfoService productStockInfoService;
 
     @Override
     public Page<StockVo> getPage(StockSelectDto dto) {
@@ -245,4 +248,131 @@ public class StockServiceImpl extends ServiceImpl<StockMapper, Stock> implements
         }
     }
 
+    /**
+     * 计算结存单价(在操作库存之前计算)
+     */
+    @Override
+    public synchronized StockJournalDetails calculateUnitPrice(InOutType inOutType, Long productId, Long warehouseId, BigDecimal inOutQuantity, Integer purchaseArrival, BigDecimal price) {
+        Warehouse warehouse = warehouseService.getById(warehouseId);
+        if (ObjectUtil.isEmpty(warehouse)) {
+            throw new ServiceException("查询不到仓库信息");
+        }
+        Long companyId = warehouse.getCompanyId();
+
+        StockJournalDetails stockJournalDetails = new StockJournalDetails();
+        stockJournalDetails.setProductId(productId);
+        stockJournalDetails.setQuantity(inOutQuantity);
+
+        //计算结存单价(在操作库存之前计算)
+        ProductStockInfo productStockInfo = productStockInfoService.getOne(q -> q
+                .eq(ProductStockInfo::getProductId, productId)
+                .eq(ProductStockInfo::getCompanyId, companyId)
+        );
+        if (ObjectUtil.isEmpty(productStockInfo)) {
+            throw new ServiceException("查询不到产品信息");
+        }
+        //在库结存单价(实时在库单价)
+        BigDecimal unitPrice = productStockInfo.getUnitPrice();
+        unitPrice = ObjectUtil.isEmpty(unitPrice) ? BigDecimal.ZERO : unitPrice;
+        //不在库结存单价(实时不在库单价)
+        BigDecimal outUnitPrice = productStockInfo.getOutUnitPrice();
+        outUnitPrice = ObjectUtil.isEmpty(outUnitPrice) ? BigDecimal.ZERO : outUnitPrice;
+        List<Stock> stockList = this.list(q -> q.eq(Stock::getProductId, productId).eq(Stock::getCompanyId, companyId));
+        //在库总库存(所有仓库)
+        BigDecimal stockQuantity = stockList.stream().map(Stock::getQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
+        //不在库总库存(所有仓库)
+        BigDecimal stockOutQuantity = stockList.stream().map(Stock::getOutQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
+        //获取产品当前仓库信息
+        Stock stock = this.getOne(q -> q.eq(Stock::getWarehouseId, warehouseId).eq(Stock::getProductId, productId).eq(Stock::getCompanyId, companyId));
+        //库存不存在创建0库存记录
+        if (ObjectUtil.isEmpty(stock)) {
+            stock = new Stock();
+            stock.setWarehouseId(warehouseId);
+            stock.setProductId(productId);
+            stock.setQuantity(BigDecimal.ZERO);
+            stock.setCompanyId(companyId);
+            this.save(stock);
+        }
+        Stock finalStock = stock;
+        if (inOutType.equals(InOutType.IN)) {
+            //入库
+            //有单价【采购入库等】按单价算,没有按【其他入库】当前价值=实时不在库单价
+            if (price == null) {
+                price = outUnitPrice;
+            }
+
+            //【入库】实时在库单价=(库存*实时在库单价 + 当前入库数量*当前价值) / (库存+当前入库数量)
+            BigDecimal multiply0 = stockQuantity.multiply(unitPrice);//库存*实时在库单价
+            BigDecimal multiply1 = inOutQuantity.multiply(price);//当前入库数量*当前价值
+            BigDecimal add0 = multiply0.add(multiply1);//(库存*实时在库单价 + 当前入库数量*当前价值)
+            BigDecimal add1 = stockQuantity.add(inOutQuantity);//(库存+当前入库数量)
+            BigDecimal newUnitPrice = add0.divide(add1, 4, RoundingMode.HALF_UP);
+
+            //【其他入库】已出库(为负数时取0) = 已出库 - 当前入库数量
+            if (purchaseArrival != 1) {
+                String format = String.format("out_quantity = IF((out_quantity - %s)<0,0,(out_quantity - %s))", inOutQuantity, inOutQuantity);
+                this.update(q -> q
+                        .eq(Stock::getId, finalStock.getId())
+                        .eq(Stock::getCompanyId, companyId)
+                        .setSql(format)
+                        .set(BasePo::getUpdateTime, new Date())
+                        .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
+                );
+            }
+            //修改产品中的库存单价
+            productStockInfoService.update(q -> q
+                    .eq(ProductStockInfo::getProductId, productId)
+                    .eq(ProductStockInfo::getCompanyId, companyId)
+                    .set(ProductStockInfo::getUnitPrice, newUnitPrice)
+                    .set(BasePo::getUpdateTime, new Date())
+                    .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
+            );
+
+            //赋值流水信息
+            stockJournalDetails.setPrice(price);
+            stockJournalDetails.setStockPrice(newUnitPrice);
+            //【入库】实时不在库单价=A物料最新流水的实时不在库单价(不用动直接获取产品的不在库单价)
+            stockJournalDetails.setOutStockPrice(outUnitPrice);
+        } else {
+            //出库
+
+            //有单价按单价算,没有按【出库】当前价值=实时在库单价
+            if (price == null) {
+                price = unitPrice;
+            }
+
+            //【出库】实时不在库单价=(不在库数量*实时不在库单价 + 当前出库数量*当前价值) / (不在库数量+当前出库数量)
+            BigDecimal multiply0 = stockOutQuantity.multiply(outUnitPrice);//不在库数量*实时不在库单价
+            BigDecimal multiply1 = inOutQuantity.multiply(price);//当前出库数量*当前价值
+            BigDecimal add0 = multiply0.add(multiply1);//(不在库数量*实时不在库单价 + 当前出库数量*当前价值)
+            BigDecimal add1 = stockOutQuantity.add(inOutQuantity);//(不在库数量+当前出库数量)
+            BigDecimal newOutUnitPrice = add0.divide(add1, 4, RoundingMode.HALF_UP);
+
+            //计算已出库库存-【出库】已出库 = 已出库+当前出库数量
+            this.update(q -> q
+                    .eq(Stock::getId, finalStock.getId())
+                    .eq(Stock::getCompanyId, companyId)
+                    .setSql("out_quantity = out_quantity + " + inOutQuantity)
+                    .set(BasePo::getUpdateTime, new Date())
+                    .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
+            );
+            //修改产品中的已出库单价
+            productStockInfoService.update(q -> q
+                    .eq(ProductStockInfo::getProductId, productId)
+                    .eq(ProductStockInfo::getCompanyId, companyId)
+                    .set(ProductStockInfo::getOutUnitPrice, newOutUnitPrice)
+                    .set(BasePo::getUpdateTime, new Date())
+                    .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
+            );
+
+            //赋值流水信息
+            stockJournalDetails.setPrice(price);
+            //【出库】实时在库单价=A物料最新流水的实时在库单价(不用动直接获取产品的在库单价)
+            stockJournalDetails.setStockPrice(unitPrice);
+            stockJournalDetails.setOutStockPrice(newOutUnitPrice);
+        }
+
+        return stockJournalDetails;
+    }
+
 }

+ 6 - 10
hx-wms/src/main/java/com/fjhx/wms/service/stock/impl/StockWaitServiceImpl.java

@@ -171,18 +171,8 @@ public class StockWaitServiceImpl extends ServiceImpl<StockWaitMapper, StockWait
         StockWaitDto stockWaitDto = BeanUtil.copyProperties(stockWaitDetailsDto, StockWaitDto.class);
         stockWaitDto.setId(stockWaitDetails.getStockWaitId());
         stockWaitDto.setStockWaitDetailsList(Collections.singletonList(BeanUtil.copyProperties(stockWaitDetailsDto, StockWaitDetails.class)));
-        this.add1(stockWaitDto);
 
-        //如果是采购退货 修改采购退货状态
-        StockWait stockWait = this.getById(stockWaitDto.getId());
-        Assert.notEmpty(stockWait, "查询不到待出库信息");
-        if (stockWait.getBusinessType() == 4) {
-            Integer status = stockWait.getStatus();
-            myPurchaseService.updateSalesReturnStatus(stockWaitDetails.getBusinessDetailsId(), status);
-        }
-    }
 
-    public void add1(StockWaitDto stockWaitDto) {
         Assert.notEmpty(stockWaitDto.getId(), "待出入库id不能为空");
         Assert.notEmpty(stockWaitDto.getWarehouseId(), "仓库id不能为空");
 
@@ -234,6 +224,12 @@ public class StockWaitServiceImpl extends ServiceImpl<StockWaitMapper, StockWait
         //保存出入库明细
         stockJournalDetailsService.saveBatch(stockJournalDetailsList);
 
+        //如果是采购退货 修改采购退货状态
+        Assert.notEmpty(stockWait, "查询不到待出库信息");
+        if (stockWait.getBusinessType() == 4) {
+            Integer status = stockWait.getStatus();
+            myPurchaseService.updateSalesReturnStatus(stockWaitDetails.getBusinessDetailsId(), status);
+        }
     }
 
     @Override