using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using EnVisage.Code; using System.Linq; namespace EnVisage.Models { public class WhatIfCalendarModel { #region Classes and enums public class ScenarioListElement { public System.Guid Id { get; set; } public string Name { get; set; } public ScenarioType Type { get; set; } public string ProjectName { get; set; } public Nullable CGSplit { get; set; } public Nullable EFXSplit { get; set; } public Nullable StartDate { get; set; } public Nullable EndDate { get; set; } } public class СhartListElement { public Nullable ScenarioId { get; set; } public Nullable WeekEndingDate { get; set; } public Nullable Quantity { get; set; } public Nullable Cost { get; set; } public Nullable ScenarioType { get; set; } public string ScenarioName { get; set; } public decimal Probability { get; set; } public string ProjectColor { get; set; } public string CGEFX { get; set; } } #endregion #region Properties public List Scenarios { get; set; } public string SelectedScenarios { get; set; } public Guid? GroupId { get; set; } [Display(Name = "Scenario Group")] public string GroupName { get; set; } [Display(Name = "Scenario Type")] public ScenarioType SelectedScenarioType { get; set; } [Display(Name = "Labor/Materials")] public LaborMaterialsType LaborMaterials { get; set; } [Display(Name = "Seats/Costs")] public SeatsCostsType SeatsCosts { get; set; } [Display(Name = "Include Actuals?")] public YesNoType IncludeActuals { get; set; } [DataType(DataType.Date), DisplayFormat(DataFormatString = "{0:MM/dd/yy}", ApplyFormatInEditMode = true)] [Display(Name = "Start Date")] public DateTime StartDate { get; set; } [DataType(DataType.Date), DisplayFormat(DataFormatString = "{0:MM/dd/yy}", ApplyFormatInEditMode = true)] [Display(Name = "End Date")] public DateTime EndDate { get; set; } public Dictionary> ChartData { get; set; } public bool? UOMSwitcherMode { get; set; } List<СhartListElement> _chartData; #endregion public WhatIfCalendarModel() { GroupId = Guid.Empty; GroupName = string.Empty; SelectedScenarioType = ScenarioType.Portfolio; StartDate = DateTime.Today.AddMonths(-1); EndDate = DateTime.Today.AddMonths(11); } #region Methods public void FormScenarioReport(EnVisageEntities db) { Scenarios = GetScenarioData(db); } public void FormСhartListElements(EnVisageEntities db) { _chartData = GetСhartData(db); ChartData = new Dictionary>(); foreach(var element in _chartData) { if(ChartData.Keys.Contains(element.ScenarioName)) { ChartData[element.ScenarioName].Add(element); } else { ChartData.Add(element.ScenarioName, new List<СhartListElement>()); ChartData[element.ScenarioName].Add(element); } } } List GetScenarioData(EnVisageEntities db) { if (GroupId == Guid.Empty) { return db.VW_Scenario2Project.Where(t => t.Status.HasValue && t.Status.Value == (int?)ScenarioStatus.Active && ((!t.SystemAttributeObjectID.HasValue && t.Type == (int?)SelectedScenarioType) || (t.Type == (int?)ScenarioType.Capacity || t.Type == (int?)ScenarioType.Vacation || t.Type == (int?)ScenarioType.Training))) .Select(x => new ScenarioListElement() { Name = x.Name, CGSplit = x.CGSplit, EFXSplit = x.EFXSplit, EndDate = x.EndDate, StartDate = x.StartDate, Id = x.Id, ProjectName = x.ShowName + (x.ParentProjectId != null ? ": " + x.ParentProjectName : ""), Type = (ScenarioType)x.Type }) .ToList(); } else { return db.VW_Scenario2Project.Where(t => t.Status.HasValue && t.Status.Value == (int?)ScenarioStatus.Active && ((t.SystemAttributeObjectID.HasValue && t.SystemAttributeObjectID.Value == GroupId && t.Type == (int?)SelectedScenarioType) || (t.Type == (int?)ScenarioType.Capacity || t.Type == (int?)ScenarioType.Vacation || t.Type == (int?)ScenarioType.Training))).Select(x => new ScenarioListElement() { Name = x.Name, CGSplit = x.CGSplit, EFXSplit = x.EFXSplit, EndDate = x.EndDate, StartDate = x.StartDate, Id = x.Id, ProjectName = x.ShowName + (x.ParentProjectId != null ? ": " + x.ParentProjectName : ""), Type = (ScenarioType)x.Type }) .ToList(); } } List<СhartListElement> GetСhartData(EnVisageEntities db) { List l = new List(); if (!string.IsNullOrEmpty(SelectedScenarios) && !"[]".Equals(SelectedScenarios)) SelectedScenarios.TrimStart('[').TrimEnd(']').Split(',').ToList().ForEach(x => l.Add(new Guid(x.TrimStart('\"').TrimEnd('\"')))); var expCats = db.ExpenditureCategory.AsNoTracking().ToDictionary(e => e.Id); var uoms = db.UOMs.AsNoTracking().ToDictionary(u => u.Id); var result = new List<СhartListElement>(); #region retreieve scenario data if (GroupId.HasValue && !GroupId.Value.Equals(Guid.Empty)) { result = (from sd in db.ScenarioDetail join sc in db.Scenarios on sd.ParentID equals sc.Id join ec in db.ExpenditureCategory on sd.ExpenditureCategoryId equals ec.Id join pr in db.Projects on sc.ParentId equals pr.Id join st in db.Status on pr.StatusId equals st.Id where ec.Type == 1 & sc.Type > 1 & sc.Status == (int?)ScenarioStatus.Active & sd.WeekEndingDate <= EndDate & sd.WeekEndingDate >= StartDate & sd.ParentID.HasValue & l.Contains(sd.ParentID.Value) & sc.SystemAttributeObjectID == GroupId select new { ScenarioId = sd.ParentID, sd.WeekEndingDate, sd.Quantity, sd.Cost, sd.ExpenditureCategoryId, ec.CGEFX, ScenarioType = sc.Type, ScenarioName = sc.Name, ProjectId = pr.Id, ProjectName = (pr.ParentProject != null ? pr.ParentProject.Name + ": " : "") + pr.Name, ProjectTypeId = pr.TypeId, StatusId = st.Id, StatusName = st.Name, pr.Probability, ProjectColor = !string.IsNullOrEmpty(pr.Color) ? pr.Color : (pr.ParentProject != null ? pr.ParentProject.Color : null), sc.Status, sc.SystemAttributeObjectID }) .ToArray().Select(t => new { t.ScenarioId, t.WeekEndingDate, Quantity = t.Quantity * Utils.GetUOMMultiplier(expCats, uoms, t.ExpenditureCategoryId ?? Guid.Empty, UOMSwitcherMode), t.Cost, t.CGEFX, t.ScenarioType, t.ScenarioName, t.ProjectId, t.ProjectName, t.ProjectTypeId, t.StatusId, t.StatusName, t.Probability, t.ProjectColor, t.Status, t.SystemAttributeObjectID }).GroupBy(t => new { t.WeekEndingDate, t.CGEFX, t.ScenarioId, t.ScenarioType, t.ScenarioName, t.Probability, t.ProjectColor, t.ProjectId, t.StatusId }) .Select(x => new СhartListElement() { ScenarioId = x.Key.ScenarioId, WeekEndingDate = x.Key.WeekEndingDate, Quantity = x.Sum(s=>s.Quantity), Cost = x.Sum(s=>s.Cost), ScenarioType = x.Key.ScenarioType, ScenarioName = x.Key.ScenarioName, Probability = x.Key.Probability, ProjectColor = x.Key.ProjectColor, CGEFX = x.Key.CGEFX }) .OrderBy(x => x.WeekEndingDate) .ThenBy(x => x.ScenarioName) .ToList(); } else { result = (from sd in db.ScenarioDetail join sc in db.Scenarios on sd.ParentID equals sc.Id join ec in db.ExpenditureCategory on sd.ExpenditureCategoryId equals ec.Id join pr in db.Projects on sc.ParentId equals pr.Id join st in db.Status on pr.StatusId equals st.Id where ec.Type == 1 & sc.Type > 1 & sc.Status == (int?)ScenarioStatus.Active & sd.WeekEndingDate <= EndDate & sd.WeekEndingDate >= StartDate & sd.ParentID.HasValue & l.Contains(sd.ParentID.Value) & !sc.SystemAttributeObjectID.HasValue select new { ScenarioId = sd.ParentID, sd.WeekEndingDate, sd.Quantity, sd.Cost, sd.ExpenditureCategoryId, ec.CGEFX, ScenarioType = sc.Type, ScenarioName = sc.Name, ProjectId = pr.Id, ProjectName = (pr.ParentProject != null ? pr.ParentProject.Name + ": " : "") + pr.Name, ProjectTypeId = pr.TypeId, StatusId = st.Id, StatusName = st.Name, pr.Probability, ProjectColor = !string.IsNullOrEmpty(pr.Color) ? pr.Color: (pr.ParentProject != null ? pr.ParentProject.Color : null), sc.Status, sc.SystemAttributeObjectID }) .ToArray().Select(t => new { t.ScenarioId, t.WeekEndingDate, Quantity = t.Quantity * Utils.GetUOMMultiplier(expCats, uoms, t.ExpenditureCategoryId ?? Guid.Empty, UOMSwitcherMode), t.Cost, t.CGEFX, t.ScenarioType, t.ScenarioName, t.ProjectId, t.ProjectName, t.ProjectTypeId, t.StatusId, t.StatusName, t.Probability, t.ProjectColor, t.Status, t.SystemAttributeObjectID }).GroupBy(t => new { t.WeekEndingDate, t.CGEFX, t.ScenarioId, t.ScenarioType, t.ScenarioName, t.Probability, t.ProjectColor, t.ProjectId, t.StatusId }) .Select(x => new СhartListElement() { ScenarioId = x.Key.ScenarioId, WeekEndingDate = x.Key.WeekEndingDate, Quantity = x.Sum(s=>s.Quantity), Cost = x.Sum(s=>s.Cost), ScenarioType = x.Key.ScenarioType, ScenarioName = x.Key.ScenarioName, Probability = x.Key.Probability, ProjectColor = x.Key.ProjectColor, CGEFX = x.Key.CGEFX }) .OrderBy(x => x.WeekEndingDate) .ThenBy(x => x.ScenarioName) .ToList(); } #endregion #region retrieve Training data if (result.Count > 0) { var scenarioIds = result.Select(t => t.ScenarioId).Distinct().ToArray(); var allTrainings = (from trainingWeek in db.PeopleResourceTrainings join vac in db.Trainings on trainingWeek.TrainingId equals vac.Id join pa in db.PeopleResourceAllocations on trainingWeek.PeopleResourceId equals pa.PeopleResourceId join ec in db.ExpenditureCategory on pa.ExpenditureCategoryId equals ec.Id where scenarioIds.Contains(pa.ScenarioId) & trainingWeek.WeekEndingDate >= StartDate & trainingWeek.WeekEndingDate <= EndDate select new { trainingWeek.Id, pa.ExpenditureCategoryId, trainingWeek.WeekEndingDate, trainingWeek.HoursOff, ec.CGEFX, Rate = db.Rates.FirstOrDefault(r => r.ExpenditureCategoryId == pa.ExpenditureCategoryId && r.StartDate <= trainingWeek.WeekEndingDate && r.EndDate >= trainingWeek.WeekEndingDate) }).Distinct().ToArray(); var dates = result.Select(t => t.WeekEndingDate).Distinct().ToArray(); foreach (var dt in dates) { var dtTrainings = allTrainings.Where(t => t.WeekEndingDate <= dt.Value && t.WeekEndingDate >= dt.Value.AddDays(-6)).ToArray(); var q = dtTrainings.Sum(s => s.HoursOff * Utils.GetUOMMultiplier(expCats, uoms, s.ExpenditureCategoryId, UOMSwitcherMode)); var c = dtTrainings.Sum(s => s.HoursOff * (s.Rate == null ? 0 : s.Rate.Rate1)); result.Add(new СhartListElement { ScenarioName = "Training", WeekEndingDate = dt, Quantity = q, Cost = c, ScenarioType = (int)ScenarioType.Training, Probability = 1, ScenarioId = Guid.NewGuid(), CGEFX = "CG ", ProjectColor = "ff0000" }); } } #endregion #region retrieve Vacation data if (result.Count > 0) { var scenarioIds = result.Select(t => t.ScenarioId).Distinct().ToArray(); var allVacations = (from vacWeek in db.PeopleResourceVacations join vac in db.Vacations on vacWeek.VacationId equals vac.Id join pa in db.PeopleResourceAllocations on vac.PeopleResourceId equals pa.PeopleResourceId join ec in db.ExpenditureCategory on pa.ExpenditureCategoryId equals ec.Id where scenarioIds.Contains(pa.ScenarioId) & vacWeek.WeekEndingDate >= StartDate & vacWeek.WeekEndingDate <= EndDate select new { vacWeek.Id, pa.ExpenditureCategoryId, vacWeek.WeekEndingDate, vacWeek.HoursOff, ec.CGEFX, Rate = db.Rates.FirstOrDefault(r => r.ExpenditureCategoryId == pa.ExpenditureCategoryId && r.StartDate <= vacWeek.WeekEndingDate && r.EndDate >= vacWeek.WeekEndingDate) }).Distinct().ToArray(); var dates = result.Select(t => t.WeekEndingDate).Distinct().ToArray(); foreach (var dt in dates) { var dtVacations = allVacations.Where(t => t.WeekEndingDate <= dt.Value && t.WeekEndingDate >= dt.Value.AddDays(-6)).ToArray(); var q = dtVacations.Sum(s => s.HoursOff * Utils.GetUOMMultiplier(expCats, uoms, s.ExpenditureCategoryId, UOMSwitcherMode)); var c = dtVacations.Sum(s => s.HoursOff * (s.Rate == null ? 0 : s.Rate.Rate1)); result.Add(new СhartListElement { ScenarioName = "Vacation", WeekEndingDate = dt, Quantity = q, Cost = c, ScenarioType = (int)ScenarioType.Vacation, Probability = 1, ScenarioId = Guid.NewGuid(), CGEFX = "CG ", ProjectColor = "ff0000" }); } } #endregion return result; } #endregion } public class WhatIfCalendarDataModel { public class WhatIfCalendarDataRow { public Guid ExpCatId { get; set; } public string ScenarioName { get; set; } public string ScenarioType { get; set; } public decimal GrandTotalCost { get; set; } public decimal GrandTotalQuantity { get; set; } public bool Checked { get; set; } public List QuantityValues { get; set; } public decimal[] CostValues { get; set; } public Guid?[] ScenarioDetailIds { get; set; } public WhatIfCalendarDataRow() { QuantityValues = new List(); CostValues = new decimal[0]; ScenarioDetailIds = new Guid?[0]; } } public Guid? CreditDepartment { get; set; } [Display(Name = "Quantity Mode")] public bool IsTableModeQuantity { get; set; } public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } public ScenarioType? ScenarioType { get; set; } public Guid ScenarioId { get; set; } public bool GrowthScenario { get; set; } public Guid ParentId { get; set; } [Display(Name = "Expenditure Categories")] public Guid[] SelectedExpCats { get; set; } public List FiscalCalendarRecordHeaders { get; set; } public List FiscalCalendarRecordMilliseconds { get; set; } public List WhatIfCalendar { get; set; } public int ColumnsCount { get { return FiscalCalendarRecordHeaders != null ? FiscalCalendarRecordHeaders.Count : 0; } } public WhatIfCalendarDataModel() { //AvailableExpenditures = new List(); //SelectedExpCats = new Guid[] { }; WhatIfCalendar = new List(); //FiscalCalendarRecordHeaders = new List(); //IsTableModeQuantity = true; } } }