示例#1
0
        private ActionResult Add(string projectId, int? transitionId, EventLevel level, EventType eventType, AppUser creator, object item, DateTime? createdOn = null)
        {
            try
            {
                var i = new ProjectHistory
                {
                    CreatedBy = creator,
                    CreatedOn = createdOn ?? DateTime.UtcNow,
                    Description = JsonConvert.SerializeObject(item),
                    Level = level,
                    ProjectId = projectId,
                    TransitionId = transitionId,
                    Type = eventType
                };

                if (!_dbContext.ChangeTracker.Entries().Where(e => e.State != EntityState.Unchanged).Any())
                {
                    _dbContext.ProjectHistory.Add(i);
                    _dbContext.SaveChanges();
                }
                else
                {
                    _dbContext.ProjectHistory.Add(i);
                }

                return ActionResult.Success(item);
            }
            catch(Exception ex)
            {
                return ActionResult.Failed(ex);
            }
        }
示例#2
0
 public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
 {
     object val = null;
     if (reader.Value != null)
     {
         if (_storeManager != null)
         {
             val = _storeManager.GetDbValue<AppUser>((u) => u.Id == reader.Value.ToString());
         }
         else
         {
             val = new AppUser { Id = reader.Value.ToString() };
         }
     }
     return val;
 }
        public async Task<ActionResult> ProcessDocumentAsync(string projectId, int link2docId, string comment, AppUser currentUser)
        {
            var prjWorkflow = await GetProject(projectId);
            var link2doc = await GetLink2Doc(link2docId);

            ActionResult result = null;

            if (link2doc.DocType == StateDocumentType.ExternalDocument)
            {
                result = await _externalDocsManager.ProcessDocumentsAsync(prjWorkflow, link2doc, comment, currentUser);
            }
            else if (link2doc.DocType == StateDocumentType.InternalDocument)
            {
                result = await _internalDocsManager.ProcessDocumentsAsync(prjWorkflow, link2doc, comment, currentUser);
            }

            _historyManager.LogInfo(projectId, null, result?.Item, EventType.CreateDoc, currentUser);

            return ActionResult.Success();
        }
示例#4
0
        public async Task<ActionResult> DeleteAlertAsync(int alertId, AppUser currentUser)
        {
            try
            {
                var item = await _dbContext.ProjectAlerts.Include(a => a.Actions).FirstOrDefaultAsync(d => d.Id == alertId);
                if (item != null)
                {
                    item.IsArchived = true;

                    _historyManager.LogInfo(item.ProjectId, item.TransitionId, item, EventType.ArchiveAlert, currentUser);

                    await _dbContext.SaveChangesAsync();
                }
                return ActionResult.Success();
            }
            catch (Exception ex)
            {
                return ActionResult.Failed(ex);
            }
        }
示例#5
0
        public async Task<ActionResult> DeleteAsync(int id, AppUser currentUser)
        {
            try
            {
                var item = await _dbContext.ProjectRemarks.FirstOrDefaultAsync(i => i.Id == id);
                if (item != null)
                {
                    _dbContext.ProjectRemarks.Remove(item);

                    _historyManager.LogInfo(item.ProjectId, item.TransitionId, item, EventType.DeleteRemark, currentUser);

                    await _dbContext.SaveChangesAsync();
                }
                return ActionResult.Success();
            }
            catch(Exception ex)
            {
                return ActionResult.Failed(ex);
            }
        }
        public async Task<ActionResult> DeleteDocumentAsync(int docId, AppUser currentUser)
        {
            try
            {
                var item = await _dbContext.ProjectDocuments.FirstOrDefaultAsync(d => d.Id == docId);
                if (item != null)
                {
                    _dbContext.ProjectDocuments.Remove(item);

                    _historyManager.LogInfo(item.ProjectId, null, item, EventType.DeleteDoc, currentUser);

                    await _dbContext.SaveChangesAsync();
                }
                return ActionResult.Success();
            }
            catch (Exception ex)
            {
                return ActionResult.Failed(ex);
            }
        }
 public async Task<ActionResult> ProcessDocumentsAsync(ProjectWorkflow prjWorkflow, DocumentToProjectLink link2doc, string comment, AppUser currentUser)
 {
     try
     {
         var dbDoc = await _dbContext.ProjectDocuments.FirstOrDefaultAsync(pd => pd.ProjectId == prjWorkflow.Id && pd.Link2StateId == link2doc.Id);
         if (dbDoc == null)
         {
             dbDoc = new ProjectDocument
             {
                 Body = System.Text.Encoding.UTF8.GetBytes(link2doc.DocName),
                 CreatedBy = currentUser,
                 CreatedOn = DateTime.UtcNow,
                 Link2StateId = link2doc.Id,
                 ProjectId = prjWorkflow.Id,
                 StateId = link2doc.StateId,
                 Comment = comment
             };
             _dbContext.ProjectDocuments.Add(dbDoc);
         }
         else
         {
             dbDoc.Body = System.Text.Encoding.UTF8.GetBytes(link2doc.DocName);
             dbDoc.CreatedBy = currentUser;
             dbDoc.CreatedOn = DateTime.UtcNow;
             dbDoc.Link2StateId = link2doc.Id;
             dbDoc.ProjectId = prjWorkflow.Id;
             dbDoc.StateId = link2doc.StateId;
             dbDoc.Comment = comment;
         }
         await _dbContext.SaveChangesAsync();
         return ActionResult.Success(dbDoc);
     }
     catch(Exception ex)
     {
         return ActionResult.Failed(ex);
     }
 }
