|
@@ -1,17 +1,20 @@
|
|
|
package com.fjhx.service.stock.impl;
|
|
|
|
|
|
+import cn.hutool.core.util.ObjectUtil;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
-import com.fjhx.constants.ErrorMsgConstant;
|
|
|
+import com.fjhx.constants.StatusConstant;
|
|
|
import com.fjhx.constants.StockJournalTypeConstant;
|
|
|
-import com.fjhx.constants.VLockConstant;
|
|
|
import com.fjhx.entity.stock.Stock;
|
|
|
+import com.fjhx.entity.stock.StockJournal;
|
|
|
+import com.fjhx.enums.stock.InTypeEnum;
|
|
|
+import com.fjhx.enums.stock.OutTypeEnum;
|
|
|
import com.fjhx.mapper.stock.StockMapper;
|
|
|
+import com.fjhx.params.stock.StockChangeVo;
|
|
|
import com.fjhx.params.stock.StockVo;
|
|
|
import com.fjhx.service.stock.StockService;
|
|
|
-import com.fjhx.utils.Assert;
|
|
|
import com.fjhx.utils.WrapperUtil;
|
|
|
import org.springblade.core.log.exception.ServiceException;
|
|
|
import org.springblade.core.redis.lock.RedisLockClient;
|
|
@@ -21,7 +24,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
|
import java.math.BigDecimal;
|
|
|
-import java.util.Map;
|
|
|
+import java.util.*;
|
|
|
|
|
|
/**
|
|
|
* <p>
|
|
@@ -67,47 +70,146 @@ public class StockServiceImpl extends ServiceImpl<StockMapper, Stock> implements
|
|
|
removeById(stockVo.getId());
|
|
|
}
|
|
|
|
|
|
+// @Transactional(rollbackFor = Exception.class)
|
|
|
+// @Override
|
|
|
+// public void changeQuantity(Long goodsId, Long warehouseId, BigDecimal quantity, Integer detailsType, String remarks) {
|
|
|
+// // 分布式锁,粒度为物品id + 仓库id
|
|
|
+// Boolean flag = redisLockClient.lockFair(VLockConstant.STOCK_LOCK + goodsId + warehouseId,
|
|
|
+// () -> {
|
|
|
+// Stock stock = getOne(q -> q.eq(Stock::getGoodsId, goodsId).eq(Stock::getWarehouseId, warehouseId));
|
|
|
+//
|
|
|
+// // 没有物料存储记录,则创建物料
|
|
|
+// if (stock == null) {
|
|
|
+// if (quantity.compareTo(BigDecimal.ZERO) < 0) {
|
|
|
+// throw new ServiceException("库存不足,出库失败");
|
|
|
+// }
|
|
|
+//
|
|
|
+// stock = new Stock();
|
|
|
+// stock.setGoodsId(goodsId);
|
|
|
+// stock.setQuantity(quantity);
|
|
|
+// stock.setWarehouseId(warehouseId);
|
|
|
+// return save(stock);
|
|
|
+// }
|
|
|
+//
|
|
|
+// BigDecimal newQuantity = stock.getQuantity().add(quantity);
|
|
|
+// if (newQuantity.compareTo(BigDecimal.ZERO) < 0) {
|
|
|
+// throw new ServiceException("库存不足,出库失败");
|
|
|
+// }
|
|
|
+//
|
|
|
+// stock.setQuantity(newQuantity);
|
|
|
+// return updateById(stock);
|
|
|
+// });
|
|
|
+//
|
|
|
+// Assert.eqTrue(flag, ErrorMsgConstant.SYSTEM_BUSY_ERROR);
|
|
|
+//
|
|
|
+// // 添加出入库明细
|
|
|
+// stockJournalService.add(
|
|
|
+// quantity.compareTo(BigDecimal.ZERO) > 0 ? StockJournalTypeConstant.IN : StockJournalTypeConstant.OUT,
|
|
|
+// detailsType,
|
|
|
+// goodsId,
|
|
|
+// warehouseId,
|
|
|
+// quantity.compareTo(BigDecimal.ZERO) > 0 ? quantity : BigDecimal.ZERO.subtract(quantity),
|
|
|
+// remarks
|
|
|
+// );
|
|
|
+// }
|
|
|
+
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
@Override
|
|
|
- public void changeQuantity(Long goodsId, Long warehouseId, BigDecimal quantity, Integer detailsType, String remarks) {
|
|
|
- // 分布式锁,粒度为物品id + 仓库id
|
|
|
- Boolean flag = redisLockClient.lockFair(VLockConstant.STOCK_LOCK + goodsId + warehouseId,
|
|
|
- () -> {
|
|
|
- Stock stock = getOne(q -> q.eq(Stock::getGoodsId, goodsId).eq(Stock::getWarehouseId, warehouseId));
|
|
|
-
|
|
|
- // 没有物料存储记录,则创建物料
|
|
|
- if (stock == null) {
|
|
|
- if (quantity.compareTo(BigDecimal.ZERO) < 0) {
|
|
|
- throw new ServiceException("库存不足,出库失败");
|
|
|
- }
|
|
|
-
|
|
|
- stock = new Stock();
|
|
|
- stock.setGoodsId(goodsId);
|
|
|
- stock.setQuantity(quantity);
|
|
|
- stock.setWarehouseId(warehouseId);
|
|
|
- return save(stock);
|
|
|
+ public void changeQuantity(StockChangeVo stockChangeVo) {
|
|
|
+
|
|
|
+ Enum<?> typeEnum = stockChangeVo.getTypeEnum();
|
|
|
+ List<? extends StockChangeVo.ChangeDetails> changeDetailsList = stockChangeVo.getChangeDetailsList();
|
|
|
+
|
|
|
+ HashMap<String, Stock> map = new HashMap<>();
|
|
|
+
|
|
|
+ for (StockChangeVo.ChangeDetails changeDetails : changeDetailsList) {
|
|
|
+
|
|
|
+ // 变更数量
|
|
|
+ BigDecimal changeQuantity = changeDetails.getChangeQuantity();
|
|
|
+ // 变更数量小于等于0,则跳过
|
|
|
+ if (changeQuantity.compareTo(BigDecimal.ZERO) <= 0) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 仓库id
|
|
|
+ Long warehouseId = ObjectUtil.defaultIfNull(changeDetails.getWarehouseId(), stockChangeVo.getDefaultWarehouseId());
|
|
|
+ // 物品id
|
|
|
+ Long goodsId = changeDetails.getGoodsId();
|
|
|
+
|
|
|
+ String key = goodsId + "" + warehouseId;
|
|
|
+
|
|
|
+ Stock stock = map.get(key);
|
|
|
+ if (null == stock) {
|
|
|
+ stock = new Stock();
|
|
|
+ stock.setWarehouseId(warehouseId);
|
|
|
+ stock.setGoodsId(goodsId);
|
|
|
+ stock.setQuantity(changeQuantity);
|
|
|
+ stock.setFrozenQuantity(changeQuantity);
|
|
|
+ map.put(key, stock);
|
|
|
+ } else {
|
|
|
+ stock.setQuantity(stock.getQuantity().add(changeQuantity));
|
|
|
+ stock.setFrozenQuantity(stock.getFrozenQuantity().add(changeQuantity));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Set<String> keySet = map.keySet();
|
|
|
+ if (keySet.size() == 0) return;
|
|
|
+
|
|
|
+ synchronized (this) {
|
|
|
+ List<Stock> list = list(Wrappers.<Stock>query().in("CONCAT(goods_id, warehouse_id)", keySet));
|
|
|
+ if (list.size() == 0) return;
|
|
|
+ for (Stock stock : list) {
|
|
|
+ String key = stock.getGoodsId() + "" + stock.getWarehouseId();
|
|
|
+ Stock itemStock = map.get(key);
|
|
|
+ itemStock.setId(stock.getId());
|
|
|
+ if (stockChangeVo.getTypeEnum() instanceof InTypeEnum) {
|
|
|
+ itemStock.setQuantity(itemStock.getQuantity().add(stock.getQuantity()));
|
|
|
+ itemStock.setFrozenQuantity(itemStock.getFrozenQuantity().add(stock.getFrozenQuantity()));
|
|
|
+ } else {
|
|
|
+ BigDecimal quantity = itemStock.getQuantity().subtract(stock.getQuantity());
|
|
|
+ if (quantity.compareTo(BigDecimal.ZERO) < 0) {
|
|
|
+ throw new ServiceException("产品库存不足,出库失败");
|
|
|
}
|
|
|
+ itemStock.setQuantity(quantity);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ saveOrUpdateBatch(new ArrayList<>(map.values()));
|
|
|
+ }
|
|
|
|
|
|
- BigDecimal newQuantity = stock.getQuantity().add(quantity);
|
|
|
- if (newQuantity.compareTo(BigDecimal.ZERO) < 0) {
|
|
|
- throw new ServiceException("库存不足,出库失败");
|
|
|
- }
|
|
|
|
|
|
- stock.setQuantity(newQuantity);
|
|
|
- return updateById(stock);
|
|
|
- });
|
|
|
-
|
|
|
- Assert.eqTrue(flag, ErrorMsgConstant.SYSTEM_BUSY_ERROR);
|
|
|
-
|
|
|
- // 添加出入库明细
|
|
|
- stockJournalService.add(
|
|
|
- quantity.compareTo(BigDecimal.ZERO) > 0 ? StockJournalTypeConstant.IN : StockJournalTypeConstant.OUT,
|
|
|
- detailsType,
|
|
|
- goodsId,
|
|
|
- warehouseId,
|
|
|
- quantity.compareTo(BigDecimal.ZERO) > 0 ? quantity : BigDecimal.ZERO.subtract(quantity),
|
|
|
- remarks
|
|
|
- );
|
|
|
+ // 添加入库明细
|
|
|
+ List<StockJournal> stockJournalList = new ArrayList<>();
|
|
|
+
|
|
|
+ for (StockChangeVo.ChangeDetails changeDetails : changeDetailsList) {
|
|
|
+
|
|
|
+ // 变更数量
|
|
|
+ BigDecimal changeQuantity = changeDetails.getChangeQuantity();
|
|
|
+
|
|
|
+ // 变更数量小于等于0,则跳过
|
|
|
+ if (changeQuantity.compareTo(BigDecimal.ZERO) <= 0) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ StockJournal stockJournal = new StockJournal();
|
|
|
+
|
|
|
+ Integer type = typeEnum instanceof InTypeEnum ? StockJournalTypeConstant.IN : StockJournalTypeConstant.OUT;
|
|
|
+
|
|
|
+ stockJournal.setType(type);
|
|
|
+ stockJournal.setDetailsType(typeEnum instanceof InTypeEnum ?
|
|
|
+ ((InTypeEnum) typeEnum).getKey() : ((OutTypeEnum) typeEnum).getKey());
|
|
|
+ stockJournal.setBusinessId(stockChangeVo.getBusinessId());
|
|
|
+ stockJournal.setGoodsId(changeDetails.getGoodsId());
|
|
|
+ stockJournal.setWarehouseId(changeDetails.getWarehouseId());
|
|
|
+ stockJournal.setChangeQuantity(changeQuantity);
|
|
|
+
|
|
|
+ if (typeEnum instanceof InTypeEnum) {
|
|
|
+ stockJournal.setActualQuantity(BigDecimal.ZERO);
|
|
|
+ stockJournal.setIsInStock(StatusConstant.NO);
|
|
|
+ }
|
|
|
+
|
|
|
+ stockJournal.setRemarks(ObjectUtil.defaultIfNull(changeDetails.getRemarks(), stockChangeVo.getDefaultRemarks()));
|
|
|
+ stockJournalList.add(stockJournal);
|
|
|
+ }
|
|
|
+
|
|
|
+ stockJournalService.saveBatch(stockJournalList);
|
|
|
}
|
|
|
|
|
|
}
|