Exemplo n.º 1
0
        public void FlowTemplateDefHelper_repeatSameJson_returnSameObj()
        {
            FlowTemplateDefHelper FlowTemplateDefHelper1 = new FlowTemplateDefHelper("{'AmountTotal': 49999}");
            FlowTemplateDefHelper FlowTemplateDefHelper0 = new FlowTemplateDefHelper("{'AmountTotal': 500000}");

            FlowTemplateDefHelper FlowTemplateDefHelper2 = new FlowTemplateDefHelper("{'AmountTotal': 49999}");

            Assert.AreSame(FlowTemplateDefHelper1.def, FlowTemplateDefHelper2.def);
            Assert.AreNotSame(FlowTemplateDefHelper1.def, FlowTemplateDefHelper0.def);
        }
Exemplo n.º 2
0
        public void getPaticipantFromGuid_validDynamicUserGuid_returnDynamicUserPaticipant()
        {
            FlowDynamicUser flowDynamicUser = db.flowDynamicUsers.Create();

            flowDynamicUser.name = "Integration_Test_XXXYYYZZZ";
            db.flowDynamicUsers.Add(flowDynamicUser);
            db.SaveChanges();

            Paticipant result = FlowTemplateDefHelper.getPaticipantFromGuid(flowDynamicUser.guid);

            Assert.NotNull(result);
            Assert.AreEqual(result.PaticipantType, "dynamic");
            Assert.AreEqual(result.PaticipantObj.guid, flowDynamicUser.guid);
        }
Exemplo n.º 3
0
        public void getPaticipantFromGuid_validRoleGuid_returnRolePaticipant()
        {
            using (EnouFlowOrgMgmtContext dbOrg = new EnouFlowOrgMgmtContext())
            {
                RoleHelper roleHelper = new RoleHelper(dbOrg);
                var        role       = roleHelper.createObject();
                role.name = "Integration_Test_XXXYYYZZZ";
                roleHelper.saveCreatedObject(role);

                Paticipant result = FlowTemplateDefHelper.getPaticipantFromGuid(role.guid);

                Assert.NotNull(result);
                Assert.AreEqual(result.PaticipantType, "role");
                Assert.AreEqual(result.PaticipantObj.guid, role.guid);
            }
        }
Exemplo n.º 4
0
        public void getPaticipantFromGuid_validUserGuid_returnUserPaticipant()
        {
            using (EnouFlowOrgMgmtContext dbOrg = new EnouFlowOrgMgmtContext())
            {
                UserHelper userHelper = new UserHelper(dbOrg);
                var        user       = userHelper.createObject();
                user.name = "Integration_Test_XXXYYYZZZ";
                userHelper.saveCreatedObject(user);

                Paticipant result = FlowTemplateDefHelper.getPaticipantFromGuid(user.guid);

                Assert.NotNull(result);
                Assert.AreEqual(result.PaticipantType, "user");
                Assert.AreEqual(result.PaticipantObj.guid, user.guid);
            }
        }
