From 1580ff9bf4f8089035add99513505759427dc64a Mon Sep 17 00:00:00 2001 From: canonical Date: Sun, 3 Dec 2023 21:42:44 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E5=8A=A8=E6=80=81=E5=AE=9E?= =?UTF-8?q?=E4=BD=93=E6=94=AF=E6=8C=81=EF=BC=8C=E6=B5=8B=E8=AF=95=E9=80=9A?= =?UTF-8?q?=E8=BF=87TestBeeflowCase?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AutoTestCaseDataBaseInitializer.java | 2 +- .../orm/persister/EntityPersisterImpl.java | 4 ++- .../java/io/nop/orm/sql/GenSqlHelper.java | 2 +- .../orm/support/DynamicOrmKeyValueTable.java | 4 +-- .../resources/_vfs/nop/orm/xlib/orm-gen.xlib | 4 ++- nop-wf/deploy/sql/mysql/_create_nop-wf.sql | 6 ++-- nop-wf/deploy/sql/oracle/_create_nop-wf.sql | 6 ++-- .../deploy/sql/postgresql/_create_nop-wf.sql | 6 ++-- nop-wf/model/nop-wf.orm.xlsx | Bin 73452 -> 73448 bytes .../java/io/nop/wf/core/IWorkflowStep.java | 24 +++++++++++++--- .../nop/wf/core/engine/IWorkflowEngine.java | 2 ++ .../wf/core/engine/WorkflowEngineImpl.java | 27 ++++++++++++++---- .../io/nop/wf/core/impl/WorkflowStepImpl.java | 14 ++++++--- .../core/model/_gen/_WfTransitionModel.java | 4 +-- .../main/resources/_vfs/nop/wf/base/oa.xwf | 4 +++ .../resources/_vfs/nop/wf/orm/_app.orm.xml | 14 ++++----- .../testSalaryAdjustment/autotest.yaml | 0 .../input/tables/nop_auth_role.csv | 1 + .../input/tables/nop_auth_user.csv | 1 + .../input/tables/nop_auth_user_role.csv | 1 + .../output/tables/nop_auth_dept.csv | 3 ++ .../output/tables/nop_auth_role.csv | 2 ++ .../output/tables/nop_auth_user.csv | 6 ++++ .../output/tables/nop_auth_user_role.csv | 2 ++ .../output/tables/nop_wf_action.csv | 3 ++ .../output/tables/nop_wf_dyn_entity.csv | 2 ++ .../output/tables/nop_wf_dyn_entity_ext.csv | 4 +++ .../output/tables/nop_wf_instance.csv | 2 ++ .../output/tables/nop_wf_status_history.csv | 3 ++ .../output/tables/nop_wf_step_instance.csv | 5 ++++ .../tables/nop_wf_step_instance_link.csv | 5 ++++ .../io/nop/wf/service/TestBeeflowCase.java | 12 +++++--- .../java/io/nop/wf/service/WfTestHelper.java | 15 ++++++---- .../_delta/default/nop/wf/orm/app.orm.xml | 2 +- .../nop/wf/beeflow/payment-application/v1.xwf | 4 +++ .../nop/wf/beeflow/salary-adjustment/v1.xwf | 4 +-- .../main/resources/_vfs/nop/schema/wf/wf.xdef | 4 +-- .../tags/FilterBeanExpressionCompiler.java | 10 ++++++- 38 files changed, 162 insertions(+), 52 deletions(-) create mode 100644 nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/autotest.yaml create mode 100644 nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/input/tables/nop_auth_role.csv create mode 100644 nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/input/tables/nop_auth_user.csv create mode 100644 nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/input/tables/nop_auth_user_role.csv create mode 100644 nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_auth_dept.csv create mode 100644 nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_auth_role.csv create mode 100644 nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_auth_user.csv create mode 100644 nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_auth_user_role.csv create mode 100644 nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_wf_action.csv create mode 100644 nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_wf_dyn_entity.csv create mode 100644 nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_wf_dyn_entity_ext.csv create mode 100644 nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_wf_instance.csv create mode 100644 nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_wf_status_history.csv create mode 100644 nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_wf_step_instance.csv create mode 100644 nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_wf_step_instance_link.csv diff --git a/nop-autotest/nop-autotest-core/src/main/java/io/nop/autotest/core/execute/AutoTestCaseDataBaseInitializer.java b/nop-autotest/nop-autotest-core/src/main/java/io/nop/autotest/core/execute/AutoTestCaseDataBaseInitializer.java index 440303017..e96fd884f 100644 --- a/nop-autotest/nop-autotest-core/src/main/java/io/nop/autotest/core/execute/AutoTestCaseDataBaseInitializer.java +++ b/nop-autotest/nop-autotest-core/src/main/java/io/nop/autotest/core/execute/AutoTestCaseDataBaseInitializer.java @@ -105,7 +105,7 @@ void createTable(IDialect dialect, IEntityModel entityModel) { jdbcTemplate.executeUpdate(new SQL(sql)); } catch (NopException e) { if (e.getErrorCode().equals(DaoErrors.ERR_SQL_BAD_SQL_GRAMMAR.getErrorCode())) { - LOG.debug("nop.create-table-fail:{}", e); + LOG.debug("nop.create-table-fail:{}", entityModel.getTableName(), e); return; } LOG.error("nop.create-table-fail:{}", entityModel.getTableName(), e); diff --git a/nop-orm/src/main/java/io/nop/orm/persister/EntityPersisterImpl.java b/nop-orm/src/main/java/io/nop/orm/persister/EntityPersisterImpl.java index 911a4db68..dbb797d98 100644 --- a/nop-orm/src/main/java/io/nop/orm/persister/EntityPersisterImpl.java +++ b/nop-orm/src/main/java/io/nop/orm/persister/EntityPersisterImpl.java @@ -119,8 +119,10 @@ public void generateId(IOrmEntity entity) { @Override public IOrmEntity newEntity(IOrmSessionImplementor session) { IOrmEntity entity = (IOrmEntity) constructor.newInstance(); - entity.orm_attach(session); + entity.orm_entityModel(entityModel); + // 需要在attach之前设置值,否则实体会被标记为dirty bindFilter(entity); + entity.orm_attach(session); return entity; } diff --git a/nop-orm/src/main/java/io/nop/orm/sql/GenSqlHelper.java b/nop-orm/src/main/java/io/nop/orm/sql/GenSqlHelper.java index aa05a4f66..96cbc9825 100644 --- a/nop-orm/src/main/java/io/nop/orm/sql/GenSqlHelper.java +++ b/nop-orm/src/main/java/io/nop/orm/sql/GenSqlHelper.java @@ -618,7 +618,7 @@ private static void addFixedFilter(boolean prependAnd, SQL.SqlBuilder sb, IDiale if (prependAnd) sb.and(); OrmColumnModel col = filter.getColumn(); - appendEq(sb, dialect, owner, col, binders[col.getPropId()], filter.getValue()); + appendEq(sb, dialect, owner, col, null, filter.getValue()); if (!prependAnd) sb.and(); }); diff --git a/nop-orm/src/main/java/io/nop/orm/support/DynamicOrmKeyValueTable.java b/nop-orm/src/main/java/io/nop/orm/support/DynamicOrmKeyValueTable.java index 3f1c03c4e..bcc4ddaac 100644 --- a/nop-orm/src/main/java/io/nop/orm/support/DynamicOrmKeyValueTable.java +++ b/nop-orm/src/main/java/io/nop/orm/support/DynamicOrmKeyValueTable.java @@ -24,14 +24,14 @@ public void setFieldName(String fieldName) { @Override public Integer getFieldType() { - int propId = orm_propId(OrmConstants.PROP_NAME_fieldName); + int propId = orm_propId(OrmConstants.PROP_NAME_fieldType); return ConvertHelper.toInteger(orm_propValue(propId), err -> this.newError(err).param(ARG_PROP_NAME, OrmConstants.PROP_NAME_fieldType)); } @Override public void setFieldType(Integer fieldType) { - int propId = orm_propId(OrmConstants.PROP_NAME_fieldName); + int propId = orm_propId(OrmConstants.PROP_NAME_fieldType); orm_propValue(propId, fieldType); } diff --git a/nop-orm/src/main/resources/_vfs/nop/orm/xlib/orm-gen.xlib b/nop-orm/src/main/resources/_vfs/nop/orm/xlib/orm-gen.xlib index 1bdb94f2a..113e6c590 100644 --- a/nop-orm/src/main/resources/_vfs/nop/orm/xlib/orm-gen.xlib +++ b/nop-orm/src/main/resources/_vfs/nop/orm/xlib/orm-gen.xlib @@ -195,7 +195,9 @@ diff --git a/nop-wf/deploy/sql/mysql/_create_nop-wf.sql b/nop-wf/deploy/sql/mysql/_create_nop-wf.sql index 9a10e3a51..413a1ed9f 100644 --- a/nop-wf/deploy/sql/mysql/_create_nop-wf.sql +++ b/nop-wf/deploy/sql/mysql/_create_nop-wf.sql @@ -119,11 +119,11 @@ CREATE TABLE nop_wf_dyn_entity( OBJ_TYPE VARCHAR(100) NOT NULL COMMENT '对象类型', NAME VARCHAR(100) NOT NULL COMMENT '名称', DISPLAY_NAME VARCHAR(500) NULL COMMENT '显示名称', - SORT_ORDER INTEGER NOT NULL COMMENT '排序', + SORT_ORDER INTEGER NULL COMMENT '排序', NOP_FLOW_ID VARCHAR(32) NULL COMMENT '工作流实例ID', - BIZ_STATUS INTEGER NOT NULL COMMENT '业务状态码', + BIZ_STATUS INTEGER NULL COMMENT '业务状态码', BIZ_STATE VARCHAR(50) NULL COMMENT '业务状态', - PARENT_ID VARCHAR(32) NOT NULL COMMENT '父ID', + PARENT_ID VARCHAR(32) NULL COMMENT '父ID', OWNER_NAME VARCHAR(50) NULL COMMENT '拥有者姓名', OWNER_ID VARCHAR(50) NULL COMMENT '拥有者ID', DEPT_ID VARCHAR(50) NULL COMMENT '部门ID', diff --git a/nop-wf/deploy/sql/oracle/_create_nop-wf.sql b/nop-wf/deploy/sql/oracle/_create_nop-wf.sql index 171d47810..80cc5d901 100644 --- a/nop-wf/deploy/sql/oracle/_create_nop-wf.sql +++ b/nop-wf/deploy/sql/oracle/_create_nop-wf.sql @@ -119,11 +119,11 @@ CREATE TABLE nop_wf_dyn_entity( OBJ_TYPE VARCHAR2(100) NOT NULL , NAME VARCHAR2(100) NOT NULL , DISPLAY_NAME VARCHAR2(500) , - SORT_ORDER INTEGER NOT NULL , + SORT_ORDER INTEGER , NOP_FLOW_ID VARCHAR2(32) , - BIZ_STATUS INTEGER NOT NULL , + BIZ_STATUS INTEGER , BIZ_STATE VARCHAR2(50) , - PARENT_ID VARCHAR2(32) NOT NULL , + PARENT_ID VARCHAR2(32) , OWNER_NAME VARCHAR2(50) , OWNER_ID VARCHAR2(50) , DEPT_ID VARCHAR2(50) , diff --git a/nop-wf/deploy/sql/postgresql/_create_nop-wf.sql b/nop-wf/deploy/sql/postgresql/_create_nop-wf.sql index 45fe07adf..c4ba25dcf 100644 --- a/nop-wf/deploy/sql/postgresql/_create_nop-wf.sql +++ b/nop-wf/deploy/sql/postgresql/_create_nop-wf.sql @@ -119,11 +119,11 @@ CREATE TABLE nop_wf_dyn_entity( OBJ_TYPE VARCHAR(100) NOT NULL , NAME VARCHAR(100) NOT NULL , DISPLAY_NAME VARCHAR(500) , - SORT_ORDER INT4 NOT NULL , + SORT_ORDER INT4 , NOP_FLOW_ID VARCHAR(32) , - BIZ_STATUS INT4 NOT NULL , + BIZ_STATUS INT4 , BIZ_STATE VARCHAR(50) , - PARENT_ID VARCHAR(32) NOT NULL , + PARENT_ID VARCHAR(32) , OWNER_NAME VARCHAR(50) , OWNER_ID VARCHAR(50) , DEPT_ID VARCHAR(50) , diff --git a/nop-wf/model/nop-wf.orm.xlsx b/nop-wf/model/nop-wf.orm.xlsx index 82a548b1c068e6b8aed543f117ef5d301c07183a..48df07c2fe73241f8de3b8d03c9823cfa2f41f11 100644 GIT binary patch delta 17576 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 Ryg2=^9HTOup#)G70|0L7l{)|c delta 17737 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 NopWfCoreConstants.WF_STEP_STATUS_HISTORY_BOUND; + return getRecord().isHistory(); } default boolean isWaiting() { - return getStepStatus() == NopWfCoreConstants.WF_STEP_STATUS_WAITING; + return getRecord().isWaiting(); } default boolean isActivated() { - return getStepStatus() == NopWfCoreConstants.WF_STEP_STATUS_ACTIVATED; + return getRecord().isActivated(); } default boolean isSuspended() { @@ -137,7 +137,23 @@ default boolean isFlowType() { void kill(Map args, IServiceContext ctx); - void triggerTransition(Map args, IServiceContext ctx); + /** + * 对于状态处于activated的步骤,触发transition迁移 + * + * @param args 输入参数 + * @param ctx 执行上下文 + * @return 返回true表示发生了迁移 + */ + boolean triggerTransition(Map args, IServiceContext ctx); + + /** + * 检查步骤状态是否可以从waiting转换为activated + * + * @param args 输入参数 + * @param ctx 执行上下文 + * @return 返回true表示状态发生了变化 + */ + boolean triggerWaiting(Map args, IServiceContext ctx); void notifySubFlowEnd(int status, Map results, IServiceContext ctx); diff --git a/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/engine/IWorkflowEngine.java b/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/engine/IWorkflowEngine.java index aa2e851d9..c7d9fb4d3 100644 --- a/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/engine/IWorkflowEngine.java +++ b/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/engine/IWorkflowEngine.java @@ -64,6 +64,8 @@ public interface IWorkflowEngine { boolean triggerTransition(IWorkflowStepImplementor step, Map args, IServiceContext ctx); + boolean triggerWaiting(IWorkflowStepImplementor step, Map args, IServiceContext ctx); + void notifySubFlowEnd(IWorkflowStepImplementor step, int status, Map args, IServiceContext ctx); boolean isAllowCall(IWorkflowStepImplementor step, IServiceContext ctx); diff --git a/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/engine/WorkflowEngineImpl.java b/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/engine/WorkflowEngineImpl.java index 273e836c0..09087309d 100644 --- a/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/engine/WorkflowEngineImpl.java +++ b/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/engine/WorkflowEngineImpl.java @@ -227,10 +227,16 @@ private Map removeStdStartParam(Map args, IWorkf wfRecord.setBizObjName(bizObjName); String bizEntityId = (String) args.remove(NopWfCoreConstants.PARAM_BIZ_OBJ_ID); - wfRecord.setBizObjId(bizEntityId); + if (!StringHelper.isEmpty(bizEntityId)) { + //VarCollector.instance().collectVar("NopWfInstance@bizEntityId",bizEntityId); + wfRecord.setBizObjId(bizEntityId); + } String bizKey = (String) args.remove(NopWfCoreConstants.PARAM_BIZ_KEY); - wfRecord.setBizKey(bizKey); + if (!StringHelper.isEmpty(bizKey)) { + //VarCollector.instance().collectVar("NopWfInstance@bizKey",bizKey); + wfRecord.setBizKey(bizKey); + } return args; } @@ -359,6 +365,11 @@ protected IWorkflowStepImplementor newStepForActor(String stepGroup, Double exec wf.getStore().addNextStepRecord(currentStep.getRecord(), fromAction, step.getRecord()); } + // 处于等待状态的join步骤,新增加上游步骤之后需要检查是否可以转入激活状态 + if (stepModel.getJoinType() != null && step.isWaiting()) { + wfRt.delayExecute(() -> checkWaitingJoinStep(step, wfRt)); + } + return step; } @@ -762,8 +773,8 @@ private boolean runStepAutoTransition(IWorkflowStepImplementor step, WfRuntime w Set onStates = stepModel.getTransition().getOnAppStates(); if (onStates != null && !onStates.isEmpty()) { if (!onStates.contains(step.getRecord().getAppState())) { - LOG.info("nop.wf.step-not-allow-transition-when-state-not-ready:state={},onStates={}", - step.getRecord().getAppState(), onStates); + LOG.info("nop.wf.step-not-allow-transition-when-state-not-ready:stepName={},state={},onStates={},wfName={},wfId={}", + step.getModel().getName(), step.getRecord().getAppState(), onStates, wfRt.getWf().getWfName(), wfRt.getWf().getWfId()); return false; } } @@ -878,10 +889,16 @@ void _killStep(IWorkflowStepImplementor step, WfRuntime wfRt) { public boolean triggerTransition(IWorkflowStepImplementor step, Map args, IServiceContext ctx) { WfRuntime wfRt = newWfRuntime(step, ctx); initArgs(wfRt, args); - checkWaitingStep(step, wfRt); return runStepAutoTransition(step, wfRt); } + @Override + public boolean triggerWaiting(IWorkflowStepImplementor step, Map args, IServiceContext ctx) { + WfRuntime wfRt = newWfRuntime(step, ctx); + initArgs(wfRt, args); + return checkWaitingStep(step, wfRt); + } + @Override public void notifySubFlowEnd(IWorkflowStepImplementor step, int status, Map results, IServiceContext ctx) { diff --git a/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/impl/WorkflowStepImpl.java b/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/impl/WorkflowStepImpl.java index c49603070..8729016c3 100644 --- a/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/impl/WorkflowStepImpl.java +++ b/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/impl/WorkflowStepImpl.java @@ -176,10 +176,16 @@ public void kill(Map args, IServiceContext ctx) { } @Override - public void triggerTransition(Map args, IServiceContext ctx) { - wf.executeNow(() -> { - wf.getEngine().triggerTransition(this, args, ctx); - return null; + public boolean triggerTransition(Map args, IServiceContext ctx) { + return wf.executeNow(() -> { + return wf.getEngine().triggerTransition(this, args, ctx); + }); + } + + @Override + public boolean triggerWaiting(Map args, IServiceContext ctx) { + return wf.executeNow(() -> { + return wf.getEngine().triggerWaiting(this, args, ctx); }); } diff --git a/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/model/_gen/_WfTransitionModel.java b/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/model/_gen/_WfTransitionModel.java index 6a998498a..2f018fd27 100644 --- a/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/model/_gen/_WfTransitionModel.java +++ b/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/model/_gen/_WfTransitionModel.java @@ -38,7 +38,7 @@ public abstract class _WfTransitionModel extends io.nop.core.resource.component. /** * * xml name: splitType - * 分支类型,and表示每个分支都执行,or表示从上至下执行,只执行第一个满足条件的迁移目标。 + * 分支类型,and表示每个分支都执行,or表示从上至下执行,只执行第一个满足条件的迁移目标。缺省为and */ private io.nop.wf.core.model.WfSplitType _splitType ; @@ -137,7 +137,7 @@ public void setOnAppStates(java.util.Set value){ /** * * xml name: splitType - * 分支类型,and表示每个分支都执行,or表示从上至下执行,只执行第一个满足条件的迁移目标。 + * 分支类型,and表示每个分支都执行,or表示从上至下执行,只执行第一个满足条件的迁移目标。缺省为and */ public io.nop.wf.core.model.WfSplitType getSplitType(){ diff --git a/nop-wf/nop-wf-core/src/main/resources/_vfs/nop/wf/base/oa.xwf b/nop-wf/nop-wf-core/src/main/resources/_vfs/nop/wf/base/oa.xwf index ce24ba91d..51e8bc95d 100644 --- a/nop-wf/nop-wf-core/src/main/resources/_vfs/nop/wf/base/oa.xwf +++ b/nop-wf/nop-wf-core/src/main/resources/_vfs/nop/wf/base/oa.xwf @@ -2,6 +2,10 @@ + + + + diff --git a/nop-wf/nop-wf-dao/src/main/resources/_vfs/nop/wf/orm/_app.orm.xml b/nop-wf/nop-wf-dao/src/main/resources/_vfs/nop/wf/orm/_app.orm.xml index 01551ec5c..5c8945cfd 100644 --- a/nop-wf/nop-wf-dao/src/main/resources/_vfs/nop/wf/orm/_app.orm.xml +++ b/nop-wf/nop-wf-dao/src/main/resources/_vfs/nop/wf/orm/_app.orm.xml @@ -200,11 +200,11 @@ + stdDataType="string" stdSqlType="VARCHAR" tagSet="var" i18n-en:displayName="BizKey"/> + stdDataType="string" stdSqlType="VARCHAR" tagSet="var" i18n-en:displayName="BizObjId"/> - + - + - diff --git a/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/autotest.yaml b/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/autotest.yaml new file mode 100644 index 000000000..e69de29bb diff --git a/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/input/tables/nop_auth_role.csv b/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/input/tables/nop_auth_role.csv new file mode 100644 index 000000000..69060e915 --- /dev/null +++ b/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/input/tables/nop_auth_role.csv @@ -0,0 +1 @@ +ROLE_ID,ROLE_NAME,CHILD_ROLE_IDS,IS_PRIMARY,DEL_FLAG,VERSION,CREATED_BY,CREATE_TIME,UPDATED_BY,UPDATE_TIME,REMARK diff --git a/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/input/tables/nop_auth_user.csv b/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/input/tables/nop_auth_user.csv new file mode 100644 index 000000000..5e5ee4612 --- /dev/null +++ b/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/input/tables/nop_auth_user.csv @@ -0,0 +1 @@ +USER_ID,USER_NAME,PASSWORD,SALT,NICK_NAME,DEPT_ID,OPEN_ID,REL_DEPT_ID,GENDER,AVATAR,EMAIL,EMAIL_VERIFIED,PHONE,PHONE_VERIFIED,BIRTHDAY,USER_TYPE,STATUS,ID_TYPE,ID_NBR,EXPIRE_AT,PWD_UPDATE_TIME,CHANGE_PWD_AT_LOGIN,REAL_NAME,MANAGER_ID,WORK_NO,POSITION_ID,TELEPHONE,CLIENT_ID,DEL_FLAG,VERSION,TENANT_ID,CREATED_BY,CREATE_TIME,UPDATED_BY,UPDATE_TIME,REMARK diff --git a/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/input/tables/nop_auth_user_role.csv b/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/input/tables/nop_auth_user_role.csv new file mode 100644 index 000000000..664791ddf --- /dev/null +++ b/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/input/tables/nop_auth_user_role.csv @@ -0,0 +1 @@ +USER_ID,ROLE_ID,VERSION,CREATED_BY,CREATE_TIME,UPDATED_BY,UPDATE_TIME,REMARK diff --git a/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_auth_dept.csv b/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_auth_dept.csv new file mode 100644 index 000000000..bc9bdcfe4 --- /dev/null +++ b/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_auth_dept.csv @@ -0,0 +1,3 @@ +_chgType,DEPT_ID,DEPT_NAME,PARENT_ID,ORDER_NUM,DEPT_TYPE,MANAGER_ID,EMAIL,PHONE,DEL_FLAG,VERSION,CREATED_BY,CREATE_TIME,UPDATED_BY,UPDATE_TIME,REMARK +A,@var:NopAuthDept@deptId,dept_a,@var:NopAuthDept@deptId_1,,,@var:NopAuthUser@userId_2,,,0,0,autotest-ref,*,autotest-ref,*, +A,@var:NopAuthDept@deptId_1,dept_b,,,,@var:NopAuthUser@userId_4,,,0,0,autotest-ref,*,autotest-ref,*, diff --git a/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_auth_role.csv b/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_auth_role.csv new file mode 100644 index 000000000..1e7532fe4 --- /dev/null +++ b/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_auth_role.csv @@ -0,0 +1,2 @@ +_chgType,ROLE_ID,ROLE_NAME,CHILD_ROLE_IDS,IS_PRIMARY,DEL_FLAG,VERSION,CREATED_BY,CREATE_TIME,UPDATED_BY,UPDATE_TIME,REMARK +A,manager,manager,,,0,0,autotest-ref,*,autotest-ref,*, diff --git a/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_auth_user.csv b/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_auth_user.csv new file mode 100644 index 000000000..14a2566ae --- /dev/null +++ b/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_auth_user.csv @@ -0,0 +1,6 @@ +_chgType,USER_ID,USER_NAME,PASSWORD,SALT,NICK_NAME,DEPT_ID,OPEN_ID,REL_DEPT_ID,GENDER,AVATAR,EMAIL,EMAIL_VERIFIED,PHONE,PHONE_VERIFIED,BIRTHDAY,USER_TYPE,STATUS,ID_TYPE,ID_NBR,EXPIRE_AT,PWD_UPDATE_TIME,CHANGE_PWD_AT_LOGIN,REAL_NAME,MANAGER_ID,WORK_NO,POSITION_ID,TELEPHONE,CLIENT_ID,DEL_FLAG,VERSION,TENANT_ID,CREATED_BY,CREATE_TIME,UPDATED_BY,UPDATE_TIME,REMARK +A,@var:NopAuthUser@userId,user_1,@var:NopAuthUser@password,,user_1,@var:NopAuthDept@deptId,@var:NopAuthUser@openId,,1,,,,,0,,1,1,,,,,,,@var:NopAuthUser@userId_1,,,,,0,0,0,autotest-ref,*,autotest-ref,*, +A,@var:NopAuthUser@userId_1,user_2,@var:NopAuthUser@password,,user_2,@var:NopAuthDept@deptId,@var:NopAuthUser@openId_1,,1,,,,,0,,1,1,,,,,,,@var:NopAuthUser@userId_2,,,,,0,0,0,autotest-ref,*,autotest-ref,*, +A,@var:NopAuthUser@userId_2,user_3,@var:NopAuthUser@password,,user_3,@var:NopAuthDept@deptId,@var:NopAuthUser@openId_2,,1,,,,,0,,1,1,,,,,,,@var:NopAuthUser@userId_4,,,,,0,0,0,autotest-ref,*,autotest-ref,*, +A,@var:NopAuthUser@userId_3,user_4,@var:NopAuthUser@password,,user_4,@var:NopAuthDept@deptId_1,@var:NopAuthUser@openId_3,,1,,,,,0,,1,1,,,,,,,,,,,,0,0,0,autotest-ref,*,autotest-ref,*, +A,@var:NopAuthUser@userId_4,user_5,@var:NopAuthUser@password,,user_5,@var:NopAuthDept@deptId_1,@var:NopAuthUser@openId_4,,1,,,,,0,,1,1,,,,,,,,,,,,0,0,0,autotest-ref,*,autotest-ref,*, diff --git a/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_auth_user_role.csv b/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_auth_user_role.csv new file mode 100644 index 000000000..81732f3bb --- /dev/null +++ b/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_auth_user_role.csv @@ -0,0 +1,2 @@ +_chgType,USER_ID,ROLE_ID,VERSION,CREATED_BY,CREATE_TIME,UPDATED_BY,UPDATE_TIME,REMARK +A,@var:NopAuthUser@userId_4,manager,0,autotest-ref,*,autotest-ref,*, diff --git a/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_wf_action.csv b/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_wf_action.csv new file mode 100644 index 000000000..dcdbcc4fb --- /dev/null +++ b/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_wf_action.csv @@ -0,0 +1,3 @@ +_chgType,SID,WF_ID,STEP_ID,ACTION_NAME,DISPLAY_NAME,EXEC_TIME,CALLER_ID,CALLER_NAME,OPINION,ERR_CODE,ERR_MSG,VERSION,CREATED_BY,CREATE_TIME,UPDATED_BY,UPDATE_TIME +A,@var:NopWfAction@sid_1,@var:NopWfInstance@wfId,@var:NopWfStepInstance@stepId_3,agree,同意,@var:NopWfAction@execTime_1,5,user_5,,,,0,autotest-ref,*,autotest-ref,* +A,@var:NopWfAction@sid,@var:NopWfInstance@wfId,@var:NopWfStepInstance@stepId_1,agree,同意,@var:NopWfAction@execTime,2,user_2,,,,0,autotest-ref,*,autotest-ref,* diff --git a/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_wf_dyn_entity.csv b/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_wf_dyn_entity.csv new file mode 100644 index 000000000..a9a57ef9b --- /dev/null +++ b/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_wf_dyn_entity.csv @@ -0,0 +1,2 @@ +_chgType,SID,OBJ_TYPE,NAME,DISPLAY_NAME,SORT_ORDER,NOP_FLOW_ID,BIZ_STATUS,BIZ_STATE,PARENT_ID,OWNER_NAME,OWNER_ID,DEPT_ID,STRING_FLD1,DECIMAL_FLD1,INT_FLD1,LONG_FLD1,DATE_FLD1,TIMESTAMP_FLD1,FILE_FLD1,STRING_FLD2,DECIMAL_FLD2,INT_FLD2,LONG_FLD2,DATE_FLD2,TIMESTAMP_FLD2,FILE_FLD2,VERSION,CREATED_BY,CREATE_TIME,UPDATED_BY,UPDATE_TIME,REMARK +A,@var:AppDynSalaryAdjustment@sid,AppDynSalaryAdjustment,abc,,,@var:NopWfInstance@wfId,,,,,,,,,,,,,,,,,,,,,0,autotest-ref,*,autotest-ref,*, diff --git a/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_wf_dyn_entity_ext.csv b/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_wf_dyn_entity_ext.csv new file mode 100644 index 000000000..78e0a6801 --- /dev/null +++ b/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_wf_dyn_entity_ext.csv @@ -0,0 +1,4 @@ +_chgType,ENTITY_ID,FIELD_NAME,FIELD_TYPE,DECIMAL_SCALE,DECIMAL_VALUE,DATE_VALUE,TIMESTAMP_VALUE,STRING_VALUE,VERSION,CREATED_BY,CREATE_TIME,UPDATED_BY,UPDATE_TIME,REMARK +A,@var:AppDynSalaryAdjustment@sid,employeeId,11,,,,,100,0,autotest-ref,*,autotest-ref,*, +A,@var:AppDynSalaryAdjustment@sid,salary1,8,,30000.0,,,,0,autotest-ref,*,autotest-ref,*, +A,@var:AppDynSalaryAdjustment@sid,salary2,8,,40000.0,,,,0,autotest-ref,*,autotest-ref,*, diff --git a/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_wf_instance.csv b/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_wf_instance.csv new file mode 100644 index 000000000..ba3d1801b --- /dev/null +++ b/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_wf_instance.csv @@ -0,0 +1,2 @@ +_chgType,WF_ID,WF_NAME,WF_VERSION,WF_PARAMS,WF_GROUP,WORK_SCOPE,TITLE,STATUS,APP_STATE,START_TIME,END_TIME,DUE_TIME,BIZ_KEY,BIZ_OBJ_NAME,BIZ_OBJ_ID,PARENT_WF_NAME,PARENT_WF_VERSION,PARENT_WF_ID,PARENT_STEP_ID,STARTER_ID,STARTER_NAME,STARTER_DEPT_ID,LAST_OPERATOR_ID,LAST_OPERATOR_NAME,LAST_OPERATOR_DEPT_ID,LAST_OPERATE_TIME,MANAGER_TYPE,MANAGER_DEPT_ID,MANAGER_NAME,MANAGER_ID,PRIORITY,SIGNAL_TEXT,TAG_TEXT,VERSION,CREATED_BY,CREATE_TIME,UPDATED_BY,UPDATE_TIME,REMARK +A,@var:NopWfInstance@wfId,beeflow/salary-adjustment,1,,default,,beeflow/salary-adjustment,40,agree,@var:NopWfInstance@startTime,@var:NopWfInstance@endTime,,,AppDynSalaryAdjustment,@var:NopWfInstance@bizObjId,,,,,1,user_1,a,5,user_5,b,@var:NopWfInstance@lastOperateTime,,,,,100,,,0,autotest-ref,*,autotest-ref,*, diff --git a/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_wf_status_history.csv b/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_wf_status_history.csv new file mode 100644 index 000000000..eb91a1e87 --- /dev/null +++ b/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_wf_status_history.csv @@ -0,0 +1,3 @@ +_chgType,SID,WF_ID,FROM_STATUS,TO_STATUS,TO_APP_STATE,CHANGE_TIME,OPERATOR_ID,OPERATOR_NAME,OPERATOR_DEPT_ID,VERSION,CREATED_BY,CREATE_TIME +A,@var:NopWfStatusHistory@sid,@var:NopWfInstance@wfId,0,30,,@var:NopWfStatusHistory@changeTime,1,user_1,a,0,autotest-ref,* +A,@var:NopWfStatusHistory@sid_1,@var:NopWfInstance@wfId,30,40,agree,@var:NopWfStatusHistory@changeTime_1,5,user_5,b,0,autotest-ref,* diff --git a/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_wf_step_instance.csv b/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_wf_step_instance.csv new file mode 100644 index 000000000..f310c9937 --- /dev/null +++ b/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_wf_step_instance.csv @@ -0,0 +1,5 @@ +_chgType,STEP_ID,WF_ID,STEP_TYPE,STEP_NAME,DISPLAY_NAME,STATUS,APP_STATE,SUB_WF_ID,SUB_WF_NAME,SUB_WF_VERSION,SUB_WF_RESULT_STATUS,IS_READ,ACTOR_MODEL_ID,ACTOR_TYPE,ACTOR_ID,ACTOR_DEPT_ID,ACTOR_NAME,OWNER_ID,OWNER_NAME,OWNER_DEPT_ID,ASSIGNER_ID,ASSIGNER_NAME,CALLER_ID,CALLER_NAME,CANCELLER_ID,CANCELLER_NAME,FROM_ACTION,LAST_ACTION,START_TIME,FINISH_TIME,DUE_TIME,READ_TIME,REMIND_TIME,REMIND_COUNT,NEXT_RETRY_TIME,RETRY_COUNT,ERR_CODE,ERR_MSG,PRIORITY,VOTE_WEIGHT,EXEC_ORDER,JOIN_GROUP,TAG_TEXT,NEXT_STEP_ID,STEP_GROUP,VERSION,CREATED_BY,CREATE_TIME,UPDATED_BY,UPDATE_TIME,REMARK +A,@var:NopWfStepInstance@stepId_1,@var:NopWfInstance@wfId,step,approve1,审批人1,40,agree,,,,,,m1,user,2,a,user_2,2,user_2,,,,2,user_2,,,_transit_,agree,,@var:NopWfStepInstance@finishTime_1,,,,,,,,,100,1,0.0,,,,@var:NopWfStepInstance@stepGroup_1,0,autotest-ref,*,autotest-ref,*, +A,@var:NopWfStepInstance@stepId,@var:NopWfInstance@wfId,step,start,发起人,40,,,,,,,m1,user,1,a,user_1,1,user_1,,,,,,,,_start_,,,@var:NopWfStepInstance@finishTime,,,,,,,,,100,1,0.0,,,,@var:NopWfStepInstance@stepGroup,0,autotest-ref,*,autotest-ref,*, +A,@var:NopWfStepInstance@stepId_2,@var:NopWfInstance@wfId,join,approve-join,合并,40,,,,,,,,user,0,,SYS,0,SYS,,,,,,,,_transit_,,,@var:NopWfStepInstance@finishTime_2,,,,,,,,,100,1,0.0,,,,@var:NopWfStepInstance@stepGroup_2,0,autotest-ref,*,autotest-ref,*, +A,@var:NopWfStepInstance@stepId_3,@var:NopWfInstance@wfId,step,approve22,审批人22,40,agree,,,,,,m1,role,manager,,manager,,,,,,5,user_5,,,_transit_,agree,,@var:NopWfStepInstance@finishTime_3,,,,,,,,,100,1,0.0,,,,@var:NopWfStepInstance@stepGroup_3,0,autotest-ref,*,autotest-ref,*, diff --git a/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_wf_step_instance_link.csv b/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_wf_step_instance_link.csv new file mode 100644 index 000000000..8205b5c6f --- /dev/null +++ b/nop-wf/nop-wf-service/cases/io/nop/wf/service/TestBeeflowCase/testSalaryAdjustment/output/tables/nop_wf_step_instance_link.csv @@ -0,0 +1,5 @@ +_chgType,WF_ID,STEP_ID,NEXT_STEP_ID,EXEC_ACTION,CREATED_BY,CREATE_TIME +A,@var:NopWfInstance@wfId,@var:NopWfStepInstance@stepId_1,@var:NopWfStepInstance@stepId_2,_transit_,autotest-ref,* +A,@var:NopWfInstance@wfId,@var:NopWfStepInstance@stepId,@var:NopWfStepInstance@stepId_1,_transit_,autotest-ref,* +A,@var:NopWfInstance@wfId,@var:NopWfStepInstance@stepId_2,@var:NopWfStepInstance@stepId_3,_transit_,autotest-ref,* +A,@var:NopWfInstance@wfId,@var:NopWfStepInstance@stepId_3,@end,_transit_,autotest-ref,* diff --git a/nop-wf/nop-wf-service/src/test/java/io/nop/wf/service/TestBeeflowCase.java b/nop-wf/nop-wf-service/src/test/java/io/nop/wf/service/TestBeeflowCase.java index 8230c17ea..8e22b041c 100644 --- a/nop-wf/nop-wf-service/src/test/java/io/nop/wf/service/TestBeeflowCase.java +++ b/nop-wf/nop-wf-service/src/test/java/io/nop/wf/service/TestBeeflowCase.java @@ -23,7 +23,7 @@ /** * 测试类钉钉审批流相关用例 */ -@NopTestConfig(localDb = true, initDatabaseSchema = true) +@NopTestConfig //(localDb = true, initDatabaseSchema = true) public class TestBeeflowCase extends JunitAutoTestCase { @Inject @@ -85,12 +85,16 @@ public void testPaymentApplication() { }); } + @EnableSnapshot @Test public void testSalaryAdjustment() { + forceStackTrace(); runInSession(() -> { + // 在/_vfs/_delta/default目录下定制wf模块的app.orm.xml,增加动态实体定义 IEntityDao dao = DaoProvider.instance().dao("AppDynSalaryAdjustment"); // 必须通过dao创建,此时实体名才会被强制设置为AppDynSalaryAdjustment NopWfDynEntity entity = dao.newEntity(); + entity.prop_set("name", "abc"); entity.prop_set("employeeId", 100); entity.prop_set("salary1", 30000); entity.prop_set("salary2", 40000); @@ -99,10 +103,10 @@ public void testSalaryAdjustment() { start(wf, "1", entity); // 根据部门条件发送到 user2 assertEquals(wf.getWfId(), entity.getNopFlowId()); - invoke(wf, "2", "agree"); // - invoke(wf, "3", "agree"); // 抄送用户 user_4 - invoke(wf, "4", "confirm"); // 抄送用户缺省后发给 角色 manager + invoke(wf, "2", "agree"); // 根据salary2条件发送user5 invoke(wf, "5", "agree"); + + assertTrue(wf.isEnded()); }); } } diff --git a/nop-wf/nop-wf-service/src/test/java/io/nop/wf/service/WfTestHelper.java b/nop-wf/nop-wf-service/src/test/java/io/nop/wf/service/WfTestHelper.java index 027fe695c..5d363cbc4 100644 --- a/nop-wf/nop-wf-service/src/test/java/io/nop/wf/service/WfTestHelper.java +++ b/nop-wf/nop-wf-service/src/test/java/io/nop/wf/service/WfTestHelper.java @@ -4,13 +4,15 @@ import io.nop.commons.util.StringHelper; import io.nop.core.context.IServiceContext; import io.nop.core.context.ServiceContextImpl; -import io.nop.core.lang.eval.IEvalScope; +import io.nop.dao.api.DaoProvider; import io.nop.wf.core.IWorkflow; import io.nop.wf.core.IWorkflowStep; import io.nop.wf.core.NopWfCoreConstants; import io.nop.wf.dao.entity.NopWfDynEntity; +import java.util.HashMap; import java.util.List; +import java.util.Map; public class WfTestHelper { public static void start(IWorkflow wf, String starterId) { @@ -21,13 +23,15 @@ public static void start(IWorkflow wf, String starterId) { } public static void start(IWorkflow wf, String starterId, NopWfDynEntity entity) { + DaoProvider.instance().dao(entity.get_entityName()).saveOrUpdateEntity(entity); + IServiceContext ctx = new ServiceContextImpl(); - IEvalScope scope = ctx.getEvalScope(); - scope.setLocalValue(NopWfCoreConstants.PARAM_BIZ_OBJ_NAME, StringHelper.simpleClassName(entity.get_entityName())); - scope.setLocalValue(NopWfCoreConstants.PARAM_BIZ_OBJ_ID, entity.orm_idString()); + Map args = new HashMap<>(); + args.put(NopWfCoreConstants.PARAM_BIZ_OBJ_NAME, StringHelper.simpleClassName(entity.get_entityName())); + args.put(NopWfCoreConstants.PARAM_BIZ_OBJ_ID, entity.orm_idString()); ctx.getContext().setUserId(starterId); - wf.start(null, ctx); + wf.start(args, ctx); wf.runAutoTransitions(ctx); } @@ -42,6 +46,7 @@ public static void invoke(IWorkflow wf, String userId, String action) { if (step.getActor().containsUser(userId)) { step.invokeAction(action, null, ctx); wf.runAutoTransitions(ctx); + wf.runAutoTransitions(ctx); return; } } diff --git a/nop-wf/nop-wf-service/src/test/resources/_vfs/_delta/default/nop/wf/orm/app.orm.xml b/nop-wf/nop-wf-service/src/test/resources/_vfs/_delta/default/nop/wf/orm/app.orm.xml index 72f0fd2b9..72c89af00 100644 --- a/nop-wf/nop-wf-service/src/test/resources/_vfs/_delta/default/nop/wf/orm/app.orm.xml +++ b/nop-wf/nop-wf-service/src/test/resources/_vfs/_delta/default/nop/wf/orm/app.orm.xml @@ -1,6 +1,6 @@ - + diff --git a/nop-wf/nop-wf-service/src/test/resources/_vfs/nop/wf/beeflow/payment-application/v1.xwf b/nop-wf/nop-wf-service/src/test/resources/_vfs/nop/wf/beeflow/payment-application/v1.xwf index 424316ff8..318b5f031 100644 --- a/nop-wf/nop-wf-service/src/test/resources/_vfs/nop/wf/beeflow/payment-application/v1.xwf +++ b/nop-wf/nop-wf-service/src/test/resources/_vfs/nop/wf/beeflow/payment-application/v1.xwf @@ -21,6 +21,7 @@ + @@ -33,6 +34,7 @@ + @@ -45,6 +47,7 @@ + @@ -80,6 +83,7 @@ + diff --git a/nop-wf/nop-wf-service/src/test/resources/_vfs/nop/wf/beeflow/salary-adjustment/v1.xwf b/nop-wf/nop-wf-service/src/test/resources/_vfs/nop/wf/beeflow/salary-adjustment/v1.xwf index 20ffa01e4..37625f518 100644 --- a/nop-wf/nop-wf-service/src/test/resources/_vfs/nop/wf/beeflow/salary-adjustment/v1.xwf +++ b/nop-wf/nop-wf-service/src/test/resources/_vfs/nop/wf/beeflow/salary-adjustment/v1.xwf @@ -82,11 +82,11 @@ - + - + diff --git a/nop-xdefs/src/main/resources/_vfs/nop/schema/wf/wf.xdef b/nop-xdefs/src/main/resources/_vfs/nop/schema/wf/wf.xdef index ff5d86d73..34ae1f895 100644 --- a/nop-xdefs/src/main/resources/_vfs/nop/schema/wf/wf.xdef +++ b/nop-xdefs/src/main/resources/_vfs/nop/schema/wf/wf.xdef @@ -127,7 +127,7 @@ -