示例#8
0
        public async Task<ActionResult> ChangeInvoiceWaitingAsync(string id, bool value, AppUser user)
        {
            try
            {
                var project = await Query().FirstOrDefaultAsync(p => p.Id == id);
                if (project != null)
                {
                    project.InvoiceWaiting = value;
                    _dbContext.SaveChanges();

                    UpdateAggregatedList(project.Id);

                    var tobePaid = _invoiceManager.GetToBePaid(id, new ProjectWorkflow(project, _workflowDefinition, new ProjectStoreWorkflowManager(_dbContext), _userManager).GetStateModel<QuoteOfEntry>()?.AmountTTC);
                    _historyManager.LogInfo(id, null, new { Value = value, ToBePaid = tobePaid }, EventType.InvoiceWaitingChanged, user);
                }
                return ActionResult.Success();
            }
            catch (Exception ex)
            {
                return ActionResult.Failed(ex);
            }
        }
示例#9
0
 public ActionResult LogInfo(string projectId, int? transitionId, object item, EventType eventType, AppUser creator = null, DateTime? createdOn = null)
 {
     return Add(projectId, transitionId, EventLevel.Info, eventType, creator, item, createdOn);
 }
示例#10
0
        public async Task<ActionResult> DeleteStateAsync(string id, string stateId, AppUser user)
        {
            try
            {
                var transition = await _dbContext.ProjectTransitions.FirstOrDefaultAsync(t => t.ProjectId == id && t.StateFromId == stateId);
                var transitionsToDelete = await _dbContext.ProjectTransitions.Where(t => t.ProjectId == id && t.Id >= transition.Id).ToListAsync();
                _dbContext.ProjectTransitionValues.RemoveRange(_dbContext.ProjectTransitionValues.Where(t => transitionsToDelete.Any(trans => trans.Id == t.TransitionId)));
                _dbContext.ProjectTransitions.RemoveRange(_dbContext.ProjectTransitions.Where(t => transitionsToDelete.Any(trans => trans.Id == t.Id)));

                var alertsToDelete = _dbContext.ProjectAlerts.Where(t => transitionsToDelete.Any(trans => trans.Id == t.TransitionId));
                var alertsActionsToDelete = _dbContext.ProjectAlertActions.Where(ac => alertsToDelete.Any(a => a.Id == ac.ProjectAlertId));
                _dbContext.ProjectAlertActions.RemoveRange(alertsActionsToDelete);
                _dbContext.ProjectAlerts.RemoveRange(alertsToDelete);

                _dbContext.ProjectInvoices.RemoveRange(_dbContext.ProjectInvoices.Where(t => transitionsToDelete.Any(trans => trans.Id == t.TransitionId)));

                await _dbContext.SaveChangesAsync();

                UpdateAggregatedList(id);

                return ActionResult.Success();
            }
            catch (Exception ex)
            {
                return ActionResult.Failed(ex);
            }
        }
示例#11
0
        public async Task<ActionResult> ReactivateProjectAsync(string id, AppUser user)
        {
            try
            {
                var item = await _dbContext.Projects.FirstOrDefaultAsync(p => p.Id == id && p.IsArchived);
                if (item != null)
                {
                    item.IsArchived = false;
                    await _dbContext.SaveChangesAsync();

                    UpdateAggregatedList(id);
                }
                return ActionResult.Success();
            }
            catch (Exception ex)
            {
                return ActionResult.Failed(ex);
            }
        }