Exemplo n.º 5
0
        public FlowActionStartResult // start
        processActionRequest(FlowActionStart req)
        {
            using (var db = new EnouFlowInstanceContext())
            {
                string failReason;
                var    reqInDb = getReqInDB(req.flowActionRequestId, db);

                var flowInst = db.flowInstances.Create();
                flowInst.flowTemplateId   = req.concreteMetaObj.flowTemplateId;
                flowInst.flowTemplateJson = FlowTemplateDBHelper.getFlowTemplate(
                    flowInst.flowTemplateId).flowTemplateJson;
                var flowDefHelper = new FlowTemplateDefHelper(
                    flowInst.flowTemplateJson);
                flowInst.creatorId       = req.concreteMetaObj.userId;
                flowInst.code            = req.concreteMetaObj.code;
                flowInst.processingState = EnumFlowInstanceProcessingState.
                                           waitingActionRequest;
                flowInst.lifeState = EnumFlowInstanceLifeState.start;
                // 此处TimeStamp不能直接取Now, 因为启动流程时会几乎同时生成两个
                // ActionRequest, 否则第二个ActionRequest的bizTimeStamp就会马上过期
                flowInst.bizTimeStamp        = flowInst.mgmtTimeStamp = req.createTime;
                flowInst.currentActivityGuid = req.concreteMetaObj.currentActivityGuid;
                flowInst.currentActivityName = flowDefHelper.getNodeFromGuid(
                    flowInst.currentActivityGuid).name;
                flowInst.startActivityGuid   = flowInst.currentActivityGuid;
                flowInst.bizDataPayloadJson  = req.bizDataPayloadJson;
                flowInst.bizDocumentGuid     = req.bizDocumentGuid;
                flowInst.bizDocumentTypeCode = req.bizDocumentTypeCode;

                db.flowInstances.Add(flowInst);

                #region 如果需要, 则Add FlowTaskForUser
                List <UserDTO> taskUsers = new List <UserDTO>();
                if (req.needGenerateTaskForUser)
                {
                    taskUsers = getUserDTOsFromPaticipantList(req.roles, flowInst);

                    if (taskUsers.Count() == 0) // 如果参与活动的用户数为0则出错
                    {
                        failReason = $"无法找到参与活动'{flowInst.currentActivityName}'" +
                                     $"的用户({req.roles.ToString()}).";

                        updateReqProcessingResultInDB(reqInDb,
                                                      EnumFlowActionRequestResultType.fail, failReason);
                        db.SaveChanges();

                        return(new FlowActionStartResult(req.flowActionRequestId,
                                                         req.clientRequestGuid, flowInst, false, failReason));
                    }
                }
                #endregion

                // 新建的流程需要回填对应的处理请求对象关于流程实例的信息,
                // 由下面updateRequestToSuccess完成
                #region  update request
                updateRequestToSuccess(reqInDb, flowInst);
                #endregion


#warning TODO: Add FlowInstanceFriendlyLog & FlowInstanceTechLog
                addFlowInstanceFriendlyLog(
                    flowInst, reqInDb.flowActionRequestId, flowInst.previousActivityName,
                    reqInDb.userId.Value, reqInDb.delegateeUserId,
                    "提交(开始)/Submit(Start)", req.userMemo, db);

                db.SaveChanges();

                return(new FlowActionStartResult(
                           req.flowActionRequestId,
                           req.clientRequestGuid,
                           flowInst));
            }
        }
