|
|
@@ -1,18 +1,13 @@
|
|
|
package com.cyksj.service.mange.stock.impl;
|
|
|
|
|
|
import cn.hutool.core.bean.BeanUtil;
|
|
|
-import cn.hutool.core.math.MathUtil;
|
|
|
-import cn.hutool.core.util.NumberUtil;
|
|
|
+import cn.hutool.core.collection.CollUtil;
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
import com.cyksj.common.exception.BusinessRuntimeException;
|
|
|
-import com.cyksj.mapper.stock.GoodsDonStockMapper;
|
|
|
-import com.cyksj.mapper.stock.GoodsDonStockRecordMapper;
|
|
|
-import com.cyksj.mapper.stock.GoodsSkuStockRelateMapper;
|
|
|
-import com.cyksj.mapper.stock.OrderDonStockMapper;
|
|
|
-import com.cyksj.model.entity.GoodsDonStock;
|
|
|
-import com.cyksj.model.entity.GoodsDonStockRecord;
|
|
|
-import com.cyksj.model.entity.GoodsSkuStockRelate;
|
|
|
-import com.cyksj.model.entity.OrderDonStock;
|
|
|
+import com.cyksj.common.snowflake.Sequence;
|
|
|
+import com.cyksj.mapper.stock.*;
|
|
|
+import com.cyksj.model.entity.*;
|
|
|
import com.cyksj.model.request.StockUpReq;
|
|
|
import com.cyksj.service.mange.stock.GoodsDonStockService;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
@@ -20,9 +15,10 @@ import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
-import java.math.BigDecimal;
|
|
|
-import java.math.RoundingMode;
|
|
|
+import java.util.ArrayList;
|
|
|
import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
|
* @author chan
|
|
|
@@ -41,6 +37,12 @@ public class GoodsDonStockServiceImpl implements GoodsDonStockService {
|
|
|
|
|
|
private final GoodsSkuStockRelateMapper skuStockRelateMapper;
|
|
|
|
|
|
+ private final GoodsSkuStockRelateChangeRecordMapper relateChangeRecordMapper;
|
|
|
+
|
|
|
+ private static final Sequence SEQUENCE = new Sequence(0);
|
|
|
+
|
|
|
+ private final List<String> ADD_OPERATE = List.of("put", "refund");
|
|
|
+
|
|
|
@Transactional(rollbackFor = Throwable.class)
|
|
|
@Override
|
|
|
public void upStockRelate(Long stockId, Long orderId, String status) {
|
|
|
@@ -52,6 +54,10 @@ public class GoodsDonStockServiceImpl implements GoodsDonStockService {
|
|
|
orderDonStock.setStatus("refund");
|
|
|
orderDonStockMapper.updateById(orderDonStock);
|
|
|
GoodsDonStockRecord putRecord = stockRecordMapper.selectById(orderDonStock.getRecordId());
|
|
|
+ //发货库存操作已撤销
|
|
|
+ if (putRecord.getIsUndo()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
GoodsDonStock stock = stockMapper.selectById(putRecord.getStockId());
|
|
|
//新增库存记录
|
|
|
@@ -81,6 +87,7 @@ public class GoodsDonStockServiceImpl implements GoodsDonStockService {
|
|
|
.eq(GoodsDonStockRecord::getStockId, stockId)
|
|
|
.eq(GoodsDonStockRecord::getType, "put")
|
|
|
.gt(GoodsDonStockRecord::getAvailable, 0)
|
|
|
+ .eq(GoodsDonStockRecord::getIsUndo, false)
|
|
|
.orderByAsc(GoodsDonStockRecord::getCreatedTime)
|
|
|
.last(" limit 1")
|
|
|
);
|
|
|
@@ -98,7 +105,7 @@ public class GoodsDonStockServiceImpl implements GoodsDonStockService {
|
|
|
GoodsDonStock stock = stockMapper.selectById(putRecord.getStockId());
|
|
|
//新增库存记录
|
|
|
GoodsDonStockRecord record = new GoodsDonStockRecord();
|
|
|
- record.setNum(-1);
|
|
|
+ record.setNum(1);
|
|
|
record.setStockId(stockId);
|
|
|
record.setThenTotal(stock.getTotal());
|
|
|
record.setType("transport");
|
|
|
@@ -145,12 +152,13 @@ public class GoodsDonStockServiceImpl implements GoodsDonStockService {
|
|
|
GoodsDonStock goodsDonStock = stockMapper.selectById(stock.getId());
|
|
|
GoodsDonStockRecord putRecord = stockRecordMapper.selectOne(
|
|
|
Wrappers.lambdaQuery(GoodsDonStockRecord.class)
|
|
|
- .eq(GoodsDonStockRecord::getStockId,stock.getId())
|
|
|
- .eq(GoodsDonStockRecord::getType,"put")
|
|
|
- .gt(GoodsDonStockRecord::getAvailable,0)
|
|
|
+ .eq(GoodsDonStockRecord::getStockId, stock.getId())
|
|
|
+ .eq(GoodsDonStockRecord::getType, "put")
|
|
|
+ .gt(GoodsDonStockRecord::getAvailable, 0)
|
|
|
+ .eq(GoodsDonStockRecord::getIsUndo, false)
|
|
|
.orderByAsc(GoodsDonStockRecord::getId)
|
|
|
.last(" limit 1")
|
|
|
- );
|
|
|
+ );
|
|
|
if(putRecord == null){
|
|
|
throw BusinessRuntimeException.getInstance("没有库存>0的批次");
|
|
|
}
|
|
|
@@ -256,4 +264,147 @@ public class GoodsDonStockServiceImpl implements GoodsDonStockService {
|
|
|
stockMapper.deleteById(stockId);
|
|
|
skuStockRelateMapper.delete(Wrappers.lambdaQuery(GoodsSkuStockRelate.class).eq(GoodsSkuStockRelate::getStockId,stockId));
|
|
|
}
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Throwable.class)
|
|
|
+ public void updateBindGoods(GoodsDonStock stock) {
|
|
|
+ GoodsDonStock dbStock = stockMapper.selectById(stock.getId());
|
|
|
+ if (dbStock == null) {
|
|
|
+ throw BusinessRuntimeException.getInstance("库存不存在");
|
|
|
+ }
|
|
|
+ if (StrUtil.isNotBlank(stock.getTitle())) {
|
|
|
+ dbStock.setTitle(stock.getTitle());
|
|
|
+ stockMapper.updateById(dbStock);
|
|
|
+ }
|
|
|
+ List<GoodsSkuStockRelate> dbStockRelateList = skuStockRelateMapper.selectList(Wrappers.lambdaQuery(GoodsSkuStockRelate.class)
|
|
|
+ .eq(GoodsSkuStockRelate::getStockId, stock.getId()));
|
|
|
+
|
|
|
+ Map<Long, List<GoodsSkuStockRelate>> dbSkuMap = dbStockRelateList.stream().collect(Collectors.groupingBy(GoodsSkuStockRelate::getSkuId));
|
|
|
+
|
|
|
+ List<GoodsSkuStockRelate> relateList = stock.getRelateList();
|
|
|
+ Map<Long, List<GoodsSkuStockRelate>> skuMap = relateList.stream().collect(Collectors.groupingBy(GoodsSkuStockRelate::getSkuId));
|
|
|
+
|
|
|
+ List<GoodsSkuStockRelate> insertList = new ArrayList<>();
|
|
|
+ List<GoodsSkuStockRelate> deleteList = new ArrayList<>();
|
|
|
+
|
|
|
+ //目前的
|
|
|
+ relateList.forEach(relate->{
|
|
|
+ List<GoodsSkuStockRelate> stockRelates = dbSkuMap.get(relate.getSkuId());
|
|
|
+ if (CollUtil.isEmpty(stockRelates)) {
|
|
|
+ insertList.add(relate);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ dbStockRelateList.forEach(data -> {
|
|
|
+ List<GoodsSkuStockRelate> stockRelates = skuMap.get(data.getSkuId());
|
|
|
+ if (CollUtil.isEmpty(stockRelates)) {
|
|
|
+ deleteList.add(data);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ Long uniformId = SEQUENCE.nextId();
|
|
|
+ String operator = stock.getOperator();
|
|
|
+
|
|
|
+ insertList.forEach(insert->{
|
|
|
+ insert.setStockId(stock.getId());
|
|
|
+ skuStockRelateMapper.insert(insert);
|
|
|
+
|
|
|
+ saveChangeRelateRecord(insert, "insert", uniformId, operator);
|
|
|
+ });
|
|
|
+
|
|
|
+ List<Long> deleteRelateIds = new ArrayList<>();
|
|
|
+ deleteList.forEach(delete->{
|
|
|
+ saveChangeRelateRecord(delete, "delete", uniformId, operator);
|
|
|
+
|
|
|
+ deleteRelateIds.add(delete.getId());
|
|
|
+ });
|
|
|
+
|
|
|
+ if (CollUtil.isNotEmpty(deleteRelateIds)) {
|
|
|
+ skuStockRelateMapper.deleteBatchIds(deleteRelateIds);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void saveChangeRelateRecord(GoodsSkuStockRelate skuStockRelate, String type, Long uniformId, String operator) {
|
|
|
+ GoodsSkuStockRelateChangeRecord changeRecord = new GoodsSkuStockRelateChangeRecord();
|
|
|
+ BeanUtil.copyProperties(skuStockRelate, changeRecord);
|
|
|
+ changeRecord.setType(type);
|
|
|
+ changeRecord.setUniformId(uniformId);
|
|
|
+ changeRecord.setOperator(operator);
|
|
|
+ relateChangeRecordMapper.insert(changeRecord);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Throwable.class)
|
|
|
+ public void undoChange(Long recordId) {
|
|
|
+ GoodsDonStockRecord goodsDonStockRecord = stockRecordMapper.selectById(recordId);
|
|
|
+ if (goodsDonStockRecord == null) {
|
|
|
+ throw BusinessRuntimeException.getInstance("该库存变更记录不存在");
|
|
|
+ }
|
|
|
+ //撤销
|
|
|
+ Long stockId = goodsDonStockRecord.getStockId();
|
|
|
+ //目前可用
|
|
|
+ Integer num = goodsDonStockRecord.getAvailable();
|
|
|
+ String type = goodsDonStockRecord.getType();
|
|
|
+ //扣减库存回滚操作 数量为正时 置为负数
|
|
|
+ if (!ADD_OPERATE.contains(type)) {
|
|
|
+ //回滚扣除操作时
|
|
|
+ num = goodsDonStockRecord.getNum();
|
|
|
+ if (num > 0) {
|
|
|
+ num = -num;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ handleUndoChange(type, goodsDonStockRecord.getId(), stockId, num);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param stockRecordId 库存存储记录id
|
|
|
+ * @param stockId 库存id
|
|
|
+ * @param num 库存数量
|
|
|
+ */
|
|
|
+ public void handleUndoChange(String type, Long stockRecordId, Long stockId, Integer num) {
|
|
|
+ GoodsDonStock goodsDonStock = stockMapper.selectById(stockId);
|
|
|
+ if (ADD_OPERATE.contains(type) && goodsDonStock.getTotal() <= 0) {
|
|
|
+ throw BusinessRuntimeException.getInstance("当前商品库存为0,不可撤销该增加库存操作");
|
|
|
+ }
|
|
|
+ int update = stockRecordMapper.update(null, Wrappers.lambdaUpdate(GoodsDonStockRecord.class)
|
|
|
+ .set(GoodsDonStockRecord::getIsUndo, true)
|
|
|
+ .set(num > 0, GoodsDonStockRecord::getAvailable, 0)
|
|
|
+ .eq(GoodsDonStockRecord::getId, stockRecordId)
|
|
|
+ .eq(GoodsDonStockRecord::getIsUndo, false));
|
|
|
+
|
|
|
+ if (update > 0) {
|
|
|
+ //回滚扣减库存操作
|
|
|
+ if (num < 0) {
|
|
|
+ String recordType = "put";
|
|
|
+ Boolean isUndo = false;
|
|
|
+ GoodsDonStockRecord record = stockRecordMapper.selectUndoRecord(stockId, isUndo, recordType);
|
|
|
+ if (record == null) {
|
|
|
+ isUndo = true;
|
|
|
+ record = stockRecordMapper.selectUndoRecord(stockId, isUndo, recordType);
|
|
|
+ }
|
|
|
+ if (record != null) {
|
|
|
+ Integer available = record.getAvailable();
|
|
|
+ //回滚新增库存的时候的可用数
|
|
|
+ update = stockRecordMapper.update(null, Wrappers.lambdaUpdate(GoodsDonStockRecord.class)
|
|
|
+ .set(GoodsDonStockRecord::getAvailable, available - num)
|
|
|
+ .set(GoodsDonStockRecord::getIsUndo, false)
|
|
|
+ .eq(GoodsDonStockRecord::getId, record.getId())
|
|
|
+ .eq(GoodsDonStockRecord::getAvailable, available));
|
|
|
+ if (update == 0) {
|
|
|
+ throw BusinessRuntimeException.getInstance("系统繁忙,请重试...");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //恢复对应储存的库存
|
|
|
+ update = stockMapper.update(null, Wrappers.lambdaUpdate(GoodsDonStock.class)
|
|
|
+ .set(GoodsDonStock::getTotal, goodsDonStock.getTotal() - num)
|
|
|
+ .set(GoodsDonStock::getStock, goodsDonStock.getStock() - num)
|
|
|
+ .eq(GoodsDonStock::getId, stockId)
|
|
|
+ .eq(GoodsDonStock::getTotal, goodsDonStock.getTotal()));
|
|
|
+ if (update == 0) {
|
|
|
+ throw BusinessRuntimeException.getInstance("系统繁忙,请重试...");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|