EnVisageOnline/Beta/Source/EnVisage/Code/BLL/ProjectManager.cs

365 lines
16 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 ProjectManager : ManagerBase<Project, ProjectModel>
{
public ProjectManager(EnVisageEntities dbContext)
: base(dbContext)
{
}
protected override Project InitInstance()
{
return new Project { Id = Guid.NewGuid() };
}
protected override Project RetrieveReadOnlyById(Guid key)
{
return DataTable.AsNoTracking().FirstOrDefault(t => t.Id == key);
}
public override DbSet<Project> DataTable
{
get
{
return DbContext.Projects;
}
}
public override Project Save(ProjectModel model)
{
if (model == null)
throw new ArgumentNullException("model");
var partManager = new ProjectPartManager(DbContext);
if (!model.HasChildren && model.Parts.Count == 1)
{
var part = model.Parts[0];
model.StatusId = part.StatusId;
model.TypeId = part.TypeId;
model.ClientId = part.ClientId;
model.Details = part.Details;
model.Priority = part.Priority;
model.IsRevenueGenerating = part.IsRevenueGenerating;
model.Deadline = part.Deadline;
model.Probability = part.Probability;
model.ParentProjectId = null;
model.ExternalContacts = part.ExternalContacts;
model.InternalContacts = part.InternalContacts;
model.AssignedTeams = part.AssignedTeams;
}
else if (model.HasChildren && model.Parts.Count > 0)
{
model.StatusId = model.Parts[0].StatusId;
model.TypeId = model.Parts[0].TypeId;
model.ClientId = model.Parts[0].ClientId;
}
var obj = base.Save(model);
if (model.HasChildren && model.Parts.Count > 0)
{
var currentParts = model.Id == Guid.Empty
? new List<Project>()
: DbContext.Projects.Where(t => t.ParentProjectId == model.Id).ToList();
for (var i=0; i < model.Parts.Count; i++)
{
var projectModel = model.Parts[i];
if (projectModel.DeletedPart && projectModel.Id != Guid.Empty)
{
var item2Delete = currentParts.FirstOrDefault(t => t.Id == projectModel.Id);
if (item2Delete !=null)
DbContext.Entry(item2Delete).State = EntityState.Deleted;
}
else if (currentParts.All(t => t.Id != projectModel.Id))
{
projectModel.ParentProjectId = obj.Id;
projectModel.SaveAsCopy = model.SaveAsCopy;
var oldId = model.Parts[i].OldId;
model.Parts[i] = (ProjectPartModel)partManager.Save(projectModel);
model.Parts[i].OldId = oldId;
}
else
{
var oldId = model.Parts[i].OldId;
projectModel.SaveAsCopy = model.SaveAsCopy;
model.Parts[i] = (ProjectPartModel)partManager.Save(projectModel);
model.Parts[i].OldId = oldId;
}
}
}
if (!model.HasChildren && model.Parts.Count == 1)
{
#region save project contacts
if (model.ExternalContacts == null)
model.ExternalContacts = new List<Guid>();
if (model.InternalContacts == null)
model.InternalContacts = new List<Guid>();
var allCurrentContacts = model.ExternalContacts.Concat(model.InternalContacts).ToList();
var oldContacts = DbContext.Contact2Project.Where(c2S => c2S.ShowId == obj.Id).ToList();
foreach (var c in oldContacts)
{
if (allCurrentContacts.Contains(c.ContactId))
allCurrentContacts.Remove(c.ContactId);
else
DbContext.Contact2Project.Remove(c);
}
foreach (var cId in allCurrentContacts)
{
DbContext.Contact2Project.Add(new Contact2Project()
{
Id = Guid.NewGuid(),
ContactId = cId,
ShowId = obj.Id,
Contact = DbContext.Contacts.FirstOrDefault(c=>c.Id == cId)
});
}
#endregion
#region save project teams
if (model.AssignedTeams == null)
model.AssignedTeams = new List<Guid>();
var oldTeams = DbContext.Team2Project.Where(x => x.ProjectId == obj.Id).ToList();
if (model.Id != Guid.Empty)
{
var oldTeamIds = oldTeams.Select(x => x.TeamId).ToList();
var oldTeamsUsers = DbContext.User2Team.Where(x => oldTeamIds.Contains(x.TeamId)).Select(x => x.UserId.ToLower()).Distinct().ToList();
var newTeamsUsers = DbContext.User2Team.Where(x => model.AssignedTeams.Contains(x.TeamId)).Select(x => x.UserId.ToLower()).Distinct().ToList();
var projectUsers = DbContext.ProjectAccesses.Where(x => x.ProjectId == obj.Id).Select(x => x.PrincipalId.ToString().ToLower()).ToList();
var usersToRemove = (from c in oldTeamsUsers where !newTeamsUsers.Contains(c) select c).ToList();
var usersToAdd = (from c in newTeamsUsers where !projectUsers.Contains(c) select c).ToList();
foreach (var user in usersToAdd)
{
DbContext.ProjectAccesses.Add(new ProjectAccess()
{
PrincipalId = new Guid(user),
ProjectId = obj.Id,
Read = 1,
Write = 1
});
}
DbContext.ProjectAccesses.RemoveRange(DbContext.ProjectAccesses.Where(x => x.ProjectId == obj.Id && usersToRemove.Contains(x.PrincipalId.ToString())).ToList());
}
foreach (var t in oldTeams)
{
if (model.AssignedTeams.Contains(t.TeamId))
model.AssignedTeams.Remove(t.TeamId);
else
{
DbContext.Team2Project.Remove(t);
}
}
foreach (var tId in model.AssignedTeams)
{
DbContext.Team2Project.Add(new Team2Project()
{
Id = Guid.NewGuid(),
ProjectId = obj.Id,
TeamId = tId
});
}
#endregion
}
return obj;
}
}
public class ProjectPartManager : ManagerBase<Project, ProjectPartModel>
{
public ProjectPartManager(EnVisageEntities dbContext)
: base(dbContext)
{
}
protected override Project InitInstance()
{
return new Project { Id = Guid.NewGuid() };
}
protected override Project RetrieveReadOnlyById(Guid key)
{
return DataTable.AsNoTracking().FirstOrDefault(t => t.Id == key);
}
public override DbSet<Project> DataTable
{
get
{
return DbContext.Projects;
}
}
public override Project Save(ProjectPartModel model)
{
var obj = base.Save(model);
#region save project contacts
if (model.ExternalContacts == null)
model.ExternalContacts = new List<Guid>();
if (model.InternalContacts == null)
model.InternalContacts = new List<Guid>();
var allCurrentContacts = model.ExternalContacts.Concat(model.InternalContacts).ToList();
var oldContacts = DbContext.Contact2Project.Where(c2S => c2S.ShowId == obj.Id).ToList();
foreach (var c in oldContacts)
{
if (allCurrentContacts.Contains(c.ContactId))
allCurrentContacts.Remove(c.ContactId);
else
DbContext.Contact2Project.Remove(c);
}
foreach (var cId in allCurrentContacts)
{
DbContext.Contact2Project.Add(new Contact2Project()
{
Id = Guid.NewGuid(),
ContactId = cId,
ShowId = obj.Id,
Contact = DbContext.Contacts.FirstOrDefault(c => c.Id == cId)
});
}
#endregion
#region save project teams
if (model.AssignedTeams == null)
model.AssignedTeams = new List<Guid>();
var oldTeams = DbContext.Team2Project.Where(x => x.ProjectId == obj.Id).ToList();
if (model.Id != Guid.Empty)
{
var oldTeamIds = oldTeams.Select(x => x.TeamId).ToList();
var oldTeamsUsers = DbContext.User2Team.Where(x => oldTeamIds.Contains(x.TeamId)).Select(x => x.UserId.ToLower()).Distinct().ToList();
var newTeamsUsers = DbContext.User2Team.Where(x => model.AssignedTeams.Contains(x.TeamId)).Select(x => x.UserId.ToLower()).Distinct().ToList();
var projectUsers = DbContext.ProjectAccesses.Where(x => x.ProjectId == obj.Id).Select(x => x.PrincipalId.ToString().ToLower()).ToList();
var usersToRemove = (from c in oldTeamsUsers where !newTeamsUsers.Contains(c) select c).ToList();
var usersToAdd = (from c in newTeamsUsers where !projectUsers.Contains(c) select c).ToList();
foreach (var user in usersToAdd)
{
DbContext.ProjectAccesses.Add(new ProjectAccess()
{
PrincipalId = new Guid(user),
ProjectId = obj.Id,
Read = 1,
Write = 1
});
}
DbContext.ProjectAccesses.RemoveRange(DbContext.ProjectAccesses.Where(x => x.ProjectId == obj.Id && usersToRemove.Contains(x.PrincipalId.ToString())).ToList());
}
foreach (var t in oldTeams)
{
if (model.AssignedTeams.Contains(t.TeamId))
model.AssignedTeams.Remove(t.TeamId);
else
{
DbContext.Team2Project.Remove(t);
}
}
foreach (var tId in model.AssignedTeams)
{
DbContext.Team2Project.Add(new Team2Project()
{
Id = Guid.NewGuid(),
ProjectId = obj.Id,
TeamId = tId
});
}
#endregion
if (model.Id == Guid.Empty)
{
#region Create Actuals scenario
if (!model.SaveAsCopy)
{
var scenario = new Scenario
{
Id = Guid.NewGuid(),
Name = "ACTUALS",
ParentId = obj.Id,
Type = ScenarioType.Actuals.GetHashCode(),
StartDate = DateTime.Now,
Color = "",
ProjectedRevenue = 0
};
DbContext.Scenarios.Add(scenario);
}
#endregion
#region Copy scenarios and referenced scenario details
if (model.SaveAsCopy)
{
var oldId = Guid.Empty;
var scenarios = DbContext.Scenarios.Where(t => t.ParentId == oldId).ToList();
foreach (var currScenario in scenarios)
{
var currDetails = DbContext.ScenarioDetail.Where(
t => t.ParentID == currScenario.Id).AsNoTracking().ToList().OrderBy(t => t.ExpenditureCategoryId).ThenBy(t => t.WeekOrdinal);
var newScenario = new Scenario
{
Id = Guid.NewGuid(),
ParentId = obj.Id,
Type = currScenario.Type,
Name = currScenario.Name,
ProjectedRevenue = currScenario.ProjectedRevenue,
ExpectedGrossMargin = currScenario.ExpectedGrossMargin,
CalculatedGrossMargin = currScenario.CalculatedGrossMargin,
CGSplit = currScenario.CGSplit,
EFXSplit = currScenario.EFXSplit,
Duration = currScenario.Duration,
TDDirectCosts = currScenario.TDDirectCosts,
BUDirectCosts = currScenario.BUDirectCosts,
Shots = currScenario.Shots,
TDRevenueShot = currScenario.TDRevenueShot,
BURevenueShot = currScenario.BURevenueShot,
LastUpdate = DateTime.Now,
Status = currScenario.Status,
UseLMMargin = currScenario.UseLMMargin,
ExpectedGrossMargin_LM = currScenario.ExpectedGrossMargin_LM,
CalculatedGrossMargin_LM = currScenario.CalculatedGrossMargin_LM,
TDDirectCosts_LM = currScenario.TDDirectCosts_LM,
BUDirectCosts_LM = currScenario.BUDirectCosts_LM,
BURevenueShot_LM = currScenario.BURevenueShot_LM,
EntryTimeStamp = DateTime.Now,
Actuals_BUDirectCosts = currScenario.Actuals_BUDirectCosts,
Actuals_BUDirectCosts_LM = currScenario.Actuals_BUDirectCosts_LM,
FreezeRevenue = currScenario.FreezeRevenue,
GrowthScenario = currScenario.GrowthScenario,
TemplateId = currScenario.TemplateId,
Color = currScenario.Color,
ProjectedExpense = currScenario.ProjectedExpense,
StartDate = currScenario.StartDate,
EndDate = currScenario.EndDate,
ShotStartDate = currScenario.ShotStartDate,
SystemAttributeObjectID = currScenario.SystemAttributeObjectID
};
DbContext.Scenarios.Add(newScenario);
foreach (var detail in currDetails)
{
var newDetailItem = new ScenarioDetail
{
Id = Guid.NewGuid(),
ExpenditureCategoryId = detail.ExpenditureCategoryId,
ParentID = newScenario.Id,
Quantity = detail.Quantity,
Cost = detail.Cost,
WeekOrdinal = detail.WeekOrdinal,
WeekEndingDate = detail.WeekEndingDate,
LastUpdate = DateTime.Now
};
DbContext.ScenarioDetail.Add(newDetailItem);
}
}
}
#endregion
}
return obj;
}
}
}