437 lines
20 KiB
C#
437 lines
20 KiB
C#
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<decimal> CGSplit { get; set; }
|
||
public Nullable<decimal> EFXSplit { get; set; }
|
||
public Nullable<System.DateTime> StartDate { get; set; }
|
||
public Nullable<System.DateTime> EndDate { get; set; }
|
||
}
|
||
|
||
public class СhartListElement
|
||
{
|
||
|
||
public Nullable<System.Guid> ScenarioId { get; set; }
|
||
public Nullable<System.DateTime> WeekEndingDate { get; set; }
|
||
public Nullable<decimal> Quantity { get; set; }
|
||
public Nullable<decimal> Cost { get; set; }
|
||
public Nullable<int> 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<ScenarioListElement> 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<string, List<СhartListElement>> 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<string, List<СhartListElement>>();
|
||
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<ScenarioListElement> 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<Guid> l = new List<Guid>();
|
||
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<long> QuantityValues { get; set; }
|
||
public decimal[] CostValues { get; set; }
|
||
public Guid?[] ScenarioDetailIds { get; set; }
|
||
|
||
public WhatIfCalendarDataRow()
|
||
{
|
||
QuantityValues = new List<long>();
|
||
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<string> FiscalCalendarRecordHeaders { get; set; }
|
||
public List<long> FiscalCalendarRecordMilliseconds { get; set; }
|
||
public List<WhatIfCalendarDataRow> WhatIfCalendar { get; set; }
|
||
|
||
public int ColumnsCount
|
||
{
|
||
get
|
||
{
|
||
return FiscalCalendarRecordHeaders != null ? FiscalCalendarRecordHeaders.Count : 0;
|
||
}
|
||
}
|
||
|
||
public WhatIfCalendarDataModel()
|
||
{
|
||
//AvailableExpenditures = new List<SelectListItem>();
|
||
//SelectedExpCats = new Guid[] { };
|
||
WhatIfCalendar = new List<WhatIfCalendarDataRow>();
|
||
//FiscalCalendarRecordHeaders = new List<string>();
|
||
//IsTableModeQuantity = true;
|
||
}
|
||
}
|
||
} |