365 lines
16 KiB
C#
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;
|
|
}
|
|
}
|
|
|
|
} |