|
@@ -1,6 +1,7 @@
|
|
|
package com.fjhx.wms.service.stock.impl;
|
|
|
|
|
|
import cn.hutool.core.bean.BeanUtil;
|
|
|
+import cn.hutool.core.util.ObjectUtil;
|
|
|
import com.baomidou.dynamic.datasource.annotation.DS;
|
|
|
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
|
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
@@ -9,11 +10,12 @@ import com.fjhx.common.constant.SourceConstant;
|
|
|
import com.fjhx.common.utils.Assert;
|
|
|
import com.fjhx.item.entity.product.po.ProductInfo;
|
|
|
import com.fjhx.item.service.product.ProductInfoService;
|
|
|
+import com.fjhx.wms.entity.purchase.po.PurchaseDetailPo;
|
|
|
import com.fjhx.wms.entity.stock.bo.InOutBo;
|
|
|
-import com.fjhx.wms.entity.stock.dto.StockJournalDetailsDto;
|
|
|
import com.fjhx.wms.entity.stock.dto.StockWaitDetailsDto;
|
|
|
import com.fjhx.wms.entity.stock.dto.StockWaitDto;
|
|
|
import com.fjhx.wms.entity.stock.dto.StockWaitSelectDto;
|
|
|
+import com.fjhx.wms.entity.stock.emums.InOutType;
|
|
|
import com.fjhx.wms.entity.stock.emums.JournalType;
|
|
|
import com.fjhx.wms.entity.stock.emums.StockWaitType;
|
|
|
import com.fjhx.wms.entity.stock.po.*;
|
|
@@ -27,13 +29,17 @@ import com.fjhx.wms.service.arrival.ArrivalStockRecordsService;
|
|
|
import com.fjhx.wms.service.stock.*;
|
|
|
import com.fjhx.wms.service.warehouse.WarehouseService;
|
|
|
import com.fjhx.wms.utils.CodeEnum;
|
|
|
+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;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
+import java.math.RoundingMode;
|
|
|
import java.util.Collections;
|
|
|
+import java.util.Date;
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
@@ -142,6 +148,13 @@ public class StockWaitServiceImpl extends ServiceImpl<StockWaitMapper, StockWait
|
|
|
.set(StockWaitDetails::getStatus, stockWaitDetailsStatus)
|
|
|
);
|
|
|
|
|
|
+ //判断业务类型是否是采购到货
|
|
|
+ int purchaseArrival = StockWaitType.PURCHASE_ARRIVAL_IN.getDetailType().equals(stockWait.getBusinessType()) ? 1 : 0;
|
|
|
+ //获取采购单价(只有采购到货才有)
|
|
|
+ PurchaseDetailPo purchaseDetail = baseMapper.getPurchaseDetail(IWrapper.getWrapper().eq("swd.id", stockWaitDetails.getId()));
|
|
|
+ //计算结存单价
|
|
|
+ StockJournalDetails stockJournalDetails = calculateUnitPrice(stockJournalType.getType(), productId, warehouseId, inOutQuantity, purchaseArrival, purchaseDetail.getPrice());
|
|
|
+
|
|
|
//操作库存
|
|
|
InOutBo inOutBo = new InOutBo(productId, inOutQuantity);
|
|
|
stockService.changeStock(Collections.singletonList(inOutBo), warehouseId, stockJournalType);
|
|
@@ -158,13 +171,25 @@ public class StockWaitServiceImpl extends ServiceImpl<StockWaitMapper, StockWait
|
|
|
stockJournal.setReceivingPerson(dto.getReceivingPerson());
|
|
|
stockJournalService.save(stockJournal);
|
|
|
//创建流水明细
|
|
|
- StockJournalDetails stockJournalDetails = new StockJournalDetailsDto();
|
|
|
stockJournalDetails.setStockJournalId(stockJournal.getId());
|
|
|
stockJournalDetails.setProductId(productId);
|
|
|
stockJournalDetails.setQuantity(inOutQuantity);
|
|
|
stockJournalDetails.setBusinessDetailsId(stockWaitDetails.getId());
|
|
|
stockJournalDetailsService.save(stockJournalDetails);
|
|
|
|
|
|
+ //更新待入库状态(等待明细操作完执行)
|
|
|
+ long count = stockWaitDetailsService.count(q -> q
|
|
|
+ .eq(StockWaitDetails::getStockWaitId, stockWait.getId())
|
|
|
+ .ne(StockWaitDetails::getStatus, 2)
|
|
|
+ );
|
|
|
+ Integer StockWaitStatus = count > 0 ? 1 : 2;
|
|
|
+ this.update(q -> q
|
|
|
+ .eq(StockWait::getId, stockWait.getId())
|
|
|
+ .set(StockWait::getStatus, StockWaitStatus)
|
|
|
+ .set(BasePo::getUpdateTime, new Date())
|
|
|
+ .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
|
|
|
+ );
|
|
|
+
|
|
|
//生产任务待出库(物料出库解冻冻结库存)
|
|
|
if (StockWaitType.PRODUCTION_TASK_OUT.getDetailType().equals(stockWait.getType())) {
|
|
|
//减少冻结库存
|
|
@@ -172,19 +197,120 @@ public class StockWaitServiceImpl extends ServiceImpl<StockWaitMapper, StockWait
|
|
|
stockFrozenService.update(q -> q
|
|
|
.eq(StockFrozen::getId, stockFrozen.getId())
|
|
|
.setSql("frozen_quantity - " + inOutQuantity)
|
|
|
+ .set(BasePo::getUpdateTime, new Date())
|
|
|
+ .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
|
|
|
);
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- //更新待入库状态(等待明细操作完执行)
|
|
|
- long count = stockWaitDetailsService.count(q -> q
|
|
|
- .eq(StockWaitDetails::getStockWaitId, stockWait.getId())
|
|
|
- .ne(StockWaitDetails::getStatus, 2)
|
|
|
- );
|
|
|
- Integer StockWaitStatus = count > 0 ? 1 : 2;
|
|
|
- this.update(q -> q.eq(StockWait::getId, stockWait.getId()).set(StockWait::getStatus, StockWaitStatus));
|
|
|
+ /**
|
|
|
+ * 计算结存单价(在操作库存之前计算)
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public synchronized StockJournalDetails calculateUnitPrice(InOutType inOutType, Long productId, Long warehouseId, BigDecimal inOutQuantity, Integer purchaseArrival, BigDecimal purchasePrice) {
|
|
|
+ StockJournalDetails stockJournalDetails = new StockJournalDetails();
|
|
|
+ stockJournalDetails.setProductId(productId);
|
|
|
+ stockJournalDetails.setQuantity(inOutQuantity);
|
|
|
|
|
|
- //计算结存单价
|
|
|
- //采购到货(单独计算结存单价)
|
|
|
+ //计算结存单价(在操作库存之前计算)
|
|
|
+ ProductInfo productInfo = productInfoService.getById(productId);
|
|
|
+ Assert.notEmpty(productInfo, "查询不到产品信息");
|
|
|
+ //在库结存单价(实时在库单价)
|
|
|
+ BigDecimal unitPrice = productInfo.getUnitPrice();
|
|
|
+ unitPrice = ObjectUtil.isEmpty(unitPrice) ? BigDecimal.ZERO : unitPrice;
|
|
|
+ //不在库结存单价(实时不在库单价)
|
|
|
+ BigDecimal outUnitPrice = productInfo.getOutUnitPrice();
|
|
|
+ outUnitPrice = ObjectUtil.isEmpty(outUnitPrice) ? BigDecimal.ZERO : outUnitPrice;
|
|
|
+ List<Stock> stockList = stockService.list(q -> q.eq(Stock::getProductId, productId));
|
|
|
+ //在库总库存(所有仓库)
|
|
|
+ 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 = stockService.getOne(q -> q.eq(Stock::getWarehouseId, warehouseId).eq(Stock::getProductId, productId));
|
|
|
+ //库存不存在创建0库存记录
|
|
|
+ if(ObjectUtil.isEmpty(stock)){
|
|
|
+ stock = new Stock();
|
|
|
+ stock.setWarehouseId(warehouseId);
|
|
|
+ stock.setProductId(productId);
|
|
|
+ stock.setQuantity(BigDecimal.ZERO);
|
|
|
+ stockService.save(stock);
|
|
|
+ }
|
|
|
+ Stock finalStock = stock;
|
|
|
+ if (inOutType.equals(InOutType.IN)) {
|
|
|
+ //入库
|
|
|
+ //【其他入库】当前价值=实时不在库单价
|
|
|
+ BigDecimal price = outUnitPrice;
|
|
|
+
|
|
|
+ //【采购入库】当前价值=采购单价
|
|
|
+ if (purchaseArrival == 1) {
|
|
|
+ price = purchasePrice;
|
|
|
+ }
|
|
|
+ //【入库】实时在库单价=(库存*实时在库单价 + 当前入库数量*当前价值) / (库存+当前入库数量)
|
|
|
+ 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);
|
|
|
+ stockService.update(q -> q
|
|
|
+ .eq(Stock::getId, finalStock.getId())
|
|
|
+ .setSql(format)
|
|
|
+ .set(BasePo::getUpdateTime, new Date())
|
|
|
+ .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
|
|
|
+ );
|
|
|
+ }
|
|
|
+ //修改产品中的库存单价
|
|
|
+ productInfoService.update(q -> q
|
|
|
+ .eq(ProductInfo::getId, productId)
|
|
|
+ .set(ProductInfo::getUnitPrice, newUnitPrice)
|
|
|
+ .set(BasePo::getUpdateTime, new Date())
|
|
|
+ .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
|
|
|
+ );
|
|
|
+
|
|
|
+ //赋值流水信息
|
|
|
+ stockJournalDetails.setPrice(price);
|
|
|
+ stockJournalDetails.setStockPrice(newUnitPrice);
|
|
|
+ //【入库】实时不在库单价=A物料最新流水的实时不在库单价(不用动直接获取产品的不在库单价)
|
|
|
+ stockJournalDetails.setOutStockPrice(outUnitPrice);
|
|
|
+ } else {
|
|
|
+ //出库
|
|
|
+ //【出库】当前价值=实时在库单价
|
|
|
+ BigDecimal 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);
|
|
|
+
|
|
|
+ //计算已出库库存-【出库】已出库 = 已出库+当前出库数量
|
|
|
+ stockService.update(q -> q
|
|
|
+ .eq(Stock::getId, finalStock.getId())
|
|
|
+ .setSql("out_quantity = out_quantity + " + inOutQuantity)
|
|
|
+ .set(BasePo::getUpdateTime, new Date())
|
|
|
+ .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
|
|
|
+ );
|
|
|
+ //修改产品中的已出库单价
|
|
|
+ productInfoService.update(q -> q
|
|
|
+ .eq(ProductInfo::getId, productId)
|
|
|
+ .set(ProductInfo::getOutUnitPrice, newOutUnitPrice)
|
|
|
+ .set(BasePo::getUpdateTime, new Date())
|
|
|
+ .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
|
|
|
+ );
|
|
|
+
|
|
|
+ //赋值流水信息
|
|
|
+ stockJournalDetails.setPrice(price);
|
|
|
+ //【出库】实时在库单价=A物料最新流水的实时在库单价(不用动直接获取产品的在库单价)
|
|
|
+ stockJournalDetails.setStockPrice(unitPrice);
|
|
|
+ stockJournalDetails.setOutStockPrice(newOutUnitPrice);
|
|
|
+ }
|
|
|
+
|
|
|
+ return stockJournalDetails;
|
|
|
}
|
|
|
|
|
|
@Override
|