using OptimaJet.Workflow; using OptimaJet.Workflow.Core.Builder; using OptimaJet.Workflow.Core.Bus; using OptimaJet.Workflow.Core.Runtime; using OptimaJet.Workflow.Core.Parser; using System.Collections.Generic; using System; using System.Collections.Specialized; using System.Configuration; using System.IO; using System.Linq; using System.Text; using System.Web.Mvc; using System.Xml.Linq; using WorkflowRuntime = OptimaJet.Workflow.Core.Runtime.WorkflowRuntime; using jQuery.DataTables.Mvc; using EnVisage.Code.BLL; using EnVisage.App_Start; using EnVisage.Code; using EnVisage.Models; using System.Net; using Kendo.Mvc.UI; using Kendo.Mvc.Extensions; namespace EnVisage.Controllers { public class WorkFlowDefinitionController : BaseController { #region Index page public ActionResult Index() { return View(); } [HttpPost] public JsonResult Index(JQueryDataTablesModel jQueryDataTablesModel) { int totalRecordCount; int searchRecordCount; var types = GetWorkFlowDefs(startIndex: jQueryDataTablesModel.iDisplayStart, pageSize: jQueryDataTablesModel.iDisplayLength, sortedColumns: jQueryDataTablesModel.GetSortedColumns(), totalRecordCount: out totalRecordCount, searchRecordCount: out searchRecordCount, searchString: jQueryDataTablesModel.sSearch); return this.DataTablesJson(items: types, totalRecords: totalRecordCount, totalDisplayRecords: searchRecordCount, sEcho: jQueryDataTablesModel.sEcho); } [HttpPost] public JsonResult WorkFlowNameAvailable(string Name, Guid id) { if (string.IsNullOrWhiteSpace(Name)) return Json(false); try { var isUnique = !(new WorkFlowManager(this.DbContext)).RecordExists(Name, id); return Json(isUnique); } catch (Exception exception) { LogException(exception); return Json(false); } } private IEnumerable GetWorkFlowDefs(int startIndex, int pageSize, IEnumerable sortedColumns, out int totalRecordCount, out int searchRecordCount, string searchString) { var wfMan = new WorkFlowManager(this.DbContext); var query = wfMan.WorkFlowModelBasicQuery; var baseQuery = wfMan.WorkFlowModelBasicQuery; //filter if (!string.IsNullOrWhiteSpace(searchString)) { query = query.Where(c => c.Name.ToLower().Contains(searchString.ToLower())); } //sort foreach (var sortedColumn in sortedColumns) { switch (sortedColumn.PropertyName) { case "Name": if (sortedColumn.Direction == SortingDirection.Ascending) query = query.OrderBy(c => c.Name); else query = query.OrderByDescending(c => c.Name); break; case "Area": if (sortedColumn.Direction == SortingDirection.Ascending) query = query.OrderBy(c => c.DomainId); else query = query.OrderByDescending(c => c.DomainId); break; } } totalRecordCount = baseQuery.Count(); searchRecordCount = query.Count(); return query.Skip(startIndex).Take(pageSize).ToList(); } [HttpGet] public ActionResult Edit(Guid? id) { try { if (id.HasValue && id.Value != Guid.Empty) { var wfMan = new WorkFlowManager(this.DbContext); var wfm = (WorkFlowModel) wfMan.Load(id); if (wfm == null) return new HttpStatusCodeResult(HttpStatusCode.NotFound); return PartialView("_edit", wfm); } else { return PartialView("_edit", (new WorkFlowModel())); } } catch (BLLException blEx) { if (blEx.DisplayError) SetErrorScript(message: blEx.Message); else { LogException(blEx); SetErrorScript(); } } catch (Exception exception) { LogException(exception); SetErrorScript(); } return new HttpStatusCodeResult(HttpStatusCode.InternalServerError); } [HttpPost] public ActionResult Edit(WorkFlowModel workFlowHeader) { if (workFlowHeader.Id != Guid.Empty && ContentLocker.IsLock("WFL", workFlowHeader.Id.ToString(), User.Identity.GetUserName())) { return Json( new { Success = false, StatusMessage = "Workflow Process not created/Updated due to errors", Id = Guid.Empty }); } try { bool isNew = workFlowHeader.Id.Value == Guid.Empty; string userid = this.HttpContext.User.Identity.GetUserId(); var wfMan = new WorkFlowManager(this.DbContext); var id = wfMan.save(workFlowHeader, Guid.Parse(userid)); this.DbContext.SaveChanges(); var wfm = wfMan.Load(id); if (wfm == null) return new HttpStatusCodeResult(HttpStatusCode.ExpectationFailed); if (isNew) { UrlHelper u = new UrlHelper(HttpContext.Request.RequestContext); string url = u.Action("EditScheme", "WorkFlowDefinition", new { WorkFlowSchemaId = wfm.Id }); return Json( new { Success = true, StatusMessage = "Workflow created ", RedirectUrl = url, }); } else { return Json( new { Success = true, StatusMessage = "Workflow updated", }); } } catch (BLLException blEx) { if (blEx.DisplayError) SetErrorScript(message: blEx.Message); else { LogException(blEx); SetErrorScript(); } } catch (Exception exception) { LogException(exception); SetErrorScript(); } return new HttpStatusCodeResult(HttpStatusCode.InternalServerError); } public ActionResult Delete(WorkFlowModel model) { if (model == null || ContentLocker.IsLock("WFL", model.Id.ToString(), User.Identity.GetUserName())) return new HttpStatusCodeResult(HttpStatusCode.BadRequest); try { var wflMan = new WorkFlowManager(this.DbContext); var modelToDelete = wflMan.Load(model.Id); wflMan.Delete(modelToDelete); this.DbContext.SaveChanges(); ContentLocker.RemoveLock("WFL", model.Id.ToString(), User.Identity.GetUserName()); return new HttpStatusCodeResult(HttpStatusCode.OK); } catch (BLLException blEx) // handle any system specific error { // display error message if required if (blEx.DisplayError) ModelState.AddModelError(string.Empty, blEx.Message); else // if display not requried then display modal form with general error message { LogException(blEx); SetErrorScript(); } } catch (Exception exception) // handle any unexpected error { LogException(exception); SetErrorScript(); } return new HttpStatusCodeResult(HttpStatusCode.InternalServerError); } public ActionResult EditScheme(Guid? WorkFlowSchemaId) { var wfMan = new WorkFlowManager(this.DbContext); WorkFlowModel wfm = null; if (WorkFlowSchemaId.HasValue) wfm = (WorkFlowModel) wfMan.Load(WorkFlowSchemaId.Value); else wfm = (WorkFlowModel) wfMan.LoadNewScheme(); return View("EditScheme", wfm); } #endregion public ActionResult API() { var pars = new NameValueCollection(); pars.Add(Request.Params); Stream filestream = null; if (pars["schemecode"] != null) { string code = pars["schemecode"]; var schema = this.DbContext.WorkflowProcessSchemes.Where(x => x.SchemeCode == code).Select(x => x.Scheme).FirstOrDefault(); if (schema == null) schema = this.DbContext.WorkflowSchemes.Where(x => x.Code == code).Select(x => x.Scheme).FirstOrDefault(); if (schema != null) { byte[] byteArray = Encoding.UTF8.GetBytes(schema); filestream = new MemoryStream(byteArray); } } if (Request.HttpMethod.Equals("POST", StringComparison.InvariantCultureIgnoreCase)) { var parsKeys = pars.AllKeys; foreach (var key in Request.Form.AllKeys) { if (!parsKeys.Contains(key)) { pars.Add(Request.Form); } } } var res = getRuntime.DesignerAPI(pars, filestream, true); if (pars["operation"].ToLower() == "downloadscheme") return File(Encoding.UTF8.GetBytes(res), "text/xml", "scheme.xml"); return Content(res); } private WorkflowRuntime getRuntime { get { return EnVisage.Code.WorkFlowEngine.Runtime(this.DbContext.Database.Connection.ConnectionString); //return null; } } #region roles public ActionResult RoleIndex() { return View(); } [HttpPost] public JsonResult RoleIndex(JQueryDataTablesModel jQueryDataTablesModel) { int totalRecordCount; int searchRecordCount; var types = GetWorkFlowRoles(startIndex: jQueryDataTablesModel.iDisplayStart, pageSize: jQueryDataTablesModel.iDisplayLength, sortedColumns: jQueryDataTablesModel.GetSortedColumns(), totalRecordCount: out totalRecordCount, searchRecordCount: out searchRecordCount, searchString: jQueryDataTablesModel.sSearch); return this.DataTablesJson(items: types, totalRecords: totalRecordCount, totalDisplayRecords: searchRecordCount, sEcho: jQueryDataTablesModel.sEcho); } private IEnumerable GetWorkFlowRoles(int startIndex, int pageSize, IEnumerable sortedColumns, out int totalRecordCount, out int searchRecordCount, string searchString) { var wfMan = new WorkFlowManager(this.DbContext); var query = wfMan.WorkFlowRoleModelBasicQuery; //filter if (!string.IsNullOrWhiteSpace(searchString)) { query = query.Where(c => c.RoleName.ToLower().Contains(searchString.ToLower())); } //sort foreach (var sortedColumn in sortedColumns) { switch (sortedColumn.PropertyName) { case "RoleName": if (sortedColumn.Direction == SortingDirection.Ascending) query = query.OrderBy(c => c.RoleName); else query = query.OrderByDescending(c => c.RoleName); break; case "count": if (sortedColumn.Direction == SortingDirection.Ascending) query = query.OrderBy(c => c.UserCount); else query = query.OrderByDescending(c => c.UserCount); break; } } totalRecordCount = DbContext.WorkFlowRoles.Count(); searchRecordCount = query.Count(); return query.Skip(startIndex).Take(pageSize).ToList(); } [HttpPost] public JsonResult WorkFlowRoleNameAvailable(string RoleName, Guid id) { if (string.IsNullOrWhiteSpace(RoleName)) return Json(false); try { var isUnique = !(new WorkFlowManager(this.DbContext)).RoleRecordExists(RoleName, id); return Json(isUnique); } catch (Exception exception) { LogException(exception); return Json(false); } } [HttpGet] public ActionResult EditRole(Guid? id) { try { if (id.HasValue && id.Value != Guid.Empty) { var wfMan = new WorkFlowManager(this.DbContext); var wfm = (WorkFlowRoleModel) wfMan.LoadRole(id); if (wfm == null) return new HttpStatusCodeResult(HttpStatusCode.NotFound); return PartialView("_editRole", wfm); } else { return PartialView("_editRole", (new WorkFlowRoleModel())); } } catch (BLLException blEx) { if (blEx.DisplayError) SetErrorScript(message: blEx.Message); else { LogException(blEx); SetErrorScript(); } } catch (Exception exception) { LogException(exception); SetErrorScript(); } return new HttpStatusCodeResult(HttpStatusCode.InternalServerError); } [HttpPost] public ActionResult EditRole(WorkFlowRoleModel workFlowrole) { if (workFlowrole.Id != Guid.Empty && ContentLocker.IsLock("WFLR", workFlowrole.Id.ToString(), User.Identity.GetUserName())) { return Json( new { Success = false, StatusMessage = "Workflow role not created/Updated due to errors", Id = Guid.Empty }); } try { bool isNew = workFlowrole.Id.Value == Guid.Empty; var wfMan = new WorkFlowManager(this.DbContext); var id = wfMan.saveRole(workFlowrole); this.DbContext.SaveChanges(); if (isNew) return Json( new { Success = true, StatusMessage = "Workflow Role created", }); else return Json( new { Success = true, StatusMessage = "Workflow Role updated", }); } catch (BLLException blEx) { if (blEx.DisplayError) SetErrorScript(message: blEx.Message); else { LogException(blEx); SetErrorScript(); } } catch (Exception exception) { LogException(exception); SetErrorScript(); } return new HttpStatusCodeResult(HttpStatusCode.InternalServerError); } public ActionResult DeleteRole(WorkFlowRoleModel model) { if (model == null || ContentLocker.IsLock("WFLR", model.Id.ToString(), User.Identity.GetUserName())) return new HttpStatusCodeResult(HttpStatusCode.BadRequest); try { var wflMan = new WorkFlowManager(this.DbContext); var modelToDelete = wflMan.LoadRole(model.Id); wflMan.DeleteRole(modelToDelete); this.DbContext.SaveChanges(); ContentLocker.RemoveLock("WFLR", model.Id.ToString(), User.Identity.GetUserName()); return new HttpStatusCodeResult(HttpStatusCode.OK); } catch (BLLException blEx) // handle any system specific error { // display error message if required if (blEx.DisplayError) ModelState.AddModelError(string.Empty, blEx.Message); else // if display not requried then display modal form with general error message { LogException(blEx); SetErrorScript(); } } catch (Exception exception) // handle any unexpected error { LogException(exception); SetErrorScript(); } return new HttpStatusCodeResult(HttpStatusCode.InternalServerError); } [HttpGet] public JsonResult GetWorkFlowRoles() { var roles = (new WorkFlowManager(null)).getAllRolesByName(); return this.Json(roles, JsonRequestBehavior.AllowGet); } #endregion } public class WorkFlowController : BaseController { public ActionResult GetAllScenariosInWorkFlow(Guid ProjectId, [DataSourceRequest]Kendo.Mvc.UI.DataSourceRequest request) { if (!isProjectId(ProjectId) && isUserId(ProjectId.ToString())) return GetAllUserWorkflowActions(ProjectId, request); var wfMan = new WorkFlowManager(this.DbContext); List projects = new List(); List rt = new List(); projects.Add(ProjectId); var userid = Guid.Parse(HttpContext.User.Identity.GetUserId()); var scenarios = (new ScenarioManager(this.DbContext)).GetScenarios4Projects(projects, ScenarioType.Portfolio, null, false, false); foreach (var s in scenarios) { string status = "N/A"; if (s.Status.HasValue) status = Utils.GetEnumDisplay(typeof(ScenarioStatus), s.Status.Value); string state = "N/A"; var wfState = wfMan.GetCurrentState(s.Id); if (wfState != null && !string.IsNullOrEmpty(wfState.state)) state = wfState.state; var Commands = wfMan.GetWorkFlowCommands(s.Id, userid,true); rt.Add(new WorkflowScenarioModel() { ProjectName = s.Project.Name, ScenarioId = s.Id, ScenarioName = s.Name, ScenarioStatus = status, WorkFlowState = state, Command = "Please Select a commmand", canExecuteCommands = (Commands.Count > 0) }); } return Json(rt, JsonRequestBehavior.AllowGet); } public ActionResult GetAllUserWorkflowActions(Guid UserID, [DataSourceRequest]Kendo.Mvc.UI.DataSourceRequest request) { var wfMan = new WorkFlowManager(this.DbContext); // List projects = new List(); List rt = new List(); var projects = (new ProjectManager(this.DbContext)).GetProjectsWithChildren(UserID, ProjectManager.LoadProjectItems.None).Select(x=>x.Id).ToList(); var userid = Guid.Parse(HttpContext.User.Identity.GetUserId()); var scenarios = (new ScenarioManager(this.DbContext)).GetScenarios4Projects(projects, ScenarioType.Portfolio, null, false, false); foreach (var s in scenarios) { string status = "N/A"; if (s.Status.HasValue) status = Utils.GetEnumDisplay(typeof(ScenarioStatus), s.Status.Value); string state = "N/A"; var wfState = wfMan.GetCurrentState(s.Id); if (wfState != null && !string.IsNullOrEmpty(wfState.state)) state = wfState.state; var Commands = wfMan.GetWorkFlowCommands(s.Id, userid, true); rt.Add(new WorkflowScenarioModel() { ProjectName = s.Project.Name, ScenarioId = s.Id, ScenarioName = s.Name, ScenarioStatus = status, WorkFlowState = state, Command = "Please Select a commmand", canExecuteCommands = (Commands.Count > 0) }); } return Json(rt, JsonRequestBehavior.AllowGet); } public ActionResult GetCommandForScenario(Guid ScenarioId) { var rt = new List(); var wfMan = new WorkFlowManager(this.DbContext); var userid = Guid.Parse(HttpContext.User.Identity.GetUserId()); var Commands = wfMan.GetWorkFlowCommands(ScenarioId,userid,true); foreach (var c in Commands) { rt.Add(new WorkflowSelectableCommandModel() { command = c.command, value = c.command }); } return Json(rt, JsonRequestBehavior.AllowGet); } public ActionResult ExecuteCommandForSceanrio(Guid ScenarioId, string command) { var wfMan = new WorkFlowManager(this.DbContext); var userid = Guid.Parse(HttpContext.User.Identity.GetUserId()); var good= wfMan.ExecuteCommand(ScenarioId, command, userid); return Json(good, JsonRequestBehavior.AllowGet); } public ActionResult GetApprovalHistoryForScenario(Guid? ScenarioId) { if (ScenarioId.HasValue && ScenarioId.Value != Guid.Empty) { var approvals = DbContext.vw_WorkflowApprovalHistoryInfo.Select(x=> new { UserName = (x.FirstName + " " + x.LastName), ScenarioName = x.ScenarioName, ScenarioId = (Guid?) x.ScenarioId, TeamName = x.TeamName, x.Approved, approvedOn = (x.DateApproved.ToString() ?? "N/A"), WorkFlowState = x.StepName }).Distinct().Where(x => x.ScenarioId == ScenarioId).ToList(); return Json(approvals, JsonRequestBehavior.AllowGet); } return Json("", JsonRequestBehavior.AllowGet); } private bool isProjectId(Guid ProjectId) { return this.DbContext.Projects.Any(x => x.Id == ProjectId); } private bool isUserId(string UserId) { return this.DbContext.AspNetUsers.Any(x => x.Id == UserId); } } }