feat: 实现出库单带明细创建 Service(含 CodeGen 单据号生成)

- IostorInvService 接口新增 createIostorInvWithDetails 方法
- IostorInvServiceImpl 实现:单据号生成、主表+明细事务写入
- ErrorCodeConstants 新增 IOSTOR_INV_BILL_CODE_GENERATE_FAIL
This commit is contained in:
zhouz
2026-07-22 09:49:07 +08:00
parent 6c8020d1c3
commit a8d18e304c
3 changed files with 84 additions and 0 deletions

View File

@@ -25,4 +25,7 @@ public interface ErrorCodeConstants {
// ================ 组盘记录相关错误码 =================
ErrorCode GROUP_PLATE_NOT_EXISTS = new ErrorCode(9, "组盘记录不存在");
// ========== 出入库单 1-030-001-000 ==========
ErrorCode IOSTOR_INV_BILL_CODE_GENERATE_FAIL = new ErrorCode(1_030_001_000, "单据号生成失败,请稍后重试");
}

View File

@@ -4,6 +4,7 @@ import java.util.*;
import jakarta.validation.*;
import cn.code.nl.module.wms.controller.admin.iostorinv.vo.*;
import cn.code.nl.module.wms.dal.dataobject.iostorinv.IostorInvDO;
import cn.code.nl.module.wms.controller.admin.iostorinv.vo.IostorInvWithDetailsSaveReqVO;
import cn.code.nl.framework.common.pojo.PageResult;
import cn.code.nl.framework.common.pojo.PageParam;
@@ -59,4 +60,12 @@ public interface IostorInvService {
*/
PageResult<IostorInvDO> getIostorInvPage(IostorInvPageReqVO pageReqVO);
/**
* 创建出库单(含明细)
*
* @param reqVO 创建请求(含明细列表)
* @return 出入单标识
*/
String createIostorInvWithDetails(@Valid IostorInvWithDetailsSaveReqVO reqVO);
}

View File

@@ -14,6 +14,13 @@ import cn.code.nl.framework.common.pojo.PageParam;
import cn.code.nl.framework.common.util.object.BeanUtils;
import cn.code.nl.module.wms.dal.mysql.iostorinv.IostorInvMapper;
import cn.code.nl.module.base.api.codegen.CodeGenApi;
import cn.code.nl.module.base.api.codegen.dto.CodeGenerateReqDTO;
import cn.code.nl.module.wms.dal.mysql.iostorinvdtl.IostorinvDtlMapper;
import cn.code.nl.module.wms.dal.dataobject.iostorinvdtl.IostorinvDtlDO;
import cn.code.nl.framework.common.pojo.CommonResult;
import cn.code.nl.module.wms.controller.admin.iostorinv.vo.IostorInvWithDetailsSaveReqVO;
import java.math.BigDecimal;
import static cn.code.nl.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.code.nl.framework.common.util.collection.CollectionUtils.convertList;
@@ -32,6 +39,12 @@ public class IostorInvServiceImpl implements IostorInvService {
@Resource
private IostorInvMapper iostorInvMapper;
@Resource
private CodeGenApi codeGenApi;
@Resource
private IostorinvDtlMapper iostorinvDtlMapper;
@Override
public String createIostorInv(IostorInvSaveReqVO createReqVO) {
// 插入
@@ -82,4 +95,63 @@ public class IostorInvServiceImpl implements IostorInvService {
return iostorInvMapper.selectPage(pageReqVO);
}
@Override
@Transactional(rollbackFor = Exception.class)
public String createIostorInvWithDetails(IostorInvWithDetailsSaveReqVO reqVO) {
// 1. 调用 base 模块生成单据号
CodeGenerateReqDTO codeReq = new CodeGenerateReqDTO();
codeReq.setRuleCode("IO_CODE");
CommonResult<String> codeResult = codeGenApi.generate(codeReq);
if (codeResult == null || codeResult.getData() == null) {
throw exception(IOSTOR_INV_BILL_CODE_GENERATE_FAIL);
}
String billCode = codeResult.getData();
// 2. 构建主表数据
IostorInvDO master = new IostorInvDO();
master.setBillCode(billCode);
master.setIoType("OUT");
master.setBillType(reqVO.getBillType());
master.setBizDate(reqVO.getBizDate());
master.setStorId(reqVO.getStorId());
master.setStorCode(reqVO.getStorCode());
master.setStorName(reqVO.getStorName());
master.setBillStatus("生成");
master.setRemark(reqVO.getRemark());
master.setDetailCount(reqVO.getDetails().size());
// 3. 计算总重量
BigDecimal totalWeight = reqVO.getDetails().stream()
.map(IostorInvWithDetailsSaveReqVO.DetailVO::getPlanQty)
.reduce(BigDecimal.ZERO, BigDecimal::add);
master.setTotalWeight(totalWeight);
// 4. 插入主表
iostorInvMapper.insert(master);
// 5. 批量插入明细
String iostorinvId = master.getIostorinvId();
int seqNo = 1;
for (IostorInvWithDetailsSaveReqVO.DetailVO detail : reqVO.getDetails()) {
IostorinvDtlDO dtl = new IostorinvDtlDO();
dtl.setIostorinvId(iostorinvId);
dtl.setSeqNo(seqNo++);
dtl.setMaterialCode(detail.getMaterialCode());
dtl.setMaterialId(detail.getMaterialId());
dtl.setPcsn(detail.getPcsn());
dtl.setPlanQty(detail.getPlanQty());
dtl.setUnassignQty(detail.getPlanQty()); // 初始未分配 = 计划数量
dtl.setAssignQty(BigDecimal.ZERO);
dtl.setQtyUnitId(detail.getQtyUnitId());
dtl.setQtyUnitName(detail.getQtyUnitName());
dtl.setRemark(detail.getRemark());
dtl.setSourceBillCode(detail.getSourceBillCode());
dtl.setSourceBillType(detail.getSourceBillType());
dtl.setSourceBilldtlId(detail.getSourceBilldtlId());
iostorinvDtlMapper.insert(dtl);
}
return iostorinvId;
}
}