Exemplo n.º 6
0
        public FlowActionMoveToAutoGeneratedResult // moveToAutoGenerated
        processActionRequest(FlowActionMoveToAutoGenerated req)
        {
            var concreteMetaObj = req.concreteMetaObj;

            using (var db = new EnouFlowInstanceContext())
            {
                var flowInst = getFlowInstance(db, req.flowInstanceId, req.bizDocumentGuid);

                var reqInDb = getReqInDB(req.flowActionRequestId, db);
                Tuple <ActivityNode, ActivityNode, ActivityConnection> from_to_conn;
                string failReason;

                #region Check BizTimeStamp Valid 自动型跳过检查
                //if (!isBizTimeStampValid((DateTime)concreteMetaObj.bizTimeStamp,
                //  req, flowInst, db, out failReason))
                //{
                //  updateReqProcessingResultInDB(reqInDb,
                //    EnumFlowActionRequestResultType.fail, failReason);
                //  db.SaveChanges();

                //  return new FlowActionMoveToAutoGeneratedResult(req.flowActionRequestId,
                //    req.clientRequestGuid, flowInst, false, failReason);
                //}
                #endregion

                #region Decide next activity, switch different activity type
                var flowDefHelper = new FlowTemplateDefHelper(
                    flowInst.flowTemplateJson);
                from_to_conn = flowDefHelper.getNodesOfConnection(req.connectionGuid);

                #region 验证流程实例当前所处的状态能够使用该connection
                if (from_to_conn.Item1.guid != flowInst.currentActivityGuid)
                {
                    failReason = $"当前所处的状态{from_to_conn.Item1.name}" +
                                 $"不支持使用连接{from_to_conn.Item3.name}";

                    updateReqProcessingResultInDB(reqInDb,
                                                  EnumFlowActionRequestResultType.fail, failReason);
                    db.SaveChanges();

                    return(new FlowActionMoveToAutoGeneratedResult(req.flowActionRequestId,
                                                                   req.clientRequestGuid, flowInst, false, failReason));
                }
                #endregion

                #endregion

                #region 目的状态是自动类型时需要根据条件为该活动自动生成接续的对应FlowActionRequest
                if (from_to_conn.Item2.type == ActivityTypeString.standard_Auto)
                {
                    var _toActivity = from_to_conn.Item2; // 目标自动活动
                    var _autoResult = ExecuteAutoRulesAsync(_toActivity.autoRules, req.bizDataPayloadJson,
                                                            req.optionalFlowActionDataJson, flowInst).Result;
                    var _effectiveConnectionGuid = _autoResult.Item1;
                    var _paticipantsOfAutoRules  = _autoResult.Item2;

                    //根据自动活动规则集的运行结果由引擎Post相应的MoveToAutoGenerated型处理请求
                    FlowActionHelper.PostFlowActionMoveToAutoGenerated(
                        Guid.NewGuid().ToString(), req.bizDocumentGuid, req.bizDocumentTypeCode,
                        DateTime.Now, "自动活动规则生成",
                        req.bizDataPayloadJson, req.optionalFlowActionDataJson,
                        flowInst.flowInstanceId, flowInst.guid, flowInst.code,
                        from_to_conn.Item2.guid, _effectiveConnectionGuid,
                        flowDefHelper.getNodesOfConnection(
                            _effectiveConnectionGuid).Item2.guid,
                        _paticipantsOfAutoRules, db);
                }
                #endregion

                #region Decide activity owners/ List<UserDTO>
                List <UserDTO> taskUsers = new List <UserDTO>();
                switch (from_to_conn.Item2.type)
                {
                case ActivityTypeString.standard_End: // 目标活动状态为结束,不需要设置activity owner, 是否需要有最终收尾处理的人 ???
                    break;

                case ActivityTypeString.standard_Start: // 下面这三类目标活动状态需要设置activity owner
                case ActivityTypeString.standard_SingleHuman:
                case ActivityTypeString.standard_MultiHuman:
                    // taskUsers = FlowTemplateDefHelper.getUserDTOsFromPaticipantList(req.roles);
                    taskUsers = getUserDTOsFromPaticipantList(req.roles, flowInst);

                    if (taskUsers.Count() == 0) // 如果参与活动的用户数为0则出错
                    {
                        failReason = $"无法找到参与活动'{from_to_conn.Item2.name}'" +
                                     $"的用户({req.roles.ToString()}).";

                        updateReqProcessingResultInDB(reqInDb,
                                                      EnumFlowActionRequestResultType.fail, failReason);
                        db.SaveChanges();

                        return(new FlowActionMoveToAutoGeneratedResult(req.flowActionRequestId,
                                                                       req.clientRequestGuid, flowInst, false, failReason));
                    }

                    break;

                case ActivityTypeString.standard_Auto:
                    // 目标活动状态为自动,暂定不设置activity owner
                    break;

                default:
                    throw new EnouFlowInstanceLib.DataLogicException(
                              $"遇到未定义处理方式的活动类型: {from_to_conn.Item2.type}");
                }
                #endregion

                #region  update instance
                switch (from_to_conn.Item2.type)
                {
                case ActivityTypeString.standard_End:
                    flowInst.lifeState = EnumFlowInstanceLifeState.end;
                    break;

                case ActivityTypeString.standard_Start:
                    flowInst.lifeState = EnumFlowInstanceLifeState.start;
                    break;

                case ActivityTypeString.standard_SingleHuman:
                case ActivityTypeString.standard_MultiHuman:
                case ActivityTypeString.standard_Auto:
                    flowInst.lifeState = EnumFlowInstanceLifeState.middle;
                    break;

                default:
                    throw new EnouFlowInstanceLib.DataLogicException(
                              $"遇到未定义处理方式的活动类型: {from_to_conn.Item2.type}");
                }
                flowInst.bizTimeStamp         = DateTime.Now;
                flowInst.currentActivityGuid  = from_to_conn.Item2.guid;
                flowInst.currentActivityName  = from_to_conn.Item2.name;
                flowInst.previousActivityGuid = from_to_conn.Item1.guid;
                flowInst.previousActivityName = from_to_conn.Item1.name;
                updateBizDataPayloadJsonOfFlowInst(flowInst, req);

                #endregion

                #region Create request automatically for auto activity

                #endregion

                #region  update tasks for user status like taskState,finishTime
                //自动型不需要做该动作,因为FromNode是自动型,应该无人工任务产生
                #endregion

                #region  add task for users: FlowTaskForUser
                taskUsers.ForEach(user => addFlowTaskForUser(db, user, flowInst));
                #endregion

                #region  write 3 type logs: FlowInstanceFriendlyLog & FlowInstanceTechLog

                #endregion

                #region  update request
                updateRequestToSuccess(reqInDb, flowInst);
                #endregion

                #region  save all to db
                db.SaveChanges();
                #endregion

                return(new FlowActionMoveToAutoGeneratedResult(req.flowActionRequestId,
                                                               req.clientRequestGuid, flowInst));
            }
        }
Exemplo n.º 7
0
        public FlowActionTerminateResult // teminate
        processActionRequest(FlowActionTerminate req)
        {
            var concreteMetaObj = req.concreteMetaObj;

            using (var db = new EnouFlowInstanceContext())
            {
                var flowInst = getFlowInstance(db, req.flowInstanceId, req.bizDocumentGuid);

                var      reqInDb = getReqInDB(req.flowActionRequestId, db);
                string   failReason;
                DateTime bizTimeStampToUse = DateTime.Now;
                var      flowDefHelper     = new FlowTemplateDefHelper(
                    flowInst.flowTemplateJson);
                var toActivity      = flowDefHelper.getNodeFromGuid(req.nextActivityGuid);
                var currentActivity = flowDefHelper.getNodeFromGuid(req.currentActivityGuid);

                #region  update instance
                switch (toActivity.type)
                {
                case ActivityTypeString.standard_End:
                    flowInst.lifeState = EnumFlowInstanceLifeState.terminated;
                    break;

                default:
                    throw new EnouFlowInstanceLib.DataLogicException(
                              $"不能终止到非停止状态的活动类型: {toActivity.type}");
                }
                var originBizTimeStamp = flowInst.bizTimeStamp;
                flowInst.bizTimeStamp         = bizTimeStampToUse;
                flowInst.currentActivityGuid  = toActivity.guid;
                flowInst.currentActivityName  = toActivity.name;
                flowInst.previousActivityGuid = currentActivity.guid;
                flowInst.previousActivityName = currentActivity.name;
                #endregion

                #region  update tasks for user status like taskState,finishTime
                updateTaskForUserStatesAfterAction(db, (int)concreteMetaObj.userId,
                                                   originBizTimeStamp, bizTimeStampToUse,
                                                   flowInst.previousActivityGuid, flowInst, reqInDb);
                #endregion

                #region  write 3 type logs: FlowInstanceFriendlyLog & FlowInstanceTechLog
                addFlowInstanceFriendlyLog(
                    flowInst, reqInDb.flowActionRequestId, flowInst.previousActivityName,
                    reqInDb.userId.Value, reqInDb.delegateeUserId,
                    "终止/Terminate", req.userMemo, db);
#warning TODO: another 2 type logs
                #endregion

                #region  update request
                updateRequestToSuccess(reqInDb, flowInst);
                #endregion

                #region  save all to db
                db.SaveChanges();
                #endregion

                return(new FlowActionTerminateResult(req.flowActionRequestId,
                                                     req.clientRequestGuid, flowInst));
            }
        }
Exemplo n.º 8
0
        processActionRequest(FlowActionInviteOtherFeedback req)
        {
            var concreteMetaObj = req.concreteMetaObj;

            using (var db = new EnouFlowInstanceContext())
            {
                var flowInst = getFlowInstance(db, req.flowInstanceId, req.bizDocumentGuid);

                var    reqInDb = getReqInDB(req.flowActionRequestId, db);
                string failReason;
                // 此类型ActionRequest不改TimeStamp
                DateTime bizTimeStampToUse = flowInst.bizTimeStamp;

                #region Check BizTimeStamp Valid
                if (!isBizTimeStampValid((DateTime)concreteMetaObj.bizTimeStamp,
                                         req, flowInst, out failReason))
                {
                    updateReqProcessingResultInDB(reqInDb,
                                                  EnumFlowActionRequestResultType.fail, failReason);
                    db.SaveChanges();

                    return(new FlowActionInviteOtherFeedbackResult(req.flowActionRequestId,
                                                                   req.clientRequestGuid, flowInst, false, failReason));
                }
                #endregion

                #region Decide List<UserDTO>
                // 需要追溯到最初发出征询意见的用户作为任务目标用户
                List <UserDTO> taskUsers       = new List <UserDTO>();
                var            taskInviteOther = db.flowTaskForUsers.Find(
                    req.relativeFlowTaskForUserId);
                var flowTaskForUserOrigin = db.flowTaskForUsers.Find(
                    taskInviteOther.relativeFlowTaskForUserId);
                using (var orgDb = new EnouFlowOrgMgmtContext())
                {
                    taskUsers.Add(
                        new UserHelper(orgDb).getUserDTO(
                            flowTaskForUserOrigin.userId));
                }
                #endregion

                #region  add the invitation-feedback "task" for users
                FlowTemplateDefHelper flowTemplateDefHelper = new
                                                              FlowTemplateDefHelper(flowInst.flowTemplateJson);
                string suggestedConnectionName = "";
                if (!string.IsNullOrWhiteSpace(req.connectionGuid))
                {
                    suggestedConnectionName =
                        flowTemplateDefHelper.getNodesOfConnection(
                            req.connectionGuid).Item3.name;
                }
                string suggestedPaticipants = "";
                if (req.roles.Count() > 0)
                {
                    suggestedPaticipants = req.roles.Aggregate(
                        "", (names, role) => {
                        if (role != null)
                        {
                            return(names + role.PaticipantObj.name + ";");
                        }
                        else
                        {
                            return(names);
                        }
                    });
                }
                taskUsers.ForEach(user => {
                    var task = addFlowTaskForUser(
                        db, user, flowInst, EnumFlowTaskType.invitationFeedback);
                    // 设置任务之间的跟踪关系
                    task.relativeFlowTaskForUserId = req.relativeFlowTaskForUserId;
                    // 设置征询意见反馈型任务的自定义字段
                    task.stringField_1 = req.userMemo;
                    task.stringField_2 = suggestedConnectionName;
                    task.stringField_3 = suggestedPaticipants;
                });
                // 顺便把原征询意见的任务也一并更新
                taskInviteOther.stringField_1 = req.userMemo;
                taskInviteOther.stringField_2 = suggestedConnectionName;
                taskInviteOther.stringField_3 = suggestedPaticipants;
                taskInviteOther.finishTime    = DateTime.Now;
                taskInviteOther.taskState     = EnumFlowTaskState.done;
                #endregion

                #region  write 3 type logs
                addFlowInstanceFriendlyLog(
                    flowInst, reqInDb.flowActionRequestId, flowInst.currentActivityName,
                    reqInDb.userId.Value, reqInDb.delegateeUserId,
                    "意见征询答复/Opinions invited", req.userMemo, db);
#warning TODO: another 2 type logs
                #endregion

                #region  update request
                updateRequestToSuccess(reqInDb, flowInst);
                #endregion

                #region  save all to db
                db.SaveChanges();
                #endregion

                return(new FlowActionInviteOtherFeedbackResult(req.flowActionRequestId,
                                                               req.clientRequestGuid, flowInst));
            }
        }
Exemplo n.º 9
0
        public FlowActionJumpToResult // jumpTo
        processActionRequest(FlowActionJumpTo req)
        {
            var concreteMetaObj = req.concreteMetaObj;

            using (var db = new EnouFlowInstanceContext())
            {
                var flowInst = getFlowInstance(db, req.flowInstanceId, req.bizDocumentGuid);

                var      reqInDb = getReqInDB(req.flowActionRequestId, db);
                string   failReason;
                DateTime bizTimeStampToUse = DateTime.Now;

                #region Check BizTimeStamp Valid
                if (!req.forceJump &&
                    !isBizTimeStampValid(
                        (DateTime)concreteMetaObj.bizTimeStamp,
                        req, flowInst, out failReason))
                {
                    updateReqProcessingResultInDB(reqInDb,
                                                  EnumFlowActionRequestResultType.fail, failReason);
                    db.SaveChanges();

                    return(new FlowActionJumpToResult(req.flowActionRequestId,
                                                      req.clientRequestGuid, flowInst, false, failReason));
                }
                #endregion

                var flowDefHelper = new FlowTemplateDefHelper(
                    flowInst.flowTemplateJson);
                var toActivity      = flowDefHelper.getNodeFromGuid(req.nextActivityGuid);
                var currentActivity = flowDefHelper.getNodeFromGuid(req.currentActivityGuid);

                #region 目的状态是自动类型时需要根据条件为该活动自动生成接续的对应FlowActionRequest
                if (toActivity.type == ActivityTypeString.standard_Auto)
                {
                    //var _toActivity = toActivity; // 目标自动活动
                    var _autoResult = ExecuteAutoRulesAsync(toActivity.autoRules,
                                                            req.bizDataPayloadJson, req.optionalFlowActionDataJson, flowInst).Result;
                    var _effectiveConnectionGuid = _autoResult.Item1;
                    var _paticipantsOfAutoRules  = _autoResult.Item2;

                    // 根据自动活动规则集的运行结果由引擎Post相应的MoveToAutoGenerated型处理请求
                    // 但不马上处理,由客户端或者流程引擎后台调度器自动调用处理
                    FlowActionHelper.PostFlowActionMoveToAutoGenerated(
                        Guid.NewGuid().ToString(), req.bizDocumentGuid, req.bizDocumentTypeCode,
                        DateTime.Now, "自动活动规则生成", req.bizDataPayloadJson,
                        req.optionalFlowActionDataJson, flowInst.flowInstanceId, flowInst.guid,
                        flowInst.code, toActivity.guid, _effectiveConnectionGuid,
                        flowDefHelper.getNodesOfConnection(_effectiveConnectionGuid).Item2.guid,
                        _paticipantsOfAutoRules, db);
                }
                #endregion

                #region Decide activity owners/ List<UserDTO>
                List <UserDTO> taskUsers = new List <UserDTO>();
                switch (toActivity.type)
                {
                case ActivityTypeString.standard_End: // 目标活动状态为结束,不需要设置activity owner, 是否需要有最终收尾处理的人 ???
                    break;

                case ActivityTypeString.standard_Start: // 下面这三类目标活动状态需要设置activity owner
                case ActivityTypeString.standard_SingleHuman:
                case ActivityTypeString.standard_MultiHuman:
                    // taskUsers = FlowTemplateDefHelper.getUserDTOsFromPaticipantList(req.roles);
                    taskUsers = getUserDTOsFromPaticipantList(req.roles, flowInst);

                    if (taskUsers.Count() == 0) // 如果参与活动的用户数为0则出错
                    {
                        failReason = $"无法找到参与活动'{toActivity.name}'" +
                                     $"的用户({req.roles.ToString()}).";

                        updateReqProcessingResultInDB(reqInDb,
                                                      EnumFlowActionRequestResultType.fail, failReason);
                        db.SaveChanges();

                        return(new FlowActionJumpToResult(req.flowActionRequestId,
                                                          req.clientRequestGuid, flowInst, false, failReason));
                    }

                    break;

                case ActivityTypeString.standard_Auto:
                    // 目标活动状态为自动,暂定不设置activity owner
                    break;

                default:
                    throw new EnouFlowInstanceLib.DataLogicException(
                              $"遇到未定义处理方式的活动类型: {toActivity.type}");
                }
                #endregion

                #region  update instance
                switch (toActivity.type)
                {
                case ActivityTypeString.standard_End:
                    flowInst.lifeState = EnumFlowInstanceLifeState.end;
                    break;

                case ActivityTypeString.standard_Start:
                    flowInst.lifeState = EnumFlowInstanceLifeState.start;
                    break;

                case ActivityTypeString.standard_SingleHuman:
                case ActivityTypeString.standard_MultiHuman:
                case ActivityTypeString.standard_Auto:
                    flowInst.lifeState = EnumFlowInstanceLifeState.middle;
                    break;

                default:
                    throw new EnouFlowInstanceLib.DataLogicException(
                              $"遇到未定义处理方式的活动类型: {toActivity.type}");
                }
                var originBizTimeStamp = flowInst.bizTimeStamp;
                flowInst.bizTimeStamp         = bizTimeStampToUse;
                flowInst.currentActivityGuid  = toActivity.guid;
                flowInst.currentActivityName  = toActivity.name;
                flowInst.previousActivityGuid = currentActivity.guid;
                flowInst.previousActivityName = currentActivity.name;
                updateBizDataPayloadJsonOfFlowInst(flowInst, req);

                #endregion

                #region  update tasks for user status like taskState,finishTime
                updateTaskForUserStatesAfterAction(db, (int)concreteMetaObj.userId,
                                                   originBizTimeStamp, bizTimeStampToUse,
                                                   flowInst.previousActivityGuid, flowInst, reqInDb);
                #endregion

                #region  add task for users: FlowTaskForUser
                taskUsers.ForEach(user => addFlowTaskForUser(db, user, flowInst));
                #endregion

                #region  write 3 type logs: FlowInstanceFriendlyLog & FlowInstanceTechLog
                addFlowInstanceFriendlyLog(
                    flowInst, reqInDb.flowActionRequestId, flowInst.previousActivityName,
                    reqInDb.userId.Value, reqInDb.delegateeUserId,
                    "跳转/Jump", req.userMemo, db);
#warning TODO: another 2 type logs
                #endregion

                #region  update request
                updateRequestToSuccess(reqInDb, flowInst);
                #endregion

                #region  save all to db
                db.SaveChanges();
                #endregion

                return(new FlowActionJumpToResult(req.flowActionRequestId,
                                                  req.clientRequestGuid, flowInst));
            }
        }
Exemplo n.º 10
0
        public FlowActionRejectToStartResult // rejectToStart
        processActionRequest(FlowActionRejectToStart req)
        {
            var concreteMetaObj = req.concreteMetaObj;

            using (var db = new EnouFlowInstanceContext())
            {
                var flowInst = getFlowInstance(db, req.flowInstanceId, req.bizDocumentGuid);

                var          reqInDb = getReqInDB(req.flowActionRequestId, db);
                string       failReason;
                ActivityNode destNode;

                #region Check BizTimeStamp Valid
                if (!isBizTimeStampValid((DateTime)concreteMetaObj.bizTimeStamp,
                                         req, flowInst, out failReason))
                {
                    updateReqProcessingResultInDB(reqInDb,
                                                  EnumFlowActionRequestResultType.fail, failReason);
                    db.SaveChanges();

                    return(new FlowActionRejectToStartResult(req.flowActionRequestId,
                                                             req.clientRequestGuid, flowInst, false, failReason));
                }
                #endregion

                #region Decide next activity, need be start type
                var flowDefHelper = new FlowTemplateDefHelper(
                    flowInst.flowTemplateJson);
                string startActivityGuid;
                if (string.IsNullOrWhiteSpace(req.startActivityGuid))
                {
                    startActivityGuid = flowInst.startActivityGuid;
                }
                else
                {
                    startActivityGuid = req.startActivityGuid;
                }
                destNode = flowDefHelper.getNodeFromGuid(startActivityGuid);

                if (destNode.type != ActivityTypeString.standard_Start)
                {
                    failReason = "目标活动不是开始类型(FlowActionRejectToStartResult)";
                    updateReqProcessingResultInDB(reqInDb,
                                                  EnumFlowActionRequestResultType.fail, failReason);
                    db.SaveChanges();

                    return(new FlowActionRejectToStartResult(req.flowActionRequestId,
                                                             req.clientRequestGuid, flowInst, false, failReason));
                }
                #endregion

                #region Decide activity owners/ List<UserDTO>
                List <UserDTO> taskUsers = new List <UserDTO>();
                // taskUsers = FlowTemplateDefHelper.getUserDTOsFromPaticipantList(req.roles);
                taskUsers = getUserDTOsFromPaticipantList(req.roles, flowInst);

                if (taskUsers.Count() == 0)
                {// 如果没有直接指定用户, 则根据流程实例的creatorId,将任务指派给流程实例的创建者
                    using (var orgDb = new EnouFlowOrgMgmtContext())
                    {
                        var creator = new UserHelper(orgDb).getUserDTO(flowInst.creatorId);
                        if (creator != null)
                        {
                            taskUsers.Add(creator);
                        }
                    }
                }

                if (taskUsers.Count() == 0) // 如果参与活动的用户数为0则出错
                {
                    failReason = $@"无法找到参与活动'{destNode.name}'的用户" +
                                 $@"({ req.roles.ToString()}). (FlowActionRejectToStartResult)";

                    updateReqProcessingResultInDB(reqInDb,
                                                  EnumFlowActionRequestResultType.fail, failReason);
                    db.SaveChanges();

                    return(new FlowActionRejectToStartResult(req.flowActionRequestId,
                                                             req.clientRequestGuid, flowInst, false, failReason));
                }
                #endregion

                #region  update instance
                DateTime newBizTimeStamp    = DateTime.Now;
                DateTime originBizTimeStamp = flowInst.bizTimeStamp;
                flowInst.bizTimeStamp         = newBizTimeStamp;
                flowInst.previousActivityGuid = flowInst.currentActivityGuid;
                flowInst.previousActivityName = flowInst.currentActivityName;
                flowInst.currentActivityGuid  = destNode.guid;
                flowInst.currentActivityName  = destNode.name;
                // RejectToStart不更新BizDataPayloadJson:
                // updateBizDataPayloadJsonOfFlowInst(flowInst, req);
                #endregion

                #region  update tasks for user status like taskState,finishTime, delegatee
                updateTaskForUserStatesAfterAction(db, (int)concreteMetaObj.userId,
                                                   originBizTimeStamp, newBizTimeStamp,
                                                   flowInst.previousActivityGuid, flowInst, reqInDb);
                #endregion

                #region  add task for users: FlowTaskForUser
                taskUsers.ForEach(user => addFlowTaskForUser(db, user, flowInst, EnumFlowTaskType.redraft));
                #endregion

                #region  write 3 type logs: FlowInstanceFriendlyLog & FlowInstanceTechLog
                addFlowInstanceFriendlyLog(
                    flowInst, reqInDb.flowActionRequestId, flowInst.previousActivityName,
                    reqInDb.userId.Value, reqInDb.delegateeUserId,
                    "退回(拒绝)/Reject", req.userMemo, db);
#warning TODO: another 2 type logs
                #endregion

                #region  update request
                updateRequestToSuccess(reqInDb, flowInst);
                #endregion

                db.SaveChanges();

                return(new FlowActionRejectToStartResult(req.flowActionRequestId,
                                                         req.clientRequestGuid, flowInst));
            }
        }
Exemplo n.º 11
0
        public void getPaticipantFromGuid_invalidGuid_returnNull(string guid)
        {
            Paticipant result = FlowTemplateDefHelper.getPaticipantFromGuid(guid);

            Assert.Null(result);
        }