示例#12
0
        public async Task<Infrastructure.ActionResult> SaveAsync(ProjectInvoice invoice, AppUser currentUser)
        {
            try
            {
                int customerId = 0;
                string customerIdValue = (from pt in _dbContext.ProjectTransitions
                                          join ptv in _dbContext.ProjectTransitionValues on pt.Id equals ptv.TransitionId
                                          where pt.ProjectId == invoice.ProjectId && ptv.ParamName == "Customer"
                                          select ptv.ParamValue).FirstOrDefault();

                if (!int.TryParse(customerIdValue, out customerId))
                {
                    throw new ArgumentNullException("Customer not found");
                }

                if (invoice.Id == 0)
                {
                    invoice.CustomerId = customerId;
                    _dbContext.ProjectInvoices.Add(invoice);

                    if (invoice.Status == InvoiceStatus.PartiallyPaid && invoice.PartialPayments != null)
                    {
                        foreach (var partialPayment in invoice.PartialPayments)
                        {
                            partialPayment.Invoice = invoice;
                            _dbContext.ProjectInvoicePartialPayments.Add(partialPayment);
                        }

                        if (invoice.LeftToPayByPartialPayments == 0)
                        {
                            invoice.Status = InvoiceStatus.Paid;
                            invoice.PaymentDate = invoice.PartialPayments.LastOrDefault()?.Date;
                        }
                    }

                    _historyManager.LogInfo(invoice.ProjectId, invoice.TransitionId, invoice, EventType.CreateInvoice, currentUser);
                }
                else
                {
                    var item = await _dbContext.ProjectInvoices.Include(i => i.PartialPayments).FirstOrDefaultAsync(i => i.Id == invoice.Id);
                    if (item != null)
                    {
                        item.Comment = invoice.Comment;
                        item.CustomerId = customerId;
                        item.InvoiceAmount = invoice.InvoiceAmount;
                        item.InvoiceDate = invoice.InvoiceDate;
                        item.InvoiceNumber = invoice.InvoiceNumber;
                        //item.LateDays = CalcLateDays(invoice);
                        item.PaymentDate = invoice.PaymentDate;
                        item.ProjectId = invoice.ProjectId;
                        item.Status = invoice.Status;
                        item.Transition = invoice.Transition;
                        item.TransitionId = invoice.TransitionId;
                        item.Type = invoice.Type;

                        var dbItems = item.PartialPayments ?? new List<ProjectInvoicePartialPayment>();
                        if (invoice.PartialPayments == null || !invoice.PartialPayments.Any())
                        {
                            if (dbItems != null)
                                _dbContext.ProjectInvoicePartialPayments.RemoveRange(dbItems);
                        }
                        else
                        {
                            var deletedItems = dbItems.Where(r => !invoice.PartialPayments.Any(rr => rr.Id == r.Id)).ToList();
                            var addedItems = invoice.PartialPayments.Where(r => !dbItems.Any(rr => rr.Id == r.Id)).ToList();
                            _dbContext.ProjectInvoicePartialPayments.RemoveRange(deletedItems);
                            _dbContext.ProjectInvoicePartialPayments.AddRange(addedItems);
                            foreach (var edit in dbItems.Except(deletedItems))
                            {
                                var property = invoice.PartialPayments.FirstOrDefault(p => p.Id == edit.Id);
                                edit.Amount = property.Amount;
                                edit.Date = property.Date;
                            }

                            if (invoice.Status == InvoiceStatus.PartiallyPaid && invoice.LeftToPayByPartialPayments == 0)
                            {
                                item.Status = InvoiceStatus.Paid;
                                item.PaymentDate = invoice.PartialPayments.LastOrDefault()?.Date;
                            }
                            else if (invoice.Status == InvoiceStatus.Paid && invoice.LeftToPayByPartialPayments > 0)
                            {
                                item.Status = InvoiceStatus.PartiallyPaid;
                                item.PaymentDate = null;
                            }
                        }
                        _historyManager.LogInfo(invoice.ProjectId, invoice.TransitionId, invoice, EventType.ModifyInvoice, currentUser);
                    }
                }
                _dbContext.SaveChanges();

                await _alertsManager.CreateScheduledAlertForInvoice(invoice);

                return Infrastructure.ActionResult.Success(invoice);
            }
            catch (Exception ex)
            {
                return Infrastructure.ActionResult.Failed(ex);
            }
        }
示例#13
0
        private async Task CreateAlertsAsync(IEnumerable<Alert> alerts, ProjectWorkflow project,
            StateTransition<string> transition, State state, AppUser currentUser)
        {
            dynamic model = project.GetComplexModel(state.Id);

            foreach (var alert in alerts)
            {
                var matchProperties = true;
                foreach (var condition in alert.ConditionQuery.Where(c => !string.IsNullOrEmpty(c)))
                {
                    if (!project.GetComplexModelDictionary(state.Id).AsQueryable().Where(condition).Any())
                    {
                        matchProperties = false;
                        break;
                    }
                }
                if (!matchProperties)
                {
                    continue;
                }

                var projectAlert = new ProjectAlert
                {
                    CreatedBy = currentUser,
                    CreatedById = currentUser.Id,
                    ProjectId = project.Id,
                    StartDate = alert.IsRecurrent ? (DateTime?)null : DateTime.UtcNow,
                    CreatedOn = DateTime.UtcNow,
                    StateId = state.Id,
                    //IsFired = isFired,
                    IsRecurrent = alert.IsRecurrent,
                    CommitActionName = alert.CommitActionName,
                    TransitionId = int.Parse(transition.Id),
                    AlertLinkId = alert.Id
                };
                _dbContext.ProjectAlerts.Add(projectAlert);

                if (!alert.IsRecurrent)
                {
                    var message = new AlertMessage
                    {
                        From = GetEmailsByRole(alert.Action.MessageTemplate.From),
                        To = GetEmailsByRole(alert.Action.MessageTemplate.To),
                        Subject = alert.Action.MessageTemplate.Subject ?? $"{project.Company.Name} alert",
                        Body = await GetMessageHtml(alert.Action.MessageTemplate.Body, model)
                    };
                    alert.Action.DoAction(message);

                    _dbContext.ProjectAlertActions.Add(new ProjectAlertAction
                    {
                        ProjectAlert = projectAlert,
                        ProjectAlertId = projectAlert.Id,
                        From = alert.Action.MessageTemplate.From,
                        To = alert.Action.MessageTemplate.To,
                        Subject = alert.Action.MessageTemplate.Subject,
                        Body = message.Body
                    });
                }

                _historyManager.LogInfo(projectAlert.ProjectId, projectAlert.TransitionId, projectAlert, EventType.FireAlert, currentUser);
            }
            //if (alerts.Any())
            {
                _dbContext.SaveChanges();
            }
        }
