商品库存流水
This commit is contained in:
parent
b3a725556d
commit
8cec1a7a4c
|
|
@ -9,10 +9,8 @@ import com.czg.log.annotation.OperationLog;
|
|||
import com.czg.product.dto.ProdConsBindDTO;
|
||||
import com.czg.product.dto.ProdSkuDTO;
|
||||
import com.czg.product.dto.ProductDTO;
|
||||
import com.czg.product.param.ProdRefundToStockParam;
|
||||
import com.czg.product.param.ProductIsSaleParam;
|
||||
import com.czg.product.param.ProductIsSoldOutParam;
|
||||
import com.czg.product.param.ProductReportDamageParam;
|
||||
import com.czg.product.entity.ProductStockFlow;
|
||||
import com.czg.product.param.*;
|
||||
import com.czg.product.service.ProdConsRelationService;
|
||||
import com.czg.product.service.ProductService;
|
||||
import com.czg.resp.CzgResult;
|
||||
|
|
@ -31,7 +29,7 @@ import java.util.List;
|
|||
|
||||
|
||||
/**
|
||||
* 商品
|
||||
* 商品管理 - 商品列表
|
||||
*
|
||||
* @author Tankaikai tankaikai@aliyun.com
|
||||
* @since 1.0 2025-02-16
|
||||
|
|
@ -44,6 +42,9 @@ public class ProductController {
|
|||
private final ProdConsRelationService prodConsRelationService;
|
||||
private final RabbitPublisher rabbitPublisher;
|
||||
|
||||
/**
|
||||
* 商品-分页
|
||||
*/
|
||||
@GetMapping("page")
|
||||
@OperationLog("商品-分页")
|
||||
//@SaAdminCheckPermission("product:page")
|
||||
|
|
@ -52,6 +53,9 @@ public class ProductController {
|
|||
return CzgResult.success(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品-列表
|
||||
*/
|
||||
@GetMapping("list")
|
||||
@OperationLog("商品-列表")
|
||||
//@SaAdminCheckPermission("product:list")
|
||||
|
|
@ -60,6 +64,9 @@ public class ProductController {
|
|||
return CzgResult.success(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品-详情
|
||||
*/
|
||||
@GetMapping("{id}")
|
||||
@OperationLog("商品-详情")
|
||||
//@SaAdminCheckPermission("product:info")
|
||||
|
|
@ -69,6 +76,9 @@ public class ProductController {
|
|||
return CzgResult.success(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品-新增
|
||||
*/
|
||||
@PostMapping
|
||||
@OperationLog("商品-新增")
|
||||
//@SaAdminCheckPermission("product:add")
|
||||
|
|
@ -86,6 +96,9 @@ public class ProductController {
|
|||
return CzgResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品-修改
|
||||
*/
|
||||
@PutMapping
|
||||
@OperationLog("商品-修改")
|
||||
@SaStaffCheckPermission("yun_xu_xiu_gai_shang_pin")
|
||||
|
|
@ -111,6 +124,10 @@ public class ProductController {
|
|||
return CzgResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品-删除
|
||||
* @param id 商品ID
|
||||
*/
|
||||
@DeleteMapping("{id}")
|
||||
@OperationLog("商品-删除")
|
||||
@SaStaffCheckPermission("yun_xu_xiu_gai_shang_pin")
|
||||
|
|
@ -209,4 +226,28 @@ public class ProductController {
|
|||
return CzgResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品-统计
|
||||
*/
|
||||
@GetMapping("statistics")
|
||||
@OperationLog("商品-统计")
|
||||
//@SaAdminCheckPermission("product:statistics")
|
||||
public CzgResult<Void> statistics(@RequestBody ProductInfoParam param) {
|
||||
Long shopId = StpKit.USER.getShopId(0L);
|
||||
param.setShopId(shopId);
|
||||
productService.getProductStatistics(param);
|
||||
return CzgResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品-库存变动记录
|
||||
*/
|
||||
@GetMapping("stockFlow")
|
||||
@OperationLog("商品-库存变动记录")
|
||||
//@SaAdminCheckPermission("consStockFlow:flow")
|
||||
public CzgResult<Page<ProductStockFlow>> stockFlow(ProductStockFlowParam param) {
|
||||
Page<ProductStockFlow> data = productService.findProductStockFlowPage(param);
|
||||
return CzgResult.success(data);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ public class Product implements Serializable {
|
|||
*/
|
||||
private String groupCategoryId;
|
||||
/**
|
||||
* 商品级库存数量
|
||||
* 商品库存数量
|
||||
*/
|
||||
private Integer stockNumber;
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -2,10 +2,9 @@ package com.czg.product.service;
|
|||
|
||||
import com.czg.product.dto.ProductDTO;
|
||||
import com.czg.product.entity.Product;
|
||||
import com.czg.product.param.ProdRefundToStockParam;
|
||||
import com.czg.product.param.ProductIsSaleParam;
|
||||
import com.czg.product.param.ProductIsSoldOutParam;
|
||||
import com.czg.product.param.ProductReportDamageParam;
|
||||
import com.czg.product.entity.ProductStockFlow;
|
||||
import com.czg.product.param.*;
|
||||
import com.czg.product.vo.ProductStatisticsVo;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
import com.mybatisflex.core.service.IService;
|
||||
|
||||
|
|
@ -99,4 +98,18 @@ public interface ProductService extends IService<Product> {
|
|||
*/
|
||||
void reportDamage(ProductReportDamageParam param);
|
||||
|
||||
/**
|
||||
* 商品统计
|
||||
*
|
||||
* @param param 商品统计入参
|
||||
*/
|
||||
ProductStatisticsVo getProductStatistics(ProductInfoParam param);
|
||||
|
||||
/**
|
||||
* 商品出入库流水查询
|
||||
* @param param 查询参数
|
||||
* @return 分页数据
|
||||
*/
|
||||
Page<ProductStockFlow> findProductStockFlowPage(ProductStockFlowParam param);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,17 +9,11 @@ import com.czg.config.RabbitPublisher;
|
|||
import com.czg.constant.CacheConstant;
|
||||
import com.czg.enums.YesNoEnum;
|
||||
import com.czg.product.dto.ProductStockSubtractDTO;
|
||||
import com.czg.product.entity.ConsInfo;
|
||||
import com.czg.product.entity.ConsStockFlow;
|
||||
import com.czg.product.entity.ProdConsRelation;
|
||||
import com.czg.product.entity.Product;
|
||||
import com.czg.product.entity.*;
|
||||
import com.czg.product.enums.InOutItemEnum;
|
||||
import com.czg.product.enums.InOutTypeEnum;
|
||||
import com.czg.product.service.ProductRpcService;
|
||||
import com.czg.service.product.mapper.ConsInfoMapper;
|
||||
import com.czg.service.product.mapper.ConsStockFlowMapper;
|
||||
import com.czg.service.product.mapper.ProdConsRelationMapper;
|
||||
import com.czg.service.product.mapper.ProductMapper;
|
||||
import com.czg.service.product.mapper.*;
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
|
@ -54,6 +48,8 @@ public class ProductRpcServiceImpl implements ProductRpcService {
|
|||
@Resource
|
||||
private ConsStockFlowMapper consStockFlowMapper;
|
||||
@Resource
|
||||
private ProductStockFlowMapper productStockFlowMapper;
|
||||
@Resource
|
||||
private RabbitPublisher rabbitPublisher;
|
||||
|
||||
@Override
|
||||
|
|
@ -65,7 +61,21 @@ public class ProductRpcServiceImpl implements ProductRpcService {
|
|||
return;
|
||||
}
|
||||
for (ProductStockSubtractDTO dto : list) {
|
||||
Product product = productMapper.selectOneById(dto.getProductId());
|
||||
productMapper.updateProductStockNum(dto.getProductId(), dto.getShopId(), "sub", dto.getNum());
|
||||
// 记录商品库存流水
|
||||
ProductStockFlow flow = new ProductStockFlow();
|
||||
flow.setCreateUserId(1L);
|
||||
flow.setCreateUserName("银收客");
|
||||
flow.setShopId(shopId);
|
||||
flow.setProductId(product.getId());
|
||||
flow.setProductName(product.getName());
|
||||
flow.setBeforeNumber(NumberUtil.toBigDecimal(product.getStockNumber()));
|
||||
flow.setInOutNumber(NumberUtil.sub(BigDecimal.ZERO, NumberUtil.toBigDecimal(dto.getNum())));
|
||||
flow.setAfterNumber(NumberUtil.sub(NumberUtil.toBigDecimal(product.getStockNumber()), NumberUtil.toBigDecimal(dto.getNum())));
|
||||
flow.setInOutType(InOutTypeEnum.OUT.value());
|
||||
flow.setInOutItem(InOutItemEnum.ORDER_OUT.value());
|
||||
productStockFlowMapper.insert(flow);
|
||||
// 查询商品绑定耗材信息
|
||||
List<ProdConsRelation> relationList = prodConsRelationMapper.selectListByQuery(QueryWrapper.create().eq(ProdConsRelation::getProductId, dto.getProductId()));
|
||||
if (CollUtil.isEmpty(relationList)) {
|
||||
|
|
@ -124,7 +134,21 @@ public class ProductRpcServiceImpl implements ProductRpcService {
|
|||
return;
|
||||
}
|
||||
for (ProductStockSubtractDTO dto : list) {
|
||||
Product product = productMapper.selectOneById(dto.getProductId());
|
||||
productMapper.updateProductStockNum(dto.getProductId(), dto.getShopId(), "add", dto.getNum());
|
||||
// 记录商品库存流水
|
||||
ProductStockFlow flow = new ProductStockFlow();
|
||||
flow.setCreateUserId(1L);
|
||||
flow.setCreateUserName("银收客");
|
||||
flow.setShopId(shopId);
|
||||
flow.setProductId(product.getId());
|
||||
flow.setProductName(product.getName());
|
||||
flow.setBeforeNumber(NumberUtil.toBigDecimal(product.getStockNumber()));
|
||||
flow.setInOutNumber(NumberUtil.toBigDecimal(dto.getNum()));
|
||||
flow.setAfterNumber(NumberUtil.add(NumberUtil.toBigDecimal(product.getStockNumber()), NumberUtil.toBigDecimal(dto.getNum())));
|
||||
flow.setInOutType(InOutTypeEnum.IN.value());
|
||||
flow.setInOutItem(InOutItemEnum.ORDER_IN.value());
|
||||
productStockFlowMapper.insert(flow);
|
||||
// 查询商品绑定耗材信息
|
||||
List<ProdConsRelation> relationList = prodConsRelationMapper.selectListByQuery(QueryWrapper.create().eq(ProdConsRelation::getProductId, dto.getProductId()));
|
||||
if (CollUtil.isEmpty(relationList)) {
|
||||
|
|
@ -186,6 +210,19 @@ public class ProductRpcServiceImpl implements ProductRpcService {
|
|||
continue;
|
||||
}
|
||||
productMapper.updateProductStockNum(dto.getProductId(), dto.getShopId(), "add", dto.getNum());
|
||||
// 记录商品库存流水
|
||||
ProductStockFlow flow = new ProductStockFlow();
|
||||
flow.setCreateUserId(1L);
|
||||
flow.setCreateUserName("银收客");
|
||||
flow.setShopId(shopId);
|
||||
flow.setProductId(product.getId());
|
||||
flow.setProductName(product.getName());
|
||||
flow.setBeforeNumber(NumberUtil.toBigDecimal(product.getStockNumber()));
|
||||
flow.setInOutNumber(NumberUtil.toBigDecimal(dto.getNum()));
|
||||
flow.setAfterNumber(NumberUtil.add(NumberUtil.toBigDecimal(product.getStockNumber()), NumberUtil.toBigDecimal(dto.getNum())));
|
||||
flow.setInOutType(InOutTypeEnum.IN.value());
|
||||
flow.setInOutItem(InOutItemEnum.ORDER_IN.value());
|
||||
productStockFlowMapper.insert(flow);
|
||||
// 查询商品绑定耗材信息
|
||||
List<ProdConsRelation> relationList = prodConsRelationMapper.selectListByQuery(QueryWrapper.create().eq(ProdConsRelation::getProductId, dto.getProductId()));
|
||||
if (CollUtil.isEmpty(relationList)) {
|
||||
|
|
|
|||
|
|
@ -14,16 +14,11 @@ import com.czg.exception.CzgException;
|
|||
import com.czg.product.dto.ProdConsRelationDTO;
|
||||
import com.czg.product.dto.ProdSkuDTO;
|
||||
import com.czg.product.dto.ProductDTO;
|
||||
import com.czg.product.entity.ConsInfo;
|
||||
import com.czg.product.entity.ConsStockFlow;
|
||||
import com.czg.product.entity.ProdSku;
|
||||
import com.czg.product.entity.Product;
|
||||
import com.czg.product.entity.*;
|
||||
import com.czg.product.enums.*;
|
||||
import com.czg.product.param.ProdRefundToStockParam;
|
||||
import com.czg.product.param.ProductIsSaleParam;
|
||||
import com.czg.product.param.ProductIsSoldOutParam;
|
||||
import com.czg.product.param.ProductReportDamageParam;
|
||||
import com.czg.product.param.*;
|
||||
import com.czg.product.service.ProductService;
|
||||
import com.czg.product.vo.ProductStatisticsVo;
|
||||
import com.czg.sa.StpKit;
|
||||
import com.czg.service.product.mapper.*;
|
||||
import com.czg.utils.PageUtil;
|
||||
|
|
@ -63,6 +58,7 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
|||
private final ProdConsRelationMapper prodConsRelationMapper;
|
||||
private final ConsInfoMapper consInfoMapper;
|
||||
private final ConsStockFlowMapper consStockFlowMapper;
|
||||
private final ProductStockFlowMapper productStockFlowMapper;
|
||||
|
||||
private QueryWrapper buildQueryWrapper(ProductDTO param) {
|
||||
QueryWrapper queryWrapper = PageUtil.buildSortQueryWrapper();
|
||||
|
|
@ -209,6 +205,24 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
|||
}
|
||||
prodSkuMapper.insertBatch(prodSkuList);
|
||||
}
|
||||
if (entity.getIsStock() == YesNoEnum.NO.value()) {
|
||||
return;
|
||||
}
|
||||
// 记录商品库存流水
|
||||
ProductStockFlow flow = new ProductStockFlow();
|
||||
Long createUserId = StpKit.USER.getLoginIdAsLong();
|
||||
String createUserName = StpKit.USER.getAccount();
|
||||
flow.setCreateUserId(createUserId);
|
||||
flow.setCreateUserName(createUserName);
|
||||
flow.setShopId(shopId);
|
||||
flow.setProductId(entity.getId());
|
||||
flow.setProductName(entity.getName());
|
||||
flow.setBeforeNumber(BigDecimal.ZERO);
|
||||
flow.setInOutNumber(NumberUtil.toBigDecimal(entity.getStockNumber()));
|
||||
flow.setAfterNumber(NumberUtil.toBigDecimal(entity.getStockNumber()));
|
||||
flow.setInOutType(InOutTypeEnum.IN.value());
|
||||
flow.setInOutItem(InOutItemEnum.WIN_IN.value());
|
||||
productStockFlowMapper.insert(flow);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -220,6 +234,7 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
|||
if (exists) {
|
||||
throw new CzgException("商品已存在");
|
||||
}
|
||||
Product old = super.getById(dto.getId());
|
||||
Product entity = BeanUtil.copyProperties(dto, Product.class);
|
||||
entity.setImages(JSON.toJSONString(dto.getImages(), JSONWriter.Feature.WriteMapNullValue));
|
||||
entity.setGroupSnap("[]");
|
||||
|
|
@ -264,6 +279,34 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
|||
.eq(ProdSku::getShopId, shopId)
|
||||
.update();
|
||||
}
|
||||
if (entity.getIsStock() == YesNoEnum.NO.value()) {
|
||||
return;
|
||||
}
|
||||
// 记录商品库存流水
|
||||
ProductStockFlow flow = new ProductStockFlow();
|
||||
Long createUserId = StpKit.USER.getLoginIdAsLong();
|
||||
String createUserName = StpKit.USER.getAccount();
|
||||
flow.setCreateUserId(createUserId);
|
||||
flow.setCreateUserName(createUserName);
|
||||
flow.setShopId(shopId);
|
||||
flow.setProductId(old.getId());
|
||||
flow.setProductName(old.getName());
|
||||
flow.setBeforeNumber(NumberUtil.toBigDecimal(old.getStockNumber()));
|
||||
BigDecimal inOutNumber = NumberUtil.sub(NumberUtil.toBigDecimal(entity.getStockNumber()), flow.getBeforeNumber());
|
||||
// 盘亏
|
||||
if (NumberUtil.isLess(inOutNumber, BigDecimal.ZERO)) {
|
||||
flow.setInOutNumber(inOutNumber);
|
||||
flow.setInOutType(InOutTypeEnum.OUT.value());
|
||||
flow.setInOutItem(InOutItemEnum.LOSS_OUT.value());
|
||||
}
|
||||
// 盘盈
|
||||
if (NumberUtil.isGreater(inOutNumber, BigDecimal.ZERO)) {
|
||||
flow.setInOutNumber(inOutNumber);
|
||||
flow.setInOutType(InOutTypeEnum.IN.value());
|
||||
flow.setInOutItem(InOutItemEnum.WIN_IN.value());
|
||||
}
|
||||
flow.setAfterNumber(NumberUtil.toBigDecimal(entity.getStockNumber()));
|
||||
productStockFlowMapper.insert(flow);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -378,6 +421,20 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
|||
throw new CzgException("商品库存不足,无法报损");
|
||||
}
|
||||
super.updateById(product);
|
||||
// 记录商品库存流水
|
||||
ProductStockFlow flow = new ProductStockFlow();
|
||||
flow.setCreateUserId(createUserId);
|
||||
flow.setCreateUserName(createUserName);
|
||||
flow.setShopId(shopId);
|
||||
flow.setProductId(product.getId());
|
||||
flow.setProductName(product.getName());
|
||||
flow.setBeforeNumber(NumberUtil.toBigDecimal(stockNumber));
|
||||
flow.setInOutNumber(NumberUtil.sub(BigDecimal.ZERO, NumberUtil.toBigDecimal(param.getNumber())));
|
||||
flow.setAfterNumber(NumberUtil.toBigDecimal(product.getStockNumber()));
|
||||
flow.setInOutType(InOutTypeEnum.OUT.value());
|
||||
flow.setInOutItem(InOutItemEnum.DAMAGE_OUT.value());
|
||||
flow.setImgUrls(JSON.toJSONString(param.getImgUrls()));
|
||||
productStockFlowMapper.insert(flow);
|
||||
// 如果绑定了耗材,则同步更新耗材库存
|
||||
List<ProdConsRelationDTO> consList = prodConsRelationMapper.selectListByProdId(param.getProductId());
|
||||
if (CollUtil.isEmpty(consList)) {
|
||||
|
|
@ -411,4 +468,31 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
|||
.update();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProductStatisticsVo getProductStatistics(ProductInfoParam param) {
|
||||
ProductStatisticsVo data = productStockFlowMapper.getProductStatistics(param);
|
||||
if (data == null) {
|
||||
data = new ProductStatisticsVo();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<ProductStockFlow> findProductStockFlowPage(ProductStockFlowParam param) {
|
||||
Long shopId = StpKit.USER.getShopId(0L);
|
||||
QueryWrapper queryWrapper = QueryWrapper.create();
|
||||
queryWrapper.eq(ProductStockFlow::getShopId, shopId);
|
||||
if (StrUtil.isNotBlank(param.getInOutType())) {
|
||||
queryWrapper.eq(ProductStockFlow::getInOutType, param.getInOutType());
|
||||
}
|
||||
if (StrUtil.isNotBlank(param.getInOutItem())) {
|
||||
queryWrapper.eq(ProductStockFlow::getInOutItem, param.getInOutItem());
|
||||
}
|
||||
if (ObjUtil.isNotNull(param.getProductId())) {
|
||||
queryWrapper.eq(ProductStockFlow::getProductId, param.getProductId());
|
||||
}
|
||||
queryWrapper.orderBy(ProductStockFlow::getId, false);
|
||||
return productStockFlowMapper.paginate(PageUtil.buildPage(), queryWrapper);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue