Example #1
0
        private static void addFlowInstanceFriendlyLog(
            FlowInstance flowInstance, int flowActionRequestId,
            string currentActivityName, int paticipantUserId,
            int?delegateeUserId, string actionName,
            string paticipantMemo, EnouFlowInstanceContext db)
        {
            var log = db.flowFriendlyLogs.Create();

            log.FlowInstance        = flowInstance;
            log.flowActionRequestId = flowActionRequestId;
            log.currentActivityName = currentActivityName;
            using (var orgDb = new EnouFlowOrgMgmtContext())
            {
                UserHelper userHelper = new UserHelper(orgDb);

                var paticipant = userHelper.getUserDTO(paticipantUserId);
                log.paticipantName = paticipant.name +
                                     (paticipant.englishName == null ? "" : "/" + paticipant.englishName);

                if (delegateeUserId.HasValue)
                {
                    var delegatee = userHelper.getUserDTO(delegateeUserId.Value);
                    log.delegateeName = delegatee.name +
                                        (delegatee.englishName == null ? "" : "/" + delegatee.englishName);
                }
            }
            log.actionName     = actionName;
            log.paticipantMemo = paticipantMemo;

            db.flowFriendlyLogs.Add(log);
        }
Example #2
0
        private void updateTaskForUserStatesAfterAction(EnouFlowInstanceContext db,
                                                        int actionUserId, DateTime bizTimeStamp, DateTime newBizTimeStamp,
                                                        string currentActivityGuid, FlowInstance flowInst, FlowActionRequest reqInDb)
        {
            var tasks = db.flowTaskForUsers.Where(t =>
                                                  t.FlowInstance.flowInstanceId == flowInst.flowInstanceId &&
                                                  t.bizTimeStamp == bizTimeStamp &&
                                                  t.currentActivityGuid == currentActivityGuid).ToList();

            tasks.ForEach(t =>
            {
                if (t.userId != actionUserId)
                {
                    // 其他用户已删除该任务或是已完成的邀请提供处理意见的任务,不需要标记为过期
                    if (t.taskState != EnumFlowTaskState.deletedByUser && t.taskState != EnumFlowTaskState.done)
                    {
                        t.taskState = EnumFlowTaskState.obsoleted;
                    }
                }
                else
                {
                    t.finishTime        = newBizTimeStamp;
                    t.taskState         = EnumFlowTaskState.done;
                    t.FlowActionRequest = reqInDb;
                    t.delegateeUserId   = reqInDb.delegateeUserId; // 有可能是被任务代理人完成
                    t.delegateeUserGuid = reqInDb.delegateeUserGuid;
                }
            });

            //db.SaveChanges();
        }
Example #3
0
        private FlowInstance getFlowInstance(EnouFlowInstanceContext db,
                                             int flowInstanceId, string bizDocumentGuid)
        {
            FlowInstance flowInst = db.flowInstances.Find(flowInstanceId);

            if (flowInst == null)
            {
                flowInst = db.flowInstances.Where(
                    inst => inst.bizDocumentGuid == bizDocumentGuid)
                           .ToList().FirstOrDefault();
            }

            return(flowInst);
        }
Example #4
0
        private FlowTaskForUser addFlowTaskForUser(EnouFlowInstanceContext db,
                                                   UserDTO user, FlowInstance flowInst,
                                                   EnumFlowTaskType taskType = EnumFlowTaskType.normal)
        {
            var task = db.flowTaskForUsers.Create();

            task.userId              = user.userId;
            task.userGuid            = user.guid;
            task.FlowInstance        = flowInst;
            task.bizDocumentGuid     = flowInst.bizDocumentGuid;
            task.bizDocumentTypeCode = flowInst.bizDocumentTypeCode;
            task.bizTimeStamp        = flowInst.bizTimeStamp;
            task.currentActivityGuid = flowInst.currentActivityGuid;
            task.taskType            = taskType;
            db.flowTaskForUsers.Add(task);

            return(task);
        }
Example #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));
            }
        }
Example #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));
            }
        }
Example #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));
            }
        }
Example #8
0
 public void Setup()
 {
     db = new EnouFlowInstanceContext();
 }