示例#14
0
        public async Task<IEnumerable<dynamic>> ListAsync(AppUser currentUser)
        {
            try
            {
                var roles = await (from userInRole in _dbContext.UserRoles
                                   join role in _dbContext.Roles on userInRole.RoleId equals role.Id
                                   where userInRole.UserId == currentUser.Id
                                   select role).ToListAsync();

                var ddd = (from alert in Query()
                           join project in _dbContext.ProjectsListAggregated on alert.ProjectId equals project.Id
                           join cust in _dbContext.Customers on project.CustomerId equals cust.Id into cust1
                           from cust in cust1.DefaultIfEmpty()
                           where
                               alert.StartDate.HasValue &&
                               (alert.CreatedById == currentUser.Id ||
                                alert.Actions.Any(aa => roles.Any(r => aa.To.Contains(r.Name))))
                           select new
                           {
                               alert,
                               project.QuotationNumber,
                               ProjectId = project.Id,
                               project.CompanyId,
                               project.CompanyName,
                               CustomerName = cust == null ? null : cust.Name,
                               PropertyNameId = project.PropertyNameId
                           }).ToList();

                var data = ddd.Select(a => new
                {
                    a.alert.Id,
                    a.alert.StartDate,
                    a.alert.Actions,
                    a.QuotationNumber,
                    Status =
                       _workflowDefinition.GetWorkflowDefinition(a.CompanyName).States.Values.FirstOrDefault(s => s.Id == a.alert.StateId)?.DisplayName,
                    CustomerName =
                       a.CustomerName + " / " +
                       (a.PropertyNameId == null ? null : _dbContext.PropertyNames.FirstOrDefault(pr => pr.Id == a.PropertyNameId)?.Name),
                    ProjectId = a.ProjectId,
                    a.alert.CommitActionName,
                    a.alert.Comment,
                    a.alert.CreatedBy,
                    a.alert.CreatedOn,
                    a.alert.IsFired,
                    a.alert.IsArchived,
                    a.alert.IsRecurrent,
                    a.alert.LastRecurrentDate,
                    a.alert.StateId,
                    Company = new Company { Id = a.CompanyId, Name = a.CompanyName },
                    alertLink =
                       (_workflowDefinition.GetWorkflowDefinition(a.CompanyName).Alerts.SelectMany(aa => aa.OnEnterAlerts)
                           .FirstOrDefault(aa => aa.Id == a.alert.AlertLinkId) ??
                        _workflowDefinition.GetWorkflowDefinition(a.CompanyName).Alerts.SelectMany(aa => aa.OnSubmitAlerts)
                            .FirstOrDefault(aa => aa.Id == a.alert.AlertLinkId) ??
                       _workflowDefinition.GetWorkflowDefinition(a.CompanyName).Alerts.SelectMany(aa => aa.ScheduledAlerts)
                       .FirstOrDefault(aa => aa.Id == a.alert.AlertLinkId))
                }).ToList();
                return data;
            }
            catch (Exception ex)
            {
                await NotificationManager.SendErrorMessageAsync(ex);
                throw;
            }
        }
示例#15
0
 public async Task<ActionResult> ProcessAlertAsync(int alertId, string comment, AppUser currentUser)
 {
     try
     {
         var item = await Query().FirstOrDefaultAsync(a => a.Id == alertId);
         if (item != null)
         {
             item.Comment = comment;
             item.CreatedBy = currentUser;
             item.CreatedById = currentUser.Id;
             item.CreatedOn = DateTime.UtcNow;
         }
         await _dbContext.SaveChangesAsync();
         return ActionResult.Success(item);
     }
     catch (Exception ex)
     {
         return ActionResult.Failed(ex);
     }
 }
示例#16
0
        public async Task<ActionResult> SendDocByEmailAsync(int docId, AppUser currentUser)
        {
            try
            {
                var doc = await GetDocumentAsync(docId);
                if (doc != null)
                {
                    var project = await GetProject(doc.ProjectId);
                    var qnumber = project.GetStateModel<QuoteOfEntry>()?.QuotationNumber;
                    var customer = project.GetStateModel<QuoteOfEntry>()?.Customer;
                    var propertyName = project.GetStateModel<QuoteOfEntry>()?.PropertyName;

                    if (!string.IsNullOrEmpty(customer?.Email))
                    {
                        _httpContextAccessor.ToString();
                        var baseurl = $"{_httpContextAccessor.HttpContext.Request.Scheme}://{_httpContextAccessor.HttpContext.Request.Host}";
                        var subject = $"Project - {qnumber}, doc - {doc.Link2State?.DocName}";
                        var bodyString = Encoding.UTF8.GetString(doc.Body).Replace("/fileman/", $"{baseurl}/fileman/");
                        var to = customer?.Email;
                        var cc = string.IsNullOrEmpty(propertyName?.CustomerAdminstratorEmail) ? null : new[] { propertyName?.CustomerAdminstratorEmail };
                        await NotificationManager.SendAsync(to, cc, subject, bodyString);

                        doc.Comment += $"Doc sent by e-mail at {DateTime.Now} by {currentUser.FullName}" + Environment.NewLine;
                        _dbContext.SaveChanges();

                        return ActionResult.Success();
                    }
                    else
                    {
                        throw new InvalidOperationException("E-mail address is not defined");
                    }
                }
                return ActionResult.Failed("Doc not found");
            }
            catch(Exception ex)
            {
                return ActionResult.Failed(ex);
            }            
        }
