/// <summary> /// Retrieves a workflow item for the work item. /// </summary> /// <param name="session">A secure session.</param> /// <param name="workItem">A work item.</param> /// <returns>An application workflow item (<see cref="ApplicationWorkflowItem"/>).</returns> private ApplicationWorkflowItem GetWorkflowItem(SecureSession session, UnitOfWork<ApplicationWorkItem> workItem) { ProductVersionList versionList = null; ProductDefinition currentVersion = null; foreach (var item in this.productCache) { if (item.Key == workItem.Item.Application.FormId) { versionList = item.Value; break; } } if (versionList == null) { versionList = new ProductVersionList(); this.productCache.Add(workItem.Item.Application.FormId, versionList); } // If current version is null, we have to load it and add it to the list. currentVersion = versionList.GetCurrentVersion(); if (currentVersion == null) { currentVersion = this.formServiceGateway.GetProduct(session, workItem.Item.Application.FormId, null); versionList.Add(currentVersion); } if (workItem.Item.Application.UseFormVersion && workItem.Item.Application.FormVersion != null && !versionList.HasVersion(workItem.Item.Application.FormVersion.Value)) { ProductDefinition specificVersion = this.formServiceGateway.GetProduct(session, workItem.Item.Application.FormId, workItem.Item.Application.FormVersion.Value); versionList.Add(specificVersion); } ProductDefinition linkedVersion = workItem.Item.Application.UseFormVersion && workItem.Item.Application.FormVersion != null ? versionList.GetVersion(workItem.Item.Application.FormVersion.Value) : currentVersion; ApplicationWorkflowItem workflowItem = new ApplicationWorkflowItem( workItem.Item.Application, workItem.Item.Application.ApplicationData, linkedVersion.FormDefinition.Pages.AllControls) { FormVersion = linkedVersion.Version }; return workflowItem; }
/// <summary> /// Sets the metadata of <paramref name="application" /> and returns a <see cref="Product" />. /// </summary> /// <param name="secureSession">The session data.</param> /// <param name="application">The application to set metadata for.</param> /// <param name="formVersion">The form version. Defaults to <see langword="null" /> (latest).</param> /// <param name="publicDidAuthenticate">If set to <c>true</c> [a public user authenticated before saving].</param> /// <param name="updateAsignee">If set to <c>true</c> the assignee will be updated to the current user.</param> /// <returns> /// A <see cref="Product" /> object with the appropriate version for the supplied <paramref name="application" />. /// </returns> private ProductDefinition UpdateApplicationMetadata(SecureSession secureSession, Application application, int? formVersion = null, bool publicDidAuthenticate = false, bool updateAsignee = false) { IApplicationUser appUser = secureSession.AuthenticatedUser != null ? new IUserMapper().Map(secureSession.AuthenticatedUser, new AuthenticatedApplicationUser()) : new AnonymousApplicationUser(secureSession.SessionId) as IApplicationUser; ProductDefinition product; application.Modified = DateTime.Now; application.ModifiedBy = appUser.Id; if (application.IsNew) { product = this.DataAccess.GetProduct(application.FormId, formVersion); ApplicationWorkflowItem workflowItem = new ApplicationWorkflowItem(application); application.AssignedTo = appUser.Id; application.AssignedToDisplayName = secureSession.AuthenticatedUser != null ? secureSession.AuthenticatedUser.DisplayName : string.Empty; application.Created = DateTime.Now; application.CreatedBy = appUser; application.OrganisationId = product.OrganisationId; application.FormOrganisationId = product.OrganisationId; application.FormVersion = product.Version; application.UseFormVersion = product.LinkApplicationsToVersion; application.VersionNumber = 1; application.WorkflowState = application.WorkflowState ?? this.workflowService.GetInitialState(workflowItem, product.Version).Name; application.StateTransitionDate = application.Created; } else { Application existingApplication = this.GetApplication(application.Id); IApplicationUser originator = existingApplication.CreatedBy == null || (existingApplication.CreatedBy.Type == ApplicationUserType.Anonymous && appUser.Type == ApplicationUserType.Authenticated && publicDidAuthenticate) ? appUser : existingApplication.CreatedBy; application.Created = existingApplication.Created; application.CreatedBy = originator; application.OrganisationId = existingApplication.OrganisationId ?? application.OrganisationId; application.FormOrganisationId = application.OrganisationId; application.FormVersion = existingApplication.FormVersion; application.UseFormVersion = existingApplication.UseFormVersion; application.VersionNumber = existingApplication.VersionNumber + 1; application.WorkflowState = existingApplication.WorkflowState; application.StateTransitionDate = existingApplication.StateTransitionDate; application.ApplicationIdDisplay = existingApplication.ApplicationIdDisplay; if (updateAsignee) { application.AssignedTo = secureSession.AuthenticatedUser != null ? secureSession.AuthenticatedUser.Id : originator.Id; application.AssignedToDisplayName = secureSession.AuthenticatedUser != null ? secureSession.AuthenticatedUser.DisplayName : existingApplication.AssignedToDisplayName; } else { application.AssignedTo = existingApplication.AssignedTo; application.AssignedToDisplayName = existingApplication.AssignedToDisplayName; } product = this.DataAccess.GetProduct(application.FormId, application.UseFormVersion ? application.FormVersion : null); } if (string.IsNullOrEmpty(application.OrganisationId)) { Organisation org = this.organisationManager.GetOrganisation(application.OrganisationId); application.OrganisationName = org.Name; } return product; }
/// <summary> /// Logs workflow state changes. /// </summary> /// <param name="secureSession">The session data.</param> /// <param name="application">The saved application.</param> /// <param name="isNew">A value indicating whether the application is new.</param> /// <param name="workflowItem">The workflow item to log.</param> /// <param name="previousState">The previous state of <paramref name="application"/>.</param> /// <param name="newState">The new state of <paramref name="application"/>.</param> private void LogWorkflow(SecureSession secureSession, Application application, bool isNew, ApplicationWorkflowItem workflowItem, ItemState previousState, ItemState newState) { if (workflowItem == null && !isNew) { return; } workflowItem = workflowItem ?? new ApplicationWorkflowItem { FormId = application.FormId, UserId = secureSession.AuthenticatedUser != null ? secureSession.AuthenticatedUser.Id : null }; workflowItem.ApplicationId = application.ApplicationId; workflowItem.VersionNumber = application.VersionNumber; workflowItem.PostedData = application.ApplicationData; if (isNew && newState != null && previousState.Name != newState.Name) { // Special case to log from blank to the first state when we are moving straight into the next state. this.workflowService.LogStateChange(workflowItem, new ItemState(null), previousState); } if (isNew && (newState == null || previousState.Name == newState.Name)) { newState = previousState; previousState = new ItemState(null); } this.workflowService.LogStateChange(workflowItem, previousState, newState); }
/// <summary> /// Performs workflow on behalf of the submit. /// </summary> /// <param name="secureSession">The session data.</param> /// <param name="application">The application to perform workflow for.</param> /// <param name="existingApplicationData">The existing application data.</param> /// <param name="product">The product definition.</param> /// <param name="scopedPageList">The list of pages required to process the application in its current state.</param> /// <param name="currentItemState">The current workflow state.</param> /// <param name="workflowState">The new / requested workflow state.</param> /// <param name="assignee">The assignee value from the workflow transition.</param> /// <param name="assigneeType">The assignee type from the workflow transition.</param> /// <param name="newState">After a successful transition, will be the new workflow state, otherwise <see langword="null"/>.</param> /// <returns>After a successful transition, the workflow item, otherwise <see langword="null"/>.</returns> private ApplicationWorkflowItem PerformWorkflow(SecureSession secureSession, Application application, ApplicationData existingApplicationData, ProductDefinition product, PageList scopedPageList, ItemState currentItemState, string workflowState, string assignee, ComparisonType? assigneeType, out ItemState newState) { newState = currentItemState; WorkflowConfigurationContainer workflowContainer = this.workflowService.GetWorkflowConfiguration(WorkflowTargetType.FormApplication, application.FormId, product.Version); WorkflowState state = workflowContainer.Configuration.States.FirstOrDefault(s => s.Name == currentItemState.Name); WorkflowTransition transition = (state == null) ? null : string.IsNullOrWhiteSpace(workflowState) ? null : state.Transitions.FirstOrDefault(t => t.Trigger != TriggerEvent.Submit && t.ExitStateName == workflowState); Organisation entitleTo; ApplicationWorkflowItem workflowItem = new ApplicationWorkflowItem(application, existingApplicationData, scopedPageList.AllControls) { FormVersion = product.Version }; // Do non-submit transition. Only Service accounts can perform this operation. if (transition != null && secureSession.AuthenticatedUser != null && secureSession.AuthenticatedUser.AccountType == AccountType.Service) { User assignTo = this.DetermineAssignee(assignee, assigneeType, application); application.WorkflowState = transition.ExitStateName; application.StateTransitionDate = DateTime.Now; application.AssignedTo = (assignTo != null) ? assignTo.Id : null; application.AssignedToDisplayName = (assignTo != null) ? assignTo.DisplayName : null; entitleTo = this.DetermineOrganisation(transition.ExitOrganisation, application); application.OrganisationId = (entitleTo != null) ? entitleTo.Id : application.OrganisationId; application.OrganisationName = (entitleTo != null) ? entitleTo.Name : application.OrganisationName; return workflowItem; } // Do submit transition. WorkflowResult result = this.workflowService.Trigger(workflowItem, new WorkflowTransition { Trigger = TriggerEvent.Submit }, currentItemState); // If result = null, there were NO valid transitions, so we leave the application essentially as is, but unassign it. if (result == null) { application.AssignedTo = null; application.AssignedToDisplayName = null; } if (result != null) { newState = result.ExitState; if (newState != null && string.Compare(newState.Name, application.WorkflowState, StringComparison.OrdinalIgnoreCase) != 0) { application.StateTransitionDate = DateTime.Now; } application.WorkflowState = (newState == null) ? null : newState.Name; User user = this.DetermineAssignee(result.ExitAssignee, result.ExitAssigneeType, application); application.AssignedTo = (user != null) ? user.Id : null; application.AssignedToDisplayName = (user != null) ? user.DisplayName : null; entitleTo = this.DetermineOrganisation(result.ExitOrganisation, application); application.OrganisationId = (entitleTo != null) ? entitleTo.Id : application.OrganisationId; application.OrganisationName = (entitleTo != null) ? entitleTo.Name : application.OrganisationName; } return workflowItem; }
/// <summary> /// Gets the control entitlements for a user. /// </summary> /// <param name="sessionData">The session data.</param> /// <param name="application">The application.</param> /// <param name="product">The product definition.</param> /// <param name="pageList">The list of pages.</param> /// <returns>The control access for a user.</returns> private List<ControlAccess> GetControlAccess(SessionData sessionData, Application application, Product product, PageList pageList) { User user = this.userManager.GetUserById(sessionData.UserId); SecureSession secureSession = new SecureSession(sessionData.DeserializationSource, sessionData.SessionId, user); if (application.IsNew) { ApplicationWorkflowItem workflowItem = new ApplicationWorkflowItem(application.FormId, sessionData.UserId); application.WorkflowState = this.workflowService.GetInitialState(workflowItem, product.Version).Name; } var roleList = this.DataAccess.GetRoleList(); List<ControlAccess> controlsAccess = this.entitlementProvider.GetControlsAccess(secureSession, application, pageList.AllControls, roleList, product.Version); return controlsAccess; }