diff --git a/ruoyi-modules/ruoyi-wms/src/main/java/org/dromara/wms/domain/WmsShippingBill.java b/ruoyi-modules/ruoyi-wms/src/main/java/org/dromara/wms/domain/WmsShippingBill.java index 67115027..4f21df45 100644 --- a/ruoyi-modules/ruoyi-wms/src/main/java/org/dromara/wms/domain/WmsShippingBill.java +++ b/ruoyi-modules/ruoyi-wms/src/main/java/org/dromara/wms/domain/WmsShippingBill.java @@ -205,6 +205,31 @@ public class WmsShippingBill extends TenantEntity { */ private String flowStatus; + /** + * 是否需要到货确认(1是 0否);发货类型1=普通时为1,2=备件/3=物流时为0 + */ + private String needArrivalConfirm; + + /** + * 到货标识(0全部到货 1部分到货),到货确认时填写 + */ + private String isAllReceiving; + + /** + * 到货收货单附件OSS ID,多个逗号分隔;全部到货必填,部分到货可为空 + */ + private String arrivalReceiptOssId; + + /** + * 到货确认时间 + */ + private Date arrivalConfirmTime; + + /** + * 到货确认人(申请人user_id) + */ + private Long arrivalConfirmBy; + /** * 发货状态,字典shipping_status:1待发货 2已发货 3已收货 4已完成 */ diff --git a/ruoyi-modules/ruoyi-wms/src/main/java/org/dromara/wms/domain/bo/WmsShippingBillBo.java b/ruoyi-modules/ruoyi-wms/src/main/java/org/dromara/wms/domain/bo/WmsShippingBillBo.java index 30496c84..8c2de131 100644 --- a/ruoyi-modules/ruoyi-wms/src/main/java/org/dromara/wms/domain/bo/WmsShippingBillBo.java +++ b/ruoyi-modules/ruoyi-wms/src/main/java/org/dromara/wms/domain/bo/WmsShippingBillBo.java @@ -205,6 +205,31 @@ public class WmsShippingBillBo extends BaseEntity { */ private String flowStatus; + /** + * 是否需要到货确认(1是 0否) + */ + private String needArrivalConfirm; + + /** + * 到货标识(0全部到货 1部分到货) + */ + private String isAllReceiving; + + /** + * 到货收货单附件OSS ID,多个逗号分隔;全部到货必填,部分到货可为空 + */ + private String arrivalReceiptOssId; + + /** + * 到货确认时间 + */ + private Date arrivalConfirmTime; + + /** + * 到货确认人 + */ + private Long arrivalConfirmBy; + /** * 发货状态,字典shipping_status:1待发货 2已发货 3已收货 4已完成 */ @@ -247,7 +272,7 @@ public class WmsShippingBillBo extends BaseEntity { public Map getVariables() { if (variables == null) { - return new HashMap<>(16); + variables = new HashMap<>(16); } variables.entrySet().removeIf(entry -> Objects.isNull(entry.getValue())); return variables; diff --git a/ruoyi-modules/ruoyi-wms/src/main/java/org/dromara/wms/domain/vo/WmsShippingBillVo.java b/ruoyi-modules/ruoyi-wms/src/main/java/org/dromara/wms/domain/vo/WmsShippingBillVo.java index 14bc74b0..713dd5ad 100644 --- a/ruoyi-modules/ruoyi-wms/src/main/java/org/dromara/wms/domain/vo/WmsShippingBillVo.java +++ b/ruoyi-modules/ruoyi-wms/src/main/java/org/dromara/wms/domain/vo/WmsShippingBillVo.java @@ -257,6 +257,52 @@ public class WmsShippingBillVo implements Serializable { @ExcelProperty(value = "流程状态") private String flowStatus; + /** + * 是否需要到货确认(1是 0否) + */ + @ExcelProperty(value = "是否需到货确认") + private String needArrivalConfirm; + + /** + * 到货标识(0全部到货 1部分到货) + */ + @ExcelProperty(value = "到货标识") + private String isAllReceiving; + + /** + * 到货收货单附件OSS ID + */ + @ExcelProperty(value = "到货收货单附件") + private String arrivalReceiptOssId; + + /** + * 到货确认时间 + */ + @ExcelProperty(value = "到货确认时间") + private Date arrivalConfirmTime; + + /** + * 到货确认人(申请人user_id) + */ + private Long arrivalConfirmBy; + + /** + * 到货确认人姓名(联表查询,展示用) + */ + @ExcelProperty(value = "到货确认人") + private String arrivalConfirmByName; + + /** + * 创建人(申请人) + */ + private Long createBy; + + /** + * 创建时间 + */ + @ExcelProperty(value = "创建时间") + private Date createTime; + /** * 发货状态,字典shipping_status:1待发货 2已发货 3已收货 4已完成 */ 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 616f934c..cbc07585 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 @@ -81,4 +81,5 @@ public interface IWmsShippingBillService { * @return Word模板数据Map */ java.util.Map buildWordExportData(Long shippingBillId); + } 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 aad264a5..f2de0b7d 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 @@ -20,7 +20,9 @@ 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.system.api.RemoteCodeRuleService; import org.dromara.wms.domain.WmsShippingBill; import org.dromara.wms.domain.WmsShippingDetails; import org.dromara.wms.domain.bo.WmsShippingBillBo; @@ -51,11 +53,16 @@ import java.util.stream.Collectors; @Slf4j public class WmsShippingBillServiceImpl implements IWmsShippingBillService { + private static final String SHIPPING_FLOW_CODE = "WMSSP"; + private static final String SHIPPING_BILL_CODE_RULE = "1014"; + private final WmsShippingBillMapper baseMapper; private final WmsShippingDetailsMapper detailsMapper; @DubboReference(timeout = 30000) private RemoteWorkflowService remoteWorkflowService; + @DubboReference(timeout = 30000) + private RemoteCodeRuleService remoteCodeRuleService; /** * 查询发货单(包含明细列表) @@ -108,6 +115,9 @@ public class WmsShippingBillServiceImpl implements IWmsShippingBillService { private MPJLambdaWrapper buildQueryWrapper(WmsShippingBillBo bo) { Map params = bo.getParams(); + if (params == null) { + params = new HashMap<>(4); + } MPJLambdaWrapper lqw = JoinWrappers.lambda(WmsShippingBill.class) .selectAll(WmsShippingBill.class) .eq(WmsShippingBill::getDelFlag, "0") @@ -145,9 +155,15 @@ public class WmsShippingBillServiceImpl implements IWmsShippingBillService { .eq(StringUtils.isNotBlank(bo.getOutStockBillStatus()), WmsShippingBill::getOutStockBillStatus, bo.getOutStockBillStatus()) .eq(StringUtils.isNotBlank(bo.getFlowStatus()), WmsShippingBill::getFlowStatus, bo.getFlowStatus()) .eq(StringUtils.isNotBlank(bo.getShippingStatus()), WmsShippingBill::getShippingStatus, bo.getShippingStatus()) + .eq(StringUtils.isNotBlank(bo.getNeedArrivalConfirm()), WmsShippingBill::getNeedArrivalConfirm, bo.getNeedArrivalConfirm()) + .eq(StringUtils.isNotBlank(bo.getIsAllReceiving()), WmsShippingBill::getIsAllReceiving, bo.getIsAllReceiving()) .eq(bo.getWarehouseId() != null, WmsShippingBill::getWarehouseId, bo.getWarehouseId()) .like(StringUtils.isNotBlank(bo.getWarehouseName()), WmsShippingBill::getWarehouseName, bo.getWarehouseName()) -; + .ge(params.get("beginShippingTime") != null, WmsShippingBill::getShippingTime, params.get("beginShippingTime")) + .le(params.get("endShippingTime") != null, WmsShippingBill::getShippingTime, params.get("endShippingTime")) + .ge(params.get("beginArrivalConfirmTime") != null, WmsShippingBill::getArrivalConfirmTime, params.get("beginArrivalConfirmTime")) + .le(params.get("endArrivalConfirmTime") != null, WmsShippingBill::getArrivalConfirmTime, params.get("endArrivalConfirmTime")) + .orderByDesc(WmsShippingBill::getCreateTime); return lqw; } @@ -161,10 +177,12 @@ public class WmsShippingBillServiceImpl implements IWmsShippingBillService { @Transactional(rollbackFor = Exception.class) public Boolean insertByBo(WmsShippingBillBo bo) { WmsShippingBill add = MapstructUtils.convert(bo, WmsShippingBill.class); + fillShippingCode(add); validEntityBeforeSave(add); boolean flag = baseMapper.insert(add) > 0; if (flag) { bo.setShippingBillId(add.getShippingBillId()); + bo.setShippingCode(add.getShippingCode()); // 同步保存明细列表 List detailsList = bo.getDetailsList(); if (CollUtil.isNotEmpty(detailsList)) { @@ -272,6 +290,7 @@ public class WmsShippingBillServiceImpl implements IWmsShippingBillService { /** * 提交发货单并发起流程 + * 发货前根据 shippingType 判定是否需要到货确认,并以流程变量 shippingType 驱动互斥网关分支 * * @param bo 发货单 * @return 发货单VO @@ -279,6 +298,11 @@ public class WmsShippingBillServiceImpl implements IWmsShippingBillService { @Override @Transactional(rollbackFor = Exception.class) public WmsShippingBillVo shippingBillSubmitAndFlowStart(WmsShippingBillBo bo) { + // 根据发货类型决定是否需要到货确认:1=普通发货需确认,2=备件/3=物流不需确认 + String shippingType = bo.getShippingType(); + boolean needConfirm = !"2".equals(shippingType) && !"3".equals(shippingType); + bo.setNeedArrivalConfirm(needConfirm ? "1" : "0"); + WmsShippingBill add = MapstructUtils.convert(bo, WmsShippingBill.class); validEntityBeforeSave(add); if (StringUtils.isNull(bo.getShippingBillId())) { @@ -286,19 +310,50 @@ public class WmsShippingBillServiceImpl implements IWmsShippingBillService { } else { this.updateByBo(bo); } + // Why:统一使用同一个变量Map,避免 variables 为空时多次 getVariables() 产生临时Map导致变量丢失 + Map variables = bo.getVariables(); + // 流程变量:shippingType 用于互斥网关分支条件,applicantId 兼容已有流程变量使用 + variables.put("shippingType", StringUtils.defaultIfBlank(shippingType, "1")); + variables.put("shippingCode", bo.getShippingCode()); + variables.put("applicantId", String.valueOf(LoginHelper.getUserId())); + // Why:到货确认节点配置了 ${tManagerId} 抄送表达式,发起流程时必须保证变量有效 + if (needConfirm) { + String tManagerId = StringUtils.trim(Convert.toStr(variables.get("tManagerId"))); + if (StringUtils.isBlank(tManagerId) || "null".equalsIgnoreCase(tManagerId)) { + throw new ServiceException("到货确认节点抄送人员不能为空"); + } + variables.put("tManagerId", tManagerId); + } // 后端发起需要忽略权限 - bo.getVariables().put("ignore", true); + variables.put("ignore", true); + if (StringUtils.isBlank(bo.getBizExt().getBusinessCode())) { + bo.getBizExt().setBusinessCode(bo.getShippingCode()); + } RemoteStartProcess startProcess = new RemoteStartProcess(); startProcess.setBusinessId(bo.getShippingBillId().toString()); - startProcess.setFlowCode(bo.getFlowCode()); - startProcess.setVariables(bo.getVariables()); + startProcess.setFlowCode(SHIPPING_FLOW_CODE); + startProcess.setVariables(variables); startProcess.setBizExt(bo.getBizExt()); bo.getBizExt().setBusinessId(startProcess.getBusinessId()); boolean flagOne = remoteWorkflowService.startCompleteTask(startProcess); if (!flagOne) { throw new ServiceException("流程发起异常"); } - return MapstructUtils.convert(add, WmsShippingBillVo.class); + return queryById(bo.getShippingBillId()); + } + + /** + * 新增时自动生成发货单号,避免前端生成导致并发重复与业务口径不一致。 + */ + private void fillShippingCode(WmsShippingBill entity) { + if (StringUtils.isNotBlank(entity.getShippingCode())) { + return; + } + String code = remoteCodeRuleService.selectCodeRuleCode(SHIPPING_BILL_CODE_RULE); + if (StringUtils.isBlank(code)) { + throw new ServiceException("生成发货单号失败"); + } + entity.setShippingCode(code); } /** diff --git a/ruoyi-modules/ruoyi-wms/src/main/resources/mapper/wms/WmsShippingBillMapper.xml b/ruoyi-modules/ruoyi-wms/src/main/resources/mapper/wms/WmsShippingBillMapper.xml index 896673a3..c5a77f62 100644 --- a/ruoyi-modules/ruoyi-wms/src/main/resources/mapper/wms/WmsShippingBillMapper.xml +++ b/ruoyi-modules/ruoyi-wms/src/main/resources/mapper/wms/WmsShippingBillMapper.xml @@ -7,15 +7,23 @@ - + - select t.shipping_bill_id, t.tenant_id, t.shipping_code, t.shipping_type, t.shipping_mode, t.bind_type, t.project_id, t.project_code, t.project_name, t.customer_id, t.customer_contact_id, t.customer_name, t.shipping_address, t.inventory_amount, t.source_bill_type, t.source_bill_id, t.source_bill_code, t.contract_id, t.contract_code, t.contract_name, c.order_contract_code as orderContractCode, t.supplier, t.supplier_id, t.contact_user, t.contact_number, t.receiver_name, t.receiver_phone, t.logistics_company, t.tracking_no, t.logistics_phone, t.directions, t.plan_arrival_time, t.shipping_time, t.received_time, t.completed_time, t.out_stock_bill_status, t.flow_status, t.shipping_status, t.warehouse_id, t.warehouse_name, t.remark, t.del_flag, t.create_dept, t.create_by, t.create_time, t.update_by, t.update_time + select t.shipping_bill_id, t.tenant_id, t.shipping_code, t.shipping_type, + t.shipping_mode, t.bind_type, t.project_id, t.project_code, t.project_name, + t.customer_id, t.customer_contact_id, t.customer_name, t.shipping_address, + t.inventory_amount, t.source_bill_type, t.source_bill_id, t.source_bill_code, + t.contract_id, t.contract_code, t.contract_name, + c.order_contract_code as orderContractCode, + t.supplier, t.supplier_id, t.contact_user, t.contact_number, t.receiver_name, t.receiver_phone, + t.logistics_company, t.tracking_no, t.logistics_phone, t.directions, + t.plan_arrival_time, t.shipping_time, t.received_time, t.completed_time, + t.out_stock_bill_status, t.flow_status, + t.need_arrival_confirm, t.is_all_receiving, t.arrival_receipt_oss_id, t.arrival_confirm_time, t.arrival_confirm_by, + u.nick_name as arrivalConfirmByName, + t.shipping_status, t.warehouse_id, t.warehouse_name, t.remark, + t.del_flag, t.create_dept, t.create_by, t.create_time, t.update_by, t.update_time from wms_shipping_bill t left join erp_contract_info c on t.contract_id = c.contract_id + left join sys_user u on t.arrival_confirm_by = u.user_id AND ${ew.sqlSegment}