示例#17
0
        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;
        }
示例#18
0
        public async Task<IEnumerable<ProjectAlert>> GetAsync(AppUser currentUser)
        {
            var roles = (from userInRole in _dbContext.UserRoles
                         join role in _dbContext.Roles on userInRole.RoleId equals role.Id
                         where userInRole.UserId == currentUser.Id
                         select role);

            return await Query()
                .Where(a => a.StartDate.HasValue)
                .Where(
                    a => a.CreatedById == currentUser.Id || a.Actions.Any(aa => roles.Any(r => aa.To.Contains(r.Name))))
                .ToListAsync();
        }
示例#19
0
 private void CreateScheduledAlerts(IEnumerable<Alert> alerts, ProjectWorkflow project,
     StateTransition<string> transition, State state, AppUser currentUser)
 {
     foreach (var alert in alerts)
     {
         var item = new ProjectAlertScheduled
         {
             AlertLinkId = alert.Id,
             ProjectId = project.Id,
             StateId = state.Id,
             TransitionId = int.Parse(transition.Id)
         };
         _dbContext.ProjectAlertsScheduled.Add(item);
     }
     if (alerts.Any())
     {
         _dbContext.SaveChanges();
     }
 }
示例#20
0
        public async Task<ActionResult> ClearAlerts(AppUser currentUser)
        {
            try
            {
                var items = await _dbContext.ProjectAlerts.Where(a => !a.IsArchived).ToListAsync();
                foreach (var item in items)
                {
                    if (item != null)
                    {
                        item.IsArchived = true;

                        _historyManager.LogInfo(item.ProjectId, item.TransitionId, item, EventType.ArchiveAlert, currentUser);
                    }
                }
                await _dbContext.SaveChangesAsync();

                return ActionResult.Success();
            }
            catch (Exception ex)
            {
                return ActionResult.Failed(ex);
            }
        }
示例#21
0
        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);
            }
        }
示例#22
0
        public async Task<ActionResult> CreateOnSubmitAlertsAsync(ProjectWorkflow project,
            StateTransition<string> transition, State state, AppUser currentUser)
        {
            try
            {
                if (state == null)
                {
                    return ActionResult.Failed("State not set");
                }
                var submitAlertsDef = project.WorkflowDefinition
                    .Alerts
                    .Where(a => a.State.Id == state.Id)
                    .SelectMany(a => a.OnSubmitAlerts).ToList();
                await CreateAlertsAsync(submitAlertsDef, project, transition, state, currentUser);

                var scheduledAlertsDef = project.WorkflowDefinition
                    .Alerts
                    .Where(a => a.State.Id == state.Id)
                    .SelectMany(a => a.ScheduledAlerts).ToList();
                CreateScheduledAlerts(scheduledAlertsDef, project, transition, state, currentUser);

                return ActionResult.Success();
            }
            catch (Exception ex)
            {
                return ActionResult.Failed(ex);
            }
        }
示例#23
0
        public async Task<IActionResult> Register(RegisterViewModel model)
        {
            if (ModelState.IsValid)
            {
                var user = new AppUser { UserName = model.UserName, Email = model.Email };
                var result = await _userManager.CreateAsync(user, model.Password);
                if (result.Succeeded)
                {
                    // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=532713
                    // Send an email with this link
                    var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
                    var callbackUrl = Url.Action("ConfirmAccount", "Account", new { userId = user.Id, code = code }, protocol: Context.Request.Scheme);

                    await NotificationManager.SendAsync(
                        model.Email,
                        "Confirm your account",
                        "Please confirm your account by clicking this link: <a href=\"" + callbackUrl + "\">link</a>");

                    await _userManager.AddToRoleAsync(user, AppRole.AdminsRole);

                    await _signInManager.SignInAsync(user, isPersistent: false);
                    return RedirectToAction("Index", "Home");
                }
                AddErrors(result);
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }
示例#24
0
        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);
            }
        }
示例#25
0
 public ActionResult LogWarning(string projectId, int? transitionId, object item, EventType eventType, AppUser creator)
 {
     return Add(projectId, transitionId, EventLevel.Warning, eventType, creator, item);
 }
示例#26
0
        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);
            }
        }
