package cn.iocoder.yudao.module.mes.service.wm.productsales;
|
|
import cn.hutool.core.util.ObjUtil;
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.detail.MesWmProductSalesDetailSaveReqVO;
|
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesDetailDO;
|
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesLineDO;
|
import cn.iocoder.yudao.module.mes.dal.mysql.wm.productsales.MesWmProductSalesDetailMapper;
|
import cn.iocoder.yudao.module.mes.dal.mysql.wm.productsales.MesWmProductSalesMapper;
|
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesDO;
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
import cn.iocoder.yudao.framework.common.exception.ServiceException;
|
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
|
import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService;
|
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
|
import jakarta.annotation.Resource;
|
import org.springframework.context.annotation.Lazy;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.validation.annotation.Validated;
|
|
import java.util.List;
|
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
|
|
/**
|
* MES 销售出库明细 Service 实现类
|
*
|
* @author 超级管理员
|
*/
|
@Service
|
@Validated
|
public class MesWmProductSalesDetailServiceImpl implements MesWmProductSalesDetailService {
|
|
@Resource
|
private MesWmProductSalesDetailMapper productSalesDetailMapper;
|
|
@Resource
|
private MesMdmItemService mdmItemService;
|
@Resource
|
@Lazy
|
private MesWmProductSalesLineService productSalesLineService;
|
@Resource
|
private MesWmMaterialStockService materialStockService;
|
@Resource
|
private MesWmWarehouseAreaService warehouseAreaService;
|
@Resource
|
private MesWmSalesReelGuard salesReelGuard;
|
@Resource
|
private MesWmOqcConcessionGuard oqcConcessionGuard;
|
@Resource
|
private MesWmProductSalesMapper salesMapper;
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public Long createProductSalesDetail(MesWmProductSalesDetailSaveReqVO createReqVO) {
|
validateEditable(createReqVO.getSalesId(), createReqVO.getLineId());
|
// 校验数据
|
validateProductSalesDetailSaveData(createReqVO);
|
|
// 插入
|
MesWmProductSalesDetailDO detail = BeanUtils.toBean(createReqVO, MesWmProductSalesDetailDO.class);
|
productSalesDetailMapper.insert(detail);
|
return detail.getId();
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void updateProductSalesDetail(MesWmProductSalesDetailSaveReqVO updateReqVO) {
|
// 校验存在
|
MesWmProductSalesDetailDO existing = validateProductSalesDetailExists(updateReqVO.getId());
|
if (!ObjUtil.equal(existing.getSalesId(), updateReqVO.getSalesId()) || !ObjUtil.equal(existing.getLineId(), updateReqVO.getLineId())) {
|
throw new ServiceException(400, "不允许更改出库明细所属单据或行");
|
}
|
validateEditable(existing.getSalesId(), existing.getLineId());
|
// 校验数据
|
validateProductSalesDetailSaveData(updateReqVO);
|
|
// 更新
|
MesWmProductSalesDetailDO updateObj = BeanUtils.toBean(updateReqVO, MesWmProductSalesDetailDO.class);
|
productSalesDetailMapper.updateById(updateObj);
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void deleteProductSalesDetail(Long id) {
|
// 校验存在
|
MesWmProductSalesDetailDO detail = validateProductSalesDetailExists(id);
|
validateEditable(detail.getSalesId(), detail.getLineId());
|
// 删除
|
productSalesDetailMapper.deleteById(id);
|
}
|
|
private void validateEditable(Long salesId, Long lineId) {
|
MesWmProductSalesDO sales = salesMapper.selectOne(new LambdaQueryWrapperX<MesWmProductSalesDO>()
|
.eq(MesWmProductSalesDO::getId, salesId).last("FOR UPDATE"));
|
MesWmProductSalesLineDO line = productSalesLineService.getProductSalesLine(lineId);
|
if (sales == null || line == null || !ObjUtil.equal(line.getSalesId(), salesId)) {
|
throw new ServiceException(400, "出库单或出库行不存在");
|
}
|
oqcConcessionGuard.validateEditable(line, sales.getStatus());
|
}
|
|
@Override
|
public MesWmProductSalesDetailDO getProductSalesDetail(Long id) {
|
return productSalesDetailMapper.selectById(id);
|
}
|
|
@Override
|
public List<MesWmProductSalesDetailDO> getProductSalesDetailListBySalesId(Long salesId) {
|
return productSalesDetailMapper.selectListBySalesId(salesId);
|
}
|
|
@Override
|
public List<MesWmProductSalesDetailDO> getProductSalesDetailListByLineId(Long lineId) {
|
return productSalesDetailMapper.selectListByLineId(lineId);
|
}
|
|
@Override
|
public void deleteProductSalesDetailByLineId(Long lineId) {
|
productSalesDetailMapper.deleteByLineId(lineId);
|
}
|
|
@Override
|
public void deleteProductSalesDetailBySalesId(Long salesId) {
|
productSalesDetailMapper.deleteBySalesId(salesId);
|
}
|
|
private MesWmProductSalesDetailDO validateProductSalesDetailExists(Long id) {
|
MesWmProductSalesDetailDO detail = productSalesDetailMapper.selectById(id);
|
if (detail == null) {
|
throw exception(WM_PRODUCT_SALES_DETAIL_NOT_EXISTS);
|
}
|
return detail;
|
}
|
|
private void validateProductSalesDetailSaveData(MesWmProductSalesDetailSaveReqVO reqVO) {
|
// 校验父数据(行)存在
|
MesWmProductSalesLineDO line = productSalesLineService.getProductSalesLine(reqVO.getLineId());
|
if (line == null) {
|
throw exception(WM_PRODUCT_SALES_LINE_NOT_EXISTS);
|
}
|
if (ObjUtil.notEqual(line.getSalesId(), reqVO.getSalesId())) {
|
throw exception(WM_PRODUCT_SALES_DETAIL_LINE_NOT_MATCH);
|
}
|
// 校验物料存在
|
mdmItemService.validateItemExistsAndEnable(reqVO.getItemId());
|
if (ObjUtil.notEqual(line.getItemId(), reqVO.getItemId())) {
|
throw exception(WM_PRODUCT_SALES_DETAIL_ITEM_MISMATCH);
|
}
|
// 校验库位存在
|
warehouseAreaService.validateWarehouseAreaExists(
|
reqVO.getWarehouseId(), reqVO.getLocationId(), reqVO.getAreaId());
|
// 校验库存记录存在且物料一致
|
materialStockService.validateSelectedStock(
|
reqVO.getMaterialStockId(), reqVO.getItemId(), reqVO.getBatchId(), reqVO.getBatchCode(),
|
reqVO.getWarehouseId(), reqVO.getLocationId(), reqVO.getAreaId(), reqVO.getQuantity());
|
salesReelGuard.validate(line, reqVO.getBatchId());
|
oqcConcessionGuard.validate(line, reqVO.getMaterialStockId(), reqVO.getBatchCode(), reqVO.getQuantity());
|
}
|
|
}
|