using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using EnVisage.Code; using System.Linq; namespace EnVisage.Models { public class SingleResQtiesOrCostByTimeModel { #region Classes and enums public class ScenarioListElement { public System.Guid Id { get; set; } public string Name { get; set; } public string ProjectName { get; set; } public ScenarioType ScenarioType { 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 System.DateTime WeekEndingDate { get; set; } public Nullable Quantity { get; set; } public Nullable Cost { get; set; } public Nullable ScenarioType { get; set; } public string ScenarioName { get; set; } public string ScenarioDispalyName { get; set; } public decimal Probability { get; set; } public string ProjectColor { get; set; } public string CGEFX { get; set; } } public class ExpenditureItem { public Guid Id { get; set; } public string Group { get; set; } public string Name { get; set; } public bool Checked { 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 = "Quantity/Costs")] public SeatsCostsType SeatsCosts { get; set; } [Display(Name = "System Attribute 1")] public string SystemAttribute1 { get; set; } [Display(Name = "System Attribute 2")] public string SystemAttribute2 { 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; } [Display(Name = "Capacity")] public Guid SelectedCapacity { get; set; } public Dictionary> ChartData { get; set; } List<СhartListElement> _chartData; public IList ExpenditureItems { get; set; } public string SelectedExpenditureItems { get; set; } public bool? UOMSwitcherMode { get; set; } #endregion public SingleResQtiesOrCostByTimeModel() { GroupId = Guid.Empty; GroupName = string.Empty; SelectedScenarioType = ScenarioType.Portfolio; StartDate = DateTime.Today.AddMonths(-1); EndDate = DateTime.Today.AddMonths(11); ExpenditureItems = new List(); } #region Methods public void FormScenarioReport(EnVisageEntities db) { Scenarios = GetScenarioData(db); } public void FormСhartListElements(EnVisageEntities db) { _chartData = GetСhartData(db); ChartData = new Dictionary>(); if (_chartData != null) { 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) { return db.VW_Scenario2Project.Where(t => t.Status.HasValue && t.Status.Value == (int?)ScenarioStatus.Active && (((GroupId == Guid.Empty || t.GroupId == GroupId) && t.Type == (int?)SelectedScenarioType))) .Select(x => new ScenarioListElement() { Name = x.Name, CGSplit = x.CGSplit, EFXSplit = x.EFXSplit, EndDate = x.EndDate, StartDate = x.StartDate, Id = x.Id, ProjectName = (x.ParentProjectId != null ? x.ParentProjectName + ": " : "") + x.ShowName, ScenarioType = (ScenarioType)x.Type, }) .ToList(); } List<СhartListElement> GetСhartData(EnVisageEntities db) { List l = new List(); List SelectedExpenditures = new List(); List ScenarioTypes = new List(){ ScenarioType.Capacity.GetHashCode(), ScenarioType.LoanOut.GetHashCode(), ScenarioType.Training.GetHashCode(), ScenarioType.Vacation.GetHashCode() }; Guid SystemAttribute1Id; if (!Guid.TryParse(SystemAttribute1, out SystemAttribute1Id)) SystemAttribute1Id = Guid.Empty; Guid SystemAttribute2Id; if (!Guid.TryParse(SystemAttribute2, out SystemAttribute2Id)) SystemAttribute2Id = Guid.Empty; if (string.IsNullOrEmpty(SelectedScenarios)) { SelectedScenarios = "[]"; } if (string.IsNullOrEmpty(SelectedExpenditureItems)) { SelectedExpenditureItems = "[]"; } SelectedScenarios.TrimStart('[').TrimEnd(']').Split(',').Where(x => !string.IsNullOrEmpty(x)).ToList().ForEach(x => l.Add(new Guid(x.TrimStart('\"').TrimEnd('\"')))); SelectedExpenditureItems.TrimStart('[').TrimEnd(']').Split(',').Where(x => !string.IsNullOrEmpty(x)).ToList().ForEach(x => SelectedExpenditures.Add(new Guid(x.TrimStart('\"').TrimEnd('\"')))); //Get by type: Capacity LoanOut Training Vacation var selectedScenarioType = this.SelectedScenarioType.GetHashCode(); var expCats = db.ExpenditureCategory.AsNoTracking().ToDictionary(e => e.Id); var uoms = db.UOMs.AsNoTracking().ToDictionary(u => u.Id); var 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 join gr in db.Scenario2Group on sc.Id equals gr.ScenarioId into gj from subquery in gj.DefaultIfEmpty() where sc.Type > 1 & ScenarioTypes.Contains(sc.Type) & sc.Status == (int?) ScenarioStatus.Active & SelectedExpenditures.Contains(sd.ExpenditureCategoryId ?? Guid.Empty) & sd.WeekEndingDate >= StartDate & sd.WeekEndingDate <= EndDate & ((ScenarioType.Capacity == (ScenarioType) sc.Type && sd.ParentID == SelectedCapacity) || ScenarioType.Capacity != (ScenarioType) sc.Type) 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), ScenarioColor = sc.Color, sc.Status, sc.SystemAttributeObjectID, GroupId = subquery == null ? (Guid?)null : subquery.GroupId, ec.SystemAttributeOne, ec.SystemAttributeTwo }).ToArray().Select(t => new { t.ScenarioId, t.WeekEndingDate, Quantity = t.Quantity* Utils.GetUOMMultiplier(expCats, uoms, t.ExpenditureCategoryId ?? Guid.Empty, UOMSwitcherMode), t.Cost, t.ExpenditureCategoryId, t.CGEFX, t.ScenarioType, t.ScenarioName, t.ProjectId, t.ProjectName, t.ProjectTypeId, t.StatusId, t.StatusName, t.Probability, t.ProjectColor, t.ScenarioColor, t.Status, t.SystemAttributeObjectID, t.GroupId, t.SystemAttributeOne, t.SystemAttributeTwo }) .GroupBy(t => new { t.WeekEndingDate, t.ScenarioType, t.Status, t.ScenarioId, t.ScenarioName, t.ScenarioColor, t.Probability, t.SystemAttributeObjectID, t.ProjectId, t.ProjectName, t.ProjectTypeId, t.ProjectColor, t.CGEFX, t.ExpenditureCategoryId, t.StatusId, t.StatusName, t.GroupId, t.SystemAttributeOne, t.SystemAttributeTwo }) .Select(x => new СhartListElement() { ScenarioId = x.Key.ScenarioId, WeekEndingDate = x.Key.WeekEndingDate.Value, Quantity = x.Sum(s => s.Quantity), Cost = x.Sum(s => s.Cost), ScenarioType = x.Key.ScenarioType, ScenarioName = x.Key.ScenarioName, ScenarioDispalyName = x.Key.ScenarioName, Probability = x.Key.Probability, ProjectColor = x.Key.ProjectColor, CGEFX = x.Key.CGEFX }) .OrderBy(x => x.WeekEndingDate) .ThenBy(x => x.ScenarioName) .ToList(); result.ForEach(x => x.ScenarioName = ((ScenarioType)x.ScenarioType.Value).ToDisplayValue()); //Get by selected scenrios result.AddRange((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 join gr in db.Scenario2Group on sc.Id equals gr.ScenarioId into gj from subquery in gj.DefaultIfEmpty() where sc.Type > 1 & sc.Type == selectedScenarioType & sc.Status == (int?) ScenarioStatus.Active & SelectedExpenditures.Contains(sd.ExpenditureCategoryId ?? Guid.Empty) & sd.WeekEndingDate >= StartDate & sd.WeekEndingDate <= EndDate & (Guid.Empty.Equals(SystemAttribute1Id) || SystemAttribute1Id == ec.SystemAttributeOne) & (Guid.Empty.Equals(SystemAttribute2Id) || SystemAttribute2Id == ec.SystemAttributeTwo) & sd.ParentID.HasValue && l.Contains(sd.ParentID.Value) & ((!GroupId.HasValue || GroupId.Value.Equals(Guid.Empty)) || subquery.GroupId == 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), ScenarioColor = sc.Color, sc.Status, sc.SystemAttributeObjectID, GroupId = subquery == null ? (Guid?)null : subquery.GroupId, ec.SystemAttributeOne, ec.SystemAttributeTwo }).ToArray().Select(t => new { t.ScenarioId, t.WeekEndingDate, Quantity = t.Quantity*Utils.GetUOMMultiplier(expCats, uoms, t.ExpenditureCategoryId ?? Guid.Empty, UOMSwitcherMode), t.Cost, t.ExpenditureCategoryId, t.CGEFX, t.ScenarioType, t.ScenarioName, t.ProjectId, t.ProjectName, t.ProjectTypeId, t.StatusId, t.StatusName, t.Probability, t.ProjectColor, t.ScenarioColor, t.Status, t.SystemAttributeObjectID, t.GroupId, t.SystemAttributeOne, t.SystemAttributeTwo }) .GroupBy(t => new { t.WeekEndingDate, t.ScenarioType, t.Status, t.ScenarioId, t.ScenarioName, t.ScenarioColor, t.Probability, t.SystemAttributeObjectID, t.ProjectId, t.ProjectName, t.ProjectTypeId, t.ProjectColor, t.CGEFX, t.ExpenditureCategoryId, t.StatusId, t.StatusName, t.GroupId, t.SystemAttributeOne, t.SystemAttributeTwo }) .Select(x => new СhartListElement() { ScenarioId = x.Key.ScenarioId, WeekEndingDate = x.Key.WeekEndingDate.Value, 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()); #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 training in db.Trainings on trainingWeek.TrainingId equals training.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) & SelectedExpenditures.Contains(ec.Id) & trainingWeek.WeekEndingDate >= StartDate & trainingWeek.WeekEndingDate <= EndDate select new { trainingWeek.Id, trainingWeek.WeekEndingDate, trainingWeek.HoursOff, pa.ExpenditureCategoryId, ec.CGEFX, Rate = db.Rates.FirstOrDefault(r => r.ExpenditureCategoryId == pa.ExpenditureCategoryId && r.StartDate <= trainingWeek.WeekEndingDate && r.EndDate >= trainingWeek.WeekEndingDate) }).Distinct().ToArray().GroupBy(groupKey => new { groupKey.Id, groupKey.WeekEndingDate, groupKey.CGEFX }) .Select(x => new СhartListElement() { //ScenarioId = Guid, WeekEndingDate = x.Key.WeekEndingDate, Quantity = x.Sum(s => s.HoursOff * Utils.GetUOMMultiplier(expCats, uoms, s.ExpenditureCategoryId, UOMSwitcherMode)), Cost = x.Sum(s => s.HoursOff * (s.Rate == null ? 0 : s.Rate.Rate1)), ScenarioType = (int)ScenarioType.Vacation, ScenarioName = "Training", Probability = 1, CGEFX = x.Key.CGEFX }) .OrderBy(x => x.WeekEndingDate).ToArray(); result.AddRange(allTrainings); } #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) & SelectedExpenditures.Contains(ec.Id) & vacWeek.WeekEndingDate >= StartDate & vacWeek.WeekEndingDate <= EndDate select new { vacWeek.Id, vacWeek.WeekEndingDate, vacWeek.HoursOff, pa.ExpenditureCategoryId, ec.CGEFX, Rate = db.Rates.FirstOrDefault(r => r.ExpenditureCategoryId == pa.ExpenditureCategoryId && r.StartDate <= vacWeek.WeekEndingDate && r.EndDate >= vacWeek.WeekEndingDate) }).Distinct().ToArray().GroupBy(groupKey => new { groupKey.Id, groupKey.WeekEndingDate, groupKey.CGEFX }) .Select(x => new СhartListElement() { //ScenarioId = Guid, WeekEndingDate = x.Key.WeekEndingDate, Quantity = x.Sum(s => s.HoursOff * Utils.GetUOMMultiplier(expCats, uoms, s.ExpenditureCategoryId, UOMSwitcherMode)), Cost = x.Sum(s => s.HoursOff * (s.Rate == null ? 0 : s.Rate.Rate1)), ScenarioType = (int)ScenarioType.Vacation, ScenarioName = "Vacation", Probability = 1, CGEFX = x.Key.CGEFX }) .OrderBy(x => x.WeekEndingDate).ToArray(); result.AddRange(allVacations); } #endregion return result; } #endregion } public class SingleResQtiesOrCostByTimeDataModel { public class SingleResQtiesOrCostByTimeDataRow { public Guid ExpCatId { get; set; } public string ScenarioName { get; set; } public string ScenarioDisplayName { get; set; } public string ScenarioType { get; set; } public string ProjectName { get; set; } public decimal GrandTotalCost { get; set; } public decimal GrandTotalQuantity { get; set; } public bool Checked { get; set; } public List QuantityValues { get; set; } public List CostValues { get; set; } public Guid?[] ScenarioDetailIds { get; set; } public SingleResQtiesOrCostByTimeDataRow() { QuantityValues = new List(); CostValues = new List(); 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 SingleResQtiesOrCostByTime { get; set; } public int ColumnsCount { get { return FiscalCalendarRecordHeaders != null ? FiscalCalendarRecordHeaders.Count : 0; } } public SingleResQtiesOrCostByTimeDataModel() { SingleResQtiesOrCostByTime = new List(); } } }