public async Task <WorkflowDefinition> RunActionForProductAsync(Guid id, string type) { User currentUser = UserRepository.CurrentUser; var product = await GetProductForActions(id); if (product == null) { return(null); } if (currentUser.Id != product.Project.OwnerId) { throw new Exception("Unable to run action. Current user is not the project owner"); } if (product.ProductWorkflow == null) { // No running workflow. Start one. int?workflowDefinitionId = GetWorkflowDefinitionIdForType(product, type); if (workflowDefinitionId.HasValue) { HangfireClient.Enqueue <WorkflowProductService>(service => service.StartProductWorkflow(id, workflowDefinitionId.Value)); return(await WorkflowDefinitionRepository.GetAsync(workflowDefinitionId.Value)); } throw new Exception($"Type '{type}' does not have workflow defined"); } // Handle special case for "Cancel" action if (type == "Cancel") { var wd = await GetExecutingWorkflowDefintion(product); if (wd == null) { throw new Exception("Could not find workflow definition!"); } if (wd.Type == WorkflowType.Startup) { throw new Exception("Cannot cancel a startup workflow"); } HangfireClient.Enqueue <WorkflowProductService>(service => service.StopProductWorkflow(id, product.ProjectId, ProductTransitionType.CancelWorkflow)); return(wd); } // Trying to start an action workflow while one is already running throw new Exception("Cannot start a workflow while one is running"); }
private async Task <WorkflowDefinition> GetExecutingWorkflowDefintion(Guid productId) { using (var scope = ServiceProvider.CreateScope()) { var product = await ProductRepository.Get() .Where(p => p.Id == productId) .Include(p => p.ProductWorkflow) .ThenInclude(pw => pw.Scheme) .FirstOrDefaultAsync(); if (product == null) { return(null); } return(await WorkflowDefinitionRepository.Get() .Where(w => w.WorkflowScheme == product.ProductWorkflow.Scheme.SchemeCode) .FirstOrDefaultAsync()); } }
private async Task StartProductWorkflowAsync(Guid productId, int workflowDefinitionId) { var product = await ProductRepository.Get() .Where(p => p.Id == productId) .Include(p => p.ProductDefinition) .ThenInclude(pd => pd.Workflow) .Include(p => p.Project) .ThenInclude(pr => pr.Owner) .FirstOrDefaultAsync(); if (product == null) { // TODO: Send notification record // Don't send exception because if the record is not there // there doesn't seem much point in retrying return; } if (!product.Project.Owner.WorkflowUserId.HasValue) { // TODO: Send notification record // If user does not have a WorkflowUserId, then User to DwSecurityUser // synchronization is not working or hasn't been done yet? // Throw exception to retry throw new Exception("WorkflowUserId not available"); } var workflowDefinition = await WorkflowDefinitionRepository.GetAsync(workflowDefinitionId); if (workflowDefinition == null) { // TODO: Send notification record // Don't send exception because if the record is not there // there doesn't seem much point in retrying return; } await createTransitionRecord(product.Id, ProductTransitionType.StartWorkflow, workflowDefinition.Type); await CreateWorkflowProcessInstance(product, workflowDefinition); }
private async Task <WorkflowDefinition> GetExecutingWorkflowDefintion(Product product) { return(await WorkflowDefinitionRepository.Get() .Where(w => w.WorkflowScheme == product.ProductWorkflow.Scheme.SchemeCode) .FirstOrDefaultAsync()); }