示例#27
0
        public async Task<ActionResult> SaveAsync(Customer customer, AppUser creator)
        {
            try
            {
                if (customer.Id == 0)
                {
                    customer.CreatedBy = creator;
                    customer.CreatedOn = DateTime.UtcNow;
                    _dbContext.Customers.Add(customer);

                    if (customer.PropertyNames != null)
                    {
                        foreach (var prop in customer.PropertyNames)
                        {
                            prop.Customer = customer;
                            prop.PropertyName = _dbContext.PropertyNames.FirstOrDefault(p => p.Id == prop.PropertyNameId);
                            _dbContext.CustomerPropertyNames.Add(prop);
                        }
                    }
                }
                else
                {
                    var item = await Query().FirstOrDefaultAsync(d => d.Id == customer.Id);
                    if (item != null)
                    {
                        item.Address = customer.Address;
                        item.CityCode = customer.CityCode;
                        item.CompanyId = customer.Company.Id;
                        item.Email = customer.Email;
                        item.Fax = customer.Fax;
                        item.Name = customer.Name;
                        item.Phone = customer.Phone;
                        item.ContactPerson = customer.ContactPerson;
                        item.CustomerTypeId = customer.CustomerType == null ? customer.CustomerTypeId : customer.CustomerType.Id;

                        var dbItems = item.PropertyNames;
                        if (customer.PropertyNames == null || !customer.PropertyNames.Any())
                        {
                            CheckIfPropertyNameLinkedToProject(dbItems);
                            _dbContext.CustomerPropertyNames.RemoveRange(dbItems);
                        }
                        else
                        {
                            var deletedItems = dbItems.Where(r => !customer.PropertyNames.Any(rr => rr.CustomerId == r.CustomerId & rr.PropertyNameId == r.PropertyNameId)).ToList();
                            var addedItems = customer.PropertyNames.Where(r => !dbItems.Any(rr => rr.CustomerId == r.CustomerId & rr.PropertyNameId == r.PropertyNameId)).ToList();

                            CheckIfPropertyNameLinkedToProject(deletedItems);

                            _dbContext.CustomerPropertyNames.RemoveRange(deletedItems);
                            _dbContext.CustomerPropertyNames.AddRange(addedItems);
                            foreach(var edit in item.PropertyNames.Except(deletedItems))
                            {
                                var property = customer.PropertyNames.FirstOrDefault(p => p.PropertyNameId == edit.PropertyNameId && p.CustomerId == edit.CustomerId);
                                edit.HasVATGovernmentDoc = property?.HasVATGovernmentDoc ?? false;
                                edit.CustomerAdminstrator = property?.CustomerAdminstrator;
                                edit.CustomerAdminstratorEmail = property?.CustomerAdminstratorEmail;
                                edit.CustomerAdminstratorPhone = property?.CustomerAdminstratorPhone;
                                edit.CustomerAdminstratorMobilePhone = property?.CustomerAdminstratorMobilePhone;
                            }
                        }
                    }
                }
                await _dbContext.SaveChangesAsync();

                CacheManager.GetInstance().Remove<IEnumerable<Customer>>();

                return ActionResult.Success(Query().FirstOrDefault(d => d.Id == customer.Id));
            }
            catch (Exception ex)
            {
                return ActionResult.Failed(ex);
            }
        }
示例#28
0
        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);
            }
        }
示例#29
0
        public async Task<Infrastructure.ActionResult> MailInvoiceLateDocAsync(int invoiceId, int link2docId, AppUser currentUser)
        {
            try
            {
                var doc = await ViewInvoiceLateDocAsync(invoiceId, link2docId);
                if (doc != null)
                {
                    var invoice = _dbContext.ProjectInvoices.FirstOrDefault(i => i.Id == invoiceId);
                    var project = GetProject(invoice.ProjectId);
                    var qnumber = project.GetStateModel<QuoteOfEntry>()?.QuotationNumber;
                    var customer = project.GetStateModel<QuoteOfEntry>()?.Customer;
                    var propertyName = project.GetStateModel<QuoteOfEntry>()?.PropertyName;

                    if (!string.IsNullOrEmpty(customer?.Email))
                    {
                        _httpContextAccessor.ToString();
                        var baseurl = $"{_httpContextAccessor.HttpContext.Request.Scheme}://{_httpContextAccessor.HttpContext.Request.Host}";
                        var subject = $"Invoice - {invoice.InvoiceNumber}, LateDays - {invoice.LateDays}";
                        var bodyString = Encoding.UTF8.GetString(doc).Replace("/fileman/", $"{baseurl}/fileman/");
                        var to = customer?.Email;
                        var cc = string.IsNullOrEmpty(propertyName?.CustomerAdminstratorEmail) ? null : new[] { propertyName?.CustomerAdminstratorEmail };
                        await NotificationManager.SendAsync(to, cc, subject, bodyString);
                        return Infrastructure.ActionResult.Success();
                    }
                    else
                    {
                        throw new InvalidOperationException("E-mail address is not defined");
                    }
                }
                return Infrastructure.ActionResult.Failed("Doc not found");
            }
            catch (Exception ex)
            {
                return Infrastructure.ActionResult.Failed(ex);
            }
        }