Example #9
0
        public FlowActionInviteOtherResult // inviteOther = More approval
        processActionRequest(FlowActionInviteOther 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 FlowActionInviteOtherResult(req.flowActionRequestId,
                                                           req.clientRequestGuid, flowInst, false, failReason));
                }
                #endregion

                #region Decide List<UserDTO>
                //use the parameters of request
                List <UserDTO> taskUsers = new List <UserDTO>();
                // taskUsers = FlowTemplateDefHelper.getUserDTOsFromPaticipantList(req.roles);
                taskUsers = getUserDTOsFromPaticipantList(req.roles, flowInst);
                #endregion

                #region  add the invitation task for users: FlowTaskForUser
                taskUsers.ForEach(user => {
                    var task = addFlowTaskForUser(
                        db, user, flowInst, EnumFlowTaskType.invitation);
                    // 邀请他人提供意见需要设置本身任务的FlowTaskForUserId用于对应跟踪
                    task.relativeFlowTaskForUserId = req.relativeFlowTaskForUserId;
                });
                #endregion

                #region  write 3 type logs
                addFlowInstanceFriendlyLog(
                    flowInst, reqInDb.flowActionRequestId, flowInst.currentActivityName,
                    reqInDb.userId.Value, reqInDb.delegateeUserId,
                    "征询意见/Invite opinion", 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 FlowActionInviteOtherResult(req.flowActionRequestId,
                                                       req.clientRequestGuid, flowInst));
            }
        }
Example #10
0
 private FlowActionRequest getReqInDB(int id, EnouFlowInstanceContext db)
 {
     return(db.flowActionRequests.Find(id));
 }
Example #11
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));
            }
        }
