Workflow design process

1. Business Scenario: Users login, receive notifications, approve business, continue to flow according to the configuration process, and send the final audit back to the applicant (final approval is completed, final approval does not agree that the applicant can continue to modify the submission).

2. The process of thinking:

- User login first obtains unprocessed message records and reminds processing of pre-approval records.
Configuration process master table and associated step list (flow by serial number)
2. Create pre-approval records (associated processes and steps) when submitting business approval, send messages to the reviewer of the first step, and modify the status of the business master table.
Step reviewer agrees: update the approval record of the owner of the node, continue sending messages to the next one if the process details still have the next approval, create the next pre-approval record, modify the status of the business master table, and update the status of the message record of oneself and the owner of the node.
Step Reviewers disagree: Stop sending the next one, send it back to the applicant, update the status of the message record and the approval record of yourself and the owner of this node
Each node can be configured with multiple approvers, and the first approval node must be the same department before it can be approved (multiple department leaders can be configured, but only to the same department leaders when applications are sent)
The login's approval shall be based on the pre-approval record sheet to check whether there is a record to be approved and to determine whether there is the next step. After the approval is completed, it shall continue to be sent to the next step.

3. Database design:

-------------------Process Approval Design--------------------------Create Process Tables Flow: ID,Number, process name, category, developer, date and status(Is it enabled?),Remarks
SELECT * FROM [dbo].[Flow]
--Create process approval list(Relevant process tables, one-to-many) FlowDetail: ID,Number, serial number, step name, reviewer's account of process master table(Multiple),Name of Judges(Multiple),state(Is it enabled?),
select *  from FlowDetail
--Create an Approval Record Table FlowRecords:ID,Main Table Number, Process Step Number, Business Number, Reviewer Account Number, Reviewer Name, Approval Status(1 Agree, 2 disagree,3 Audit in progress),Examination and approval date, remarks,
select * from FlowRecords where BusinessNum='4C4CED8E3F8D42C997E2424D83C447B8'
--Create a message notification table Message :ID,Title, Content, Business Number, Receiver's Account, Receiver's Name, Sender's Account, Sender's Name, Sender's Time, Status(1 Unprocessed, 2 processed)
select * from FlowMessage where BusinessNum='4C4CED8E3F8D42C997E2424D83C447B8'
 --Business Main Table (Increase Field Related Approval Process: Process Main Table Number, Process Details Number)

