using EnVisage.Code.BLL;
using EnVisage.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace EnVisage.Code.Charts
{
public class DashboardCharthManager
{
private class Data
{
public decimal? cost { get; set; }
public decimal? quantity { get; set; }
public DateTime? weekend { get; set; }
public string projectStatus { get; set; }
public int? type { get; set; }
public string Name { get; set; }
public Guid? ExpCatId { get; set; }
public Guid ProjectId { get; set; }
public Guid ProjectType { get; set; }
public decimal? ScenarioBUCost { get; set; }
public int ScenarioDuration { get; set; }
}
public class PieData
{
public Guid TypeId { get; set; }
public string Label { get; set; }
public decimal Cost { get; set; }
public int Time { get; set; }
}
EnVisageEntities db = new EnVisageEntities();
///
///
///
///
///
///
///
///
///
///
///
///
/// Indicates whether UOM (unit of measure) is hours or resources.
///
public Dictionary> GetData(DateTime StartDate, DateTime EndDate, Guid[] principals, Guid userId, string type, string status, string classification, ForecastDashboardMode mode, Guid teamId, Guid viewId, bool? isUOMHours, bool isLaborMode, string filterGroup)
{
var result = new Dictionary>();
IQueryable projects = (from c in db.Projects join o in db.ProjectAccesses on c.Id equals o.ProjectId where principals.Contains(o.PrincipalId) select c);
List teams = new List();
if (ForecastDashboardMode.TeamForecast == mode)
{
projects = projects.Where(p => p.Team2Project.Any(t2p => t2p.TeamId == teamId));
teams.Add(teamId);
}
if (ForecastDashboardMode.ViewForecast == mode)
{
projects = projects.Where(p => p.Team2Project.Any(t2p => t2p.Team.Team2View.Any(tv => tv.ViewId == viewId)));
teams.AddRange(db.Teams.Where(t=>t.Team2View.Any(tv=>tv.ViewId == viewId)).Select(t=>t.Id).ToList());
}
var days = EndDate.Subtract(StartDate).TotalDays;
int typeInt = 0;
if(!string.IsNullOrWhiteSpace(type) && type != "null")
typeInt = (int)Enum.Parse(typeof(ScenarioType), type);
Dictionary expCats = new Dictionary();
if (isLaborMode)
expCats = (from e in db.ExpenditureCategory where e.Type == (int)ExpenditureCategoryModel.CategoryTypes.Labor select e).ToDictionary(e => e.Id);
else
expCats = (from e in db.ExpenditureCategory where e.Type != (int)ExpenditureCategoryModel.CategoryTypes.Labor select e).ToDictionary(e => e.Id);
List expCatGuids = expCats.Keys.ToList();
var uoms = db.UOMs.AsNoTracking().ToDictionary(u => u.Id);
IQueryable data = null;
long[] fiscalCalendarChartPoints = null;
if (days <= 400)
{
data = GetWeeksData(StartDate, EndDate.AddDays(7), projects, status, classification, typeInt, mode != ForecastDashboardMode.MainDashboard, isLaborMode, filterGroup);
fiscalCalendarChartPoints = (from c in db.FiscalCalendars
where c.Type == (int)FiscalCalendarModel.FiscalYearType.Week &&
c.EndDate >= StartDate && c.EndDate <= EndDate
orderby c.StartDate
select c.EndDate).ToArray().Select(t => (long)t.Subtract(new DateTime(1970, 1, 1)).TotalMilliseconds).ToArray();
}
else
{
data = GetMonthData(StartDate, EndDate, projects, status, classification, typeInt, mode != ForecastDashboardMode.MainDashboard, isLaborMode, filterGroup);
fiscalCalendarChartPoints = (from c in db.FiscalCalendars
where c.Type == (int)FiscalCalendarModel.FiscalYearType.Month &&
c.EndDate >= StartDate && c.EndDate <= EndDate
orderby c.StartDate
select c.EndDate).ToArray().Select(t => (long)t.Subtract(new DateTime(1970, 1, 1)).TotalMilliseconds).ToArray();
}
var projectIds = projects.Select(t => t.Id).ToArray();
var allVacations = (from vacWeek in db.PeopleResourceVacations
join vac in db.Vacations on vacWeek.VacationId equals vac.Id
join p in db.PeopleResources on vac.PeopleResourceId equals p.Id
join t in db.Team2Project on p.TeamId equals t.TeamId
where (teams.Count == 0 || (p.TeamId.HasValue && teams.Contains(p.TeamId.Value))) && projectIds.Contains(t.ProjectId) && expCatGuids.Contains(p.ExpenditureCategoryId)
select new {vacWeek.Id, vacWeek.WeekEndingDate, vacWeek.HoursOff,
Rate = db.Rates.Where(r => r.ExpenditureCategoryId == p.ExpenditureCategoryId && r.StartDate <= vacWeek.WeekEndingDate && r.EndDate >= vacWeek.WeekEndingDate).FirstOrDefault()}).Distinct().ToArray();
var allTrainings = (from traningWeek in db.PeopleResourceTrainings
join training in db.Trainings on traningWeek.TrainingId equals training.Id
join p in db.PeopleResources on traningWeek.PeopleResourceId equals p.Id
join t in db.Team2Project on p.TeamId equals t.TeamId
where (teams.Count == 0 || (p.TeamId.HasValue && teams.Contains(p.TeamId.Value))) && projectIds.Contains(t.ProjectId) && expCatGuids.Contains(p.ExpenditureCategoryId)
select new
{
traningWeek.Id,
traningWeek.WeekEndingDate,
traningWeek.HoursOff,
Rate = db.Rates.Where(r => r.ExpenditureCategoryId == p.ExpenditureCategoryId && r.StartDate <= traningWeek.WeekEndingDate && r.EndDate >= traningWeek.WeekEndingDate).FirstOrDefault()
}).Distinct().ToArray();
long wkending = 0;
//decimal tmpTraining = 0.0M;
//decimal tmpTrainingQ = 0.0M;
Dictionary tmpProjectStatus = new Dictionary();
Dictionary tmpCapacity = new Dictionary();
//init result dictionary
if (mode == ForecastDashboardMode.MainDashboard)
{
result.Add("plannedCapacity", new List());
result.Add("plannedCapacityQ", new List());
}
result.Add("training", new List());
result.Add("trainingQ", new List());
result.Add("vacation", new List());
result.Add("vacationQ", new List());
result.Add("totalPlannedCapacity", new List());
result.Add("totalPlannedCapacityQ", new List());
result.Add("resourceCapacity", new List());
result.Add("resourceCapacityQ", new List());
//capacity and project status data remains uninitialized as we do not know what capacity scenarios and project statuses we have
foreach (var sd in data)
{
if ((long)sd.weekend.Value.Subtract(new DateTime(1970, 1, 1)).TotalMilliseconds != wkending)
{
//new week, push result data and reinit temps
if (0 != wkending)
{
if (mode == ForecastDashboardMode.MainDashboard)
{
//result["training"].Add(new long[] { wkending, (long)(Math.Round(tmpTraining)) });
//result["trainingQ"].Add(new long[] { wkending, (long)(Math.Round(tmpTrainingQ)) });
foreach (string cn in tmpCapacity.Keys)
{
if (!result.ContainsKey(cn))
{
result.Add(cn, new List());
}
result[cn].Add(new long[] { wkending, (long)(Math.Round(tmpCapacity[cn])) });
}
}
//TRAININGS
var ed = new DateTime(1970, 1, 1).AddMilliseconds(wkending);
var startd = ed.AddDays(-6);
decimal tmpTrainingQ = allTrainings.Where(t => t.WeekEndingDate <= ed && t.WeekEndingDate >= startd).Sum(t => t.HoursOff);
result["trainingQ"].Add(new long[] { wkending, (long)(tmpTrainingQ * Utils.GetUOMMultiplier(expCats, uoms, sd.ExpCatId ?? Guid.Empty, isUOMHours)) });
decimal tmpTraining = allTrainings.Where(t => t.WeekEndingDate <= ed && t.WeekEndingDate >= startd).Sum(t => t.HoursOff * (t.Rate != null ? t.Rate.Rate1 : 0));
result["training"].Add(new long[] { wkending, (long)tmpTraining });
//VACATIONS
ed = new DateTime(1970, 1, 1).AddMilliseconds(wkending);
startd = ed.AddDays(-6);
decimal tmpVacationQ = allVacations.Where(t => t.WeekEndingDate <= ed && t.WeekEndingDate >= startd).Sum(t => t.HoursOff);
result["vacationQ"].Add(new long[] { wkending, (long)(tmpVacationQ * Utils.GetUOMMultiplier(expCats, uoms, sd.ExpCatId ?? Guid.Empty, isUOMHours)) });
decimal tmpVacation = allVacations.Where(t => t.WeekEndingDate <= ed && t.WeekEndingDate >= startd).Sum(t => t.HoursOff * (t.Rate != null ? t.Rate.Rate1 : 0));
result["vacation"].Add(new long[] { wkending, (long)tmpVacation });
foreach (string sn in tmpProjectStatus.Keys)
{
if (!result.ContainsKey(sn))
{
result.Add(sn, new List());
}
result[sn].Add(new long[] { wkending, (long)(Math.Round(tmpProjectStatus[sn])) });
}
}
wkending = (long)sd.weekend.Value.Subtract(new DateTime(1970, 1, 1)).TotalMilliseconds;
//tmpTraining = 0.0M;
//tmpTrainingQ = 0.0M;
tmpProjectStatus = new Dictionary();
tmpCapacity = new Dictionary();
}
//fill data into tmps
if (!sd.type.HasValue)
continue;
//else if ((int)ScenarioType.Training == sd.type.Value)
//{
// tmpTraining += sd.cost ?? 0;
// tmpTrainingQ += (sd.quantity ?? 0) * Utils.GetUOMMultiplier(expCats, uoms, sd.ExpCatId ?? Guid.Empty, isUOMHours);
//}
else if ((int)ScenarioType.Portfolio == sd.type.Value || (int)ScenarioType.Scheduling == sd.type.Value)
{
//the dataset is already filtered by correct scenario type so we're just summarizing the numbers here
if (!tmpProjectStatus.ContainsKey(sd.projectStatus))
{
tmpProjectStatus.Add(sd.projectStatus, 0.0M);
tmpProjectStatus.Add(sd.projectStatus + "Q", 0.0M);
}
tmpProjectStatus[sd.projectStatus] += sd.cost ?? 0;
tmpProjectStatus[sd.projectStatus + "Q"] += (sd.quantity ?? 0) * Utils.GetUOMMultiplier(expCats, uoms, sd.ExpCatId ?? Guid.Empty, isUOMHours);
}
else if ((int)ScenarioType.Capacity == sd.type.Value)
{
if (!tmpCapacity.ContainsKey(sd.Name))
{
tmpCapacity.Add(sd.Name, 0.0M);
tmpCapacity.Add(sd.Name + "Q", 0.0M);
}
tmpCapacity[sd.Name] += sd.cost ?? 0;
tmpCapacity[sd.Name + "Q"] += (sd.quantity ?? 0) * Utils.GetUOMMultiplier(expCats, uoms, sd.ExpCatId ?? Guid.Empty, isUOMHours);
}
else
{
throw new InvalidOperationException("Incorrect scenario type found");
}
}
List teamCapacity;
Guid[] userTeams = new TeamManager(db).GetTeamsByUser(userId).Select(t => t.Id).ToArray();
if (ForecastDashboardMode.TeamForecast == mode)
{
teamCapacity = new TotalCapacity(new Guid[] {teamId}, expCats, uoms, isUOMHours).GetDataByDateRange((new DateTime(1970, 1, 1).AddMilliseconds(fiscalCalendarChartPoints.Min())), (new DateTime(1970, 1, 1).AddMilliseconds(fiscalCalendarChartPoints.Max())));
}
else if (ForecastDashboardMode.ViewForecast == mode)
{
teamCapacity = new ViewCapacity(viewId, expCats, uoms, isUOMHours).GetDataByDateRange((new DateTime(1970, 1, 1).AddMilliseconds(fiscalCalendarChartPoints.Min())), (new DateTime(1970, 1, 1).AddMilliseconds(fiscalCalendarChartPoints.Max())));
}
else
{
teamCapacity = new TotalCapacity(userTeams, expCats, uoms, isUOMHours).GetDataByDateRange((new DateTime(1970, 1, 1).AddMilliseconds(fiscalCalendarChartPoints.Min())), (new DateTime(1970, 1, 1).AddMilliseconds(fiscalCalendarChartPoints.Max())));
}
result["resourceCapacity"].AddRange(teamCapacity.Select(x => new long[]
{
(long)x.WeekEnding.Subtract(new DateTime(1970, 1, 1)).TotalMilliseconds,
(long)(Math.Round(x.Cost))
}));
result["resourceCapacityQ"].AddRange(teamCapacity.Select(x => new long[]
{
(long)x.WeekEnding.Subtract(new DateTime(1970, 1, 1)).TotalMilliseconds,
(long)(Math.Round(x.Quantity))
}));
Dictionary totalPlannedCapacity = null;
if (mode == ForecastDashboardMode.MainDashboard)
totalPlannedCapacity = GetWeeklyTeamPlannedCapacity(StartDate, EndDate, userTeams, expCats, uoms, isUOMHours);
else if (mode == ForecastDashboardMode.TeamForecast)
totalPlannedCapacity = GetWeeklyTeamPlannedCapacity(StartDate, EndDate, new Guid[] { teamId }, expCats, uoms, isUOMHours);
else if (mode == ForecastDashboardMode.ViewForecast)
totalPlannedCapacity = GetWeeklyViewPlannedCapacity(StartDate, EndDate, viewId, expCats, uoms, isUOMHours);
result["totalPlannedCapacity"].AddRange(totalPlannedCapacity.Select(x => new long[]
{
(long)x.Key.Subtract(new DateTime(1970, 1, 1)).TotalMilliseconds,
(long)(Math.Round(x.Value.Cost))
}));
result["totalPlannedCapacityQ"].AddRange(totalPlannedCapacity.Select(x => new long[]
{
(long)x.Key.Subtract(new DateTime(1970, 1, 1)).TotalMilliseconds,
(long)(Math.Round(x.Value.Quantity))
}));
//Fill missing weekends for all items in dictionary
foreach (string key in result.Keys)
{
List lst = FillMissingWeeends(result[key], fiscalCalendarChartPoints);
result[key].Clear();
result[key].AddRange(lst);
}
return result;
}
///
/// Заполняем нулями данные за недели, которых нет в списке list.
///
/// Список с данными по неделям.
/// Список недель в заданном диапазоне дат.
private List FillMissingWeeends(List list, IEnumerable weekEnds)
{
if (list.Count < weekEnds.Count())
{
var result = weekEnds.Except(list.Select(x => x[0]));
list.AddRange(result.Select(x => new long[] { x, 0 }));
list.RemoveAll(x => !weekEnds.Contains(x[0]));
}
return list.OrderBy(x => x[0]).ToList();
}
///
///
///
///
///
///
///
///
///
///
///
private IQueryable GetWeeksData(DateTime StartDate, DateTime EndDate, IQueryable projects, string status, string classification, int scenarioType, bool noOldCapacities, bool isLaborMode, string filterGroup)
{
if (!string.IsNullOrWhiteSpace(status) && status != "All")
projects = projects.Where(x => x.StatusId.ToString() == status);
if (!string.IsNullOrWhiteSpace(classification) && classification != "All")
projects = projects.Where(x => x.Type.Id.ToString() == classification);
Guid scenarioGroup = Guid.Empty;
Guid.TryParse(filterGroup, out scenarioGroup);
Guid[] projectIds = (from p in projects select p.Id).ToArray();
Guid[] expCatIds = null;
if (isLaborMode) expCatIds = (from e in db.ExpenditureCategory where e.Type == (int)ExpenditureCategoryModel.CategoryTypes.Labor select e.Id).ToArray();
else expCatIds = (from e in db.ExpenditureCategory where e.Type != (int)ExpenditureCategoryModel.CategoryTypes.Labor select e.Id).ToArray();
List scTypes = new List();
if(!noOldCapacities)
scTypes.AddRange(new int[] { (int)ScenarioType.Capacity, (int)ScenarioType.Vacation, (int)ScenarioType.Training });
if (scenarioType != 0)
scTypes.Add(scenarioType);
else
scTypes.Add((int)ScenarioType.Portfolio);
IQueryable data = null;
if (scenarioGroup != Guid.Empty)
{
data = (from sd in db.ScenarioDetail.AsNoTracking()
join s in db.Scenarios on sd.ParentID equals s.Id
join p in db.Projects on s.ParentId equals p.Id
where sd.WeekEndingDate >= StartDate && sd.WeekEndingDate <= EndDate
&& projectIds.Contains(s.ParentId.Value) && s.Status == (int?)ScenarioStatus.Active
&& scTypes.Contains(s.Type) && expCatIds.Contains(sd.ExpenditureCategoryId.Value) && s.Scenario2Group.Any(g => g.GroupId == scenarioGroup)
orderby sd.WeekEndingDate
select new Data
{
cost = sd.Cost,
quantity = sd.Quantity,
weekend = sd.WeekEndingDate,
projectStatus = projects.FirstOrDefault(x => x.Id == s.ParentId).Status.Name,
type = s.Type,
Name = s.Name,
ScenarioBUCost = (s.UseLMMargin ?? 0) == 1 ? s.BUDirectCosts_LM : s.BUDirectCosts,
ScenarioDuration = s.Duration ?? 0,
ExpCatId = sd.ExpenditureCategoryId,
ProjectId = s.ParentId.Value,
ProjectType = p.TypeId
});
}
else
{
data = (from sd in db.ScenarioDetail.AsNoTracking()
join s in db.Scenarios on sd.ParentID equals s.Id
join p in db.Projects on s.ParentId equals p.Id
where sd.WeekEndingDate >= StartDate && sd.WeekEndingDate <= EndDate
&& projectIds.Contains(s.ParentId.Value) && s.Status == (int?)ScenarioStatus.Active
&& scTypes.Contains(s.Type) && expCatIds.Contains(sd.ExpenditureCategoryId.Value)
orderby sd.WeekEndingDate
select new Data
{
cost = sd.Cost,
quantity = sd.Quantity,
weekend = sd.WeekEndingDate,
projectStatus = projects.FirstOrDefault(x => x.Id == s.ParentId).Status.Name,
type = s.Type,
Name = s.Name,
ScenarioBUCost = (s.UseLMMargin ?? 0) == 1 ? s.BUDirectCosts_LM : s.BUDirectCosts,
ScenarioDuration = s.Duration ?? 0,
ExpCatId = sd.ExpenditureCategoryId,
ProjectType = p.TypeId
});
}
return data;
}
///
///
///
///
///
///
///
///
///
///
/// A value of resource capacity multiplier. E.g. if user wants to see data in hours, then
/// equals to 1. If user wants to see data in resources then equals to 1/40 = 0.025.
///
private IQueryable GetMonthData(DateTime StartDate, DateTime EndDate, IQueryable projects, string status, string classification, int scenarioType, bool noOldCapacities, bool isLaborMode, string filterGroup)
{
var startDate = StartDate.AddMonths(-1);
var monthDates = (from c in db.FiscalCalendars where c.Type == 1 && c.StartDate >= startDate && c.EndDate <= EndDate orderby c.StartDate select c.EndDate);
if (!string.IsNullOrWhiteSpace(status) && status != "All")
projects = projects.Where(x => x.StatusId.ToString() == status);
if (!string.IsNullOrWhiteSpace(classification) && classification != "All")
projects = projects.Where(x => x.Type.Id.ToString() == classification);
Guid scenarioGroup = Guid.Empty;
Guid.TryParse(filterGroup, out scenarioGroup);
Guid[] projectIds = (from p in projects select p.Id).ToArray();
Guid[] expCatIds = null;
if (isLaborMode) expCatIds = (from e in db.ExpenditureCategory where e.Type == (int)ExpenditureCategoryModel.CategoryTypes.Labor select e.Id).ToArray();
else expCatIds = (from e in db.ExpenditureCategory where e.Type != (int)ExpenditureCategoryModel.CategoryTypes.Labor select e.Id).ToArray();
List scTypes = new List();
if (!noOldCapacities)
scTypes.AddRange(new int[] { (int)ScenarioType.Capacity, (int)ScenarioType.Vacation, (int)ScenarioType.Training });
if (scenarioType != 0)
scTypes.Add(scenarioType);
else
scTypes.Add((int)ScenarioType.Portfolio);
IQueryable data = null;
if (scenarioGroup != Guid.Empty)
{
data = (from sd in db.ScenarioDetail.AsNoTracking()
join s in db.Scenarios on sd.ParentID equals s.Id
join p in db.Projects on s.ParentId equals p.Id
where monthDates.Contains(sd.WeekEndingDate.Value)
&& projectIds.Contains(s.ParentId.Value) && s.Status == (int?)ScenarioStatus.Active
&& scTypes.Contains(s.Type) && expCatIds.Contains(sd.ExpenditureCategoryId.Value) && s.Scenario2Group.Any(g => g.GroupId == scenarioGroup)
orderby sd.WeekEndingDate
select new Data
{
cost = sd.Cost,
quantity = sd.Quantity,
weekend = sd.WeekEndingDate,
projectStatus = projects.FirstOrDefault(x => x.Id == s.ParentId).Status.Name,
type = s.Type,
Name = s.Name,
ScenarioBUCost = (s.UseLMMargin ?? 0) == 1 ? s.BUDirectCosts_LM : s.BUDirectCosts,
ScenarioDuration = s.Duration ?? 0,
ExpCatId = sd.ExpenditureCategoryId,
ProjectId = s.ParentId.Value,
ProjectType = p.TypeId
});
}
else
{
data = (from sd in db.ScenarioDetail.AsNoTracking()
join s in db.Scenarios on sd.ParentID equals s.Id
join p in db.Projects on s.ParentId equals p.Id
where monthDates.Contains(sd.WeekEndingDate.Value)
&& projectIds.Contains(s.ParentId.Value) && s.Status == (int?)ScenarioStatus.Active
&& scTypes.Contains(s.Type) && expCatIds.Contains(sd.ExpenditureCategoryId.Value)
orderby sd.WeekEndingDate
select new Data
{
cost = sd.Cost,
quantity = sd.Quantity,
weekend = sd.WeekEndingDate,
projectStatus = projects.FirstOrDefault(x => x.Id == s.ParentId).Status.Name,
type = s.Type,
Name = s.Name,
ScenarioBUCost = (s.UseLMMargin ?? 0) == 1 ? s.BUDirectCosts_LM : s.BUDirectCosts,
ScenarioDuration = s.Duration ?? 0,
ExpCatId = sd.ExpenditureCategoryId,
ProjectId = s.ParentId.Value,
ProjectType = p.TypeId
});
}
return data;
}
public List GetPieData(DateTime startDate, DateTime endDate, Guid[] principals, Guid userId, ForecastDashboardMode mode, Guid teamId, Guid viewId, bool isLaborMode)
{
IQueryable projects = (from c in db.Projects
join o in db.ProjectAccesses on c.Id equals o.ProjectId
where principals.Contains(o.PrincipalId) && !c.ParentProjectId.HasValue
select c);
List teams = new List();
if (ForecastDashboardMode.TeamForecast == mode)
{
projects = projects.Where(p => p.Team2Project.Any(t2p => t2p.TeamId == teamId));
teams.Add(teamId);
}
if (ForecastDashboardMode.ViewForecast == mode)
{
projects = projects.Where(p => p.Team2Project.Any(t2p => t2p.Team.Team2View.Any(tv => tv.ViewId == viewId)));
teams.AddRange(db.Teams.Where(t => t.Team2View.Any(tv => tv.ViewId == viewId)).Select(t => t.Id).ToList());
}
return GetPieChartData(startDate, endDate.AddDays(7), projects, isLaborMode);
}
///
///
///
/// Start of reporting period.
/// End of reporting period.
/// A queryable collection of projects to filter by.
/// Indicates whether to load data for labor or for materials expenditure categories.
/// A list of data for each classification.
private List GetPieChartData(DateTime startDate, DateTime endDate, IQueryable projects, bool isLaborMode)
{
var projectIds = (from p in projects select p.Id).ToArray();
var expCatIds = isLaborMode
? (from e in db.ExpenditureCategory
where e.Type == (int) ExpenditureCategoryModel.CategoryTypes.Labor
select e.Id).ToArray()
: (from e in db.ExpenditureCategory
where e.Type != (int) ExpenditureCategoryModel.CategoryTypes.Labor
select e.Id).ToArray();
var scTypes = new List {(int) ScenarioType.Portfolio, (int) ScenarioType.Scheduling};
var types = db.Types.AsNoTracking().ToDictionary(key => key.Id, elem => elem.Name);
var data = (from sd in db.ScenarioDetail
join s in db.Scenarios on sd.ParentID equals s.Id
join p in db.Projects on s.ParentId equals p.Id
//where !(s.StartDate <= StartDate || s.EndDate >= EndDate)
where sd.WeekEndingDate >= startDate && sd.WeekEndingDate <= endDate
&& projectIds.Contains(s.ParentId.Value) && s.Status == (int?)ScenarioStatus.Active
&& scTypes.Contains(s.Type) && expCatIds.Contains(sd.ExpenditureCategoryId.Value)
select new
{
s.Id,
s.UseLMMargin,
s.BUDirectCosts_LM,
s.BUDirectCosts,
s.Duration,
p.TypeId,
}).Distinct().ToArray().GroupBy(group=> group.TypeId).Select(grouping => new PieData
{
TypeId = grouping.Key,
Cost = grouping.Sum(x=> (x.UseLMMargin ?? 0) == 1 ? x.BUDirectCosts_LM??0 : x.BUDirectCosts??0),
Time = grouping.Sum(x=>x.Duration??0),
Label = types.ContainsKey(grouping.Key) ? types[grouping.Key] : string.Empty
}).ToList();
return data;
}
private Dictionary GetWeeklyViewPlannedCapacity(DateTime StartDate, DateTime EndDate, Guid ViewId, Dictionary expCats, Dictionary uoms, bool? isUOMMode)
{
var context = new EnVisageEntities();
var plannedScenarios = (from s in context.Teams
join tv in context.Team2View on s.Id equals tv.TeamId
where tv.ViewId == ViewId && s.PlannedCapacityScenarioId != null
select s.PlannedCapacityScenarioId.Value).ToArray();
return GetWeeklyPlannedCapacity(StartDate, EndDate, plannedScenarios, expCats, uoms, isUOMMode);
}
private Dictionary GetWeeklyTeamPlannedCapacity(DateTime StartDate, DateTime EndDate, Guid[] TeamIds, Dictionary expCats, Dictionary uoms, bool? isUOMMode)
{
var context = new EnVisageEntities();
var plannedScenarios = (from s in context.Teams where TeamIds.Contains(s.Id) && s.PlannedCapacityScenarioId != null select s.PlannedCapacityScenarioId.Value).ToArray();
return GetWeeklyPlannedCapacity(StartDate, EndDate, plannedScenarios, expCats, uoms, isUOMMode);
}
private Dictionary GetWeeklyPlannedCapacity(DateTime StartDate, DateTime EndDate, Guid[] SccenarioIds, Dictionary expCats, Dictionary uoms, bool? isUOMMode)
{
var dict = new Dictionary();
var context = new EnVisageEntities();
// get weekending dates between resource Start and End dates
var weekendings = context.FiscalCalendars
.Where(x => x.Type == (int)EnVisage.Models.FiscalCalendarModel.FiscalYearType.Week &&
x.StartDate >= StartDate && x.EndDate <= EndDate).Select(x => x.EndDate);
var plannedScenarios = (from s in context.Scenarios where s.Type == (int)ScenarioType.TeamPlannedCapacity select s.Id).ToArray();
Guid[] expCatIds = expCats.Keys.ToArray();
var sds = (from sd in context.ScenarioDetail where SccenarioIds.Contains(sd.ParentID.Value) && weekendings.Contains(sd.WeekEndingDate.Value) && expCatIds.Contains(sd.ExpenditureCategoryId.Value) select sd).ToList();
// fill dictionary with weekly capacity for each week
foreach (var week in weekendings)
{
if (!dict.ContainsKey(week))
{
var quantity = 0M;
var cost = 0M;
var sd = (from s in sds where s.WeekEndingDate == week select s).ToList();
foreach (var s in sd)
{
quantity += s.Quantity.Value * Utils.GetUOMMultiplier(expCats, uoms, s.ExpenditureCategoryId ?? Guid.Empty, isUOMMode);
cost += s.Cost.Value;
}
dict.Add(week, new PeopleResourceModel.CapacityValues()
{
Quantity = quantity,
Cost = cost,
WeekEnding = week
});
}
}
return dict;
}
}
}