示例#30
0
        public async Task<IEnumerable<dynamic>> ListAsync(AppUser currentUser, ProjectsQueryParameters queryParameters)
        {
            try
            {
                bool isAdmin = false;
                if (currentUser != null)
                {
                    isAdmin = (from user in _dbContext.UserRoles
                               join role in _dbContext.Roles on user.RoleId equals role.Id
                               where user.UserId == currentUser.Id && role.Name.ToLower() == AppRole.AdminsRole
                               select user).Any();
                }
                double searchValueDouble = 0;
                double.TryParse(queryParameters.ProjectsSearch, out searchValueDouble);

                if (queryParameters.IsFilterActivate())
                {
                    queryParameters.ItemsCount = 99999;
                    queryParameters.PageNr = 0;
                }

                var data = (from prj in _dbContext.ProjectsListAggregated
                            join customer in _dbContext.Customers on prj.CustomerId equals customer.Id into customer1
                            from customer in customer1.Where(c => string.IsNullOrEmpty(queryParameters.CustomersSearch) || c.Name.ToLower().Contains(queryParameters.CustomersSearch)).DefaultIfEmpty()
                            join cat in _dbContext.SyndicCategories on prj.SyndicCategoryId equals cat.Id into cat1
                            from cat in cat1.Where(c => string.IsNullOrEmpty(queryParameters.ProjectsSearch) ||
                                                      c.Name.ToLower().Contains(queryParameters.ProjectsSearch) ||
                                                      c.Label.ToLower().Contains(queryParameters.ProjectsSearch) ||
                                                      prj.QuotationNumber.ToLower().Contains(queryParameters.ProjectsSearch) ||
                                                      (searchValueDouble > 0 && prj.QuotationAmountHT == searchValueDouble) ||
                                                      (searchValueDouble > 0 && prj.QuotationAmountTTC == searchValueDouble) ||
                                                      (searchValueDouble > 0 && prj.QuotationAmountVAT == searchValueDouble) ||
                                                      prj.QuotationPurpose.ToLower().Contains(queryParameters.ProjectsSearch)
                                                  ).DefaultIfEmpty()
                            join tl in _dbContext.Users on prj.TeamLeaderId equals tl.Id into tl1
                            from tl in tl1.DefaultIfEmpty()
                            join po in _dbContext.Users on prj.PaperOwnerId equals po.Id into po1
                            from po in po1.DefaultIfEmpty()
                            join at in _dbContext.Users on prj.AssignedToId equals at.Id into at1
                            from at in at1.DefaultIfEmpty()
                            join pn in _dbContext.PropertyNames on prj.PropertyNameId equals pn.Id into pn1
                            from pn in pn1.Where(c => string.IsNullOrEmpty(queryParameters.ProjectsSearch) ||
                                                      (
                                                          prj.QuotationNumber.ToLower().Contains(queryParameters.ProjectsSearch) ||
                                                          c.Name.ToLower().Contains(queryParameters.ProjectsSearch) ||
                                                          (searchValueDouble > 0 && prj.QuotationAmountHT == searchValueDouble) ||
                                                          (searchValueDouble > 0 && prj.QuotationAmountTTC == searchValueDouble) ||
                                                          (searchValueDouble > 0 && prj.QuotationAmountVAT == searchValueDouble) ||
                                                          prj.QuotationPurpose.ToLower().Contains(queryParameters.ProjectsSearch) ||
                                                          cat != null
                                                      )).DefaultIfEmpty()
                            where prj.IsArchived == queryParameters.IncludeArchived &&
                                  (!queryParameters.CompanyId.HasValue || prj.CompanyId == queryParameters.CompanyId) &&
                                  (!queryParameters.OpenRemarksOnly.HasValue || prj.HasOpenRemarks == queryParameters.OpenRemarksOnly) &&
                                  (!queryParameters.Waranty5percentOnly.HasValue || prj.Waranty5Percent == queryParameters.Waranty5percentOnly) &&
                                  (!queryParameters.BigWorkOnly.HasValue || prj.BigWork == queryParameters.BigWorkOnly) &&
                                  (!queryParameters.ToPlan.HasValue || (prj.ActiveStateId == "-1-SEC-QuotationDatas") || (prj.ActiveStateId == "-2-COM-Assignments") || (prj.ActiveStateId == "-3-SEC-SendOrderConfirmation")) &&
                                  (!queryParameters.InvoiceWaited.HasValue || 
                                  (
                                    (prj.ActiveStateId == "-5-SEC-ACE-WorkPlan") || (prj.ActiveStateId == "-6A-PartialInvoice") || (prj.ActiveStateId == "-8-SEC-EndOfWork-Invoice") && 
                                    _invoiceManager.GetToBeInvoiced(prj.Id, prj.QuotationAmountTTC) == 0
                                  )) &&
                                  (queryParameters.ProjectsSearch == null ||
                                  (
                                    prj.QuotationNumber.ToLower().Contains(queryParameters.ProjectsSearch) ||
                                    (searchValueDouble > 0 && prj.QuotationAmountHT == searchValueDouble) ||
                                    (searchValueDouble > 0 && prj.QuotationAmountTTC == searchValueDouble) ||
                                    (searchValueDouble > 0 && prj.QuotationAmountVAT == searchValueDouble) ||
                                    prj.QuotationPurpose.ToLower().Contains(queryParameters.ProjectsSearch) ||
                                    cat != null ||
                                    pn != null
                                  )) &&
                                  (string.IsNullOrEmpty(queryParameters.InvoicesSearch) || _dbContext.ProjectInvoices.Any(i => i.ProjectId == prj.Id && i.InvoiceNumber.ToLower().Contains(queryParameters.InvoicesSearch))) &&
                                  (string.IsNullOrEmpty(queryParameters.CustomersSearch) || customer != null)
                            select new
                            {
                                prj.Id,
                                Company = new Company { Id = prj.CompanyId, Name = prj.CompanyName },
                                prj.QuotationNumber,
                                prj.Decadal,
                                CustomerName = customer == null ? null : customer.Name,
                                prj.QuotationAmountHT,
                                prj.QuotationAmountTTC,
                                prj.QuotationAmountVAT,
                                prj.QuotationPurpose,
                                Category = cat == null ? null : cat.Name,
                                CE = tl == null ? null : tl.FullName,
                                StartDate = prj.StartWorkDate,
                                EndWorkDate = prj.EndWorkDate,
                                PropertyName = pn == null ? null : pn.Name,
                                prj.CreatedOn,
                                prj.AccountingYear,
                                prj.IsArchived,
                                AssignedTo = at == null ? null : at.FullName,
                                PaperOwner = po == null ? null : po.FullName,
                                ToBePaid = _invoiceManager.GetToBePaid(prj.Id, prj.QuotationAmountTTC),
                                ToBeInvoiced = _invoiceManager.GetToBeInvoiced(prj.Id, prj.QuotationAmountTTC),
                                InvoicesInfo = _dbContext.ProjectInvoices.Where(i => i.ProjectId == prj.Id).Select(i => new { i.InvoiceDate, i.InvoiceNumber }),
                                LawyerStateInvoices = _dbContext.ProjectInvoices.Where(i => i.ProjectId == prj.Id && i.Status == InvoiceStatus.Lawyer).Select(i => new { i.InvoiceDate, i.InvoiceNumber }),
                                LastInvoiceDate = string.Join("$$$", _dbContext.ProjectInvoices.Where(i => i.ProjectId == prj.Id).OrderByDescending(i => i.InvoiceDate).Select(i => i.InvoiceDate)),
                                LastInvoiceNumber = string.Join("<br>", _dbContext.ProjectInvoices.Where(i => i.ProjectId == prj.Id).OrderByDescending(i => i.InvoiceDate).Select(i => i.InvoiceNumber)),
                                prj.ActiveStateId,
                                prj.HasOpenRemarks,
                                prj.InvoiceWaiting
                            });
                if (string.IsNullOrEmpty(queryParameters.OrderBy))
                {
                    data = data.OrderByDescending(p => p.CreatedOn);
                }
                else
                {
                    var orderParams = queryParameters.OrderBy.Split(new[] { ':' }, StringSplitOptions.RemoveEmptyEntries).Select(s => s.Replace("\"", "")).ToArray();
                    if (orderParams.Length == 2 && orderParams[1].Trim().ToLower() == "desc")
                    {
                        data = data.OrderByDescending(orderParams[0]);
                    }
                    else
                    {
                        data = data.OrderBy(orderParams[0]);
                    }
                }

                var qqq = data.Skip((queryParameters.PageNr ?? 0) * (queryParameters.ItemsCount ?? 0))
                        .Take(queryParameters.ItemsCount ?? 10000)
                        .ToList()
                                .Select(p => new
                                {
                                    p.Id,
                                    p.Company,
                                    p.QuotationNumber,
                                    p.Decadal,
                                    p.CustomerName,
                                    p.QuotationAmountHT,
                                    p.QuotationAmountTTC,
                                    p.QuotationAmountVAT,
                                    p.QuotationPurpose,
                                    p.Category,
                                    p.CE,
                                    p.StartDate,
                                    p.EndWorkDate,
                                    p.CreatedOn,
                                    p.AccountingYear,
                                    p.IsArchived,
                                    p.ToBePaid,
                                    p.ToBeInvoiced,
                                    p.AssignedTo,
                                    p.PaperOwner,
                                    p.PropertyName,
                                    p.ActiveStateId,
                                    p.InvoicesInfo,
                                    p.LawyerStateInvoices,
                                    p.LastInvoiceDate,
                                    p.LastInvoiceNumber,
                                    p.HasOpenRemarks,
                                    p.InvoiceWaiting,
                                    Status = _workflowDefinition.GetWorkflowDefinition(p.Company.Name).States.Values.FirstOrDefault(s => s.Id == p.ActiveStateId)?.DisplayName,
                                    States = _workflowDefinition.GetWorkflowDefinition(p.Company.Name).States.Values.Cast<State>().Select(st => new { st.Id, st.CategoryName, st.IsActive, st.IsCompleted, st.DisplayName }),
                                })
                                .Where(p => currentUser == null || isAdmin || (p.AssignedTo != null && p.AssignedTo.Equals(currentUser.FullName)));
                return qqq;
            }
            catch (Exception ex)
            {
                await NotificationManager.SendErrorMessageAsync(ex);
                return null;
            }
        }