private static void checkToCloseWorkflowAdimStates(ActorApprovalType approvalType, WorkflowState to, SNAP_Workflow_State newState, DateTime dueDate) { if (approvalType == ActorApprovalType.Workflow_Admin) { if (to == WorkflowState.Closed_Cancelled || to == WorkflowState.Closed_Completed || to == WorkflowState.Closed_Denied || to == WorkflowState.Closed_Abandon) { newState.completedDate = DateTime.Now; newState.dueDate = dueDate; } } }
private static DateTime getDueDate(ActorApprovalType approvalType, WorkflowState fr, WorkflowState to) { int day = 1; DateTime due; SLAConfiguration slaCfg = new SLAConfiguration((NameValueCollection)ConfigurationManager.GetSection( "Apollo.AIM.SNAP/Workflow.SLA")); switch (approvalType) { case ActorApprovalType.Manager: day = System.Convert.ToInt16(slaCfg.ManagerApprovalInDays); break; case ActorApprovalType.Team_Approver: day = System.Convert.ToInt16(slaCfg.TeamApprovalInDays); break; case ActorApprovalType.Technical_Approver: day = System.Convert.ToInt16(slaCfg.TechnicalApprovalInDays); break; case ActorApprovalType.Workflow_Admin: if (to == WorkflowState.Workflow_Created) // same as the due day for technical approval since workflow admin depend on it day = System.Convert.ToInt16(slaCfg.TechnicalApprovalInDays); break; } using (var db = new SNAPDatabaseDataContext()) { due = db.udf_get_next_business_day(DateTime.Now, day) ?? DateTime.Now.AddDays(-1); } return due; }
private static void checkToCloseMangerOrTeamOrTechnicalWorkflowStates(ActorApprovalType approvalType, WorkflowState to, SNAP_Workflow_State newState, DateTime dueDate) { if (approvalType != ActorApprovalType.Workflow_Admin) { if (to == WorkflowState.Approved || to == WorkflowState.Closed_Denied) { newState.completedDate = DateTime.Now; newState.dueDate = dueDate; } } }
internal static void stateTransition(ActorApprovalType approvalType, SNAP_Workflow wf, WorkflowState from, WorkflowState to) { // // !!! if the state completion date is null, it is the WF current state !!! // // a brand new apporval WF has from not-active to not-active state and have not pref state yet, // such as when creating a new manager, team and techical approval workflow. // Rememeber that: the accessTeamWF has prev state because it being inserted by the // store procedure when inserting the request the first time var prevDueDate = DateTime.Now; SNAP_Workflow_State prevWFState=null; if (from != WorkflowState.Not_Active) { // complete current/prev state prevWFState = wf.SNAP_Workflow_States.Single( s => s.workflowStatusEnum == (byte)from && s.completedDate == null); // To prevent looping in old state, null date is the latest state if (prevWFState != null) { prevWFState.completedDate = DateTime.Now; prevDueDate = prevWFState.dueDate ?? DateTime.Now; } } // create new state var newState = new SNAP_Workflow_State() { completedDate = null, //notifyDate = DateTime.Now, dueDate = getDueDate(approvalType, from, to), workflowStatusEnum = (byte)to }; // we don't need to notify workflow admin/access team. they have to monitor the open request constantly if (approvalType == ActorApprovalType.Workflow_Admin) { newState.notifyDate = DateTime.Now; } else if (from == WorkflowState.Not_Active && to == WorkflowState.Pending_Approval) { // approval wf from not-active -> pending approval, we alread send the email out newState.notifyDate = DateTime.Now; } if (prevWFState != null) { newState.notifyDate = prevWFState.notifyDate; // just propergate the notify date to new state...it is primarily for approval manager } // for end/close states set the completion date checkToCloseWorkflowAdimStates(approvalType, to, newState, prevDueDate); // workflowstate.approved is end state for manger, team approval and techical aproval but not for workflow adim checkToCloseMangerOrTeamOrTechnicalWorkflowStates(approvalType, to, newState, prevDueDate); // go to new state wf.SNAP_Workflow_States.Add(newState); }
protected bool wfStateChange(ActorApprovalType approvalType, WorkflowState toState) { var wf = db.SNAP_Workflows.Single(w => w.pkId == Id); if (wf.SNAP_Request.statusEnum != (byte)RequestState.Pending) return false; var currentState = wf.SNAP_Workflow_States.Single(s => s.completedDate == null); AccessRequest.stateTransition(approvalType, wf, (WorkflowState)currentState.workflowStatusEnum, toState); // !!! because of this we are force to use TransactionScope // !!! so we can make sure every technical approver has approved which moves the request approved state db.SubmitChanges(); return true; }
protected WebMethodResponse requestToChangeBy(ActorApprovalType approvalType, string comment) { /* if (req.statusEnum != (byte)RequestState.Pending) return new WebMethodResponse(false, "Approver Error", AccessRequest.SeeDetailsReqTracking); */ //using (TransactionScope ts = new TransactionScope()) //{ if (wfStateChange(approvalType, WorkflowState.Change_Requested)) { comment = comment.Replace("<br />", string.Empty); approvalRequestToChange(comment); db.SubmitChanges(); //ts.Complete(); return new WebMethodResponse(true, "Approver", "Success"); ; } //} return new WebMethodResponse(false, "Approver Error", AccessRequest.SeeDetailsReqTracking); ; }
protected void approvalDeny(ActorApprovalType type, string comment) { var wfs = accessReq.FindApprovalTypeWF(db, (byte)type); foreach (var f in wfs) { if (f.SNAP_Workflow_States.Count(s => s.workflowStatusEnum == (byte)WorkflowState.Closed_Denied) == 1) { f.SNAP_Workflow_Comments.Add(new SNAP_Workflow_Comment() { commentText = comment, createdDate = DateTime.Now, commentTypeEnum = (byte)CommentsType.Denied }); // set accessTeam WF and request to close-denied AccessRequest.stateTransition(ActorApprovalType.Workflow_Admin, accessTeamWF, WorkflowState.Workflow_Created, WorkflowState.Closed_Denied); req.statusEnum = (byte)RequestState.Closed; comment = comment.Replace("<br />", string.Empty); if (req.submittedBy.ToString() != req.userId.ToString()) { Email.SendTaskEmail(EmailTaskType.UpdateRequester, req.userId + "@apollogrp.edu", req.userDisplayName, req.pkId, req.submittedBy, WorkflowState.Closed_Denied, comment); } Email.SendTaskEmail(EmailTaskType.UpdateRequester, req.submittedBy + "@apollogrp.edu", Utilities.GetFullNameByLoginId(req.submittedBy), req.pkId, req.submittedBy, WorkflowState.Closed_Denied, comment); Email.SendTaskEmail(EmailTaskType.UpdateRequester, ConfigurationManager.AppSettings["AIM-DG"], "AIM for " + req.userDisplayName, req.pkId, req.submittedBy, WorkflowState.Closed_Denied, comment); break; } } }