EnVisageOnline/Main-RMO/Source/EnVisage/Code/BLL/TeamManager.cs

295 lines
10 KiB
C#

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;
using EnVisage.Models;
namespace EnVisage.Code.BLL
{
public class TeamManager : ManagerBase<Team, TeamModel>
{
public TeamManager(EnVisageEntities dbContext)
: base(dbContext)
{
}
protected override Team InitInstance()
{
return new Team { Id = Guid.NewGuid() };
}
protected override Team RetrieveReadOnlyById(Guid key)
{
var team = DataTable.AsNoTracking().FirstOrDefault(t => t.Id == key);
if (team != null && team.PeopleResources != null)
team.PeopleResources = team.PeopleResources.OrderBy(r => r.LastName).ToList();
return team;
}
public override DbSet<Team> DataTable
{
get
{
return DbContext.Teams;
}
}
public TeamModel LoadWithChildCollections(Guid? value, bool isReadOnly = true)
{
TeamModel result = (TeamModel)base.Load(value, isReadOnly);
return result;
}
public override Team Save(TeamModel model)
{
if (model == null)
throw new ArgumentNullException("model");
return Save(model, model.Id == Guid.Empty);
}
public Team Save(TeamModel model, bool saveAsNew)
{
Team team = null;
if (saveAsNew && !DbContext.Teams.Any(x => x.Id == model.Id))
{
team = new Team()
{
Id = model.Id
};
model.CopyTo(team);
var capScen = DbContext.Scenarios.Create();
capScen.Type = (int)ScenarioType.TeamPlannedCapacity;
capScen.Name = model.Name + " Planned Capacity";
capScen.Id = Guid.NewGuid();
team.PlannedCapacityScenarioId = capScen.Id;
var actCapScen = DbContext.Scenarios.Create();
actCapScen.Type = (int)ScenarioType.TeamActualCapacity;
actCapScen.Name = model.Name + " Actual Capacity";
actCapScen.Id = Guid.NewGuid();
team.ActualCapacityScenarioId = actCapScen.Id;
if (team.Id == Guid.Empty)
team.Id = Guid.NewGuid();
DbContext.Teams.Add(team);
DbContext.Scenarios.Add(capScen);
DbContext.Scenarios.Add(actCapScen);
//DbContext.SaveChanges();
if (model.UserId != null)
{
foreach (var userId in model.UserId)
{
DbContext.User2Team.Add(new User2Team
{
Id = Guid.NewGuid(),
TeamId = team.Id,
UserId = userId.ToString()
});
}
}
}
else
{
team = base.Save(model);
var projectsWithParents = (from c in DbContext.Team2Project where c.TeamId == model.Id select new { c.ProjectId, c.Project.ParentProjectId }).Distinct().ToList();
var projects = projectsWithParents.Select(x => x.ProjectId).Distinct().ToList();
if (projectsWithParents.Any(x => x.ParentProjectId.HasValue))
projects.AddRange(projectsWithParents.Where(x => x.ParentProjectId.HasValue).Select(x => x.ParentProjectId.Value).Distinct());
var parts = DbContext.Projects.Where(x => x.ParentProjectId.HasValue && projects.Contains(x.ParentProjectId.Value)).Select(x => x.Id).ToList();
projects.AddRange(parts.Where(x => !projects.Contains(x)));
var users = DbContext.User2Team.Where(x => x.TeamId == model.Id).ToList();
var users2remove = users.Where(x => model.UserId == null || !model.UserId.Contains(Guid.Parse(x.UserId))).Select(x => x.UserId).ToList();
users.Where(x => model.UserId == null || !model.UserId.Contains(Guid.Parse(x.UserId))).ToList().
ForEach(x => DbContext.Entry(x).State = EntityState.Deleted);
if (model.UserId != null)
{
foreach (var userId in model.UserId.Where(c => users.All(u => !c.ToString().Equals(u.UserId, StringComparison.InvariantCultureIgnoreCase))))
{
DbContext.User2Team.Add(new User2Team
{
Id = Guid.NewGuid(),
TeamId = team.Id,
UserId = userId.ToString()
});
}
}
foreach (var project in projects.Distinct())
{
var projectUsers = (from c in DbContext.ProjectAccesses where c.ProjectId == project select c.PrincipalId).Distinct().ToList();
DbContext.ProjectAccesses.RemoveRange(DbContext.ProjectAccesses.Where(x => x.ProjectId == project && users2remove.Contains(x.PrincipalId.ToString())).ToList());
foreach (var userId in (from c in model.UserId where !projectUsers.Contains(c) select c).Distinct().ToList())
{
DbContext.ProjectAccesses.Add(new ProjectAccess()
{
PrincipalId = userId,
ProjectId = project,
Read = 1,
Write = 1
});
}
}
}
if (IsContextLocal)
DbContext.SaveChanges();
return team;
}
public IList<Team> GetTeamsByUser(Guid? userId)
{
if (userId.HasValue)
{
var teams = DbContext.User2Team.AsNoTracking()
.Where(x => x.UserId == userId.Value.ToString())
.Select(x => x.Team).Include(x => x.PeopleResources).ToList();
teams.ForEach(t => t.PeopleResources = t.PeopleResources.OrderBy(r => r.FirstName + r.LastName).ToList());
return teams;
}
return new List<Team>();
}
/// <summary>
/// Returns team list, which contains specified expenditure category
/// </summary>
/// <param name="userId">Visible for this user</param>
/// <param name="expCatId">Category to filter teams</param>
/// <returns>Query to get teams</returns>
/// <remarks>SA. ENV-1254</remarks>
public IQueryable<Team> GetTeamsByExpenditureCategory(Guid expCatId, Guid? userId)
{
IQueryable<Team> teamsP =
from Team t in DbContext.Teams
join VW_ExpCategoriesInScenario vv in DbContext.VW_ExpCategoriesInScenario
on t.PlannedCapacityScenarioId equals vv.ScenarioID
where (vv.Id == expCatId)
select t;
IQueryable<Team> teamsA =
from Team t in DbContext.Teams
join VW_ExpCategoriesInScenario vv in DbContext.VW_ExpCategoriesInScenario
on t.ActualCapacityScenarioId equals vv.ScenarioID
where (vv.Id == expCatId)
select t;
IQueryable<Team> teams = teamsP.Union(teamsA);
if (userId.HasValue)
{
string userIdAsText = userId.Value.ToString();
teams.Join(DbContext.User2Team.Where(x => x.UserId.Equals(userIdAsText)),
k => k.Id, l => l.TeamId, (k, l) => k);
}
return teams.Distinct();
}
public Guid?[] GetPlannedCapacityCategoriesIds(Guid teamId)
{
return (from sd in DbContext.ScenarioDetail
join s in DbContext.Scenarios on sd.ParentID equals s.Id
join t in DbContext.Teams on s.Id equals t.PlannedCapacityScenarioId
where t.Id == teamId
select sd.ExpenditureCategoryId).Distinct().ToArray();
}
public List<Team> FindTeams(IEnumerable<Guid> teams, IEnumerable<Guid> views, string userId)
{
if (teams == null && views == null)
return new List<Team>();
if (teams == null)
teams = new List<Guid>();
if (views == null)
views = new List<Guid>();
return DataTable.Where(x => (teams.Contains(x.Id) || DbContext.Team2View.Any(t => views.Contains(t.ViewId) && t.TeamId == x.Id)) &&
DbContext.User2Team.Any(u => u.UserId == userId))
.Include(x => x.Team2Project)
.Distinct().ToList();
}
public List<TeamAllocation> GetTeamsAllocation(List<Guid> teams, List<Guid> scenarios, List<Guid> expenditureCategories, bool onlyActiveScenarios = true)
{
if (teams == null || teams.Count <= 0)
return new List<TeamAllocation>();
var teamsAllocation = DbContext.TeamAllocations.Where(x => teams.Contains(x.TeamId));
if (scenarios != null && scenarios.Count > 0)
teamsAllocation = teamsAllocation.Where(x => scenarios.Contains(x.ScenarioId));
if (expenditureCategories != null && expenditureCategories.Count > 0)
teamsAllocation = teamsAllocation.Where(x => expenditureCategories.Contains(x.ExpenditureCategoryId));
if (onlyActiveScenarios)
teamsAllocation = teamsAllocation.Where(x => x.Scenario.Status == (int)ScenarioStatus.Active);
return teamsAllocation.ToList();
}
/// <summary>Returns tree-structure of teams allocation: Teams[TeamId, Scenarios[ScenarioId, ExpCats[ExpCatId, [{WeekEnding: TeamAllocation}]]]</summary>
public Dictionary<Guid, Dictionary<Guid, Dictionary<Guid, Dictionary<DateTime, TeamAllocation>>>> GetTeamsAllocationTree(List<Guid> teams, List<Guid> scenarios, List<Guid> expenditureCategories)
{
return GetTeamsAllocation(teams, scenarios, expenditureCategories)
.GroupBy(x => x.TeamId)
.ToDictionary(tms => tms.Key, sc => sc.GroupBy(scenario => scenario.ScenarioId)
.ToDictionary(scenario => scenario.Key, expCats => expCats.GroupBy(expCat => expCat.ExpenditureCategoryId)
.ToDictionary(expCat => expCat.Key, allocations => allocations.ToDictionary(allocation => allocation.WeekEndingDate))));
}
public List<Team2Scenario> GetRelationsWithScenarios(List<Guid> teams, ScenarioType? scenarioType, ScenarioStatus? scenarioStatus)
{
var team2ScenarioQuery = DbContext.Team2Scenario.Where(x => teams.Contains(x.TeamId));
if (scenarioType.HasValue)
team2ScenarioQuery = team2ScenarioQuery.Where(x => x.Scenario.Type == (int)scenarioType.Value);
if (scenarioStatus.HasValue)
team2ScenarioQuery = team2ScenarioQuery.Where(x => x.Scenario.Status == (int)scenarioStatus.Value);
return team2ScenarioQuery.ToList();
}
/// <summary>
/// Returns tree-structure of teams to scenario relations: Teams[TeamId, Team2ScenarioList]
/// </summary>
/// <param name="teams"></param>
/// <param name="scenarioType"></param>
/// <param name="scenarioStatus"></param>
/// <returns></returns>
public Dictionary<Guid, List<Team2Scenario>> GetRelationsWithScenariosTree(List<Guid> teams, ScenarioType? scenarioType, ScenarioStatus? scenarioStatus)
{
return GetRelationsWithScenarios(teams, scenarioType, scenarioStatus).GroupBy(x => x.TeamId).ToDictionary(x => x.Key, g => g.ToList());
}
public List<Team> GetTeamsByUser(string userId, List<Guid> teams, List<Guid> views)
{
var userTeams = DbContext.User2Team.AsNoTracking()
.Where(u2t => u2t.UserId.Equals(userId, StringComparison.InvariantCultureIgnoreCase))
.Select(x => x.Team);
if (teams != null && views != null && teams.Count > 0 && views.Count > 0)
{
userTeams = userTeams.Where(x => teams.Contains(x.Id) || x.Team2View.Any(v => views.Contains(v.ViewId)));
}
else if (teams != null && teams.Count > 0)
{
userTeams = userTeams.Where(x => teams.Contains(x.Id));
}
else if (views != null && views.Count > 0)
{
userTeams = userTeams.Where(x => x.Team2View.Any(v => views.Contains(v.ViewId)));
}
return userTeams.ToList();
}
}
}