public async Task<ActionResult> GetStateAsync(string id, string stateId, AppUser currentUser) { try { var project = (await Query() .Where(p => p.Id == id) .ToListAsync()) .Select(p => new ProjectWorkflow(p, _workflowDefinition, new ProjectStoreWorkflowManager(_dbContext))) .FirstOrDefault(); if (project == null) { return ActionResult.Failed("Project not found"); } var state = project.States.FirstOrDefault(s => s.Id == stateId); if (state == null) { return ActionResult.Failed("State not found"); } var result = new ProjectViewModel { Company = project.Company, Project = project, State = (State)state, ModelType = state.GetModel().GetType().FullName, FinishedStates = GetFinishedStates(id, project.States.Cast<State>()), }; return ActionResult<ProjectViewModel>.Success(result); } catch (Exception ex) { return ActionResult.Failed(ex); } }
public async Task<ActionResult> SkipStateAsync(AppUser creator, ProjectViewModel currentState) { try { Company company = GetCompany(currentState.Company.Id); if (currentState.Project == null) { return ActionResult.Failed("Project was not created"); } var projectWorkflow = new ProjectWorkflow(currentState.Project, _workflowDefinition, new ProjectStoreWorkflowManager(_dbContext), _userManager); var nextState = projectWorkflow.SkipState(currentState.State, creator, _alertsManager); if (nextState != null) { var result = new ProjectViewModel { Company = company, Project = projectWorkflow, State = nextState, ModelType = nextState.GetModel().GetType().FullName, FinishedStates = GetFinishedStates(currentState.Project.Id, projectWorkflow.States.Cast<State>()), }; UpdateAggregatedList(currentState.Project.Id); return ActionResult<ProjectViewModel>.Success(result); } throw new InvalidOperationException($"Cannot process state {currentState.State.Id}"); } catch (Exception ex) { return ActionResult.Failed(ex); } }
public async Task<ActionResult> SetNextStateAsync(AppUser creator, ProjectViewModel currentState) { try { var entityProcessors = new BaseProcessor[] { new InvoiceProcessor(_invoiceManager), new InvoicesCollectionProcessor(_invoiceManager) }; Company company = GetCompany(currentState.Company.Id); var project = currentState.Project != null ? currentState.Project : new Project { Id = Guid.NewGuid().ToString(), CreatedBy = creator, CreatedOn = DateTime.UtcNow, Company = company, CompanyId = company.Id, AccountingYear = DateTime.Now.Year, ActiveStateId = _workflowDefinition.GetWorkflowDefinition(company.Name).States.Values.First().Id }; var projectWorkflow = new ProjectWorkflow(project, _workflowDefinition, new ProjectStoreWorkflowManager(_dbContext), _userManager); projectWorkflow.ToBePaid = _invoiceManager.GetToBePaid(projectWorkflow.Id, projectWorkflow.GetStateModel<QuoteOfEntry>()?.AmountTTC); projectWorkflow.ToBeInvoiced = _invoiceManager.GetToBeInvoiced(projectWorkflow.Id, projectWorkflow.GetStateModel<QuoteOfEntry>()?.AmountTTC); projectWorkflow.InvoicesPaid = _invoiceManager.GetInvoicesPaid(projectWorkflow.Id); projectWorkflow.InvoicesToPay = _invoiceManager.GetInvoicesToPay(projectWorkflow.Id); projectWorkflow.InvoicesInLate = _invoiceManager.GetInvoicesInLate(projectWorkflow.Id); var nextState = projectWorkflow.NextStep(currentState.State, creator, async (parameters) => { foreach (var processor in entityProcessors) { if (processor.CanProcess(parameters.StateModel.GetType())) { await processor.ProcessAsync(parameters); } } }, async (alertsParameters) => { await _alertsManager.CreateOnSubmitAlertsAsync(alertsParameters.Project, alertsParameters.Transition, (State)alertsParameters.CurrentState, creator); await _alertsManager.CreateOnEnterAlertsAsync(alertsParameters.Project, alertsParameters.Transition, (State)alertsParameters.NextState, creator); }); if (nextState != null) { var result = new ProjectViewModel { Company = company, Project = projectWorkflow, State = nextState, ModelType = nextState.GetModel().GetType().FullName, FinishedStates = GetFinishedStates(project.Id, projectWorkflow.States.Cast<State>()), }; if (currentState != null && currentState.State != null) { _historyManager.LogInfo(projectWorkflow.Id, result.FinishedStates.LastOrDefault()?.Transition?.Id, new { FromState = currentState.State, ToState = nextState, Model = (projectWorkflow.States.FirstOrDefault(s => s.Id == currentState.State.Id)?.Model as BaseStateModel)?.ToDictionary().Select(k => new Tuple<string, object>(k.Key, k.Value)) }, EventType.ProjectStateChanged, creator); } UpdateAggregatedList(project.Id); return ActionResult<ProjectViewModel>.Success(result); } else if (projectWorkflow.States.Last().Id == currentState.State.Id) { project = Query().First(p => p.Id == project.Id); project.IsArchived = true; _dbContext.SaveChanges(); var result = new ProjectViewModel { Project = new ProjectWorkflow(project, _workflowDefinition, new ProjectStoreWorkflowManager(_dbContext), _userManager), }; UpdateAggregatedList(project.Id); return ActionResult<ProjectViewModel>.Success(result); } throw new InvalidOperationException($"Cannot process state {currentState.State.Id}"); } catch (Exception ex) { try { ex.Data.Add("creator", JsonConvert.SerializeObject(creator)); ex.Data.Add("currentState", JsonConvert.SerializeObject(currentState)); } catch { } return ActionResult.Failed(ex); } }
public async Task<ActionResult> UpdateStateAsync(AppUser creator, ProjectViewModel currentState = null) { try { Company company = GetCompany(currentState.Company.Id); if (currentState.Project == null) { return ActionResult.Failed("Project was not created"); } var entityProcessors = new BaseProcessor[] { new InvoiceProcessor(_invoiceManager), new InvoicesCollectionProcessor(_invoiceManager) }; var projectWorkflow = new ProjectWorkflow(currentState.Project, _workflowDefinition, new ProjectStoreWorkflowManager(_dbContext), _userManager); projectWorkflow.UpdateState(currentState.State, creator, async (parameters) => { foreach (var processor in entityProcessors) { if (processor.CanProcess(parameters.StateModel.GetType())) { await processor.ProcessAsync(parameters); } } }); var result = new ProjectViewModel { Company = company, Project = projectWorkflow, State = projectWorkflow.States.OfType<State>().FirstOrDefault(s => s.Id == currentState.State.Id), ModelType = _workflowDefinition.GetWorkflowDefinition(company.Name).States[currentState.State.Id].GetModel().GetType().FullName, FinishedStates = currentState.FinishedStates, }; UpdateAggregatedList(currentState.Project.Id); if (currentState != null && currentState.State != null) { _historyManager.LogInfo(currentState.Project.Id, null, new { FromState = currentState.State, ToState = currentState.State, Model = (projectWorkflow.States.FirstOrDefault(s => s.Id == currentState.State.Id)?.Model as BaseStateModel)?.ToDictionary().Select(k => new Tuple<string, object>(k.Key, k.Value)) }, (EventType)99, creator); } return ActionResult<ProjectViewModel>.Success(result); } catch (Exception ex) { return ActionResult.Failed(ex); } }
public async Task<ProjectViewModel> GetByIdAsync(string id, AppUser currentUser) { var project = (await Query() .Where(p => p.Id == id) .ToListAsync()) .Select(p => new ProjectWorkflow(p, _workflowDefinition, new ProjectStoreWorkflowManager(_dbContext), _userManager)) .FirstOrDefault(); var currentState = project.States.Any(s => s.IsActive) ? project.States.First(s => s.IsActive) : (project.States.Last().IsCompleted ? project.States.Last() : project.States.First()); currentState.IsActive = true; project.InitStateModel((State)currentState, currentUser); project.ToBePaid = _invoiceManager.GetToBePaid(id, project.GetStateModel<QuoteOfEntry>()?.AmountTTC); project.ToBeInvoiced = _invoiceManager.GetToBeInvoiced(id, project.GetStateModel<QuoteOfEntry>()?.AmountTTC); project.InvoicesPaid = _invoiceManager.GetInvoicesPaid(id); project.InvoicesToPay = _invoiceManager.GetInvoicesToPay(id); project.InvoicesInLate = _invoiceManager.GetInvoicesInLate(id); var customer = project.GetStateModel<QuoteOfEntry>()?.Customer; if (customer != null) { project.PaidByCustomer = _invoiceManager.GetPaidByCustomer(customer.Id, new DateTime(DateTime.UtcNow.Year, 1, 1), new DateTime(DateTime.UtcNow.Year, 12, 31, 23, 59, 59)); project.TotalAmountByCustomer = _invoiceManager.GetTotalAmountByCustomer(customer.Id, new DateTime(DateTime.UtcNow.Year, 1, 1), new DateTime(DateTime.UtcNow.Year, 12, 31, 23, 59, 59)); project.InLateAmountByCustomer = _invoiceManager.GetInLateAmountByCustomer(customer.Id, new DateTime(DateTime.UtcNow.Year, 1, 1), new DateTime(DateTime.UtcNow.Year, 12, 31, 23, 59, 59)); } var result = new ProjectViewModel { Company = project.Company, Project = project, State = (State)currentState, ModelType = currentState.GetModel().GetType().FullName, FinishedStates = GetFinishedStates(id, project.States.Cast<State>()), }; return result; }