using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Reflection; using EnVisage.Code; using EnVisage.Code.BLL; //using Excel; namespace EnVisage.Models { public class ProjectTeamUsage { public bool HasProjectionsResourceAllocations { get; set; } public bool HasActualsResourceAllocations { get; set; } } public class ProjectModel : IBaseModel, IValidatableObject { public Guid Id { get; set; } [Required] [MaxLength(100, ErrorMessage = "Name should not exceed 100 characters")] [Display(Name = "Name")] public string Name { get; set; } [MaxLength(50, ErrorMessage = "Project Number should not exceed 50 characters")] // SA. ENV-906. Added [Display(Name = "Project Number")] public string Number { get; set; } //[Required] [Display(Name = "Status")] public Guid StatusId { get; set; } [Display(Name = "Status")] public string StatusName { get; set; } //[Required] [Display(Name = "Type")] public Guid TypeId { get; set; } [Display(Name = "Type")] public string TypeName { get; set; } //[Required] [Display(Name = "Client")] public Guid? ClientId { get; set; } [Display(Name = "Client")] public string ClientName { get; set; } [Required] [Display(Name = "Business Unit")] public Guid? CompanyId { get; set; } [Display(Name = "Business Unit")] public string CompanyName { get; set; } [MaxLength(8)] public string Color { get; set; } [Display(Name = "Details")] [MaxLength(2000, ErrorMessage = "Details text should not exceed 2000 characters")] public string Details { get; set; } [Display(Name = "Number of Scenarios")] public int ScenariosCount { get; set; } public decimal Priority { get; set; } [Display(Name = "Probability")] [Range(0, 100)] [UIHint("Slider")] public short Probability { get; set; } [Display(Name = "Revenue Generating")] public bool IsRevenueGenerating { get; set; } [Display(Name = "Deadline")] [DataType(DataType.Date), DisplayFormat(DataFormatString = "{0:MM/dd/yy}", ApplyFormatInEditMode = true)] public DateTime? Deadline { get; set; } [Display(Name = "Teams")] public List AssignedTeams { get; set; } public Dictionary TeamsUsage { get; set; } [Display(Name = "Internal Contacts")] public List InternalContacts { get; set; } [Display(Name = "External Contacts")] public List ExternalContacts { get; set; } [Display(Name = "Performance Green Threshold")] [Range(0, 100)] public short? PerformanceYellowThreshold { get; set; } [Display(Name = "Performance Red Threshold")] [Range(0, 100)] public short? PerformanceRedThreshold { get; set; } [Display(Name = "Strategic Goals")] public List StrategicGoals { get; set; } public Guid? ExpandedPartId { get; set; } public int PartsCount { get; set; } public bool IsProbability100 { get; set; } public Guid? ParentProjectId { get; set; } public bool DeletedPart { get; set; } [Display(Name = "Project has multiple parts")] public bool HasChildren { get; set; } /// /// Gets a value indicating whether to display Project Dates readonly fields or not /// public bool ShowProjectDates { get { var dt = DateTime.Today; return !string.IsNullOrWhiteSpace(ProjectMinStartDate) && !string.IsNullOrWhiteSpace(ProjectMaxEndDate) && DateTime.TryParse(ProjectMinStartDate, out dt) && DateTime.TryParse(ProjectMaxEndDate, out dt); } } /// /// Gets or sets a minimum start date of protfolio scenarios related to any of project parts. /// public string ProjectMinStartDate { get; set; } /// /// Gets or sets a maximum end date of protfolio scenarios related to any of project parts. /// public string ProjectMaxEndDate { get; set; } public bool InitialHasChildrenState { get; set; } public Guid? TemplateId { get; set; } public bool SaveAsCopy { get; set; } public bool ContinueToScenarios { get; set; } public virtual List Scenarios { get; set; } public virtual List InactiveScenarios { get; set; } public Guid? PartForScenarioId { get; set; } public List Notes { get { var result = new List(); using (var dbContext = new EnVisageEntities()) { var notes = (from c in dbContext.Notes where c.ParentId == Id select c).ToList(); result.AddRange(notes.Select(note => (NoteModel)note)); } return result; } } public IList Parts { get; set; } public string BackUrl { get; set; } public string BackName { get; set; } public string Timestamp { get; set; } [Display(Name = "Portfolio/Product Tag")] public List PortfolioTags { get; set; } [Display(Name = "Project Tag")] public List ProjectTags { get; set; } public List UserDefinedFields { get; set; } [Display(Name = "Workflow Contacts")] public List WorkFlowContacts { get; set; } /// /// Casts a obect to the object of type . /// /// A object. /// A object filled with data from db. public static explicit operator ProjectModel(Project obj) { if (obj == null) return null; // TODO: possible reason of locked objects return GetProjectModel(obj, new EnVisageEntities()); } public static ProjectModel GetProjectModel(Project obj, EnVisageEntities dbContext) { var model = new ProjectModel { Id = obj.Id, Name = obj.Name, Number = obj.ProjectNumber, StatusId = obj.StatusId, StatusName = obj.Status != null ? obj.Status.Name : string.Empty, TypeId = obj.TypeId, TypeName = obj.Type != null ? obj.Type.Name : string.Empty, ClientId = obj.ClientId, ClientName = obj.Client != null ? obj.Client.Name : string.Empty, CompanyId = obj.CompanyId, CompanyName = obj.Company != null ? obj.Company.Name : string.Empty, Color = obj.Color, Details = obj.Details, ScenariosCount = 0, Priority = obj.Priority, IsRevenueGenerating = obj.IsRevenueGenerating, Deadline = obj.Deadline, Probability = Convert.ToInt16(obj.Probability * 100), IsProbability100 = obj.Status != null && obj.Status.Probability100, Scenarios = new List(), InactiveScenarios = new List(), Parts = new List(), HasChildren = obj.HasChildren, InitialHasChildrenState = obj.HasChildren, ParentProjectId = obj.ParentProjectId, PerformanceYellowThreshold = obj.PerformanceYellowThreshold == null ? (short?)null : Convert.ToInt16(obj.PerformanceYellowThreshold.Value * 100), PerformanceRedThreshold = obj.PerformanceRedThreshold == null ? (short?)null : Convert.ToInt16(obj.PerformanceRedThreshold.Value * 100), Timestamp = obj.EditTimestamp.ByteArrayToString() }; var wfManager = new WorkFlowManager(dbContext); if (model.HasChildren) { foreach (var childProject in obj.ChildProjects.OrderBy(pp => pp.PartNum)) { var part = (ProjectPartModel)childProject; model.Parts.Add(part); foreach (var scenario in childProject.Scenarios) { if (scenario.Type != ScenarioType.Actuals.GetHashCode()) model.ScenariosCount++; model.Scenarios.Add((ScenarioTabModel)scenario); //if (scenario.Status == (int) ScenarioStatus.Active) //{ var wfstate = wfManager.GetCurrentState(scenario.Id); if (wfstate != null) part.WorkFlowState = wfstate.state; //} } part.AssignedTeams = childProject.Team2Project.Select(t => t.TeamId).ToList(); part.StrategicGoals = childProject.StrategicGoal2Project.Select(s => s.StrategicGoalId).ToList(); var partContacts = childProject.Contact2Project.Select(c => c.Contact); part.InternalContacts = partContacts.Where(c => c.Type == ContactType.CompanyContact).Select(c => c.Id).ToList(); part.ExternalContacts = partContacts.Where(c => c.Type == ContactType.ClientContact).Select(c => c.Id).ToList(); part.CompanyId = model.CompanyId; part.TrimStringProperties(); if (part.WorkFlowState == null) { var scenario = dbContext.Scenarios.FirstOrDefault(x => x.ParentId == part.Id && x.Type == (int)ScenarioType.Portfolio); if (scenario != null) { var wfstate = wfManager.GetCurrentState(scenario.Id); if (wfstate != null) part.WorkFlowState = wfstate.state; } else { var wfstate2 = wfManager.GetCurrentState(part.Id); if (wfstate2 != null) part.WorkFlowState = wfstate2.state; } } part.ProjectTags = dbContext.TagLinks.Where(x => x.ParentID == part.Id && x.TagLinkType == (int)TagType.Project).OrderBy(x => x.Tag.TagName).Select(x => x.TagID).ToList(); part.PortfolioTags = dbContext.TagLinks.Where(x => x.ParentID == part.Id && x.TagLinkType == (int)TagType.Portfolio).OrderBy(x => x.Tag.TagName).Select(x => x.TagID).ToList(); } } else if (!obj.ParentProjectId.HasValue) { // if this is a main project then add one part to display it as main project properties model.Parts.Add(new ProjectPartModel { StatusId = obj.StatusId, StatusName = obj.Status != null ? obj.Status.Name : string.Empty, TypeId = obj.TypeId, TypeName = obj.Type != null ? obj.Type.Name : string.Empty, ClientId = obj.ClientId, ClientName = obj.Client != null ? obj.Client.Name : string.Empty, Details = obj.Details, Priority = obj.Priority, IsRevenueGenerating = obj.IsRevenueGenerating, Deadline = obj.Deadline, Probability = Convert.ToInt16(obj.Probability * 100), IsProbability100 = obj.Status != null && obj.Status.Probability100, ParentProjectId = obj.Id, AssignedTeams = obj.Team2Project.Select(t2p => t2p.TeamId).ToList(), StrategicGoals = obj.StrategicGoal2Project.Select(s2p => s2p.StrategicGoalId).ToList(), CompanyId = obj.CompanyId, PerformanceYellowThreshold = obj.PerformanceYellowThreshold == null ? (short?)null : Convert.ToInt16(obj.PerformanceYellowThreshold.Value * 100), PerformanceRedThreshold = obj.PerformanceRedThreshold == null ? (short?)null : Convert.ToInt16(obj.PerformanceRedThreshold.Value * 100), UseThreshold = obj.PerformanceYellowThreshold != null, }); foreach (var scenario in obj.Scenarios) { if (scenario.Type != ScenarioType.Actuals.GetHashCode()) model.ScenariosCount++; model.Scenarios.Add((ScenarioTabModel)scenario); //if (scenario.Status == (int) ScenarioStatus.Active) //{ var wfstate = wfManager.GetCurrentState(scenario.Id); if (wfstate != null) { model.Parts[0].WorkFlowState = wfstate.state; } // } } model.Parts[0].AssignedTeams = obj.Team2Project.Select(t2p => t2p.TeamId).ToList(); model.Parts[0].StrategicGoals = obj.StrategicGoal2Project.Select(s2p => s2p.StrategicGoalId).ToList(); var contacts = obj.Contact2Project.Select(c2p => c2p.Contact); model.Parts[0].InternalContacts = contacts.Where(c => c.Type == ContactType.CompanyContact).Select(c => c.Id).ToList(); model.Parts[0].ExternalContacts = contacts.Where(c => c.Type == ContactType.ClientContact).Select(c => c.Id).ToList(); if (model.Parts[0].Attachments == null) model.Parts[0].Attachments = new List(); if (model.Parts[0].Links == null) model.Parts[0].Links = new List(); model.Parts[0].ProjectTags = new List(); model.Parts[0].PortfolioTags = new List(); model.Parts[0].WorkFlowContacts = new List(); } model.PartsCount = model.Parts.Count; model.TrimStringProperties(); // SA. ENV-502. Attachments if (model.PartsCount > 0) { if (model.PartsCount == 1 && model.Parts.First().Id.Equals(Guid.Empty)) { // Project has no parts. Single existing in model part is virtual // ENV-2379. It does not make sense to load anything for new project if (!Guid.Empty.Equals(model.Id)) { model.Parts[0].Attachments = dbContext.Attachments .Where(x => x.ParentId.Equals(model.Id) && string.IsNullOrEmpty(x.Link) && string.IsNullOrEmpty(x.Link)).ToList().Select(y => (AttachmentModel)y).ToList(); model.Parts[0].Links = dbContext.Attachments .Where(x => x.ParentId.Equals(model.Id) && !string.IsNullOrEmpty(x.Link) && !string.IsNullOrEmpty(x.Link)).ToList().Select(y => (AttachmentModel)y).ToList(); model.Parts[0].ProjectTags = dbContext.TagLinks.Where(x => x.ParentID == model.Id && x.TagLinkType == (int)TagType.Project).OrderBy(x => x.Tag.TagName).Select(x => x.TagID).ToList(); model.Parts[0].PortfolioTags = dbContext.TagLinks.Where(x => x.ParentID == model.Id && x.TagLinkType == (int)TagType.Portfolio).OrderBy(x => x.Tag.TagName).Select(x => x.TagID).ToList(); model.Parts[0].WorkFlowContacts = (new WorkFlowManager(dbContext)).GetContactList(model.Id, WorkFlowContactNotificationType.None); } } else { // Project has parts var partIds = model.Parts.Select(x => x.Id); IEnumerable allAttachments = dbContext.Attachments.AsNoTracking() .Where(x => partIds.Contains(x.ParentId) && string.IsNullOrEmpty(x.Link)); IEnumerable allLinks = dbContext.Attachments.AsNoTracking() .Where(x => partIds.Contains(x.ParentId) && !string.IsNullOrEmpty(x.Link)); foreach (ProjectPartModel part in model.Parts) { part.Attachments = allAttachments.Where(x => x.ParentId.Equals(part.Id)).ToList() .Select(y => (AttachmentModel)y).ToList(); part.Links = allLinks.Where(x => x.ParentId.Equals(part.Id)).ToList() .Select(y => (AttachmentModel)y).ToList(); part.ProjectTags = dbContext.TagLinks.Where(x => x.ParentID == part.Id && x.TagLinkType == (int)TagType.Project).OrderBy(x => x.Tag.TagName).Select(x => x.TagID).ToList(); part.PortfolioTags = dbContext.TagLinks.Where(x => x.ParentID == part.Id && x.TagLinkType == (int)TagType.Portfolio).OrderBy(x => x.Tag.TagName).Select(x => x.TagID).ToList(); part.WorkFlowContacts = (new WorkFlowManager(dbContext)).GetContactList(part.Id, WorkFlowContactNotificationType.None); } } } var udfMan = new UDFManager(dbContext); model.UserDefinedFields = udfMan.LoadCollection(model.Id, UserDefinedFieldDomain.Project); return model; } /// /// Copies data from model to DAL object. /// /// A target DAL object. public void CopyTo(Project dbObj) { if (dbObj == null) throw new ArgumentNullException(); dbObj.Name = Name; dbObj.ProjectNumber = Number; dbObj.StatusId = StatusId; dbObj.TypeId = TypeId; dbObj.ClientId = ClientId; dbObj.CompanyId = CompanyId; dbObj.Details = Details; dbObj.Color = Color?.Replace("#", "") ?? Color; dbObj.Priority = Priority; dbObj.Probability = Probability / 100.0M; dbObj.IsRevenueGenerating = IsRevenueGenerating; dbObj.Deadline = Deadline; dbObj.HasChildren = HasChildren; dbObj.PerformanceYellowThreshold = PerformanceYellowThreshold / 100.0M; dbObj.PerformanceRedThreshold = PerformanceRedThreshold / 100.0M; } public ProjectModel Clone() { return new ProjectModel { Id = this.Id, TemplateId = this.TemplateId, ClientId = this.ClientId, ClientName = this.ClientName, Color = this.Color, CompanyId = this.CompanyId, CompanyName = this.CompanyName, Details = this.Details, InactiveScenarios = this.InactiveScenarios, IsRevenueGenerating = this.IsRevenueGenerating, Deadline = this.Deadline, Name = this.Name, Number = this.Number, Priority = this.Priority, Probability = this.Probability, SaveAsCopy = this.SaveAsCopy, ContinueToScenarios = this.ContinueToScenarios, Scenarios = this.Scenarios, ScenariosCount = this.ScenariosCount, StatusId = this.StatusId, StatusName = this.StatusName, TypeId = this.TypeId, TypeName = this.TypeName, AssignedTeams = this.AssignedTeams, TeamsUsage = this.TeamsUsage, StrategicGoals = this.StrategicGoals, InternalContacts = this.InternalContacts, ExternalContacts = this.ExternalContacts, DeletedPart = this.DeletedPart, HasChildren = this.HasChildren, InitialHasChildrenState = this.HasChildren, IsProbability100 = this.IsProbability100, PartsCount = this.PartsCount, Parts = this.Parts, PortfolioTags = this.PortfolioTags, ProjectTags = this.ProjectTags, WorkFlowContacts = this.WorkFlowContacts, UserDefinedFields = this.UserDefinedFields }; } public ProjectModel() { TeamsUsage = new Dictionary(); Parts = new List(); WorkFlowContacts = new List(); UserDefinedFields = new List(); StrategicGoals = new List(); Scenarios = new List(); ProjectTags = new List(); PortfolioTags = new List(); InternalContacts = new List(); ExternalContacts = new List(); AssignedTeams = new List(); } public IEnumerable Validate(ValidationContext validationContext) { if (HasChildren && Parts != null && Parts.Count > 0) { for (var i = 0; i < Parts.Count; i++) { if (string.IsNullOrEmpty(Parts[i].Name)) yield return new ValidationResult(string.Format(Constants.ERROR_TEMPLATE_REQUIRED, "Part " + (i + 1) + " Name"), null); } } } } public class ProjectPartModel : IBaseModel, IValidatableObject { public Guid Id { get; set; } //[Required] [MaxLength(100, ErrorMessage = "Name should not exceed 100 characters")] [Display(Name = "Name")] public string Name { get; set; } [Required] [Display(Name = "Status")] public Guid StatusId { get; set; } [Display(Name = "Status")] public string StatusName { get; set; } [Required] [Display(Name = "Type")] public Guid TypeId { get; set; } [Display(Name = "Type")] public string TypeName { get; set; } [Required] [Display(Name = "Client")] public Guid? ClientId { get; set; } [Display(Name = "Client")] public string ClientName { get; set; } [Display(Name = "Details")] [MaxLength(2000, ErrorMessage = "Details text should not exceed 2000 characters")] // SA. ENV-906. Added message public string Details { get; set; } [Display(Name = "Priority")] [Range(1, 500, ErrorMessage = "Your priority must be a number from 1 to 500")] public decimal Priority { get; set; } [Display(Name = "Probability")] [Range(0, 100)] [UIHint("Slider")] public short Probability { get; set; } [Display(Name = "Performance Indicators")] public bool UseThreshold { get; set; } [Display(Name = "Revenue Generating")] public bool IsRevenueGenerating { get; set; } [Display(Name = "Deadline")] [DataType(DataType.Date), DisplayFormat(DataFormatString = "{0:MM/dd/yy}", ApplyFormatInEditMode = true)] public DateTime? Deadline { get; set; } [Display(Name = "Teams")] public List AssignedTeams { get; set; } public Dictionary TeamsUsage { get; set; } [Display(Name = "Internal Contacts")] public List InternalContacts { get; set; } [Display(Name = "External Contacts")] public List ExternalContacts { get; set; } [Display(Name = "Performance Green Threshold")] [Range(0, 100)] public short? PerformanceYellowThreshold { get; set; } [Display(Name = "Performance Red Threshold")] [Range(0, 100)] public short? PerformanceRedThreshold { get; set; } [Display(Name = "Strategic Goals")] public List StrategicGoals { get; set; } public bool IsProbability100 { get; set; } public Guid? ParentProjectId { get; set; } public bool DeletedPart { get; set; } public bool SaveAsCopy { get; set; } public Guid? CompanyId { get; set; } public int? PartNum { get; set; } [UIHint("FileUploadModel")] public IList Attachments { get; set; } [UIHint("FileLinkModel")] public IList Links { get; set; } [Display(Name = "Portfolio/Product Labels")] public List PortfolioTags { get; set; } [Display(Name = "Project Tags")] public List ProjectTags { get; set; } [Display(Name = "Workflow Contacts")] public List WorkFlowContacts { get; set; } [Display(Name = "Workflow State")] public string WorkFlowState { get; set; } /// /// Gets or sets a collection of project dependencies. /// [Display(Name = "Project Dependencies")] public ProjectDependencies.ProjectDependencyListModel Dependencies { get; set; } /// /// Casts a obect to the object of type . /// /// A object. /// A object filled with data from db. public static explicit operator ProjectPartModel(Project obj) { if (obj == null) return null; var model = new ProjectPartModel { Id = obj.Id, Name = obj.Name, StatusId = obj.StatusId, StatusName = obj.Status != null ? obj.Status.Name : string.Empty, TypeId = obj.TypeId, TypeName = obj.Type != null ? obj.Type.Name : string.Empty, ClientId = obj.ClientId, ClientName = obj.Client != null ? obj.Client.Name : string.Empty, Details = obj.Details, Priority = obj.Priority, IsRevenueGenerating = obj.IsRevenueGenerating, Deadline = obj.Deadline, Probability = Convert.ToInt16(obj.Probability * 100), IsProbability100 = obj.Status != null && obj.Status.Probability100, ParentProjectId = obj.ParentProjectId, PerformanceYellowThreshold = obj.PerformanceYellowThreshold == null ? (short?) null : Convert.ToInt16(obj.PerformanceYellowThreshold.Value * 100), PerformanceRedThreshold = obj.PerformanceRedThreshold == null ? (short?) null : Convert.ToInt16(obj.PerformanceRedThreshold.Value * 100), PartNum = obj.PartNum, UseThreshold = obj.PerformanceYellowThreshold != null, AssignedTeams = obj.Team2Project.Select(t2p => t2p.TeamId).ToList(), StrategicGoals = obj.StrategicGoal2Project.Select(s2p => s2p.StrategicGoalId).ToList() }; var contacts = obj.Contact2Project.Where(x => x.Contact != null).Select(c2p => c2p.Contact); model.InternalContacts = contacts.Where(c => c.Type == ContactType.CompanyContact).Select(c => c.Id).ToList(); model.ExternalContacts = contacts.Where(c => c.Type == ContactType.ClientContact).Select(c => c.Id).ToList(); if (model.Attachments == null) model.Attachments = new List(); if (model.Links == null) model.Links = new List(); model.TrimStringProperties(); return model; } /// /// Copies data from model to DAL object. /// /// A target DAL object. public void CopyTo(Project dbObj) { if (dbObj == null) throw new ArgumentNullException(); dbObj.Name = Name; dbObj.StatusId = StatusId; dbObj.TypeId = TypeId; dbObj.ClientId = ClientId; dbObj.Details = Details; dbObj.Priority = Priority; dbObj.Probability = Probability / 100.0M; dbObj.IsRevenueGenerating = IsRevenueGenerating; dbObj.Deadline = Deadline; dbObj.ParentProjectId = ParentProjectId; dbObj.PerformanceYellowThreshold = (PerformanceYellowThreshold == null || !UseThreshold) ? (decimal?)null : PerformanceYellowThreshold.Value / 100.0M; dbObj.PerformanceRedThreshold = (PerformanceRedThreshold == null || !UseThreshold) ? (decimal?)null : PerformanceRedThreshold.Value / 100.0M; dbObj.Color = null; dbObj.CompanyId = null; dbObj.ProjectNumber = null; dbObj.PartNum = PartNum; } public ProjectPartModel Clone() { return new ProjectPartModel { Id = this.Id, ClientId = this.ClientId, ClientName = this.ClientName, Details = this.Details, IsRevenueGenerating = this.IsRevenueGenerating, Deadline = this.Deadline, Name = this.Name, Priority = this.Priority, Probability = this.Probability, StatusId = this.StatusId, StatusName = this.StatusName, TypeId = this.TypeId, TypeName = this.TypeName, AssignedTeams = this.AssignedTeams, TeamsUsage = this.TeamsUsage, StrategicGoals = this.StrategicGoals, InternalContacts = this.InternalContacts, ExternalContacts = this.ExternalContacts, DeletedPart = this.DeletedPart, IsProbability100 = this.IsProbability100, ParentProjectId = this.ParentProjectId, PerformanceRedThreshold = this.PerformanceRedThreshold, PerformanceYellowThreshold = this.PerformanceYellowThreshold, PartNum = this.PartNum, Attachments = this.Attachments, ProjectTags = this.ProjectTags, PortfolioTags = this.PortfolioTags, WorkFlowContacts = this.WorkFlowContacts, Links = this.Links }; } public IEnumerable Validate(ValidationContext validationContext) { if (PerformanceYellowThreshold.HasValue && PerformanceRedThreshold.HasValue && PerformanceYellowThreshold > PerformanceRedThreshold) { yield return new ValidationResult("Performance Yellow value cannot be greater than Red value", new[] { "PerformanceYellowThreshold" }); } if (Deadline.HasValue) { var _Id = (Id == Guid.Empty) ? ParentProjectId : Id; var DbContext = new EnVisageEntities(); var ActiveScenario = DbContext.Scenarios.Where(x => x.ParentId == _Id && x.Status == (int)ScenarioStatus.Active).FirstOrDefault(); var ActualsScenario = DbContext.Scenarios.Where(x => x.ParentId == _Id && x.Type == (int)ScenarioType.Actuals).FirstOrDefault(); if ((ActiveScenario != null && ActiveScenario.EndDate.HasValue && Deadline.Value < ActiveScenario.EndDate.Value) || (ActualsScenario != null && ActualsScenario.EndDate.HasValue && Deadline.Value < ActualsScenario.EndDate.Value)) yield return new ValidationResult(string.Format(Constants.ERROR_DEADLINE_DATE_LATE, Name), new[] { "Deadline" }); } } public ProjectPartModel() { Attachments = new List(); Links = new List(); PortfolioTags = new List(); ProjectTags = new List(); WorkFlowContacts = new List(); } } /// /// An UI representation of project to be displayed as list items /// public class ProjectListModel { public Guid Id { get; set; } public Guid ProjectId { get; set; } public string ProjectName { get; set; } public string ProjectNumber { get; set; } public string Status { get; set; } public decimal Priority { get; set; } public short Probability { get; set; } public string Classification { get; set; } public string Client { get; set; } public string Company { get; set; } public string Teams { get; set; } = string.Empty; public string Team { get; set; } public Guid TeamId { get; set; } public bool WritePermissionEnabledForCurrentUser { get; set; } public ScenarioInProjectModel ActiveScenario { get; set; } public List InactiveScenarios { get; set; } public bool HasChildren { get; set; } public List ProjectParts { get; set; } public int? PartNum { get; set; } public DateTime? Deadline { get; set; } public int Rank { get; set; } public bool ReadOnly { get; set; } } public class ProjectPartListModel : ProjectListModel { } public class ScenarioInProjectModel : IComparable { public Guid Id { get; set; } public string Name { get; set; } public int CompareTo(ScenarioInProjectModel other) { if (Name == null && other == null) return 0; if (Name == null) return -1; if (other == null) return 1; return Name.CompareTo(other.Name); } } public class InactiveScenarioInProjectModel : ScenarioInProjectModel { public long? StartDate { get; set; } public long? EndDate { get; set; } } public class ImportActualsModel { public Guid Id { get; set; } public string ProjectName { get; set; } public List Projects { get; set; } public bool ResetActuals { get; set; } public Guid SessionId { get; set; } public bool ImportSuccessful { get; set; } public string Message { get; set; } public ImportActualsModel() { Projects = new List(); } } public class ImportActualsProject { public Guid ProjectId { get; set; } public string ProjectName { get; set; } public Guid ActualsScenarioId { get; set; } public bool Checked { get; set; } public string StartDate { get; set; } public string EndDate { get; set; } public List ProjectParts { get; set; } public Dictionary ProjectPartsDistribution { get; set; } public ImportActualsProject() { ProjectParts = new List(); ProjectPartsDistribution = new Dictionary(); } } public class ImportActualsProjectPart { public Guid PartId { get; set; } public string PartName { get; set; } public bool Checked { get; set; } public Guid ActualsScenarioId { get; set; } public string StartDate { get; set; } public string EndDate { get; set; } public int Distribution { get; set; } } public class ImportActualsScenarioDetails { public Guid Id { get; set; } public Guid? SDId { get; set; } public Guid ParentId { get; set; } public Guid ProjectId { get; set; } public Guid ExpenditureCategoryId { get; set; } public DateTime WeekEndingDate { get; set; } public decimal Cost { get; set; } public decimal Quantity { get; set; } public Guid? PeopleResourceID { get; set; } } public class ProjectWithChildrenView { public Guid Id { get; set; } public Guid? CompanyId { get; set; } public string CompanyName { get; set; } public Guid? ClientId { get; set; } public string ClientName { get; set; } public string Name { get; set; } public string TypeName { get; set; } public DateTime? Deadline { get; set; } public decimal Priority { get; set; } public bool HasChildren { get; set; } public string Color { get; set; } public bool ReadOnly { get; set; } public Guid StatusId { get; set; } public Guid TypeId { get; set; } public string StatusName { get; set; } public decimal Probability { get; set; } public Guid? ParentProjectId { get; set; } public decimal? PerformanceYellowThreshold { get; set; } public decimal? PerformanceRedThreshold { get; set; } public List Teams { get; set; } public List StrategicGoals { get; set; } public ParentProjectView ParentProject { get; set; } public List Scenarios { get; set; } #region Internal Classes public class ParentProjectView { public Guid Id { get; set; } public Guid? CompanyId { get; set; } public string Name { get; set; } public string Color { get; set; } } public class ScenarioView { public Guid Id { get; set; } public Guid? ParentId { get; set; } public string Name { get; set; } public bool IsBottomUp { get; set; } public ScenarioStatus? Status { get; set; } public ScenarioType? Type { get; set; } public DateTime? StartDate { get; set; } public DateTime? EndDate { get; set; } public DateTime? DateCreated { get; set; } } #endregion } }