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 { 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 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 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(); } /// /// Returns team list, which contains specified expenditure category /// /// Visible for this user /// Category to filter teams /// Query to get teams /// SA. ENV-1254 public IQueryable GetTeamsByExpenditureCategory(Guid expCatId, Guid? userId) { IQueryable 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 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 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 FindTeams(IEnumerable teams, IEnumerable views, string userId) { if (teams == null && views == null) return new List(); if (teams == null) teams = new List(); if (views == null) views = new List(); 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 GetTeamsAllocation(List teams, List scenarios, List expenditureCategories, bool onlyActiveScenarios = true) { if (teams == null || teams.Count <= 0) return new List(); 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(); } /// Returns tree-structure of teams allocation: Teams[TeamId, Scenarios[ScenarioId, ExpCats[ExpCatId, [{WeekEnding: TeamAllocation}]]] public Dictionary>>> GetTeamsAllocationTree(List teams, List scenarios, List 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 GetRelationsWithScenarios(List 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(); } /// /// Returns tree-structure of teams to scenario relations: Teams[TeamId, Team2ScenarioList] /// /// /// /// /// public Dictionary> GetRelationsWithScenariosTree(List teams, ScenarioType? scenarioType, ScenarioStatus? scenarioStatus) { return GetRelationsWithScenarios(teams, scenarioType, scenarioStatus).GroupBy(x => x.TeamId).ToDictionary(x => x.Key, g => g.ToList()); } public List GetTeamsByUser(string userId, List teams, List 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(); } } }