商品报损

This commit is contained in:
Tankaikai 2025-03-07 11:46:29 +08:00
parent 1b84a435ff
commit e679054486
8 changed files with 145 additions and 9 deletions

View File

@ -83,7 +83,7 @@ public class ConsStockFlowController {
* 耗材报损
*/
@PostMapping("reportDamage")
@OperationLog("库存盘点")
@OperationLog("耗材报损")
//@SaAdminCheckPermission("consStockFlow:reportDamage")
public CzgResult<Void> reportDamage(@RequestBody ConsReportDamageParam param) {
ValidatorUtil.validateEntity(param, DefaultGroup.class);

View File

@ -11,6 +11,7 @@ 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.service.ProdConsRelationService;
import com.czg.product.service.ProductService;
import com.czg.resp.CzgResult;
@ -180,4 +181,16 @@ public class ProductController {
return CzgResult.success();
}
/**
* 商品-报损
*/
@PostMapping("reportDamage")
@OperationLog("商品-报损")
//@SaAdminCheckPermission("product:reportDamage")
public CzgResult<Void> reportDamage(@RequestBody ProductReportDamageParam param) {
ValidatorUtil.validateEntity(param, DefaultGroup.class);
productService.reportDamage(param);
return CzgResult.success();
}
}

View File

@ -54,5 +54,17 @@ public class ProdConsRelationDTO implements Serializable {
* 耗材单位
*/
private String conUnit;
/**
* 耗材名称
*/
private String conName;
/**
* 耗材单价
*/
private BigDecimal price;
/**
* 耗材库存数量
*/
private BigDecimal stockNumber;
}

View File

@ -0,0 +1,41 @@
package com.czg.product.param;
import com.czg.validator.group.DefaultGroup;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.List;
/**
* 商品报损入参
*
* @author tankaikai
* @since 2025-03-06 18:35
*/
@Data
public class ProductReportDamageParam implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 商品id
*/
@NotNull(message = "商品id不能为空", groups = DefaultGroup.class)
private Long productId;
/**
* 报损数量
*/
@NotNull(message = "报损数量不能为空", groups = DefaultGroup.class)
@Min(value = 1, message = "报损数量不能小于1")
private Integer number;
/**
* 报损照片
*/
private List<String> imgUrls;
}

View File

@ -5,6 +5,7 @@ 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.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.service.IService;
@ -90,4 +91,11 @@ public interface ProductService extends IService<Product> {
* @param warnLine 预警线
*/
void stockWarning(Integer warnLine);
/**
* 商品报损
*
* @param param 商品报损入参
*/
void reportDamage(ProductReportDamageParam param);
}

View File

@ -7,10 +7,12 @@ import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.NumberUtil;
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.enums.InOutItemEnum;
import com.czg.product.enums.InOutTypeEnum;
import com.czg.product.service.ProductRpcService;
@ -180,6 +182,11 @@ public class ProductRpcServiceImpl implements ProductRpcService {
return;
}
for (ProductStockSubtractDTO dto : list) {
Product product = productMapper.selectOneById(dto.getProductId());
// 商品是否允许退款退货时归还库存
if (product.getIsRefundStock() == YesNoEnum.NO.value()) {
continue;
}
productMapper.updateProductStockNum(dto.getProductId(), dto.getShopId(), "add", dto.getNum());
// 查询商品绑定耗材信息
List<ProdConsRelation> relationList = prodConsRelationMapper.selectListByQuery(QueryWrapper.create().eq(ProdConsRelation::getProductId, dto.getProductId()));

View File

@ -15,20 +15,17 @@ 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.enums.ProductIsSaleTypeEnum;
import com.czg.product.enums.ProductSaleStatusEnum;
import com.czg.product.enums.ProductTypeEnum;
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.service.ProductService;
import com.czg.sa.StpKit;
import com.czg.service.product.mapper.ConsInfoMapper;
import com.czg.service.product.mapper.ProdConsRelationMapper;
import com.czg.service.product.mapper.ProdSkuMapper;
import com.czg.service.product.mapper.ProductMapper;
import com.czg.service.product.mapper.*;
import com.czg.utils.PageUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
@ -67,6 +64,7 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
private final ProdSkuMapper prodSkuMapper;
private final ProdConsRelationMapper prodConsRelationMapper;
private final ConsInfoMapper consInfoMapper;
private final ConsStockFlowMapper consStockFlowMapper;
private QueryWrapper buildQueryWrapper(ProductDTO param) {
QueryWrapper queryWrapper = PageUtil.buildSortQueryWrapper();
@ -339,4 +337,58 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
.eq(Product::getShopId, shopId)
.update();
}
@Override
@Transactional(rollbackFor = Exception.class)
public void reportDamage(ProductReportDamageParam param) {
Long shopId = StpKit.USER.getShopId(0L);
Long createUserId = StpKit.USER.getLoginIdAsLong();
String createUserName = StpKit.USER.getAccount();
Product product = mapper.selectOneById(param.getProductId());
if (product == null) {
throw new CzgException("商品不存在");
}
if (product.getIsStock() == YesNoEnum.NO.value()) {
throw new CzgException("商品未开启库存不支持报损操作");
}
// 商品现有库存数量
Integer stockNumber = product.getStockNumber();
product.setStockNumber(stockNumber - param.getNumber());
if (product.getStockNumber() < 0) {
throw new CzgException("商品库存不足,无法报损");
}
super.updateById(product);
// 如果绑定了耗材则同步更新耗材库存
List<ProdConsRelationDTO> consList = prodConsRelationMapper.selectListByProdId(param.getProductId());
if (CollUtil.isEmpty(consList)) {
return;
}
for (ProdConsRelationDTO consInfo : consList) {
ConsStockFlow entity = new ConsStockFlow();
entity.setCreateUserId(createUserId);
entity.setCreateUserName(createUserName);
entity.setShopId(shopId);
entity.setConId(consInfo.getConsInfoId());
entity.setConName(consInfo.getConName());
entity.setPurchasePrice(consInfo.getPrice());
BigDecimal balance = NumberUtil.sub(consInfo.getStockNumber(), param.getNumber());
if (NumberUtil.isLess(balance, BigDecimal.ZERO)) {
throw new CzgException(StrUtil.format("耗材{}存在发生变动,请刷新后重试", entity.getConName()));
}
entity.setBeforeNumber(consInfo.getStockNumber());
entity.setInOutNumber(NumberUtil.sub(BigDecimal.ZERO, balance));
entity.setAfterNumber(balance);
entity.setInOutType(InOutTypeEnum.OUT.value());
entity.setInOutItem(InOutItemEnum.DAMAGE_OUT.value());
entity.setSubTotal(NumberUtil.mul(param.getNumber(), consInfo.getPrice()));
entity.setImgUrls(JSON.toJSONString(param.getImgUrls()));
entity.setRemark("商品报损,自动报损相关耗材");
consStockFlowMapper.insert(entity);
consInfo.setStockNumber(entity.getAfterNumber());
UpdateChain.of(ConsInfo.class)
.set(ConsInfo::getStockNumber, consInfo.getStockNumber())
.eq(ConsInfo::getId, consInfo.getConsInfoId())
.update();
}
}
}

View File

@ -13,7 +13,10 @@
</select>
<select id="selectListByProdId" resultType="com.czg.product.dto.ProdConsRelationDTO">
SELECT t1.*,
t2.con_unit
t2.con_unit,
t2.con_name,
t2.price,
t2.stock_number
FROM tb_prod_cons_relation t1
LEFT JOIN tb_cons_info t2 on t1.cons_info_id = t2.id
WHERE t1.product_id = #{prodId}