From 11b89ab75d8d294eea9a0d66acb2dfb0cff0e8dc Mon Sep 17 00:00:00 2001 From: "zangch@mesnac.com" Date: Tue, 10 Mar 2026 14:20:33 +0800 Subject: [PATCH] =?UTF-8?q?feat(wms):=20=E6=96=B0=E5=A2=9E=E5=8F=91?= =?UTF-8?q?=E8=B4=A7=E8=8D=89=E7=A8=BF=E5=8A=9F=E8=83=BD=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E8=87=AA=E5=8A=A8=E5=88=9B=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 ruoyi-api-wms 模块及 RemoteWmsShippingBillService 远程服务接口 - 实现 createDraftByProject 方法根据项目快照自动创建发货草稿 - 添加 RemoteWmsShippingDraft 和 RemoteWmsShippingDraftItem 数据传输对象 - 在项目完成后自动预生成发货草稿,用户只需补充业务细节无需手工新建 - 集成合同物料信息到发货草稿明细,支持合同物料快照转换 - 优化注释文案,统一使用中文注释格式 - 修复 WMS 模块依赖配置,确保 API 模块正确引用 --- ruoyi-api/pom.xml | 1 + ruoyi-api/ruoyi-api-bom/pom.xml | 7 + ruoyi-api/ruoyi-api-wms/pom.xml | 31 +++ .../wms/api/RemoteWmsShippingBillService.java | 20 ++ .../api/domain/RemoteWmsShippingDraft.java | 170 +++++++++++++++ .../domain/RemoteWmsShippingDraftItem.java | 80 ++++++++ ruoyi-modules/ruoyi-oa/pom.xml | 5 + .../impl/ErpContractInfoServiceImpl.java | 8 +- .../impl/ErpProjectInfoServiceImpl.java | 194 +++++++++++++++--- ruoyi-modules/ruoyi-wms/pom.xml | 5 + .../RemoteWmsShippingBillServiceImpl.java | 27 +++ .../wms/service/IWmsShippingBillService.java | 12 +- .../impl/WmsShippingBillServiceImpl.java | 85 ++++++++ 13 files changed, 612 insertions(+), 33 deletions(-) create mode 100644 ruoyi-api/ruoyi-api-wms/pom.xml create mode 100644 ruoyi-api/ruoyi-api-wms/src/main/java/org/dromara/wms/api/RemoteWmsShippingBillService.java create mode 100644 ruoyi-api/ruoyi-api-wms/src/main/java/org/dromara/wms/api/domain/RemoteWmsShippingDraft.java create mode 100644 ruoyi-api/ruoyi-api-wms/src/main/java/org/dromara/wms/api/domain/RemoteWmsShippingDraftItem.java create mode 100644 ruoyi-modules/ruoyi-wms/src/main/java/org/dromara/wms/dubbo/RemoteWmsShippingBillServiceImpl.java diff --git a/ruoyi-api/pom.xml b/ruoyi-api/pom.xml index eef7cf34..e0e99eba 100644 --- a/ruoyi-api/pom.xml +++ b/ruoyi-api/pom.xml @@ -13,6 +13,7 @@ ruoyi-api-system ruoyi-api-resource ruoyi-api-workflow + ruoyi-api-wms ruoyi-api diff --git a/ruoyi-api/ruoyi-api-bom/pom.xml b/ruoyi-api/ruoyi-api-bom/pom.xml index 96177272..a3283eb5 100644 --- a/ruoyi-api/ruoyi-api-bom/pom.xml +++ b/ruoyi-api/ruoyi-api-bom/pom.xml @@ -41,6 +41,13 @@ ${revision} + + + org.dromara + ruoyi-api-wms + ${revision} + + diff --git a/ruoyi-api/ruoyi-api-wms/pom.xml b/ruoyi-api/ruoyi-api-wms/pom.xml new file mode 100644 index 00000000..46ad8183 --- /dev/null +++ b/ruoyi-api/ruoyi-api-wms/pom.xml @@ -0,0 +1,31 @@ + + + + org.dromara + ruoyi-api + ${revision} + + 4.0.0 + + ruoyi-api-wms + + + ruoyi-api-wms WMS接口模块 + + + + + + org.dromara + ruoyi-common-core + + + com.fasterxml.jackson.core + jackson-annotations + + + + + diff --git a/ruoyi-api/ruoyi-api-wms/src/main/java/org/dromara/wms/api/RemoteWmsShippingBillService.java b/ruoyi-api/ruoyi-api-wms/src/main/java/org/dromara/wms/api/RemoteWmsShippingBillService.java new file mode 100644 index 00000000..1c495e89 --- /dev/null +++ b/ruoyi-api/ruoyi-api-wms/src/main/java/org/dromara/wms/api/RemoteWmsShippingBillService.java @@ -0,0 +1,20 @@ +package org.dromara.wms.api; + +import org.dromara.wms.api.domain.RemoteWmsShippingDraft; + +/** + * 发货单远程服务 + * + * @author Codex + */ +public interface RemoteWmsShippingBillService { + + /** + * 根据项目快照创建发货草稿 + * + * @param draft 发货草稿快照 + * @return 发货单ID + */ + Long createDraftByProject(RemoteWmsShippingDraft draft); + +} diff --git a/ruoyi-api/ruoyi-api-wms/src/main/java/org/dromara/wms/api/domain/RemoteWmsShippingDraft.java b/ruoyi-api/ruoyi-api-wms/src/main/java/org/dromara/wms/api/domain/RemoteWmsShippingDraft.java new file mode 100644 index 00000000..387ea778 --- /dev/null +++ b/ruoyi-api/ruoyi-api-wms/src/main/java/org/dromara/wms/api/domain/RemoteWmsShippingDraft.java @@ -0,0 +1,170 @@ +package org.dromara.wms.api.domain; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 发货草稿快照 + * + * @author Codex + */ +@Data +public class RemoteWmsShippingDraft implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 项目ID + */ + private Long projectId; + + /** + * 项目编号 + */ + private String projectCode; + + /** + * 项目名称 + */ + private String projectName; + + /** + * 绑定类型 + */ + private String bindType; + + /** + * 发货方式 + */ + private String shippingMode; + + /** + * 发货类型 + */ + private String shippingType; + + /** + * 合同ID + */ + private Long contractId; + + /** + * 合同编号 + */ + private String contractCode; + + /** + * 合同名称 + */ + private String contractName; + + /** + * SAP订单号 + */ + private String orderContractCode; + + /** + * 客户ID + */ + private Long customerId; + + /** + * 客户名称 + */ + private String customerName; + + /** + * 收货地址 + */ + private String shippingAddress; + + /** + * 收货联系人 + */ + private String receiverName; + + /** + * 收货电话 + */ + private String receiverPhone; + + /** + * 发货说明 + */ + private String directions; + + /** + * 备注 + */ + private String remark; + + /** + * 合同跟进人 + */ + private Long contractUserId; + + /** + * 项目经理 + */ + private Long managerId; + + /** + * 草稿物料快照 + */ + private List details; + + + + + /** + * 租户编号 + */ + private String tenantId; + + /** + * 搜索值 + */ + @JsonIgnore + private String searchValue; + + /** + * 创建部门 + */ + private Long createDept; + + /** + * 创建者 + */ + private Long createBy; + + /** + * 创建时间 + */ + private Date createTime; + + /** + * 更新者 + */ + private Long updateBy; + + /** + * 更新时间 + */ + private Date updateTime; + + /** + * 请求参数 + */ + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private Map params = new HashMap<>(); + +} diff --git a/ruoyi-api/ruoyi-api-wms/src/main/java/org/dromara/wms/api/domain/RemoteWmsShippingDraftItem.java b/ruoyi-api/ruoyi-api-wms/src/main/java/org/dromara/wms/api/domain/RemoteWmsShippingDraftItem.java new file mode 100644 index 00000000..01fbd7fa --- /dev/null +++ b/ruoyi-api/ruoyi-api-wms/src/main/java/org/dromara/wms/api/domain/RemoteWmsShippingDraftItem.java @@ -0,0 +1,80 @@ +package org.dromara.wms.api.domain; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 发货草稿物料快照 + * + * @author Codex + */ +@Data +public class RemoteWmsShippingDraftItem implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 来源明细ID + */ + private Long sourceDetailId; + + /** + * ERP物料ID + */ + private Long erpMaterialId; + + /** + * 物料ID + */ + private Long materielId; + + /** + * 物料编码 + */ + private String materialCode; + + /** + * 物料名称 + */ + private String materialName; + + /** + * 规格型号 + */ + private String materielSpecification; + + /** + * 数量 + */ + private BigDecimal shippingStockAmount; + + /** + * 单位ID + */ + private Long unitId; + + /** + * 单位名称 + */ + private String unitName; + + /** + * 单价 + */ + private BigDecimal unitPrice; + + /** + * 总价 + */ + private BigDecimal totalPrice; + + /** + * 备注 + */ + private String remark; + +} diff --git a/ruoyi-modules/ruoyi-oa/pom.xml b/ruoyi-modules/ruoyi-oa/pom.xml index 22566120..33e7e93b 100644 --- a/ruoyi-modules/ruoyi-oa/pom.xml +++ b/ruoyi-modules/ruoyi-oa/pom.xml @@ -105,6 +105,11 @@ ruoyi-api-workflow + + org.dromara + ruoyi-api-wms + + org.dromara ruoyi-common-bus diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpContractInfoServiceImpl.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpContractInfoServiceImpl.java index 41e7ba96..eacbc7ea 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpContractInfoServiceImpl.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpContractInfoServiceImpl.java @@ -446,7 +446,7 @@ public class ErpContractInfoServiceImpl implements IErpContractInfoService { data.put("外部合同号", strVal(contractInfo.getExternalContractCode())); data.put("订单号", strVal(contractInfo.getOrderContractCode())); data.put("项目号", strVal(contractInfo.getProjectContractCode())); - // Why:当前业务已明确“交付启动期限”与“交货期”同义,双键同时输出可兼容不同模板占位符命名 + // 当前业务已明确“交付启动期限”与“交货期”同义,双键同时输出可兼容不同模板占位符命名 String deliveryPeriod = strVal(contractInfo.getDeliveryStart()); data.put("交货期", deliveryPeriod); data.put("交付启动期限", deliveryPeriod); @@ -464,7 +464,7 @@ public class ErpContractInfoServiceImpl implements IErpContractInfoService { // 审批单只展示“已办节点”,避免把待办节点(无审批时间/意见)混入导出文档 Map flowData = remoteWorkflowService.flowHisTaskList(String.valueOf(contractId)); List> handledTasks = extractHandledTasks(flowData == null ? null : flowData.get("list")); - // Why:固定审批区块要按流程节点名精确落位,避免后续流程扩展后把别的节点意见写错位置 + // 固定审批区块要按流程节点名精确落位,避免后续流程扩展后把别的节点意见写错位置 fillApprovalNodeData(data, handledTasks, BUSINESS_DIRECTION_LEADER_NODE_NAME, "业务方向负责人"); fillApprovalNodeData(data, handledTasks, FINANCE_MANAGER_NODE_NAME, "财务经理"); List approvalRows = new ArrayList<>(); @@ -536,7 +536,7 @@ public class ErpContractInfoServiceImpl implements IErpContractInfoService { } for (int i = handledTasks.size() - 1; i >= 0; i--) { Map task = handledTasks.get(i); - // Why:不同工作流版本可能返回 nodeName / targetNodeName,双字段兼容可以减少后续接口改动带来的模板失效 + // 不同工作流版本可能返回 nodeName / targetNodeName,双字段兼容可以减少后续接口改动带来的模板失效 String taskNodeName = strVal(task.get("nodeName")); String targetNodeName = strVal(task.get("targetNodeName")); if (nodeName.equals(taskNodeName) || nodeName.equals(targetNodeName)) { @@ -559,7 +559,7 @@ public class ErpContractInfoServiceImpl implements IErpContractInfoService { return ""; } try { - // Why:Dubbo 导出链路返回的是纯 Map 后,工作流里的 @Translation 不再生效,这里补一层用户昵称查询保证导出给业务人员的是可读姓名 + // Dubbo 导出链路返回的是纯 Map 后,工作流里的 @Translation 不再生效,这里补一层用户昵称查询保证导出给业务人员的是可读姓名 String nickname = remoteUserService.selectNicknameByIds(approver); return StringUtils.isNotBlank(nickname) ? nickname : approver; } catch (Exception e) { diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectInfoServiceImpl.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectInfoServiceImpl.java index 753e3b67..2d8fe33d 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectInfoServiceImpl.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectInfoServiceImpl.java @@ -1,47 +1,51 @@ package org.dromara.oa.erp.service.impl; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.map.MapUtil; -import lombok.extern.slf4j.Slf4j; -import org.dromara.common.core.enums.BusinessStatusEnum; -import org.dromara.common.core.enums.OAStatusEnum; -import org.dromara.common.core.utils.MapstructUtils; -import org.dromara.common.core.utils.StringUtils; -import org.dromara.common.mybatis.core.page.TableDataInfo; -import org.dromara.common.mybatis.core.page.PageQuery; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.github.yulichang.toolkit.JoinWrappers; import com.github.yulichang.wrapper.MPJLambdaWrapper; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.dubbo.config.annotation.DubboReference; +import org.apache.seata.spring.annotation.GlobalTransactional; +import org.dromara.common.core.enums.BusinessStatusEnum; +import org.dromara.common.core.enums.OAStatusEnum; +import org.dromara.common.core.exception.ServiceException; +import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.common.tenant.helper.TenantHelper; import org.dromara.oa.erp.constant.ProjectCategoryConstant; +import org.dromara.oa.erp.domain.ErpProjectContracts; +import org.dromara.oa.erp.domain.ErpProjectInfo; +import org.dromara.oa.erp.domain.bo.ErpProjectContractsBo; +import org.dromara.oa.erp.domain.bo.ErpProjectInfoBo; +import org.dromara.oa.erp.domain.vo.ErpContractInfoVo; +import org.dromara.oa.erp.domain.vo.ErpContractMaterialVo; +import org.dromara.oa.erp.domain.vo.ErpProjectInfoVo; import org.dromara.oa.erp.enums.ProjectCategoryEnum; +import org.dromara.oa.erp.mapper.ErpProjectContractsMapper; +import org.dromara.oa.erp.mapper.ErpProjectInfoMapper; +import org.dromara.oa.erp.service.IErpContractInfoService; +import org.dromara.oa.erp.service.IErpProjectInfoService; +import org.dromara.wms.api.RemoteWmsShippingBillService; +import org.dromara.wms.api.domain.RemoteWmsShippingDraft; +import org.dromara.wms.api.domain.RemoteWmsShippingDraftItem; +import org.dromara.workflow.api.RemoteWorkflowService; +import org.dromara.workflow.api.domain.RemoteStartProcess; import org.dromara.workflow.api.event.ProcessEvent; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; -import org.dromara.oa.erp.domain.bo.ErpProjectInfoBo; -import org.dromara.oa.erp.domain.vo.ErpProjectInfoVo; -import org.dromara.oa.erp.domain.ErpProjectInfo; -import org.dromara.oa.erp.mapper.ErpProjectInfoMapper; -import org.dromara.oa.erp.service.IErpProjectInfoService; -import org.dromara.oa.erp.domain.bo.ErpProjectContractsBo; -import org.dromara.oa.erp.domain.ErpProjectContracts; -import org.dromara.oa.erp.mapper.ErpProjectContractsMapper; -import org.apache.dubbo.config.annotation.DubboReference; -import org.apache.seata.spring.annotation.GlobalTransactional; -import org.dromara.common.core.exception.ServiceException; -import org.dromara.workflow.api.RemoteWorkflowService; -import org.dromara.workflow.api.domain.RemoteStartProcess; - -import java.util.List; -import java.util.Map; -import java.util.Collection; -import java.util.Objects; -import java.util.Set; -import java.util.stream.Collectors; - import org.springframework.transaction.annotation.Transactional; +import java.util.*; +import java.util.stream.Collectors; + /** * 项目信息Service业务层处理 * @@ -57,9 +61,14 @@ public class ErpProjectInfoServiceImpl implements IErpProjectInfoService { private final ErpProjectContractsMapper projectContractsMapper; + private final IErpContractInfoService erpContractInfoService; + @DubboReference(timeout = 30000) private RemoteWorkflowService remoteWorkflowService; + @DubboReference(timeout = 30000) + private RemoteWmsShippingBillService remoteWmsShippingBillService; + /** * 查询项目信息 * @@ -292,6 +301,8 @@ public class ErpProjectInfoServiceImpl implements IErpProjectInfoService { projectInfo.setProjectStatus(OAStatusEnum.APPROVING.getStatus()); } else if (Objects.equals(processEvent.getStatus(), BusinessStatusEnum.FINISH.getStatus())) { projectInfo.setProjectStatus(OAStatusEnum.COMPLETED.getStatus()); + // 项目一旦转“可用”就预生成发货草稿,用户后续只补业务细节,不需要再手工新建整单 + remoteWmsShippingBillService.createDraftByProject(buildShippingDraft(projectInfo)); } else if (Objects.equals(processEvent.getStatus(), BusinessStatusEnum.INVALID.getStatus()) || Objects.equals(processEvent.getStatus(), BusinessStatusEnum.TERMINATION.getStatus())) { projectInfo.setProjectStatus(OAStatusEnum.INVALID.getStatus()); @@ -355,4 +366,131 @@ public class ErpProjectInfoServiceImpl implements IErpProjectInfoService { } + + /** + * 组装项目发货草稿快照 + * + * @param projectInfo 项目 + * @return 发货草稿 + */ + private RemoteWmsShippingDraft buildShippingDraft(ErpProjectInfo projectInfo) { + RemoteWmsShippingDraft draft = new RemoteWmsShippingDraft(); + draft.setProjectId(projectInfo.getProjectId()); + draft.setProjectCode(projectInfo.getProjectCode()); + draft.setProjectName(projectInfo.getProjectName()); + draft.setBindType("1"); + draft.setShippingMode("1"); + draft.setShippingType(resolveShippingType(projectInfo)); + draft.setManagerId(projectInfo.getManagerId()); + draft.setContractUserId(projectInfo.getContractUserId()); + draft.setRemark("系统根据项目完成自动创建,请补充后发起审批"); + + Long contractId = resolveShippingContractId(projectInfo); + if (contractId == null) { + return draft; + } + + ErpContractInfoVo contractInfo = erpContractInfoService.queryById(contractId); + if (contractInfo == null) { + return draft; + } + draft.setContractId(contractInfo.getContractId()); + draft.setContractCode(contractInfo.getContractCode()); + draft.setContractName(contractInfo.getContractName()); + draft.setOrderContractCode(contractInfo.getOrderContractCode()); + draft.setCustomerId(contractInfo.getOneCustomerId()); + draft.setCustomerName(contractInfo.getOneCustomerName()); + draft.setShippingAddress(contractInfo.getDetailedAddress()); + // 自动草稿只做“带得出来就先带”,联系人优先取商务联系人,没有时再退化到技术联系人,避免无意义空白单 + draft.setReceiverName(firstNonBlank(contractInfo.getOneBusinessContact(), contractInfo.getOneTechnicalContact(), contractInfo.getOneRepresent())); + draft.setReceiverPhone(firstNonBlank(contractInfo.getOneBusinessContactPhone(), contractInfo.getOneTechnicalContactPhone())); + draft.setDirections(StringUtils.defaultIfBlank(contractInfo.getMaterialRemark(), contractInfo.getRemark())); + draft.setDetails(buildShippingDraftDetails(contractInfo.getContractMaterialList())); + + //显示填充租户、创建人、创建时间 + draft.setTenantId(TenantHelper.getTenantId()); + draft.setCreateBy(LoginHelper.getUserId()); + draft.setCreateTime(new Date()); + + return draft; + } + + /** + * 解析发货默认类型 + * + * @param projectInfo 项目 + * @return 发货类型 + */ + private String resolveShippingType(ErpProjectInfo projectInfo) { + if ("1".equals(projectInfo.getSpareFlag())) { + return "2"; + } + return null; + } + + /** + * 解析发货默认合同 + * + * @param projectInfo 项目 + * @return 合同ID + */ + private Long resolveShippingContractId(ErpProjectInfo projectInfo) { + if (projectInfo.getContractId() != null) { + return projectInfo.getContractId(); + } + List projectContracts = projectContractsMapper.selectList(Wrappers.lambdaQuery() + .eq(ErpProjectContracts::getProjectId, projectInfo.getProjectId()) + .eq(ErpProjectContracts::getDelFlag, "0") + .orderByAsc(ErpProjectContracts::getSortOrder) + .orderByAsc(ErpProjectContracts::getProjectContractsId)); + if (CollUtil.isEmpty(projectContracts)) { + return null; + } + return projectContracts.get(0).getContractId(); + } + + /** + * 合同物料转发货快照 + * + * @param materials 合同物料 + * @return 发货快照明细 + */ + private List buildShippingDraftDetails(List materials) { + if (CollUtil.isEmpty(materials)) { + return new ArrayList<>(); + } + List details = new ArrayList<>(materials.size()); + for (ErpContractMaterialVo material : materials) { + RemoteWmsShippingDraftItem item = new RemoteWmsShippingDraftItem(); + // 这里复制的是“合同当前版本”的展示快照,发货草稿生成后即与合同解耦,后续合同调整不回写历史草稿 + item.setSourceDetailId(material.getContractMaterialId()); + item.setErpMaterialId(material.getMaterialId()); + item.setMaterielId(material.getMaterialId()); + item.setMaterialCode(material.getMaterialCode()); + item.setMaterialName(firstNonBlank(material.getSaleMaterialName(), material.getMaterialName(), material.getProductName())); + item.setMaterielSpecification(material.getSpecificationDescription()); + item.setShippingStockAmount(material.getAmount()); + item.setUnitId(material.getUnitId()); + item.setUnitName(material.getUnitName()); + item.setUnitPrice(material.getIncludingPrice()); + item.setTotalPrice(material.getSubtotal()); + item.setRemark(material.getRemark()); + details.add(item); + } + return details; + } + + private String firstNonBlank(String... values) { + if (values == null) { + return null; + } + for (String value : values) { + if (StringUtils.isNotBlank(value)) { + return value; + } + } + return null; + } + + } diff --git a/ruoyi-modules/ruoyi-wms/pom.xml b/ruoyi-modules/ruoyi-wms/pom.xml index 8e2637a6..93416dbe 100644 --- a/ruoyi-modules/ruoyi-wms/pom.xml +++ b/ruoyi-modules/ruoyi-wms/pom.xml @@ -104,6 +104,11 @@ org.dromara ruoyi-api-workflow + + + org.dromara + ruoyi-api-wms + org.dromara ruoyi-common-bus diff --git a/ruoyi-modules/ruoyi-wms/src/main/java/org/dromara/wms/dubbo/RemoteWmsShippingBillServiceImpl.java b/ruoyi-modules/ruoyi-wms/src/main/java/org/dromara/wms/dubbo/RemoteWmsShippingBillServiceImpl.java new file mode 100644 index 00000000..0696b6c1 --- /dev/null +++ b/ruoyi-modules/ruoyi-wms/src/main/java/org/dromara/wms/dubbo/RemoteWmsShippingBillServiceImpl.java @@ -0,0 +1,27 @@ +package org.dromara.wms.dubbo; + +import lombok.RequiredArgsConstructor; +import org.apache.dubbo.config.annotation.DubboService; +import org.dromara.wms.api.RemoteWmsShippingBillService; +import org.dromara.wms.api.domain.RemoteWmsShippingDraft; +import org.dromara.wms.service.IWmsShippingBillService; +import org.springframework.stereotype.Service; + +/** + * 发货单远程服务实现 + * + * @author Codex + */ +@RequiredArgsConstructor +@Service +@DubboService +public class RemoteWmsShippingBillServiceImpl implements RemoteWmsShippingBillService { + + private final IWmsShippingBillService wmsShippingBillService; + + @Override + public Long createDraftByProject(RemoteWmsShippingDraft draft) { + return wmsShippingBillService.createDraftByProject(draft); + } + +} diff --git a/ruoyi-modules/ruoyi-wms/src/main/java/org/dromara/wms/service/IWmsShippingBillService.java b/ruoyi-modules/ruoyi-wms/src/main/java/org/dromara/wms/service/IWmsShippingBillService.java index cbc07585..0209a153 100644 --- a/ruoyi-modules/ruoyi-wms/src/main/java/org/dromara/wms/service/IWmsShippingBillService.java +++ b/ruoyi-modules/ruoyi-wms/src/main/java/org/dromara/wms/service/IWmsShippingBillService.java @@ -2,11 +2,13 @@ package org.dromara.wms.service; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.wms.api.domain.RemoteWmsShippingDraft; import org.dromara.wms.domain.bo.WmsShippingBillBo; import org.dromara.wms.domain.vo.WmsShippingBillVo; import java.util.Collection; import java.util.List; +import java.util.Map; /** * 发货单Service接口 @@ -80,6 +82,14 @@ public interface IWmsShippingBillService { * @param shippingBillId 发货单ID * @return Word模板数据Map */ - java.util.Map buildWordExportData(Long shippingBillId); + Map buildWordExportData(Long shippingBillId); + + /** + * 根据项目快照创建发货草稿 + * + * @param draft 发货草稿快照 + * @return 发货单ID + */ + Long createDraftByProject(RemoteWmsShippingDraft draft); } diff --git a/ruoyi-modules/ruoyi-wms/src/main/java/org/dromara/wms/service/impl/WmsShippingBillServiceImpl.java b/ruoyi-modules/ruoyi-wms/src/main/java/org/dromara/wms/service/impl/WmsShippingBillServiceImpl.java index d35d4406..14455960 100644 --- a/ruoyi-modules/ruoyi-wms/src/main/java/org/dromara/wms/service/impl/WmsShippingBillServiceImpl.java +++ b/ruoyi-modules/ruoyi-wms/src/main/java/org/dromara/wms/service/impl/WmsShippingBillServiceImpl.java @@ -23,6 +23,8 @@ import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.common.tenant.helper.TenantHelper; import org.dromara.system.api.RemoteCodeRuleService; +import org.dromara.wms.api.domain.RemoteWmsShippingDraft; +import org.dromara.wms.api.domain.RemoteWmsShippingDraftItem; import org.dromara.wms.domain.WmsShippingBill; import org.dromara.wms.domain.WmsShippingDetails; import org.dromara.wms.domain.bo.WmsShippingBillBo; @@ -243,6 +245,58 @@ public class WmsShippingBillServiceImpl implements IWmsShippingBillService { return flag; } + /** + * 根据项目快照创建发货草稿 + * + * @param draft 发货草稿快照 + * @return 发货单ID + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Long createDraftByProject(RemoteWmsShippingDraft draft) { + if (draft == null || draft.getProjectId() == null) { + throw new ServiceException("项目发货草稿参数不完整"); + } + WmsShippingBill existing = baseMapper.selectOne(Wrappers.lambdaQuery() + .select(WmsShippingBill::getShippingBillId) + .eq(WmsShippingBill::getProjectId, draft.getProjectId()) + .eq(WmsShippingBill::getOutStockBillStatus, OAStatusEnum.DRAFT.getStatus()) + .eq(WmsShippingBill::getFlowStatus, BusinessStatusEnum.DRAFT.getStatus()) + .eq(WmsShippingBill::getDelFlag, "0") + .last("limit 1"), false); + if (existing != null) { + return existing.getShippingBillId(); + } + + WmsShippingBillBo bo = new WmsShippingBillBo(); + bo.setBindType(StringUtils.defaultIfBlank(draft.getBindType(), "1")); + bo.setShippingMode(StringUtils.defaultIfBlank(draft.getShippingMode(), "1")); + bo.setShippingType(draft.getShippingType()); + bo.setProjectId(draft.getProjectId()); + bo.setProjectCode(draft.getProjectCode()); + bo.setProjectName(draft.getProjectName()); + bo.setSourceBillType("PROJECT"); + bo.setSourceBillId(draft.getProjectId()); + bo.setSourceBillCode(draft.getProjectCode()); + bo.setContractId(draft.getContractId()); + bo.setContractCode(draft.getContractCode()); + bo.setContractName(draft.getContractName()); + bo.setCustomerId(draft.getCustomerId()); + bo.setCustomerName(draft.getCustomerName()); + bo.setShippingAddress(draft.getShippingAddress()); + bo.setReceiverName(draft.getReceiverName()); + bo.setReceiverPhone(draft.getReceiverPhone()); + bo.setDirections(draft.getDirections()); + bo.setRemark(StringUtils.defaultIfBlank(draft.getRemark(), "系统根据项目自动生成发货草稿")); + // 发货代办页面就是“草稿提醒页”,这里显式落草稿状态,后续只允许用户在编辑页补全后再手工发起流程 + bo.setOutStockBillStatus(OAStatusEnum.DRAFT.getStatus()); + bo.setFlowStatus(BusinessStatusEnum.DRAFT.getStatus()); + bo.setShippingStatus(OAStatusEnum.DRAFT.getStatus()); + bo.setDetailsList(buildDraftDetails(draft.getDetails())); + this.insertByBo(bo); + return bo.getShippingBillId(); + } + /** * 保存前的数据校验 */ @@ -262,6 +316,37 @@ public class WmsShippingBillServiceImpl implements IWmsShippingBillService { } } + /** + * 合同物料快照转发货明细 + * + * @param details 草稿快照 + * @return 发货明细 + */ + private List buildDraftDetails(List details) { + if (CollUtil.isEmpty(details)) { + return Collections.emptyList(); + } + return details.stream().map(item -> { + WmsShippingDetails detail = new WmsShippingDetails(); + // 草稿创建时直接落快照,避免后续合同物料被修改后影响已生成的发货代办内容 + detail.setMaterialSourceType("1"); + detail.setSourceDetailType("CONTRACT_DETAIL"); + detail.setSourceDetailId(item.getSourceDetailId()); + detail.setErpMaterialId(item.getErpMaterialId()); + detail.setMaterielId(item.getMaterielId()); + detail.setMaterialCode(item.getMaterialCode()); + detail.setMaterialName(item.getMaterialName()); + detail.setMaterielSpecification(item.getMaterielSpecification()); + detail.setShippingStockAmount(item.getShippingStockAmount()); + detail.setUnitId(item.getUnitId()); + detail.setUnitName(item.getUnitName()); + detail.setUnitPrice(item.getUnitPrice()); + detail.setTotalPrice(item.getTotalPrice()); + detail.setRemark(item.getRemark()); + return detail; + }).collect(Collectors.toList()); + } + /** * 校验并批量删除发货单信息(同时删除明细) *