4. Code process:

        /// <summary>
        /// Audit documents
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public override string Audite(ReceiveOrderEntity entity)
        {
            using (TransactionScope ts = new TransactionScope())
            {
                //1.Obtain records of your current business needs to be audited,No, it can't be audited.
                FlowRecordsEntity record = new FlowRecordsEntity();
                record.IncludeAll();
                record.Where(a => a.BusinessNum == entity.SnNum).And(a => a.ApproverUserNum == entity.UserName);
                var myRecord = this.FlowRecords.GetList(record).FirstOrDefault();
                if (myRecord == null) return "1003";
                if(myRecord.ApproverResult!=3) return "1004";
                //2.Get whether there are next steps in the process
                FlowProvider provider = new FlowProvider(CompanyID);
                List<FlowDetailEntity> FlowDetails = provider
                    .GetFlowDetail(new FlowDetailEntity {FlowSnNum = entity.FlowSnNum}).OrderBy(x => x.Seq).ToList();
                FlowDetailEntity nextFlowDeail = null;
                int line = 0;
                if (FlowDetails != null && FlowDetails.Count > 0)
                {
                    int count = 0;
                    foreach (var obj in FlowDetails)
                    {
                        if (obj.Seq == myRecord.FlowDtlSeq)
                            break;
                        else
                            count++;
                    }
                    //Is there a next step in the process?
                    if (FlowDetails.Count > count && FlowDetails.Count!=count+1)
                    {
                        nextFlowDeail = FlowDetails[count + 1];
                    }
                }
                #region Disagree with process
                if (entity.Status == (int) EAudite.NotPass)
                {
                    entity.FlowDtlSeq = myRecord.FlowDtlSeq;
                    entity.IncludeStatus(true).IncludeReason(true).IncludeFlowDtlSeq(true)
                        .Where(a => a.SnNum == entity.SnNum)
                        .And(a => a.CompanyID == this.CompanyID)
                        ;
                    line += this.ReceiveOrder.Update(entity);
                    //1.Update your own approval records
                    myRecord.ApproverResult = 2;
                    myRecord.ApproverDate = DateTime.Now;
                    myRecord.IncludeApproverResult(true).IncludeApproverDate(true);
                    line += this.FlowRecords.Update(myRecord);
                    //2.Renewal of oneself(This step is for everyone)Message Recording
                    FlowMessageEntity msg = new FlowMessageEntity();
                    msg.Status = 2;
                    msg.IncludeStatus(true);
                    msg.Where(a => a.BusinessNum == entity.SnNum).And(a => a.FlowSnNum == entity.FlowSnNum)
                        .And(a => a.FlowDtlSeq == myRecord.FlowDtlSeq);
                    line += this.FlowMessage.Update(msg);
                    //3.Send only messages back to the applicant
                    FlowMessageEntity nextMsg = new FlowMessageEntity()
                    {
                        SendUserNum = entity.UserName,
                        SendUserName = entity.RealName,
                        AcceptUserNum = entity.CusNum,
                        AcceptUserName = entity.CusName,
                        BusinessNum = entity.SnNum,
                        FlowSnNum = entity.FlowSnNum,
                        FlowDtlSeq = myRecord.FlowDtlSeq,
                        Status = 1,
                        SendDate = DateTime.Now,
                        Title = "Examination and verification of the application for the acquisition of articles",
                        Notice = "Your number is:"+entity.OrderNum+"The application for goods acquisition has been rejected!"
                    };
                    nextMsg.IncludeAll();
                    line += this.FlowMessage.Add(nextMsg);
                    ts.Complete();
                    return line > 0 ? "1000" : string.Empty;
                }
                #endregion
                #region Consent process
                else if (entity.Status == (int) EAudite.Pass) 
                {
                    //1.Update your own approval records
                    myRecord.ApproverResult = 1;
                    myRecord.ApproverDate = DateTime.Now;
                    myRecord.IncludeApproverResult(true).IncludeApproverDate(true);
                    line += this.FlowRecords.Update(myRecord);
                    //2.Renewal of oneself(This step is for everyone)Message Recording
                    FlowMessageEntity msg = new FlowMessageEntity();
                    msg.Status = 2;
                    msg.IncludeStatus(true);
                    msg.Where(a => a.BusinessNum == entity.SnNum).And(a => a.FlowSnNum == entity.FlowSnNum)
                        .And(a => a.FlowDtlSeq == myRecord.FlowDtlSeq);
                    line += this.FlowMessage.Update(msg);
                    //If there is a next audit
                    if (nextFlowDeail != null)
                    {
                        //1.Modify business status
                        entity.Status = 5;
                        //2.Get a list of approvers'accounts for the next step
                        var users = nextFlowDeail.ApproverUserNum.Split(',')
                            .Where(x => string.IsNullOrEmpty(x) == false).ToList();
                        List<AdminEntity> sendUser = new List<AdminEntity>();
                        users.ForEach(x =>
                        {
                            AdminEntity model = new AdminEntity();
                            model.IncludeAll();
                            model.Where(a => a.IsDelete == (int)EIsDelete.NotDelete).And(item => item.UserName == x);
                            var user = this.Admin.GetSingle(model);
                            if (user != null)
                            {
                                sendUser.Add(user);
                            }
                        });
                        foreach (var user in sendUser)
                        {
                            //3.Create a pre-approval record for the next approver
                            FlowRecordsEntity nextRecord = new FlowRecordsEntity()
                            {
                                ApproverUserName = user.RealName,
                                ApproverUserNum = user.UserName,
                                BusinessNum = entity.SnNum,
                                FlowSnNum = entity.FlowSnNum,
                                FlowDtlSeq = nextFlowDeail.Seq,
                                ApproverResult = 3
                            };
                            nextRecord.IncludeAll();
                            line += this.FlowRecords.Add(nextRecord);
                            //4.Send a message to the next approver
                            FlowMessageEntity nextMsg = new FlowMessageEntity()
                            {
                                SendUserNum = entity.UserName,
                                SendUserName = entity.RealName,
                                AcceptUserNum = user.UserName,
                                AcceptUserName = user.RealName,
                                BusinessNum = entity.SnNum,
                                FlowSnNum = entity.FlowSnNum,
                                FlowDtlSeq = nextFlowDeail.Seq,
                                Status = 1,
                                SendDate = DateTime.Now,
                                Title = "Examination and verification of the application for the acquisition of articles",
                                Notice = "No.:" + entity.OrderNum + "The application for goods acquisition needs to be examined by you! ____________"
                            };
                            nextMsg.IncludeAll();
                            line += this.FlowMessage.Add(nextMsg);
                        }
                    }
                    else
                    {
                        //Process End
                        entity.Status = (int) EAudite.Pass;
                        //Send a message back to the applicant
                        FlowMessageEntity fristMsg = new FlowMessageEntity()
                        {
                            SendUserNum = entity.UserName,
                            SendUserName = entity.RealName,
                            AcceptUserNum = entity.CusNum,
                            AcceptUserName = entity.CusName,
                            BusinessNum = entity.SnNum,
                            FlowSnNum = entity.FlowSnNum,
                            FlowDtlSeq = myRecord.FlowDtlSeq,
                            Status = 1,
                            SendDate = DateTime.Now,
                            Title = "Examination and verification of the application for the acquisition of articles",
                            Notice = "Your number is:" + entity.OrderNum + "The application for goods acquisition has been approved!"
                        };
                        fristMsg.IncludeAll();
                        line += this.FlowMessage.Add(fristMsg);
                    }
                    entity.FlowDtlSeq = myRecord.FlowDtlSeq;
                    entity.AuditeTime = DateTime.Now;
                    entity.Include(a => new {a.Status, a.AuditUser, a.AuditeTime, a.Reason, a.Remark,a.FlowDtlSeq});
                    entity.Where(a => a.SnNum == entity.SnNum).And(a => a.CompanyID == this.CompanyID);
                    line += this.ReceiveOrder.Update(entity);
                    ts.Complete();
                    return line > 0 ? EnumHelper.GetEnumDesc<EReturnStatus>(EReturnStatus.Success) : string.Empty;
                }
                #endregion
               
            }
            return string.Empty;
        }

 

 

 

Keywords: ASP.NET Database

Added by themire on Tue, 13 Aug 2019 15:16:51 +0300