using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Web.Mvc; using EnVisage.Code; using System.Linq; using EnVisage.Models.ValidationAttributes.Scenarios; using EnVisage.Models.Cache; using EnVisage.Code.BLL; using EnVisage.Models.ProjectDependencies; namespace EnVisage.Models { public class ScenarioDetailModel : IBaseModel { #region Properties public Guid Id { get; set; } [Required] [AllowHtml] [MaxLength(100)] public string Name { get; set; } /// /// Gets or sets an Id of the template. /// [Display(Name = "Template")] public Guid TemplateId { get; set; } [Display(Name = "Project Name")] public string ProjectName { get; set; } [Display(Name = "Project Deadline")] [DataType(DataType.Date)] [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")] public DateTime? ProjectDeadline { get; set; } [Display(Name = "Part Name")] public string PartName { get; set; } /// /// Gets or sets an Id of the project. /// public Guid ParentId { get; set; } /// /// Gets or sets a color that will be used for scenario in reports. /// [MaxLength(8)] public string Color { get; set; } /// /// Gets or sets a type of scenario. /// public ScenarioType? Type { get; set; } /// /// Gets or sets a scenario of scenario. /// public ScenarioStatus? Status { get; set; } [Display(Name = "Active Scenario")] public bool IsActiveScenario { get; set; } [DataType(DataType.Date), DisplayFormat(DataFormatString = "{0:MM/dd/yy}", ApplyFormatInEditMode = true)] [Display(Name = "Scenario Start Date")] [Required] [ScenarioStartDateValidator] public DateTime? StartDate { get; set; } [DataType(DataType.Date), DisplayFormat(DataFormatString = "{0:MM/dd/yy}", ApplyFormatInEditMode = true)] [Display(Name = "Scenario End Date")] [Required] [ScenarioEndDateValidator] [DateGreaterThanOrEqual("StartDate", "Scenario End Date should not be less than Start Date")] public DateTime? EndDate { get; set; } [DataType(DataType.Date), DisplayFormat(DataFormatString = "{0:MM/dd/yy}", ApplyFormatInEditMode = true)] [Display(Name = "Milestone Start Date")] public DateTime? MilestoneStartDate { get; set; } [Display(Name = "Growth Scenario?")] public bool GrowthScenario { get; set; } [Display(Name = "Total Milestones")] // not editable //[Range(1, 2147483647)] public int TotalMilestones { get; set; } [Display(Name = "Calculated Duration (weeks)")] public int? Duration { get; set; } public IList Expenditures { get; set; } public IList ScenarioExpenditures { get; set; } public RatesModel RatesModel { get; set; } public string BackUrl { get; set; } public string BackName { get; set; } public string ActiveTab { get; set; } public bool HasActuals { get; set; } public long ActualsStartDate { get; set; } public long ActualsEndDate { get; set; } public bool NeedToRecalculateScenarioDetails { get; set; } /// /// True, if parent project has dependencies with other projects /// public bool ProjectHasDependencies { get; set; } public DateTime? StartDateConstraint { get; set; } public DateTime? EndDateConstraint { get; set; } public long? StartDateConstraintMs => StartDateConstraint.HasValue ? Utils.ConvertToUnixDate(StartDateConstraint.Value.ToUniversalTime()) : (long?)null; public long? EndDateConstraintMs => EndDateConstraint.HasValue ? Utils.ConvertToUnixDate(EndDateConstraint.Value.ToUniversalTime()) : (long?)null; [Display(Name = "Scenario Type")] public bool IsBottomUp { get; set; } public ScenarioFinInfoModel FinInfo { get; set; } public List UserDefinedFields { get; set; } public string WorkFlowCommand { get; set; } [Display(Name = "Workflow State")] public string WorkFlowState { get; set; } [Display(Name = "Workflow Process")] public string WorkFlowScheme { get; set; } public Guid ProjectId { get; internal set; } public IReadOnlyCollection Projects { get; internal set; } #endregion #region Constructors public ScenarioDetailModel() { Expenditures = new List(); RatesModel = new RatesModel(); FinInfo = new ScenarioFinInfoModel(); var udfMan = new UDFManager(new EnVisageEntities()); UserDefinedFields = udfMan.LoadCollection(Guid.Empty, UserDefinedFieldDomain.Scenario); } #endregion #region Methods /// /// Copies data from model to DAL object. /// /// A target DAL object. public void CopyTo(Scenario dbObj) { if (dbObj == null) throw new ArgumentNullException(); dbObj.Name = Name; // SA. Fixed bug ENV-707. Begin fix dbObj.Color = !string.IsNullOrEmpty(Color) ? Color.Replace("#", "") : null; // End fix ENV-707 dbObj.Type = Type.GetHashCode(); dbObj.Status = IsActiveScenario ? Code.ScenarioStatus.Active.GetHashCode() : ScenarioStatus.Inactive.GetHashCode(); dbObj.IsBottomUp = IsBottomUp; dbObj.ShotStartDate = MilestoneStartDate; } #endregion } public class LaborMaterialsCostInfo { public decimal Labor { get; set; } public decimal Materials { get; set; } public decimal Total { get; set; } public string LaborAndMaterialSplit { get { if (Labor == 0 && Materials == 0) return "0/0"; decimal laborPart = Math.Round((Labor / (Labor + Materials)) * 100, 2); return string.Format("{0:G29}/{1:G29}", laborPart, 100 - laborPart); } } } public class ScenarioCopyModel { public Guid ScenarioId { get; set; } [Required] [Display(Name = "Target Project")] public Guid TargetProjectId { get; set; } public ScenarioStatus TargetStatus { get; set; } public bool includeCostSavings { get; set; } public bool hasCostSavings { get; set; } public IReadOnlyCollection Projects { get; set; } } public class ScenarioDetailsCalendarModel { #region Properties public Guid Id { get; set; } public string Name { get; set; } public Guid ParentId { get; set; } public Guid? TemplateId { get; set; } public long StartDate { get; set; } public long EndDate { get; set; } public decimal ProjectedRevenue { get; set; } public bool GrowthScenario { get; set; } public ScenarioType Type { get; set; } public bool UseLMMargin { get; set; } public decimal? GrossMargin { get; set; } public decimal? LMMargin { get; set; } public int Duration { get; set; } public decimal TDDirectCosts { get; set; } public decimal CGSplit { get; set; } public decimal EFXSplit { get; set; } public bool Pinned { get; set; } public int Shots { get; set; } public bool IsActiveScenario { get; set; } public bool ShowAvgTotals { get; set; } public bool IsUOMHours { get; set; } public bool ShowActuals { get; set; } public bool IsTableModeQuantity { get; set; } public bool IsViewModeMonth { get; set; } public bool ShowFilters { get; set; } public string DataSection { get { return "scenarioCalendar"; } } public List AvailableExpenditures { get; set; } = new List(); public List TeamsInScenario { get; set; } = new List(); public bool NeedToRecalculateScenarioDetails { get; set; } public bool NeedToAdjustMargin { get; set; } /// /// Rebuild calendar only by request /// public bool InitOnDemand { get; set; } public string PagePreferences { get; set; } public ScenarioCalendarOpener Opener { get; set; } public bool IsBottomUp { get; set; } public DateTime? ProjectDeadline { get; set; } public bool ProjectHasDependencies { get; set; } public DateTime? StartDateConstraint { get; set; } public DateTime? EndDateConstraint { get; set; } public long? StartDateConstraintMs { get { return StartDateConstraint.HasValue ? Utils.ConvertToUnixDate(StartDateConstraint.Value.ToUniversalTime()) : (long?)null; } } public long? EndDateConstraintMs { get { return EndDateConstraint.HasValue ? Utils.ConvertToUnixDate(EndDateConstraint.Value.ToUniversalTime()) : (long?)null; } } public ProjectDependencyListModel DependencyListModel { get; set; } public DateTime? EndDateConstrantWithDeadline { get { if (EndDateConstraint.HasValue && ProjectDeadline.HasValue) { //deadline date comes before end date from dependancy if ((EndDateConstraint.Value - ProjectDeadline.Value).TotalDays > 0) return ProjectDeadline; //deadline date comes after end date from dependancy if ((EndDateConstraint.Value - ProjectDeadline.Value).TotalDays < 0) return EndDateConstraint; //both dates are the same if ((EndDateConstraint.Value - ProjectDeadline.Value).TotalDays == 0) return EndDateConstraint; } else if (ProjectDeadline.HasValue) return ProjectDeadline; else if (EndDateConstraint.HasValue) return EndDateConstraint; return null; } } #endregion #region Enums public enum ScenarioCalendarOpener { CreateScenarioWizard = 0, Details = 1, RMO = 2 } #endregion } public class ScenarioFinInfoModel { [DataType(DataType.Date), DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)] [Display(Name = "Date for start of change")] [DateForStartOfChangeValidator] public DateTime? DateForStartOfChanges { get; set; } public bool IsRevenueGenerating { get; set; } [Display(Name = "Projected Revenue")] [DataType(DataType.Currency), DisplayFormat(DataFormatString = "{0:G29}", ApplyFormatInEditMode = true)] public decimal? ProjectedRevenue { get; set; } [Display(Name = "Calculated Revenue After Cost")] public decimal RevenueAfterCost { get; set; } [Display(Name = "Actual Revenue After Cost")] public decimal? ActualRevenueAfterCost { get; set; } [Display(Name = "Projected Margin")] [Range(1, 100)] [EitherOfRequired("FinInfo_ProjectedRevenue", "Either Projected Revenue or Margin should be entered", "", true)] public int? GrossMargin { get; set; } [Display(Name = "L&M Margin")] [Range(1, 100)] [EitherOfRequired("FinInfo_ProjectedRevenue", "Either Projected Revenue or Margin should be entered", "", true)] public int? LMMargin { get; set; } [Display(Name = "Use L&M Margin?")] public bool UseLMMargin { get; set; } [Display(Name = "Calculated Gross Margin (Forecast)")] public int CalculatedGrossMargin { get; set; } [Display(Name = "Calculated Gross Margin LM (Forecast)")] public int CalculatedGrossMarginLM { get; set; } [Display(Name = "Calculated Gross Margin (Actuals)")] public int? CalculatedGrossMarginActuals { get; set; } [Display(Name = "Calculated Gross Margin LM (Actuals)")] public int? CalculatedGrossMarginLMActuals { get; set; } [Display(Name = "Top-Down Expense")] [TDDirectCostValidator] public decimal TDDirectCosts { get; set; } [Display(Name = "Bottom-Up Expense")] public decimal BUDirectCosts { get; set; } [Display(Name = "Actual Labor")] public decimal? ActualLabor { get; set; } [Display(Name = "Labor/Materials Split")] public string LaborMaterialsSplit { get; set; } [Display(Name = "Actual Labor/Materials Split")] public string ActualLaborMaterialsSplit { get; set; } [Display(Name = "Actual Materials")] public decimal? ActualMaterials { get; set; } public decimal ActualsTotal { get; set; } public decimal EFXSplit { get; set; } public short LaborSplitPercentage { get; set; } public CostSavingModel CostSaving { get; set; } #region Constructors public ScenarioFinInfoModel() { CostSaving = new CostSavingModel(); } #endregion } public class ScenarioDetailsListItem { public Guid Id { get; set; } public Guid ParentId { get; set; } public Guid ExpenditureCategoryId { get; set; } public DateTime? WeekEndingDate { get; set; } public decimal Quantity { get; set; } public int WeekOrdinal { get; set; } public decimal DetailCost { get; set; } public string ExpenditureCategoryName { get; set; } public Guid? GlId { get; set; } public Guid? UOMId { get; set; } public Guid? CreditId { get; set; } public ExpenditureCategoryModel.CategoryTypes CategoryType { get; set; } public ExpenditureCategoryModel.UseTypes UseType { get; set; } public ExpenditureCategoryModel.CgEfx CG_EFX { get; set; } public Guid? SysField1 { get; set; } public Guid SysField2 { get; set; } public int? SortOrder { get; set; } public bool ExpenditureCatagoryAllowsResource { get; set; } } public class ScenarioTeamInfoModel { public Guid Id { get; set; } public string Name { get; set; } public int Allocation { get; set; } public bool CanBeDeleted { get; set; } public Guid? PlannedCapacityScenarioId { get; set; } public ICollection Resources { get; set; } public bool IsAccessible { get; set; } public ScenarioTeamInfoModel() { Resources = new List(); } } }