Example #12
0
        static void Main(string[] args)
        {
            bool testCreateOrgStru       = false;
            bool testQueryOrgStru        = false;
            bool testCreateSystemManager = false;

            bool testImportFlowDefinitionJSON = false;
            bool testCreateFlowTemplate       = false;

            // Actions
            bool testCreateFlowActionStart         = false;
            bool testCreateFlowActionMoveTo_1      = false;
            bool testCreateFlowActionMoveTo_2      = false;
            bool testCreateFlowActionMoveTo_3      = false;
            bool testCreateFlowActionMoveTo_4      = false;
            bool testCreateFlowActionRejectToStart = false;
            bool testCreateFlowActionJumpTo_1      = false;
            //bool testCreateFlowActionTake = false;
            //bool testCreateFlowActionInviteOther = false;
            //bool testCreateFlowActionFeedBackOfInvite = false;

            // Engine
            bool testRunEngine = false;

            // OPAS2Model
            bool testBizDocumentSerialNoGenerator = false;
            bool testCreatePR = false;
            bool testGenerateBizDataPayloadJson = false;

            // FlowDynamicUser
            bool testFlowDynamicUser = false;

            #region Test OrgMgmtLib

            #region Creation
            if (testCreateOrgStru)
            {
                using (var db = new EnouFlowOrgMgmtContext())
                {
                    // var DBHelper = DBHelper;

                    var orgHelper = new OrgHelper(db);

                    var _org = orgHelper.createObject();
                    _org.name = "CQAC集团";
                    orgHelper.saveCreatedObject(_org);

                    var orgSchemaHelper = new OrgSchemaHelper(db);

                    var _orgSchema = orgSchemaHelper.createObject();
                    _orgSchema.name = "默认组织结构方案";
                    _orgSchema.Org  = _org;
                    orgSchemaHelper.saveCreatedObject(_orgSchema);

                    var bizEntityHelper = new BizEntityHelper(db);
                    var _bizEntity      = bizEntityHelper.createObject();
                    _bizEntity.name = "Qoros汽车有限公司";
                    bizEntityHelper.saveCreatedObject(_orgSchema, _bizEntity, null);

                    //var _bizEntityChild = OrgMgmtDBHelper.createBizEntity(db);
                    //_bizEntityChild.name = "上海总部";
                    //OrgMgmtDBHelper.saveCreatedBizEntity(_orgSchema, _bizEntityChild, _bizEntity, db);

                    //var _bizEntityChild2 = OrgMgmtDBHelper.createBizEntity(db);
                    //_bizEntityChild2.name = "常熟生产基地";
                    //OrgMgmtDBHelper.saveCreatedBizEntity(_orgSchema, _bizEntityChild2, _bizEntity, db);

                    BizEntitySchemaHelper bizEntitySchemaHelper = new BizEntitySchemaHelper(db);
                    var _bizEntitySchema = bizEntitySchemaHelper.createObject();
                    _bizEntitySchema.name      = "Qoros默认公司架构";
                    _bizEntitySchema.BizEntity = _bizEntity;
                    bizEntitySchemaHelper.saveCreatedObject(_bizEntitySchema);

                    DepartmentHelper departmentHelper = new DepartmentHelper(db);
                    var _department0 = departmentHelper.createObject();
                    _department0.name = "董事会";
                    departmentHelper.saveCreatedObject(_bizEntitySchema, _department0, null);

                    //var _department = departmentHelper.createObject() ;
                    //_department.name = "后台部门";
                    //OrgMgmtDBHelper.saveCreatedDepartment(_bizEntitySchema, _department, null, db);

                    var _department1 = departmentHelper.createObject();
                    _department1.name = "产品部";
                    departmentHelper.saveCreatedObject(_bizEntitySchema, _department1, null);

                    var _departmentChild = departmentHelper.createObject();
                    _departmentChild.name = "财务部";
                    departmentHelper.saveCreatedObject(_bizEntitySchema, _departmentChild, null);

                    UserHelper userHelper = new UserHelper(db);
                    var        _user      = userHelper.createObject();
                    _user.name = "张三";
                    userHelper.saveCreatedObject(_user);

                    var _user2 = userHelper.createObject();
                    _user2.name = "李四";
                    userHelper.saveCreatedObject(_user2);

                    var _user3 = userHelper.createObject();
                    _user3.name = "王五";
                    userHelper.saveCreatedObject(_user3);

                    userHelper.createDepartmentUserRelation(_departmentChild, _user);
                    userHelper.createDepartmentUserRelation(_departmentChild, _user2);
                    userHelper.createDepartmentUserRelation(_department1, _user3);

                    RoleHelper roleHelper = new RoleHelper(db);
                    var        _role      = roleHelper.createObject();
                    _role.name = "系统管理员";
                    roleHelper.saveCreatedObject(_role);

                    var _role1 = roleHelper.createObject();
                    _role1.name = "CXOs";
                    roleHelper.saveCreatedObject(_role1);

                    userHelper.setUserRole(_user.userId, _role);
                    userHelper.setUserRole(_user.userId, _role1);
                    userHelper.setUserRole(_user2.userId, _role1);

                    RoleTypeHelper roleTypeHelper = new RoleTypeHelper(db);
                    RoleType       _roleType      = roleTypeHelper.createObject();
                    _roleType.name = "系统";
                    roleTypeHelper.saveCreatedObject(_roleType);

                    roleHelper.createRole_RoleTypeRelation(_role, _roleType);
                }
            }
            #endregion

            #region Query
            if (testQueryOrgStru)
            {
                using (var db = new EnouFlowOrgMgmtContext())
                {
                    //找到一个OrgSchema下的顶级业务实体集
                    var defaultOrg = db.orgs.ToList().FirstOrDefault();
                    if (defaultOrg == null)
                    {
                        Console.WriteLine("No defaultOrg Exists.");
                        Console.Read();
                        return;
                    }

                    var defaultOrgSchema = defaultOrg.orgSchema;
                    if (defaultOrgSchema == null)
                    {
                        Console.WriteLine("No defaultOrgSchema Exists.");
                        Console.Read();
                        return;
                    }

                    var rootBizEntities = defaultOrg.orgSchema.rootBizEntities;

                    var rootBizEntity = rootBizEntities[0];
                    if (rootBizEntity == null)
                    {
                        Console.WriteLine("No rootBizEntity Exists.");
                        Console.Read();
                        return;
                    }

                    //找到一个业务实体指定OrgSchema的下级业务实体集
                    var bizEntityChildren = rootBizEntity.getBizEntitiesChildren(
                        db, db.orgs.ToList().FirstOrDefault().orgSchema);

                    var bizEntityChild = bizEntityChildren[0];

                    //找到一个业务实体指定OrgSchema的上级业务实体
                    var bizEntityParent = bizEntityChild.getBizEntitiyParent(
                        db, db.orgs.ToList().FirstOrDefault().orgSchema);

                    //找到一个业务实体指定BizEntitySchema下的顶级部门集
                    var depts = bizEntityChild.bizEntitySchemas[0].getRootDepartments(db);

                    //找到一个部门的所有下级部门
                    var dps = depts.LastOrDefault().getDepartmentChildren(db);

                    //找到一个部门的上级部门
                    var dp1 = depts.LastOrDefault().getDepartmentChildren(db)[1];

                    var dpParent = dp1.getParentDepartment(db);
                    dpParent = dpParent.getParentDepartment(db);

                    //找到一个部门的所有用户
                    var usrs = dp1.getUserChildren(db);

                    //找到一个用户的所有部门
                    var u      = usrs[0];
                    var depts1 = u.getDepartmentsBelongTo(db);

                    //找到一个用户的所有角色
                    var roles = u.getRolesBelongTo(db);

                    //找到一个角色的所有用户
                    var cxos = db.roles.ToList()[1].getUsersBelongTo(db);

                    Console.WriteLine("查询完成.");
                    //return;
                }
            }
            #endregion

            #endregion

            #region Test OrgMgmtLib.SystemManager

            if (testCreateSystemManager)
            {
                using (var db = new EnouFlowOrgMgmtContext())
                {
                    //if (db.systemManagers.Count() <= 0)
                    //{
                    //  var _sysmgr = db.systemManagers.Create();
                    //  _sysmgr.name = "系统管理员";
                    //  _sysmgr.logonName = "sys";
                    //  _sysmgr.logonSalt = "f6152039-1745-4f4c-8f8e-3ed37770fa0d";
                    //  _sysmgr.logonPasswordHash = Convert.ToBase64String(
                    //    new System.Security.Cryptography.SHA256Managed().ComputeHash(
                    //      Encoding.UTF8.GetBytes(
                    //        "111111" + //测试密码
                    //        "f6152039-1745-4f4c-8f8e-3ed37770fa0d")));

                    //  db.systemManagers.Add(_sysmgr);
                    //  db.SaveChanges();
                    //  Console.WriteLine("成功创建系统管理员");
                    //}
                }
            }

            #endregion

            var PRFlowTemplateFilePath = @"C:\data\MyProjs\99Flow\EnouFlow\internal\test_flow.json";
            var POFlowTemplateFilePath = @"C:\data\MyProjs\99Flow\EnouFlow\EnouFlowEngine\PO.json";
            var GRFlowTemplateFilePath = @"C:\data\MyProjs\99Flow\EnouFlow\EnouFlowEngine\GR.json";
            var PMFlowTemplateFilePath = @"C:\data\MyProjs\99Flow\EnouFlow\EnouFlowEngine\PM.json";

            #region Test import Flow Definition JSON
            if (testImportFlowDefinitionJSON)
            {
                StreamReader oJsonFile = new StreamReader(
                    POFlowTemplateFilePath);

                //StreamReader oJsonFile = new System.IO.StreamReader(
                //@"C:\data\MyProjs\99Flow\EnouFlow\EnouFlowEngine\test_flow.json");

                var flowTemplateDefTest = JsonHelper.DeserializeJsonToObject <FlowTemplateDef>(
                    oJsonFile.ReadToEnd());

                dynamic temp = parseJsonToDynamicObject("{'AmountTotal': 49999}");

                Console.WriteLine("成功导入流程定义文件");
            }
            #endregion

            #region Test Create Flow Template in DB
            if (testCreateFlowTemplate)
            {
                StreamReader oJsonFile = new StreamReader(PMFlowTemplateFilePath);

                var tplJson             = oJsonFile.ReadToEnd();
                var flowTemplateDefTest = JsonHelper.DeserializeJsonToObject <FlowTemplateDef>(
                    tplJson);

                Tuple <bool, FlowTemplate, List <string> > result = FlowTemplateDBHelper.createFlowTemplate(
                    flowTemplateDefTest.basicInfo.guid,
                    flowTemplateDefTest.basicInfo.name,
                    flowTemplateDefTest.basicInfo.displayName,
                    flowTemplateDefTest.basicInfo.version,
                    "PM",
                    tplJson
                    );
                var tpl = result.Item2;
                //tpl.guid = flowTemplateDefTest.basicInfo.guid;
                //tpl.name = flowTemplateDefTest.basicInfo.name;
                //tpl.displayName = flowTemplateDefTest.basicInfo.displayName;
                //tpl.version = flowTemplateDefTest.basicInfo.version;
                //tpl.code = "PM";
                //tpl.flowTemplateJson = tplJson;

                FlowTemplateDBHelper.saveCreatedFlowTemplate(tpl);
                Console.WriteLine("成功创建流程定义模板");
            }
            #endregion

            #region Test Create FlowActions

            #region Test Create FlowActionStart
            if (testCreateFlowActionStart)
            {
                var actionStart = FlowActionHelper.PostFlowActionStart(
                    "aaaaaaa-1745-4f4c-8f8e-3ed37770fa0d",
                    "bizDocumentGuid", "PR",
                    "用户输入的备注内容aaa", null, null, 1,
                    "abc", 1, "def", null, "TestFlow-001",
                    "f6152039-1745-4f4c-8f8e-3ed37770fa0d"
                    );
            }
            #endregion

            #region Test Create FlowActionMoveTo
            if (testCreateFlowActionMoveTo_1)
            {
                var action1 = FlowActionHelper.PostFlowActionMoveTo(
                    "bbbbbbb-1745-4f4c-8f8e-3ed37770fa0d",
                    "bizDocumentGuid", "PR",
                    DateTime.Now.AddSeconds(1), "用户输入的备注内容bbb",
                    "{'AmountTotal': 50001}",
                    "{'AmountTotalUpdated': 49999}", 1,
                    "user-guid", 0, null, "TestFlow-001",
                    "f6152039-1745-4f4c-8f8e-3ed37770fa0d",
                    "9d985ac5-a1da-4c63-8aea-83e9974ffccc",
                    "9d4a6006-1099-46ad-b037-24e84476ab50",
                    new List <Paticipant>()
                {
                    new Paticipant("user",
                                   new PaticipantDigest(
                                       "李四",
                                       "27bcd361-12c7-4376-8dd8-ce68ad964431",
                                       2, null, null)
                                   )
                },
                    null,
                    null
                    );
            }

            if (testCreateFlowActionMoveTo_2)
            {
                var action2 = FlowActionHelper.PostFlowActionMoveTo(
                    "cccccc-1745-4f4c-8f8e-3ed37770fa0d",
                    "bizDocumentGuid", "PR",
                    DateTime.Now.AddSeconds(2),
                    "用户输入的备注内容ccc", null, null, 1,
                    "user-guid", 1, "flow-inst-guid", "TestFlow-001",
                    "2dde0ed2-c10b-4c98-b263-1016dcfa951d",
                    "55d72a3e-051a-46a0-9aae-0be1c62b2e24",
                    "ab0f92f6-35cd-44b9-a7bd-5a17e544aa9c",
                    new List <Paticipant>()
                {
                    new Paticipant("user",
                                   new PaticipantDigest(
                                       "王五",
                                       "f17004ea-1246-40df-9f48-2adf0cfa8517",
                                       3, null, null)
                                   )
                },
                    null,
                    null
                    );
            }

            if (testCreateFlowActionMoveTo_3)
            {
                var action3 = FlowActionHelper.PostFlowActionMoveTo(
                    "dddddd-1745-4f4c-8f8e-3ed37770fa0d",
                    "bizDocumentGuid", "PR",
                    DateTime.Now.AddSeconds(3),
                    "用户输入的备注内容ddd", null, null, 1,
                    "user-guid", 1, "flow-inst-guid", "TestFlow-001",
                    "ab0f92f6-35cd-44b9-a7bd-5a17e544aa9c",
                    "ceeae036-7b21-438f-bc46-33bfad0cc546",
                    "5ee19a5b-df8b-4c11-a0d4-082848b5f216",
                    new List <Paticipant>()
                {
                    new Paticipant("user",
                                   new PaticipantDigest(
                                       "张三",
                                       "85a14f4d-e68e-4684-88b2-3bf9dea386e6",
                                       1, null, null)
                                   )
                },
                    null,
                    null
                    );
            }

            if (testCreateFlowActionMoveTo_4)
            {
                var action4 = FlowActionHelper.PostFlowActionMoveTo(
                    "eeeeee-1745-4f4c-8f8e-3ed37770fa0d",
                    "bizDocumentGuid", "PR",
                    DateTime.Now.AddSeconds(4),
                    "用户输入的备注内容eee", null, null, 1,
                    "user-guid", 1, "flow-inst-guid", "TestFlow-001",
                    "5ee19a5b-df8b-4c11-a0d4-082848b5f216",
                    "0dade9b8-acc9-4223-8dab-9d55480722a8",
                    "c09fcfbe-92a9-48cd-bd14-975996e063a7",
                    new List <Paticipant>(),
                    null,
                    null
                    //{
                    //  new Paticipant("user",
                    //    new PaticipantDigest(
                    //    "川普",
                    //    "c4961686-41a6-469a-afa9-df05e42ba9f8",
                    //    16,null)
                    //    )
                    //}
                    );
            }

            #endregion

            #region TODO: Test Create FlowActionTake

            #endregion

            #region TODO: Test Create FlowActionInviteOther
            #endregion

            #region TODO: Test Create FlowActionFeedBackOfInvite
            #endregion

            #endregion

            #region Test Engine
            if (testRunEngine)
            {
                var dispatcher = new FlowActionRequestDispatcher();
                //EnumFlowActionRequestType[] types = new EnumFlowActionRequestType[] { EnumFlowActionRequestType.moveToAutoGenerated };
                //dispatcher.processNextActionOfSpecifiedInstance(1, types);
                var result = dispatcher.processNextAction();
            }

            #endregion

            #region Test BizDocumentSerialNoGenerator
            if (testBizDocumentSerialNoGenerator)
            {
                var prNumberNew = new OPAS2ModelDBHelper().
                                  generateDocumentSerialNo(EnumBizDocumentType.PR, "QOROS", "SH", "2017", "IT");
                Console.WriteLine(prNumberNew);
            }

            #endregion

            #region Test CreatePR
            if (testCreatePR)
            {
                var prNumberNew = new OPAS2ModelDBHelper().
                                  generateDocumentSerialNo(EnumBizDocumentType.PR, "QOROS", "SH", "2017", "IT");
                Console.WriteLine(prNumberNew);
                using (var db = new OPAS2DbContext())
                {
                    var pr = db.purchaseReqs.Create();
                    pr.guid       = "test-pr-guid:" + Guid.NewGuid().ToString();
                    pr.documentNo = new OPAS2ModelDBHelper().generateDocumentSerialNo(
                        EnumBizDocumentType.PR, "QOROS", "SH", "2017", "IT");
                    pr.WBSNo = "test-WBS";
                    pr.contactOfficePhone     = "contactOfficePhone";
                    pr.contactMobile          = "contactMobile";
                    pr.contactOtherMedia      = "contactOtherMedia";
                    pr.departmentId           = 1;
                    pr.departmentIdBelongTo   = 1;
                    pr.costCenterId           = 1;
                    pr.expectReceiveBeginTime = DateTime.Now;
                    pr.expectReceiveEndTime   = DateTime.Now;
                    pr.isBidingRequired       = true;
                    pr.noBiddingReason        = "noBiddingReason";
                    pr.reason                = "reason";
                    pr.description           = "description";
                    pr.estimatedCost         = (decimal)123456.789;
                    pr.currencyTypeId        = 1;
                    pr.mainCurrencyRate      = (decimal)1.0;
                    pr.estimatedCostInRMB    = (decimal)123456.789;
                    pr.averageBenchmark      = (decimal)787654.78;
                    pr.benchmarkDescription  = "benchmarkDescription";
                    pr.isFirstBuy            = false;
                    pr.firstBuyDate          = DateTime.Now;
                    pr.firstCostAmount       = (decimal)73663387.87;
                    pr.firstBuyDescription   = "firstBuyDescription";
                    pr.remarkOfAprrovers     = "remarkOfAprrovers";
                    pr.otherVendorsNotInList = "otherVendorsNotInList";
                    pr.submitTime            = DateTime.Now;
                    pr.submitor              = "ChaoQin";
                    pr.submitorUserId        = 1;
                    pr.creator               = "ChaoQin";
                    pr.creatorUserId         = 1;

                    var prDtl1 = db.purchaseReqDetails.Create();
                    prDtl1.PurchaseReq   = pr;
                    prDtl1.estimatedCost = (decimal)123.45;
                    prDtl1.lineNo        = 5;
                    prDtl1.itemName      = "name1";
                    prDtl1.itemType      = (EnumPRItemType)1;
                    prDtl1.description   = "description1";
                    prDtl1.creator       = "ChaoQin";
                    prDtl1.creatorUserId = 1;

                    //pr.details.Add(prDtl1);

                    db.purchaseReqs.Add(pr);
                    db.purchaseReqDetails.Add(prDtl1);

                    db.SaveChanges();

                    Console.WriteLine("PR: " + pr.purchaseReqId.ToString());
                }
            }

            #endregion

            #region Test GenerateBizDataPayloadJson
            if (testGenerateBizDataPayloadJson)
            {
                using (var db = new OPAS2DbContext())
                {
                    var     pr             = db.purchaseReqs.Find(8);
                    dynamic bizDataPayload = new ExpandoObject();
                    bizDataPayload.document = pr;
                    //bizDataPayload.subDocuments = pr.details;
                    bizDataPayload.AmountTotal =
                        pr.details.Aggregate <PurchaseReqDetail, decimal>(
                            0, (total, detail) =>
                    {
                        return(total + detail.estimatedCost.Value);
                    });
                    var s = JsonConvert.SerializeObject(bizDataPayload, Formatting.Indented,
                                                        new JsonSerializerSettings
                    {
                        ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                    }
                                                        );
                    Console.WriteLine(s);
                }
            }
            #endregion

            #region testFlowDynamicUser
            Console.Out.WriteLine("Enter into script:");
            var _session     = new DictionaryContext();
            var flowInstDb   = new EnouFlowInstanceContext();
            var flowInstance = FlowInstanceHelper.GetFlowInstance(42, flowInstDb);

            _session.globals.Add("flowInstance", flowInstance);
            var _references = new Assembly[] { typeof(DictionaryContext).Assembly,
                                               typeof(System.Runtime.CompilerServices.DynamicAttribute).Assembly,
                                               typeof(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo).Assembly,
                                               typeof(ExpandoObject).Assembly,
                                               typeof(JsonConvert).Assembly,
                                               typeof(ExpandoObjectConverter).Assembly,
                                               typeof(Paticipant).Assembly,
                                               typeof(UserDTO).Assembly,
                                               typeof(FlowInstance).Assembly,
                                               typeof(List <>).Assembly };
            var _imports = new string[] { typeof(DictionaryContext).Namespace,
                                          typeof(System.Runtime.CompilerServices.DynamicAttribute).Namespace,
                                          typeof(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo).Namespace,
                                          typeof(ExpandoObject).Namespace,
                                          typeof(JsonConvert).Namespace,
                                          typeof(ExpandoObjectConverter).Namespace,
                                          typeof(Paticipant).Namespace,
                                          typeof(UserDTO).Namespace,
                                          typeof(FlowInstance).Namespace,
                                          typeof(List <>).Namespace };
            var _options = ScriptOptions.Default
                           .AddReferences(_references)
                           .AddImports(_imports);
            //var code = @"var result = new List<UserDTO>();
            //              result.Add(OrgMgmtDBHelper.getUserDTO(((FlowInstance)globals[""flowInstance""]).creatorId));
            //              return result;";

            using (var db = new EnouFlowOrgMgmtContext())
            {
                var retShouldBe = new DepartmentHelper(db).getUserDTOsOfPositionInDepartment(
                    new UserHelper(db).getUserDefaultDepartment(flowInstance.creatorId).departmentId,
                    UserPositionToDepartment.manager);
            }
            var code    = @"
      FlowInstance flowInstance = (FlowInstance)globals[""flowInstance""];
      Department department = OrgMgmtDBHelper.getUserDefaultDepartment(flowInstance.creatorId);
      if(department!=null){
        return OrgMgmtDBHelper.getUserDTOsOfPositionInDepartment(
              department.departmentId, UserPositionToDepartment.manager);
      }else{
        return null;
      }";
            var result1 = CSharpScript.RunAsync(code,
                                                globals: _session, options: _options).Result.ReturnValue;
            var retList = (List <UserDTO>)result1;

            #endregion

            Console.WriteLine("All done!");
            Console.Read();
        }
Example #13
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));
            }
        }
Example #14
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));
            }
        }