1829 lines
85 KiB
C#
1829 lines
85 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data.Entity;
|
|
using System.Data.Entity.Infrastructure;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Web;
|
|
using System.Web.Mvc;
|
|
using EnVisage.Code;
|
|
using EnVisage.Code.BLL;
|
|
using EnVisage.Models;
|
|
using EnVisage.Models.ProjectDependencies;
|
|
using jQuery.DataTables.Mvc;
|
|
using EnVisage.App_Start;
|
|
using System.Collections.ObjectModel;
|
|
using System.ComponentModel;
|
|
using System.IO;
|
|
using FileHelpers;
|
|
using System.Web.Script.Serialization;
|
|
using EnVisage.Code.Cache;
|
|
using EnVisage.Code.Validation;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using Kendo.Mvc.UI;
|
|
using Prevu.Core.Main;
|
|
|
|
namespace EnVisage.Controllers
|
|
{
|
|
[Authorize]
|
|
public class ProjectController : BaseController
|
|
{
|
|
#region Private Members
|
|
|
|
private ProjectManager ProjectManager { get; }
|
|
private IUserManager UserManager { get; }
|
|
|
|
#endregion
|
|
|
|
#region Contructors
|
|
|
|
public ProjectController(ProjectManager projectManager, IUserManager userManager)
|
|
{
|
|
ProjectManager = projectManager;
|
|
UserManager = userManager;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Actions
|
|
|
|
/// <summary>
|
|
/// GET: /Project/
|
|
/// </summary>
|
|
/// <returns>Empty view</returns>
|
|
[HttpGet]
|
|
[AreaSecurity(area = Areas.Projects, level = AccessLevel.Read)]
|
|
public ActionResult Index()
|
|
{
|
|
if (!SecurityManager.CheckSecurityObjectPermission(Areas.Projects, AccessLevel.Read))
|
|
return Redirect("/");
|
|
return View();
|
|
}
|
|
/// <summary>
|
|
/// GET: /Project/
|
|
/// </summary>
|
|
/// <returns>Empty view</returns>
|
|
[HttpGet]
|
|
[AreaSecurity(area = Areas.Projects, level = AccessLevel.Read)]
|
|
public ActionResult Index2()
|
|
{
|
|
|
|
return View("MyProjectsList");
|
|
}
|
|
public ActionResult MyProjectsList([DataSourceRequest]Kendo.Mvc.UI.DataSourceRequest request)
|
|
{
|
|
Guid userId = Guid.Parse(HttpContext.User.Identity.GetUserId());
|
|
int totalRecordCount;
|
|
int searchRecordCount;
|
|
var projects = new ProjectManager(DbContext).GetProjects4User(userId, false, null, 1, 100000000, "", out totalRecordCount, out searchRecordCount)
|
|
.Where(x => IsPart(x.Id) == false)
|
|
.Select(x => new
|
|
{
|
|
x.ProjectName,
|
|
ScenarioName = x.ActiveScenario != null ? x.ActiveScenario.Name : "",
|
|
ScenarioId = x.ActiveScenario?.Id ?? Guid.Empty,
|
|
x.Status,
|
|
Number = x.ProjectNumber,
|
|
x.Priority,
|
|
x.Classification,
|
|
x.Teams,
|
|
DeadLine = x.Deadline,
|
|
x.Client,
|
|
x.Id,
|
|
isPart = true,
|
|
Parts = x.ProjectParts.Select(z => new
|
|
{
|
|
z.ProjectName,
|
|
ScenarioName = z.ActiveScenario != null ? z.ActiveScenario.Name : "",
|
|
ScenarioId = z.ActiveScenario?.Id ?? Guid.Empty,
|
|
z.Status,
|
|
Number = z.ProjectNumber,
|
|
z.Priority,
|
|
z.Classification,
|
|
z.Teams,
|
|
DeadLine = z.Deadline,
|
|
z.Client,
|
|
z.Id
|
|
})
|
|
}).ToList();
|
|
return Json(projects, JsonRequestBehavior.AllowGet);
|
|
}
|
|
public ActionResult MyProjectPartList(Guid ParentId, [DataSourceRequest]Kendo.Mvc.UI.DataSourceRequest request)
|
|
{
|
|
var projects = this.DbContext.Projects.Where(x => x.ParentProjectId == ParentId).ToList().Select(x => new
|
|
{
|
|
ProjectName = x.Name,
|
|
ProjectParentId = x.ParentProjectId ?? Guid.Empty,
|
|
ProjectParentName = x.ParentProject.Name,
|
|
Status = x.Status.Name,
|
|
Number = x.ProjectNumber,
|
|
x.Priority,
|
|
Classification = x.Type.Name,
|
|
Teams = GetTeamNames(x.Id),
|
|
DeadLine = x.Deadline,
|
|
Client = x.Client.Name,
|
|
ScenarioName = GetActiveScenarioName(x.Id),
|
|
ScenarioId = GetActiveScenarioId(x.Id),
|
|
x.Id
|
|
}).Where(x => x.ProjectParentId == ParentId).ToList();
|
|
return Json(projects, JsonRequestBehavior.AllowGet);
|
|
}
|
|
|
|
[HttpPost]
|
|
[AreaSecurity(area = Areas.Projects, level = AccessLevel.Read)]
|
|
public ActionResult GetScenariosForProject(Guid ProjectId)
|
|
{
|
|
List<object> rt = new List<object>();
|
|
List<Guid> projects = new List<Guid> { ProjectId };
|
|
var scenarios = new ScenarioManager(DbContext).GetScenarios4Projects(projects, ScenarioType.Portfolio, null);
|
|
foreach (var s in scenarios)
|
|
{
|
|
rt.Add(new
|
|
{
|
|
key = s.Name,
|
|
value = s.Id
|
|
});
|
|
}
|
|
return Json(rt, JsonRequestBehavior.AllowGet);
|
|
}
|
|
/// <summary>
|
|
/// Returns JSON project list with filters and sort for jQuery DataTables
|
|
/// </summary>
|
|
[HttpPost]
|
|
[AreaSecurity(area = Areas.Projects, level = AccessLevel.Read)]
|
|
public JsonResult Index(JQueryDataTablesModel jQueryDataTablesModel)
|
|
{
|
|
int totalRecordCount;
|
|
int searchRecordCount;
|
|
|
|
var clients = GetProjects(startIndex: jQueryDataTablesModel.iDisplayStart,
|
|
pageSize: jQueryDataTablesModel.iDisplayLength, sortedColumns: jQueryDataTablesModel.GetSortedColumns(),
|
|
totalRecordCount: out totalRecordCount, searchRecordCount: out searchRecordCount, searchString: jQueryDataTablesModel.sSearch);
|
|
|
|
return this.DataTablesJson(items: clients,
|
|
totalRecords: totalRecordCount,
|
|
totalDisplayRecords: searchRecordCount,
|
|
sEcho: jQueryDataTablesModel.sEcho);
|
|
|
|
}
|
|
|
|
[HttpGet]
|
|
[AreaSecurity(area = Areas.Projects, level = AccessLevel.Write)]
|
|
public ActionResult Copy(Guid? id)
|
|
{
|
|
if (id != null && id != Guid.Empty)
|
|
if (!SecurityManager.CheckProjectPermission(id.Value, AccessLevel.Write))
|
|
return RedirectToAccessDenied();
|
|
|
|
var model = new ProjectModel();
|
|
try
|
|
{
|
|
var manager = new ProjectManager(DbContext);
|
|
model = (ProjectModel)manager.Load(id) ?? new ProjectModel();
|
|
|
|
var projectStatus = DbContext.Status.FirstOrDefault(x => x.Id == model.StatusId);
|
|
if (projectStatus != null)
|
|
{
|
|
if (projectStatus.Probability100)
|
|
model.Probability = 100;
|
|
ViewBag.IsProbability100 = projectStatus.Probability100;
|
|
}
|
|
else
|
|
{
|
|
ViewBag.IsProbability100 = false;
|
|
}
|
|
|
|
var statuses = DbContext.Status.Select(x => new { x.Id, x.Probability100 }).ToList();
|
|
ViewBag.Statuses = new JavaScriptSerializer().Serialize(statuses);
|
|
}
|
|
catch (BLLException blEx)
|
|
{
|
|
if (blEx.DisplayError)
|
|
SetErrorScript(message: blEx.Message);
|
|
else
|
|
{
|
|
LogException(blEx);
|
|
SetErrorScript();
|
|
}
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
LogException(exception);
|
|
SetErrorScript();
|
|
}
|
|
model.SaveAsCopy = true;
|
|
return Edit(model);
|
|
}
|
|
|
|
// GET: /Project/Edit/5
|
|
[HttpGet]
|
|
[AreaSecurity(area = Areas.Projects, level = AccessLevel.Write)]
|
|
public ActionResult Edit(Guid? id, Guid? partId, string backUrl, string backName)
|
|
{
|
|
if (id != null && id != Guid.Empty)
|
|
if (!SecurityManager.CheckProjectPermission(id.Value, AccessLevel.Write))
|
|
return RedirectToAccessDenied();
|
|
|
|
var model = new ProjectModel();
|
|
try
|
|
{
|
|
var manager = new ProjectManager(DbContext);
|
|
var scenarioManager = new ScenarioManager(DbContext);
|
|
model = (ProjectModel)manager.Load(id) ?? new ProjectModel();
|
|
if (model.ParentProjectId != null && model.ParentProjectId != Guid.Empty)
|
|
{
|
|
return RedirectToAction("Edit", "Project", new { id = model.ParentProjectId, partId = model.Id, backUrl, backName });
|
|
}
|
|
if (id == null || Guid.Empty.Equals(id))
|
|
{
|
|
model.ClientId = Guid.Empty;
|
|
model.Priority = 1;
|
|
}
|
|
else
|
|
{
|
|
model.ExpandedPartId = partId;
|
|
var projectIds = new List<Guid>();
|
|
if (model.HasChildren)
|
|
{
|
|
foreach (var part in model.Parts)
|
|
{
|
|
part.TeamsUsage = manager.GetProjectTeamsUsageInfo(part.Id);
|
|
projectIds.Add(part.Id);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
model.TeamsUsage = manager.GetProjectTeamsUsageInfo(partId ?? id.Value);
|
|
projectIds.Add(model.Id);
|
|
}
|
|
|
|
var scenarios = scenarioManager.GetScenarios4Projects(projectIds, ScenarioType.Portfolio, ScenarioStatus.Active);
|
|
var projectMinStartDate = scenarios.Min(t => t.StartDate);
|
|
var projectMaxEndDate = scenarios.Max(t => t.EndDate);
|
|
model.ProjectMinStartDate = projectMinStartDate?.ToShortDateString() ?? string.Empty;
|
|
model.ProjectMaxEndDate = projectMaxEndDate?.ToShortDateString() ?? string.Empty;
|
|
}
|
|
|
|
model.BackUrl = !string.IsNullOrEmpty(backUrl) ? backUrl : Url.Action("Index", "Project");
|
|
model.BackName = !string.IsNullOrEmpty(backName) ? backName : "projects";
|
|
new NotificationManager(null).UpdateNotificationAsViewedOnLoad(Guid.Parse(this.HttpContext.User.Identity.GetID()), model.Id);
|
|
var scenarios4Notifications = this.DbContext.Scenarios.Where(x => x.ParentId == model.Id && x.Type == (int)ScenarioType.Portfolio).ToList();
|
|
foreach (var s in scenarios4Notifications)
|
|
{
|
|
new NotificationManager(null).UpdateNotificationAsViewedOnLoad(Guid.Parse(this.HttpContext.User.Identity.GetID()), s.Id);
|
|
}
|
|
var statuses = DbContext.Status.Select(x => new { x.Id, x.Probability100 }).ToList();
|
|
ViewBag.Statuses = new JavaScriptSerializer().Serialize(statuses);
|
|
}
|
|
catch (BLLException blEx)
|
|
{
|
|
if (blEx.DisplayError)
|
|
SetErrorScript(message: blEx.Message);
|
|
else
|
|
{
|
|
LogException(blEx);
|
|
SetErrorScript();
|
|
}
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
LogException(exception);
|
|
SetErrorScript();
|
|
}
|
|
return View(model);
|
|
}
|
|
|
|
// POST: /Project/Edit/5
|
|
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
|
|
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
|
|
[HttpPost]
|
|
[ValidateAntiForgeryToken]
|
|
[AreaSecurity(area = Areas.Projects, level = AccessLevel.Write)]
|
|
public ActionResult Edit(ProjectModel model)
|
|
{
|
|
if (model == null || ContentLocker.IsLock("Project", model.Id.ToString(), User.Identity.GetUserName()))
|
|
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
|
|
if (model.Id != Guid.Empty)
|
|
if (!SecurityManager.CheckProjectPermission(model.Id, AccessLevel.Write))
|
|
return RedirectToAccessDenied();
|
|
|
|
var projectManager = new ProjectManager(DbContext);
|
|
var projectPartManager = new ProjectPartManager(DbContext);
|
|
var scenarioManager = new ScenarioManager(DbContext);
|
|
var fileManager = new FileManager(DbContext);
|
|
var workflowManager = new WorkFlowManager(DbContext);
|
|
var udfMan = new UDFManager(DbContext);
|
|
var statusManager = new StatusManager(DbContext);
|
|
|
|
// Trim model string properties and look if the project is a new one
|
|
model.TrimStringProperties();
|
|
var isNew = Guid.Empty.Equals(model.Id) || model.SaveAsCopy;
|
|
var userId = SecurityManager.GetUserPrincipal();
|
|
|
|
#region Remove incorrect propery values
|
|
|
|
//if user converted ordinary project to project with parts we need to convert old project to a "part" and create a parent project for it
|
|
//so basically we need to set project model's first part a successor of project that now became project with parts so all scenarios, permissions, etc. will be "reassigned" to the first part
|
|
//technically we just need to assign project ID to the first part and drop the ID of project + remove CompanyId, Projectnumber and Color from newly "added" part (done by ProjectPartModel itself)
|
|
if (model.Id != Guid.Empty && model.InitialHasChildrenState == false && model.HasChildren)
|
|
{
|
|
if (model.Parts.Count == 0)
|
|
throw new InvalidOperationException();
|
|
|
|
model.Parts[0].Id = model.Id;
|
|
model.Id = Guid.Empty;
|
|
model.InitialHasChildrenState = model.HasChildren;
|
|
|
|
//also need to drop ParentProjectId from all parts
|
|
foreach (ProjectPartModel pp in model.Parts)
|
|
pp.ParentProjectId = Guid.Empty;
|
|
}
|
|
|
|
var model2Save = model.Clone();
|
|
model2Save.ClientId = null;
|
|
var revalidationRequired = false;
|
|
for (var i = 0; i < model2Save.Parts.Count; i++)
|
|
{
|
|
if (model2Save.Parts[i].DeletedPart)
|
|
{
|
|
model.Parts.RemoveAt(i);
|
|
revalidationRequired = true;
|
|
}
|
|
}
|
|
foreach (var part in model2Save.Parts)
|
|
{
|
|
part.InternalContacts?.RemoveAll(t => t == Guid.Empty);
|
|
part.ExternalContacts?.RemoveAll(t => t == Guid.Empty);
|
|
}
|
|
|
|
if (revalidationRequired)
|
|
{
|
|
ModelState.Clear();
|
|
TryValidateModel(model);
|
|
}
|
|
|
|
#endregion
|
|
|
|
var updatedStatus = new Dictionary<Guid, Guid>();
|
|
var savedProjects = model.Parts.SelectMany(x => new[] { x.Id, x.ParentProjectId ?? Guid.Empty })
|
|
.Where(x => x != Guid.Empty).Distinct();
|
|
|
|
if (savedProjects.Any())
|
|
{
|
|
var projects = projectManager.GetProjects(savedProjects, true).ToDictionary(x => x.Id);
|
|
foreach (var part in model.Parts)
|
|
{
|
|
var projectId = model.HasChildren ? part.Id : part.ParentProjectId ?? Guid.Empty;
|
|
if (projectId == Guid.Empty || !projects.ContainsKey(projectId))
|
|
continue;
|
|
|
|
var project = projects[projectId];
|
|
if (project.StatusId != part.StatusId && part.StatusId != Guid.Empty)
|
|
updatedStatus.Add(project.Id, part.StatusId);
|
|
}
|
|
}
|
|
|
|
if (ModelState.IsValid)
|
|
{
|
|
//using (DbContextTransaction transaction = DbContext.Database.BeginTransaction())
|
|
//{
|
|
var transactionId = Utils.GetOrCreateTransactionId(DbContext, string.Empty);
|
|
|
|
var projectId = model2Save.Id;
|
|
|
|
try
|
|
{
|
|
var addedTeams = new List<Guid>();
|
|
foreach (var p in model.Parts)
|
|
{
|
|
var id = model.Id;
|
|
if (model.HasChildren)
|
|
{
|
|
id = p.Id;
|
|
|
|
}
|
|
var status = this.DbContext.Status.Where(x => x.Id == p.StatusId).Select(x => x.Name).FirstOrDefault();
|
|
var s = this.DbContext.Scenarios.FirstOrDefault(x => x.ParentId == id && x.Type == (int)ScenarioType.Portfolio);// && x.Status == (int) ScenarioStatus.Active).FirstOrDefault();
|
|
if (s != null)
|
|
{
|
|
var cmds = workflowManager.GetAvailableCommands(userId, s.Id);
|
|
foreach (var c in cmds)
|
|
{
|
|
if (c.CommandName == status)
|
|
DoWorkFlowAction(c, s.Id, userId);
|
|
}
|
|
}
|
|
var existingTeams = this.DbContext.Team2Project.Where(y => y.ProjectId == id).Select(z => z.TeamId).ToList() ??
|
|
new List<Guid>();
|
|
if (p.AssignedTeams == null)
|
|
p.AssignedTeams = new List<Guid>();
|
|
if (p.AssignedTeams.Count <= 0) continue;
|
|
{
|
|
var newTeams = p.AssignedTeams.Where(x => !existingTeams.Contains(x)).ToList();
|
|
foreach (var t in newTeams)
|
|
{
|
|
if (addedTeams.Contains(t))
|
|
continue;
|
|
addedTeams.Add(t);
|
|
var scenarios = this.DbContext.Scenarios.Where(x => x.ParentId == id && x.Type == (int)ScenarioType.Portfolio).ToList();
|
|
if (scenarios.Count > 0)
|
|
{
|
|
foreach (var scenario in scenarios)
|
|
{
|
|
var st = workflowManager.GetCurrentState(scenario.Id);
|
|
string state = null;
|
|
if (!string.IsNullOrEmpty(st?.state))
|
|
state = st.state;
|
|
var who = workflowManager.GetContactTeamDetails(t, WorkFlowContactNotificationType.TeamScenarioAdd, state);
|
|
if (who.Count > 0)
|
|
{
|
|
who = who.Distinct().ToList();
|
|
new NotificationManager(this.DbContext).CreateTeamAddNotification(who, scenario.Id, 0, true, state);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var who = workflowManager.GetContactTeamDetails(t, WorkFlowContactNotificationType.TeamScenarioAdd, null);
|
|
if (who.Count > 0)
|
|
{
|
|
who = who.Distinct().ToList();
|
|
(new NotificationManager(this.DbContext)).CreateTeamAddNotification(who, id, 0, true, null);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if (!isNew)
|
|
{
|
|
//this situation occurs when we convert project to project with parts (see above). we rewrite ids between "part" and project and Event Logger needs to be aware of this
|
|
bool bConvertToProjectWithParts = projectId.Equals(Guid.Empty);
|
|
|
|
projectManager.LogProjectEvents(User.Identity.GetUserId(), model2Save, transactionId, bConvertToProjectWithParts);
|
|
|
|
//projectId is Guid.Empty if we just converted project to project with parts. Since we don't track events for added parts yet, it makes no sense
|
|
//to query DB here to find anything - first "virtual" part becomes real first part of new project with parts and all other parts will be new
|
|
//CHANGE if we begin to track "part added" event
|
|
if (!projectId.Equals(Guid.Empty))
|
|
{
|
|
var partItemsToLoad = ProjectManager.LoadProjectItems.PortfolioLabels | ProjectManager.LoadProjectItems.Tags;
|
|
var partsInDatabase = projectPartManager.GetItemsAsModelWithChildren(projectId, partItemsToLoad);
|
|
|
|
if (partsInDatabase != null)
|
|
{
|
|
foreach (var partId in partsInDatabase.Keys)
|
|
{
|
|
var partInDatabase = partsInDatabase[partId];
|
|
var clientPartModel = model2Save.Parts.FirstOrDefault(x => (x.Id == partId));
|
|
if (clientPartModel != null) //part is not deleted
|
|
projectManager.LogProjectPartsEvents(true, partInDatabase, clientPartModel, userId.ToString(), transactionId, false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
var newProject = projectManager.Save(model2Save);
|
|
|
|
if (isNew)
|
|
projectManager.LogProjectCreateEvent(newProject, User.Identity.GetUserId(), transactionId);
|
|
|
|
DbContext.SaveChanges();
|
|
|
|
var statusUpdatepartIds = DbContext.Projects.Where(t => t.ParentProjectId.HasValue && t.ParentProjectId.Value == newProject.Id).Select(t => t.Id).ToList();
|
|
statusUpdatepartIds.Add(newProject.Id);
|
|
foreach (var partId in statusUpdatepartIds)
|
|
{
|
|
var p = this.DbContext.Projects.FirstOrDefault(x => x.Id == partId);
|
|
if (p == null || p.Id == Guid.Empty)
|
|
continue;
|
|
var status = this.DbContext.Status.FirstOrDefault(x => x.Id == p.StatusId && x.ResetScenariosToInactive == true);
|
|
if (status != null && status.Id != Guid.Empty)
|
|
{
|
|
var scenarios = this.DbContext.Scenarios.Where(x => x.ParentId == partId && x.Type == (int)ScenarioType.Portfolio).ToList();
|
|
foreach (var scenario in scenarios)
|
|
{
|
|
scenario.Status = (int)ScenarioStatus.Inactive;
|
|
this.DbContext.Entry(scenario).State = EntityState.Modified;
|
|
}
|
|
}
|
|
}
|
|
var partIds = DbContext.Projects.Where(t => t.ParentProjectId.HasValue && t.ParentProjectId.Value == newProject.Id).Select(t => t.Id).ToArray();
|
|
//Give user Full Access permissions to the new project
|
|
var teamIds = new List<Guid>();
|
|
|
|
foreach (var part in model2Save.Parts)
|
|
{
|
|
if (part.AssignedTeams != null)
|
|
teamIds.AddRange(part.AssignedTeams);
|
|
}
|
|
|
|
var existingUsersPermissions =
|
|
DbContext.ProjectAccesses.Where(t => partIds.Contains(t.ProjectId) || t.ProjectId == newProject.Id)
|
|
.Select(t => new { t.ProjectId, t.PrincipalId }).ToList();
|
|
|
|
var users = (from c in DbContext.User2Team where teamIds.Contains(c.TeamId) select c.UserId).Distinct().ToList();
|
|
|
|
if (!users.Contains(User.Identity.GetID(), StringComparer.OrdinalIgnoreCase))
|
|
users.Add(User.Identity.GetID());
|
|
|
|
foreach (var contributor in users)
|
|
{
|
|
if (!existingUsersPermissions.Any(t => t.PrincipalId == new Guid(contributor) && t.ProjectId == newProject.Id))
|
|
{
|
|
DbContext.ProjectAccesses.Add(new ProjectAccess
|
|
{
|
|
PrincipalId = new Guid(contributor),
|
|
ProjectId = newProject.Id,
|
|
Read = 1,
|
|
Write = 1
|
|
});
|
|
}
|
|
foreach (var partId in partIds)
|
|
{
|
|
if (!existingUsersPermissions.Any(t => t.PrincipalId == new Guid(contributor) && t.ProjectId == partId))
|
|
{
|
|
DbContext.ProjectAccesses.Add(new ProjectAccess
|
|
{
|
|
PrincipalId = new Guid(contributor),
|
|
ProjectId = partId,
|
|
Read = 1,
|
|
Write = 1
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
if (isNew)
|
|
{
|
|
if (model.SaveAsCopy)
|
|
{
|
|
#region Copy attachments
|
|
|
|
if (model.Parts != null)
|
|
{
|
|
foreach (var part in model.Parts)
|
|
{
|
|
var holderId = model.HasChildren ? part.Id : newProject.Id;
|
|
if (part.Attachments != null)
|
|
{
|
|
// we need to copy only existing attachments to new project, not new
|
|
var existingAttachments = part.Attachments.Where(x => !x.IsNew).ToList();
|
|
if (existingAttachments.Count > 0)
|
|
{
|
|
part.Attachments = part.Attachments.Where(x => x.IsNew).ToList();
|
|
var copiedAttachments = fileManager.CopyPermanentFiles(existingAttachments, holderId, part.GetType());
|
|
if (copiedAttachments != null && copiedAttachments.Count > 0)
|
|
{
|
|
foreach (var attachment in copiedAttachments)
|
|
part.Attachments.Add(attachment);
|
|
}
|
|
}
|
|
}
|
|
if (part.Links != null)
|
|
{
|
|
// we need to copy only existing attachments to new project, not new
|
|
var existingLinks = part.Links.Where(x => !x.IsNew).ToList();
|
|
if (existingLinks.Count > 0)
|
|
{
|
|
part.Links = part.Links.Where(x => x.IsNew).ToList();
|
|
if (existingLinks != null && existingLinks.Count > 0)
|
|
{
|
|
foreach (var link in existingLinks)
|
|
part.Links.Add(link.Copy());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
#region copy udfs
|
|
if (model.UserDefinedFields == null)
|
|
model.UserDefinedFields = new List<UDFValueCollection>();
|
|
foreach (var udf in model.UserDefinedFields)
|
|
{
|
|
if (udf.Values != null)
|
|
{
|
|
udfMan.saveValue(udf.Values.Copy(), udf.Id, newProject.Id, userId);
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
|
|
#region Move attachments to permanent storage
|
|
|
|
if (model.Parts.Count > 0)
|
|
{
|
|
foreach (var partModel in model.Parts)
|
|
{
|
|
var parentId = partModel.Id;
|
|
var parentType = partModel.GetType();
|
|
|
|
if ((model.Parts.Count == 1) && partModel.Id.Equals(Guid.Empty))
|
|
{
|
|
parentId = newProject.Id;
|
|
parentType = model.GetType();
|
|
}
|
|
|
|
if ((partModel.Attachments != null) && (partModel.Attachments.Count > 0))
|
|
{
|
|
var newAttachments = partModel.Attachments.Where(x => x.IsNew).ToList();
|
|
var existingAttachments = partModel.Attachments.Where(x => !x.IsNew).ToList();
|
|
|
|
var undeletedFiles = fileManager.MoveToPermanentStorage(newAttachments, parentId, parentType);
|
|
if (undeletedFiles != null && undeletedFiles.Count > 0)
|
|
{
|
|
var errorMessage = string.Join(", ", undeletedFiles);
|
|
LogError(string.Format("Temp attachments copied to permanent storage, but some temp files were not deleted: {0}", errorMessage));
|
|
}
|
|
|
|
if (!model.SaveAsCopy && (existingAttachments.Count > 0))
|
|
fileManager.ChangeFilesParent(existingAttachments, parentId, parentType);
|
|
}
|
|
if (partModel.Links != null && (partModel.Links.Count > 0))
|
|
{
|
|
var linksToAdd = partModel.Links.Where(x => x.IsNew).ToList();
|
|
|
|
|
|
if (linksToAdd.Count > 0)
|
|
{
|
|
foreach (var l in linksToAdd)
|
|
{
|
|
this.DbContext.Attachments.Add(new Attachment()
|
|
{
|
|
Id = Guid.NewGuid(),
|
|
FileName = l.Name,
|
|
SourceFileName = l.Name,
|
|
ContentType = "link",
|
|
Created = DateTime.Now,
|
|
FileSize = 0,
|
|
Link = l.Link,
|
|
ParentId = parentId,
|
|
ParentType = parentType.FullName
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
|
|
if (!isNew && model.Parts.Count > 0 && !model.SaveAsCopy)
|
|
{
|
|
#region Update project attachments
|
|
|
|
var partsIds = model.Parts.Select(x => x.Id).ToList();
|
|
|
|
if (partsIds.Count == 1 && partsIds.First().Equals(Guid.Empty))
|
|
{
|
|
partsIds.Clear();
|
|
partsIds.Add(model.Id);
|
|
}
|
|
|
|
List<Guid> attachmentsToRemove = fileManager.GetPermanentFilesByHolder(partsIds) as List<Guid>;
|
|
|
|
foreach (ProjectPartModel partModel in model.Parts)
|
|
{
|
|
if ((partModel.Attachments != null) && (partModel.Attachments.Count > 0))
|
|
{
|
|
var foundAttachments = partModel.Attachments.Where(x => !x.IsNew).Select(y => y.Id);
|
|
attachmentsToRemove.RemoveAll(x => foundAttachments.Contains(x));
|
|
var attachmentsToAdd = partModel.Attachments.Where(x => x.IsNew).ToList();
|
|
|
|
Guid holderId = partModel.Id;
|
|
System.Type holderType = partModel.GetType();
|
|
|
|
if (holderId.Equals(Guid.Empty) && (model.Parts.Count == 1) && !model.Id.Equals(Guid.Empty))
|
|
{
|
|
holderId = model.Id;
|
|
holderType = model.GetType();
|
|
}
|
|
|
|
if (attachmentsToAdd.Count > 0)
|
|
{
|
|
var undeletedFiles = fileManager.MoveToPermanentStorage(attachmentsToAdd, holderId, holderType);
|
|
if (undeletedFiles != null && undeletedFiles.Count > 0)
|
|
{
|
|
var errorMessage = string.Join(", ", undeletedFiles);
|
|
LogError(String.Format("Temp attachments copied to permanent storage, but some temp files were not deleted: {0}", errorMessage));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (attachmentsToRemove.Count > 0)
|
|
fileManager.DeletePermanentFiles(attachmentsToRemove, true);
|
|
|
|
#endregion
|
|
#region Links
|
|
partsIds = model.Parts.Select(x => x.Id).ToList();
|
|
|
|
if (partsIds.Count == 1 && partsIds.First().Equals(Guid.Empty))
|
|
{
|
|
partsIds.Clear();
|
|
partsIds.Add(model.Id);
|
|
}
|
|
|
|
List<Guid> linksToRemove = this.DbContext.Attachments.Where(x => partsIds.Contains(x.ParentId) && !string.IsNullOrEmpty(x.Link)).Select(x => x.Id).ToList();
|
|
|
|
foreach (ProjectPartModel partModel in model.Parts)
|
|
{
|
|
if ((partModel.Links != null) && (partModel.Links.Count > 0))
|
|
{
|
|
var foundLinks = partModel.Links.Where(x => !x.IsNew).Select(y => y.Id);
|
|
linksToRemove.RemoveAll(x => foundLinks.Contains(x));
|
|
var linksToAdd = partModel.Links.Where(x => x.IsNew).ToList();
|
|
|
|
Guid holderId = partModel.Id;
|
|
System.Type holderType = partModel.GetType();
|
|
|
|
if (holderId.Equals(Guid.Empty) && (model.Parts.Count == 1) && !model.Id.Equals(Guid.Empty))
|
|
{
|
|
holderId = model.Id;
|
|
holderType = model.GetType();
|
|
}
|
|
|
|
if (linksToAdd.Count > 0)
|
|
{
|
|
foreach (var l in linksToAdd)
|
|
{
|
|
this.DbContext.Attachments.Add(new Attachment()
|
|
{
|
|
Id = Guid.NewGuid(),
|
|
FileName = l.Name,
|
|
SourceFileName = l.Name,
|
|
ContentType = "link",
|
|
Created = DateTime.Now,
|
|
FileSize = 0,
|
|
Link = l.Link,
|
|
ParentId = holderId,
|
|
ParentType = holderType.FullName
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (linksToRemove.Count > 0)
|
|
{
|
|
foreach (var l in linksToRemove)
|
|
{
|
|
var link = this.DbContext.Attachments.Where(x => x.Id == l).FirstOrDefault();
|
|
if (link != null)
|
|
{
|
|
this.DbContext.Attachments.Remove(link);
|
|
this.DbContext.Entry(link).State = EntityState.Deleted;
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
#region tags
|
|
if (model.Parts != null)
|
|
{
|
|
foreach (var part in model.Parts)
|
|
{
|
|
|
|
var holderId = model.HasChildren ? part.Id : newProject.Id;
|
|
var tagObjsInDb = DbContext.TagLinks.Where(x => x.ParentID == holderId).ToList();
|
|
if (part.ProjectTags == null)
|
|
part.ProjectTags = new List<Guid>();
|
|
if (part.PortfolioTags == null)
|
|
part.PortfolioTags = new List<Guid>();
|
|
|
|
//remove any tags from db that do not exist in collection returned from edit form (they were deleted)
|
|
foreach (var tagObjInDb in tagObjsInDb)
|
|
{
|
|
switch (tagObjInDb.TagLinkType)
|
|
{
|
|
case (int)TagType.Portfolio:
|
|
if (part.PortfolioTags.Where(x => x == tagObjInDb.TagID && tagObjInDb.TagLinkType == (int)TagType.Portfolio).ToList().Count == 0)
|
|
DbContext.TagLinks.Remove(tagObjInDb);
|
|
break;
|
|
case (int)TagType.Project:
|
|
if (part.ProjectTags.Where(x => x == tagObjInDb.TagID && tagObjInDb.TagLinkType == (int)TagType.Project).ToList().Count == 0)
|
|
DbContext.TagLinks.Remove(tagObjInDb);
|
|
break;
|
|
}
|
|
}
|
|
|
|
//add new portfolio tag link records
|
|
if (part.PortfolioTags != null)
|
|
{
|
|
|
|
foreach (var portTagId in part.PortfolioTags)
|
|
{
|
|
if (portTagId != Guid.Empty)
|
|
{
|
|
var tag = this.DbContext.TagLinks.Where(x => x.TagID == portTagId && x.ParentID == holderId).FirstOrDefault();
|
|
if (tag == null || tag.Id == Guid.Empty)
|
|
{
|
|
tag = new TagLink
|
|
{
|
|
Id = Guid.NewGuid(),
|
|
ParentID = holderId,
|
|
TagID = portTagId,
|
|
TagLinkType = (int)TagType.Portfolio
|
|
};
|
|
this.DbContext.TagLinks.Add(tag);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
//add new project tag link records
|
|
foreach (var projTagId in part.ProjectTags)
|
|
{
|
|
if (projTagId != Guid.Empty)
|
|
{
|
|
var tag = this.DbContext.TagLinks.Where(x => x.TagID == projTagId && x.ParentID == holderId).FirstOrDefault();
|
|
if (tag == null || tag.Id == Guid.Empty)
|
|
{
|
|
tag = new TagLink
|
|
{
|
|
Id = Guid.NewGuid(),
|
|
ParentID = holderId,
|
|
TagID = projTagId,
|
|
TagLinkType = (int)TagType.Project
|
|
};
|
|
this.DbContext.TagLinks.Add(tag);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
#region UDFS
|
|
if (model.UserDefinedFields == null)
|
|
model.UserDefinedFields = new List<UDFValueCollection>();
|
|
foreach (var udf in model.UserDefinedFields)
|
|
{
|
|
if (udf.Values != null)
|
|
{
|
|
udfMan.saveValue(udf.Values, udf.Id, newProject.Id, userId);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
DbContext.SaveChanges();
|
|
//transaction.Commit();
|
|
Task.Run(() => AuditProxy.CommitHistoryChanges(transactionId, userId.ToString()));
|
|
Task.Run(() => AuditProxy.CommitEventChanges(transactionId));
|
|
#region Update workflow statuses
|
|
if (updatedStatus.Any())
|
|
{
|
|
try
|
|
{
|
|
var updatedProjects = updatedStatus.Keys.ToList();
|
|
var scenarios = scenarioManager.GetScenarios4Projects(updatedProjects, null, null, false, true)
|
|
.GroupBy(x => x.ParentId.Value)
|
|
.ToDictionary(x => x.Key, g => g.ToList());
|
|
var statuses = statusManager.GetStatuses(updatedStatus.Values, true).ToDictionary(x => x.Id);
|
|
foreach (var partId in updatedProjects)
|
|
{
|
|
var part = model.Parts.Where(x => x.Id == partId || (x.Id == Guid.Empty && x.ParentProjectId == partId)).FirstOrDefault();
|
|
var status = statuses.ContainsKey(part.StatusId) ? statuses[part.StatusId] : null;
|
|
var partScenarios = scenarios.ContainsKey(partId) ? scenarios[partId] : null;
|
|
|
|
if (status != null && !string.IsNullOrWhiteSpace(status.WorkFlowState) && partScenarios != null)
|
|
{
|
|
foreach (var scenario in partScenarios)
|
|
{
|
|
if (workflowManager.isProcessExists(scenario.Id))
|
|
{
|
|
var state = workflowManager.GetCurrentState(scenario.Id);
|
|
var schemeName = workflowManager.getScenarioSchemeName(scenario.Id);
|
|
var states = workflowManager.getStatesForProcess(schemeName);
|
|
if ((state == null || state.state != status.WorkFlowState) && states.Any(x => x.state == status.WorkFlowState))
|
|
workflowManager.SetState(userId, scenario.Id, null, new WorkFlowState() { state = status.WorkFlowState, Selected = true, HasChanges = true });
|
|
}
|
|
}
|
|
}
|
|
(new NotificationManager(null)).RemoveNotification(userId, partId);
|
|
if (part.ParentProjectId.HasValue && part.ParentProjectId.Value != Guid.Empty)
|
|
(new NotificationManager(null)).RemoveNotification(userId, part.ParentProjectId.Value);
|
|
|
|
}
|
|
}
|
|
catch (Exception wfstatEx)
|
|
{
|
|
LogException(wfstatEx);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
new ProjectAccessCache().Invalidate();
|
|
|
|
ContentLocker.RemoveLock("Project", model.Id.ToString(), User.Identity.GetUserName());
|
|
return !model.SaveAsCopy
|
|
? (model2Save.ContinueToScenarios
|
|
? RedirectToAction("Edit", new { id = newProject.Id, ptab = model.HasChildren ? "scenarios" : "newscenario" })
|
|
: RedirectToAction("Edit", "Project", new { id = newProject.Id }))
|
|
: RedirectToAction("Edit", "Project", new { id = newProject.Id });
|
|
}
|
|
catch (BLLException blEx) // handle any system specific error
|
|
{
|
|
//transaction.Rollback();
|
|
AuditProxy.ClearHistoryChanges(transactionId);
|
|
AuditProxy.ClearEventChanges(transactionId);
|
|
|
|
// display error message if required
|
|
if (blEx.DisplayError)
|
|
ModelState.AddModelError(string.Empty, blEx.Message);
|
|
else // if display not requried then display modal form with general error message
|
|
{
|
|
LogException(blEx);
|
|
SetErrorScript();
|
|
}
|
|
}
|
|
catch (Exception exception) // handle any unexpected error
|
|
{
|
|
//transaction.Rollback();
|
|
AuditProxy.ClearHistoryChanges(transactionId);
|
|
AuditProxy.ClearEventChanges(transactionId);
|
|
|
|
LogException(exception);
|
|
SetErrorScript();
|
|
}
|
|
//}
|
|
}
|
|
|
|
if (model.Id != null && model.Id != Guid.Empty)
|
|
{
|
|
model.Scenarios = new List<ScenarioTabModel>();
|
|
var projDb = DbContext.Projects.FirstOrDefault(x => x.Id == model.Id);
|
|
|
|
foreach (var childProject in projDb.ChildProjects.OrderBy(pp => pp.PartNum))
|
|
{
|
|
foreach (var scenario in childProject.Scenarios)
|
|
{
|
|
if (scenario.Type != ScenarioType.Actuals.GetHashCode())
|
|
model.ScenariosCount++;
|
|
model.Scenarios.Add((ScenarioTabModel)scenario);
|
|
}
|
|
}
|
|
}
|
|
|
|
// return empty model with validation messages (if any)
|
|
var statusesWithProb100 = DbContext.Status.Select(x => new { x.Id, x.Probability100 }).ToList();
|
|
ViewBag.Statuses = new JavaScriptSerializer().Serialize(statusesWithProb100);
|
|
return View(model);
|
|
}
|
|
|
|
[AreaSecurity(area = Areas.Projects, level = AccessLevel.Write)]
|
|
public ActionResult AddPart(ProjectPartModel model, int count)
|
|
{
|
|
try
|
|
{
|
|
if (ContentLocker.IsLock("Project", (model.ParentProjectId ?? Guid.Empty).ToString(), User.Identity.GetUserName()))
|
|
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
|
|
if (model.ParentProjectId.HasValue && model.ParentProjectId != Guid.Empty)
|
|
if (!SecurityManager.CheckProjectPermission(model.ParentProjectId.Value, AccessLevel.Write))
|
|
return new HttpStatusCodeResult(HttpStatusCode.Unauthorized);
|
|
|
|
//ENV-680. As we pass something to the action method, ModelState object is being generated and passed items being automatically validated
|
|
//The issue is - we pass ProjectPartModel instance with empty values and it is being validated and partial view being rendered with validation errors
|
|
//(for now ClientId and Priority are invalid). This it a standard MVC behavior and we cannot change that, so we have two options:
|
|
//1. reset the validation on the client side manipulating jQuery unobtrusive validation, but this will drop all the validation errors from the entire form
|
|
// and not just the part we've added
|
|
//2. clear errors in the ModelState manually - ModelState is not preserved during roundtrips so we're just dropping it now and validation
|
|
// still performs on the project save
|
|
//Option 2 seems to be much better choice here so here is the magic:
|
|
foreach (var key in ModelState.Keys)
|
|
{
|
|
ModelState[key].Errors.Clear();
|
|
}
|
|
if (model.PortfolioTags == null)
|
|
model.PortfolioTags = new List<Guid>();
|
|
if (model.ProjectTags == null)
|
|
model.ProjectTags = new List<Guid>();
|
|
if (model.WorkFlowContacts == null)
|
|
model.WorkFlowContacts = new List<Guid>();
|
|
if (model.Links == null)
|
|
model.Links = new List<AttachmentModel>();
|
|
return PartialView("~/Views/Shared/EditorTemplates/ProjectPartModel.cshtml", model);
|
|
}
|
|
catch (BLLException blEx) // handle any system specific error
|
|
{
|
|
// display error message if required
|
|
if (blEx.DisplayError)
|
|
SetErrorScript(message: blEx.Message);
|
|
else // if display not requried then display modal form with general error message
|
|
{
|
|
LogException(blEx);
|
|
SetErrorScript();
|
|
}
|
|
}
|
|
catch (Exception exception) // handle any unexpected error
|
|
{
|
|
LogException(exception);
|
|
SetErrorScript();
|
|
}
|
|
return new EmptyResult();
|
|
}
|
|
|
|
public ActionResult NewLink()
|
|
{
|
|
return View(new AttachmentModel());
|
|
}
|
|
// GET: /Project/Delete/5
|
|
[HttpGet]
|
|
[AreaSecurity(area = Areas.Projects, level = AccessLevel.Write)]
|
|
public ActionResult Delete(Guid? id)
|
|
{
|
|
if (id == null || id == Guid.Empty)
|
|
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
|
|
if (!SecurityManager.CheckProjectPermission(id.Value, AccessLevel.Write))
|
|
return RedirectToAccessDenied();
|
|
|
|
var model = new ProjectModel();
|
|
try
|
|
{
|
|
var manager = new ProjectManager(DbContext);
|
|
model = (ProjectModel)manager.Load(id);
|
|
if (model == null)
|
|
return HttpNotFound();
|
|
|
|
var transactionId = DbContext.GetClientConnectionId();
|
|
manager.LogProjectDeleteEvent(model, User.Identity.GetUserId(), transactionId);
|
|
Task.Run(() => AuditProxy.CommitEventChanges(transactionId));
|
|
}
|
|
catch (BLLException blEx)
|
|
{
|
|
if (blEx.DisplayError)
|
|
SetErrorScript(message: blEx.Message);
|
|
else
|
|
{
|
|
LogException(blEx);
|
|
SetErrorScript();
|
|
}
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
LogException(exception);
|
|
SetErrorScript();
|
|
}
|
|
return View(model);
|
|
}
|
|
|
|
// POST: /Project/Delete/5
|
|
[HttpPost, ActionName("Delete")]
|
|
[ValidateAntiForgeryToken]
|
|
[AreaSecurity(area = Areas.Projects, level = AccessLevel.Write)]
|
|
public ActionResult Delete(ProjectModel model)
|
|
{
|
|
if (ContentLocker.IsLock("Project", model.Id.ToString(), User.Identity.GetUserName()))
|
|
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
|
|
if (!SecurityManager.CheckProjectPermission(model.Id, AccessLevel.Write))
|
|
return RedirectToAccessDenied();
|
|
var noteMan = new NoteManager(this.DbContext);
|
|
var manager = new ProjectManager(DbContext);
|
|
var dbObj = manager.Load(model.Id, false);
|
|
if (dbObj == null)
|
|
return HttpNotFound();
|
|
|
|
IList<Guid> holders = manager.GetSubprojectsAndParts(dbObj);
|
|
FileManager fileMngr = new FileManager(DbContext);
|
|
fileMngr.QueuePermanentFilesToDelete(holders);
|
|
|
|
foreach (var s in dbObj.Scenarios)
|
|
{
|
|
noteMan.RemoveNotesForDomain(s.Id);
|
|
}
|
|
var type = DbContext.Types.FirstOrDefault(x => x.Id == dbObj.TypeId && x.NotifyOnProjectDelete == true);
|
|
var status = DbContext.Status.FirstOrDefault(x => x.Id == dbObj.StatusId && x.NotifyOnProjectDelete == true);
|
|
(DbContext as IObjectContextAdapter).ObjectContext.ExecuteStoreCommand(string.Format("exec sp_DeleteProject '{0}'", dbObj.Id));
|
|
DbContext.SaveChanges();
|
|
if (type != null || status != null)
|
|
(new NotificationManager(null)).SendProjectChangeNotifications(dbObj, type, status, EntityState.Deleted, null);
|
|
fileMngr.DeleteQueuedFiles(true);
|
|
|
|
ContentLocker.RemoveLock("Project", dbObj.Id.ToString(), User.Identity.GetUserName());
|
|
return RedirectToAction("Index");
|
|
}
|
|
|
|
[HttpGet]
|
|
[AreaSecurity(area = Areas.ImportActuals, level = AccessLevel.Read)]
|
|
public ActionResult ImportActuals(Guid? id)
|
|
{
|
|
ImportActualsModel model = null;
|
|
return View(model);
|
|
}
|
|
|
|
// POST: /Project/Import/5
|
|
[HttpPost, ActionName("ImportActuals")]
|
|
[AreaSecurity(area = Areas.ImportActuals, level = AccessLevel.Write)]
|
|
public ActionResult ImportActuals(ImportActualsModel model, HttpPostedFileBase fileUpload)
|
|
{
|
|
if (model == null || model.Id == Guid.Empty)
|
|
{
|
|
var file = fileUpload;
|
|
|
|
if (file == null || file.ContentLength < 1)
|
|
{
|
|
ModelState.AddModelError("", @"File was not loaded");
|
|
return View();
|
|
}
|
|
|
|
using (var reader = new StreamReader(file.InputStream))
|
|
{
|
|
try
|
|
{
|
|
var engine = new FileHelperEngine<EnVisage.Code.ActualsImportRow>();
|
|
ActualsImportRow[] dataRead = engine.ReadStream(reader);
|
|
var importer = new ImportActuals();
|
|
string log = string.Empty;
|
|
model = importer.ProcessImport(dataRead, Request["firstRowHeaders"] == "on", Request["zeroOut"] == "on", Request["uomHours"] == "on", User.Identity.GetUserName(), out log);
|
|
ViewBag.ImportResult = model.ImportSuccessful;
|
|
ViewBag.ImportLog = log;
|
|
return View(model);
|
|
}
|
|
catch (Exception c)
|
|
{
|
|
LogException(c);
|
|
ModelState.AddModelError("", c.Message);
|
|
return View(model);
|
|
}
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
string log;
|
|
var importer = new ImportActuals();
|
|
var result = importer.CommitImport(model, User.Identity.GetUserName(), out log);
|
|
//ViewBag.ImportResult = result;
|
|
ViewBag.ComletedImport = result;
|
|
ViewBag.ImportLog = log;
|
|
return View(model);
|
|
}
|
|
}
|
|
|
|
[HttpPost]
|
|
[AreaSecurity(area = Areas.Projects, level = AccessLevel.Write)]
|
|
public ActionResult AddNote(NoteModel model)
|
|
{
|
|
//if (model.ScenarioId != Guid.Empty && ContentLocker.IsLock("Scenarios", model.ScenarioId.ToString(), User.Identity.GetUserName()))
|
|
// return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
|
|
model.TrimStringProperties();
|
|
if (ModelState.IsValid)
|
|
{
|
|
try
|
|
{
|
|
using (var noteManager = new NoteManager())
|
|
{
|
|
model.NoteType = NoteType.Project.GetHashCode();
|
|
model.Id = Guid.NewGuid();
|
|
noteManager.Save(model);
|
|
}
|
|
}
|
|
catch (BLLException blEx) // handle any system specific error
|
|
{
|
|
// display error message if required
|
|
if (blEx.DisplayError)
|
|
ModelState.AddModelError(string.Empty, blEx.Message);
|
|
else // if display not requried then display modal form with general error message
|
|
{
|
|
LogException(blEx);
|
|
SetErrorScript();
|
|
}
|
|
}
|
|
catch (Exception exception) // handle any unexpected error
|
|
{
|
|
LogException(exception);
|
|
SetErrorScript();
|
|
}
|
|
}
|
|
UriBuilder builder = new UriBuilder(HttpContext.Request.UrlReferrer);
|
|
var query = HttpUtility.ParseQueryString(builder.Query);
|
|
query["ptab"] = "notes";
|
|
builder.Query = query.ToString();
|
|
var url = builder.Path + builder.Query;
|
|
if (Url.IsLocalUrl(url))
|
|
return Redirect(url);
|
|
return Redirect("/");
|
|
|
|
}
|
|
|
|
[HttpPost]
|
|
[AreaSecurity(area = Areas.Projects, level = AccessLevel.Write)]
|
|
public ActionResult EditNote(NoteModel model)
|
|
{
|
|
//if (model.ScenarioId != Guid.Empty && ContentLocker.IsLock("Scenarios", model.ScenarioId.ToString(), User.Identity.GetUserName()))
|
|
// return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
|
|
model.TrimStringProperties();
|
|
if (ModelState.IsValid)
|
|
{
|
|
try
|
|
{
|
|
using (var noteManager = new NoteManager())
|
|
{
|
|
var note = noteManager.Load(model.Id);
|
|
if (note == null) return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
|
|
model.NoteType = NoteType.Project.GetHashCode();
|
|
noteManager.Save(model);
|
|
|
|
}
|
|
}
|
|
catch (BLLException blEx) // handle any system specific error
|
|
{
|
|
// display error message if required
|
|
if (blEx.DisplayError)
|
|
ModelState.AddModelError(string.Empty, blEx.Message);
|
|
else // if display not requried then display modal form with general error message
|
|
{
|
|
LogException(blEx);
|
|
SetErrorScript();
|
|
}
|
|
}
|
|
catch (Exception exception) // handle any unexpected error
|
|
{
|
|
LogException(exception);
|
|
SetErrorScript();
|
|
}
|
|
}
|
|
UriBuilder builder = new UriBuilder(HttpContext.Request.UrlReferrer);
|
|
var query = HttpUtility.ParseQueryString(builder.Query);
|
|
query["ptab"] = "notes";
|
|
builder.Query = query.ToString();
|
|
var url = builder.Path + builder.Query;
|
|
return Redirect(Url.IsLocalUrl(url) ? url : "/");
|
|
}
|
|
|
|
// GET: /User/Edit/5
|
|
[AreaSecurity(area = Areas.Projects, level = AccessLevel.Write)]
|
|
public ActionResult DeleteNote(string Id)
|
|
{
|
|
if (string.IsNullOrEmpty(Id) || Id == "JSVar")
|
|
{
|
|
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
}
|
|
var noteId = new Guid(Id);
|
|
|
|
using (var noteManager = new NoteManager())
|
|
{
|
|
var note = noteManager.Load(noteId);
|
|
if (note == null) return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
noteManager.Delete(noteId);
|
|
}
|
|
|
|
|
|
var url = HttpContext.Request.UrlReferrer.PathAndQuery;
|
|
if (Url.IsLocalUrl(url))
|
|
return Redirect(url);
|
|
return Redirect("/");
|
|
}
|
|
|
|
// GET: /User/Edit/5
|
|
[AreaSecurity(area = Areas.Projects, level = AccessLevel.Write)]
|
|
public ActionResult EditNote(string Id)
|
|
{
|
|
if (string.IsNullOrEmpty(Id) || Id == "JSVar")
|
|
{
|
|
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
}
|
|
var noteId = new Guid(Id);
|
|
var note = (from c in DbContext.Notes where c.Id == noteId select c).FirstOrDefault();
|
|
if (note == null) return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
return PartialView("_addNote", (NoteModel)note);
|
|
}
|
|
// GET: /User/Edit/5
|
|
[AreaSecurity(area = Areas.Projects, level = AccessLevel.Write)]
|
|
public ActionResult AddNote(string Id)
|
|
{
|
|
if (string.IsNullOrEmpty(Id))
|
|
{
|
|
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
}
|
|
var parentId = new Guid(Id);
|
|
return PartialView("_addNote", new NoteModel(parentId));
|
|
}
|
|
|
|
[HttpGet]
|
|
public JsonResult LoadExternalContacts(Guid? clientId, string selectControlId)
|
|
{
|
|
return Json(new
|
|
{
|
|
contacts = LoadContacts(clientId),
|
|
selectControlId
|
|
}
|
|
, JsonRequestBehavior.AllowGet);
|
|
}
|
|
|
|
[HttpGet]
|
|
public JsonResult LoadInternalContacts(Guid? companyId, string selectControlId)
|
|
{
|
|
return Json(new
|
|
{
|
|
contacts = LoadContacts(companyId),
|
|
selectControlId
|
|
}
|
|
, JsonRequestBehavior.AllowGet);
|
|
}
|
|
|
|
[HttpGet]
|
|
public JsonResult LoadCompanyGoals(Guid? companyId, string selectControlId)
|
|
{
|
|
return Json(new
|
|
{
|
|
goals = Utils.GetStrategicGoals(companyId),
|
|
selectControlId
|
|
}
|
|
, JsonRequestBehavior.AllowGet);
|
|
}
|
|
|
|
[HttpPost]
|
|
public async Task<ActionResult> GetProjectEvents([DataSourceRequest]Kendo.Mvc.UI.DataSourceRequest request, Guid entityId)
|
|
{
|
|
try
|
|
{
|
|
string orderBy = "DateCreated";
|
|
var isOrderAsc = false;
|
|
if (request.Sorts.Any())
|
|
{
|
|
orderBy = request.Sorts.First().Member;
|
|
isOrderAsc = request.Sorts.First().SortDirection == ListSortDirection.Ascending;
|
|
}
|
|
|
|
var eventsData = await ProjectManager.GetProjectEvents(entityId, request.PageSize,
|
|
(request.Page - 1) * request.PageSize, orderBy, isOrderAsc);
|
|
return new SuccessContentJsonResult(Json(eventsData, JsonRequestBehavior.AllowGet));
|
|
}
|
|
catch (BLLException blEx) // handle any system specific error
|
|
{
|
|
// display error message if required
|
|
if (blEx.DisplayError)
|
|
ModelState.AddModelError(string.Empty, blEx.Message);
|
|
else // if display not requried then display modal form with general error message
|
|
{
|
|
LogException(blEx);
|
|
ModelState.AddModelError(string.Empty, @"Cannot validate project dependencies. Try again later.");
|
|
}
|
|
}
|
|
catch (Exception exception) // handle any unexpected error
|
|
{
|
|
LogException(exception);
|
|
ModelState.AddModelError(string.Empty, @"Cannot validate project dependencies. Try again later.");
|
|
}
|
|
return new FailedJsonResult(ModelState);
|
|
}
|
|
|
|
#region livelink intergration
|
|
[HttpGet]
|
|
public ActionResult Import(string Id)
|
|
{
|
|
var man = new IntegrationManager(this.DbContext);
|
|
var m = man.getModel(IntergrationAccessType.ProjectImport);
|
|
m.ImportControllerName = "Project";
|
|
m.ImportRecordId = Id;
|
|
return string.IsNullOrEmpty(m.UserId) || string.IsNullOrEmpty(m.DecodedPassword) || string.IsNullOrEmpty(m.Url)
|
|
? View(m)
|
|
: Import(m);
|
|
}
|
|
public ActionResult Import(IntegrationConnectionModel m)
|
|
{
|
|
var Id = ImportProject(m);
|
|
return RedirectToAction("Edit", "Project", new { id = Id.ToString() });
|
|
}
|
|
|
|
#endregion
|
|
//function will do autocomplete for project number on the
|
|
//Edit Project page. It returns a list of unused project numbers from the supt_tbl_ProjectIds
|
|
[HttpGet]
|
|
public ActionResult ProjectNumberSearch(string term)
|
|
{
|
|
using (var dbContext = new EnVisageEntities())
|
|
{
|
|
var projectIDs = dbContext.supt_tbl_ProjectIds.AsNoTracking().Where(x => x.ProjectID.StartsWith(term)).OrderBy(p => p.ProjectID);
|
|
|
|
var projects = dbContext.Projects.AsNoTracking().OrderBy(p => p.ProjectNumber);
|
|
var list = from pid in projectIDs
|
|
join d in projects
|
|
on pid.ProjectID equals d.ProjectNumber into output
|
|
from d in output.DefaultIfEmpty()
|
|
where d == null
|
|
select new { pid.ProjectID };
|
|
|
|
return this.Json(list.Select(x => x.ProjectID).ToList(),
|
|
JsonRequestBehavior.AllowGet);
|
|
}
|
|
}
|
|
|
|
|
|
#region Manage project dependencies
|
|
[HttpGet]
|
|
public ActionResult GetDependencies(Guid sessionKey, Guid? id)
|
|
{
|
|
try
|
|
{
|
|
if (!id.HasValue)
|
|
return new HttpNotFoundResult();
|
|
var cachedDependencies = new List<DependencyChainItem>();
|
|
var cache = Session[ProjectManager.EDIT_DEPENDENCY_KEY] as ProjectDependencyCache;
|
|
if (cache != null)
|
|
if (cache.ContainsKey(sessionKey))
|
|
{
|
|
var pageCache = cache[sessionKey];
|
|
if (pageCache != null)
|
|
cachedDependencies = pageCache.Select(t => new DependencyChainItem
|
|
{
|
|
Id = t.Id,
|
|
SourceProjectId = t.SourceProjectId,
|
|
TargetProjectId = t.TargetProjectId,
|
|
Type = t.Type
|
|
}).ToList();
|
|
}
|
|
var manager = new ProjectDependencyManager(DbContext);
|
|
// load dependencies from DB
|
|
var dbRecords = manager.LoadProjectDependencies(new List<Guid> { id.Value });
|
|
// union db records with records from cache
|
|
var mergedRecords = dbRecords.Values.Union(cachedDependencies).Distinct();
|
|
// build UI model for merged collection
|
|
var model = manager.BuildDependencyListModel(id.Value, mergedRecords, SecurityManager.GetUserPrincipal()) ?? new ProjectDependencyListModel();
|
|
//Logger.Debug("ProjectController.GetDependencies ended");
|
|
return Json(model, JsonRequestBehavior.AllowGet);
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
LogException(exception);
|
|
}
|
|
|
|
return new HttpStatusCodeResult(HttpStatusCode.InternalServerError);
|
|
}
|
|
[HttpPost]
|
|
public ActionResult EditDependency(ProjectDependencyModel model)
|
|
{
|
|
if (model == null)
|
|
{
|
|
ModelState.AddModelError(string.Empty, @"Cannot save project dependency. Try again later.");
|
|
return new FailedJsonResult(ModelState);
|
|
}
|
|
model.TrimStringProperties();
|
|
if (ModelState.IsValid)
|
|
{
|
|
try
|
|
{
|
|
Logger.Debug("EditDependency controller method. Model object:");
|
|
var sb = new StringBuilder();
|
|
model.DebugObjectProperties(sb);
|
|
Logger.Debug(sb);
|
|
|
|
var manager = new ProjectDependencyManager(DbContext);
|
|
// if this is a new project then save new item to session
|
|
if (Guid.Empty.Equals(model.SourceProjectId) || Guid.Empty.Equals(model.TargetProjectId))
|
|
{
|
|
if (Guid.Empty.Equals(model.SessionKey))
|
|
{
|
|
Logger.Error("Cannot save project dependency because SessionKey is empty");
|
|
sb = new StringBuilder();
|
|
model.DebugObjectProperties(sb);
|
|
Logger.Debug(sb);
|
|
}
|
|
else
|
|
{
|
|
ProjectDependencyCache cache = null;
|
|
if (Session[ProjectManager.EDIT_DEPENDENCY_KEY] == null)
|
|
{
|
|
cache = new ProjectDependencyCache();
|
|
Session[ProjectManager.EDIT_DEPENDENCY_KEY] = cache;
|
|
}
|
|
if (cache != null && !cache.ContainsKey(model.SessionKey))
|
|
cache.Add(model.SessionKey, new List<ProjectDependencyModel>());
|
|
var pageCache = cache[model.SessionKey];
|
|
var storedItem = pageCache.FirstOrDefault(t => t.Id == model.Id);
|
|
if (storedItem == null)
|
|
pageCache.Add(model);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
manager.Save(model);
|
|
if (model.ResolveConflicts != null)
|
|
manager.ResolveConflicts(model.ResolveConflicts);
|
|
DbContext.SaveChanges();
|
|
}
|
|
return new SuccessJsonResult();
|
|
}
|
|
catch (BLLException blEx) // handle any system specific error
|
|
{
|
|
// display error message if required
|
|
if (blEx.DisplayError)
|
|
ModelState.AddModelError(string.Empty, blEx.Message);
|
|
else // if display not requried then display modal form with general error message
|
|
{
|
|
LogException(blEx);
|
|
ModelState.AddModelError(string.Empty, @"Cannot save project dependency. Try again later.");
|
|
}
|
|
}
|
|
catch (Exception exception) // handle any unexpected error
|
|
{
|
|
LogException(exception);
|
|
ModelState.AddModelError(string.Empty, @"Cannot save project dependency. Try again later.");
|
|
}
|
|
}
|
|
return new FailedJsonResult(ModelState);
|
|
}
|
|
|
|
[HttpPost]
|
|
public ActionResult DeleteDependency(Guid id, Guid sessionKey)
|
|
{
|
|
if (Guid.Empty.Equals(id) || Guid.Empty.Equals(sessionKey))
|
|
{
|
|
ModelState.AddModelError(string.Empty, @"Cannot delete project dependency. Try again later.");
|
|
Logger.Error("Cannot delete project dependency. id={0}, sessionKey={1}", id, sessionKey);
|
|
return new FailedJsonResult(ModelState);
|
|
}
|
|
|
|
try
|
|
{
|
|
var manager = new ProjectDependencyManager(DbContext);
|
|
manager.Delete(id, User.Identity.GetUserId());
|
|
DbContext.SaveChanges();
|
|
return new SuccessJsonResult();
|
|
}
|
|
catch (BLLException blEx) // handle any system specific error
|
|
{
|
|
// display error message if required
|
|
if (blEx.DisplayError)
|
|
ModelState.AddModelError(string.Empty, blEx.Message);
|
|
else // if display not requried then display modal form with general error message
|
|
{
|
|
LogException(blEx);
|
|
ModelState.AddModelError(string.Empty, @"Cannot delete project dependency. Try again later.");
|
|
}
|
|
}
|
|
catch (Exception exception) // handle any unexpected error
|
|
{
|
|
LogException(exception);
|
|
ModelState.AddModelError(string.Empty, @"Cannot delete project dependency. Try again later.");
|
|
}
|
|
return new FailedJsonResult(ModelState);
|
|
}
|
|
|
|
[HttpGet]
|
|
public ActionResult GetProjects(short type, Guid projectId, Guid sessionKey)
|
|
{
|
|
//Logger.Debug("ProjectController.GetProjects started");
|
|
|
|
if (Guid.Empty.Equals(projectId) || Guid.Empty.Equals(sessionKey))
|
|
{
|
|
ModelState.AddModelError(string.Empty, @"Cannot load projects. Try again later.");
|
|
Logger.Error("Cannot load projects. type={0}, projectId={1}, sessionKey={2}", type, projectId, sessionKey);
|
|
return new HttpStatusCodeResult(HttpStatusCode.InternalServerError);
|
|
}
|
|
|
|
try
|
|
{
|
|
var manager = new ProjectDependencyManager(DbContext);
|
|
var result = manager.GetAvailableProjects(projectId, sessionKey, SecurityManager.GetUserPrincipal());
|
|
return Json(result, JsonRequestBehavior.AllowGet);
|
|
//Logger.Debug("ProjectController.GetProjects ended");
|
|
}
|
|
catch (Exception exception) // handle any unexpected error
|
|
{
|
|
LogException(exception);
|
|
}
|
|
//Logger.Debug("ProjectController.GetProjects ended");
|
|
return new HttpStatusCodeResult(HttpStatusCode.InternalServerError);
|
|
}
|
|
|
|
[HttpPost]
|
|
[ValidateJsonAntiForgeryToken]
|
|
public ActionResult ValidateDependencyConflicts(DependencyResolveModel model)
|
|
{
|
|
if (model == null)
|
|
{
|
|
ModelState.AddModelError(string.Empty, @"Cannot save validate project dependency. Try again later.");
|
|
return new FailedJsonResult(ModelState);
|
|
}
|
|
model.TrimStringProperties();
|
|
if (ModelState.IsValid)
|
|
{
|
|
try
|
|
{
|
|
Logger.Debug("ValidateDependencyConflicts controller method. Model object:");
|
|
var sb = new StringBuilder();
|
|
model.DebugObjectProperties(sb);
|
|
Logger.Debug(sb);
|
|
|
|
var manager = new ProjectDependencyManager(DbContext);
|
|
DependencyResolveModel validationResult;
|
|
manager.ValidateProjects(model, out validationResult);
|
|
ModelState.Clear();
|
|
TryValidateModel(validationResult);
|
|
return ModelState.IsValid ? new PartialViewJsonResult(true, null, "~/Views/Shared/EditorTemplates/DependencyResolveModel.cshtml", validationResult, ControllerContext, ViewData, TempData) : new PartialViewJsonResult(false, null, "~/Views/Shared/EditorTemplates/DependencyResolveModel.cshtml", validationResult, ControllerContext, ViewData, TempData);
|
|
}
|
|
catch (BLLException blEx) // handle any system specific error
|
|
{
|
|
// display error message if required
|
|
if (blEx.DisplayError)
|
|
ModelState.AddModelError(string.Empty, blEx.Message);
|
|
else // if display not requried then display modal form with general error message
|
|
{
|
|
LogException(blEx);
|
|
ModelState.AddModelError(string.Empty, @"Cannot validate project dependencies. Try again later.");
|
|
}
|
|
}
|
|
catch (Exception exception) // handle any unexpected error
|
|
{
|
|
LogException(exception);
|
|
ModelState.AddModelError(string.Empty, @"Cannot validate project dependencies. Try again later.");
|
|
}
|
|
}
|
|
return new FailedJsonResult(ModelState);
|
|
}
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
#region Private Methods
|
|
|
|
private string GetActiveScenarioName(Guid ProjectId)
|
|
{
|
|
string name = this.DbContext.Scenarios.Where(x => x.ParentId == ProjectId && x.Type == (int)ScenarioType.Portfolio && x.Status == (int)ScenarioStatus.Active).Select(x => x.Name).FirstOrDefault();
|
|
return string.IsNullOrEmpty(name) ? "" : name;
|
|
}
|
|
private Guid GetActiveScenarioId(Guid projectId)
|
|
{
|
|
return DbContext.Scenarios.Where(x => x.ParentId == projectId && x.Type == (int)ScenarioType.Portfolio && x.Status == (int)ScenarioStatus.Active).Select(x => x.Id).FirstOrDefault();
|
|
}
|
|
|
|
private bool IsPart(Guid projectId)
|
|
{
|
|
return DbContext.Projects.Any(x => x.Id == projectId && x.ParentProjectId != null && x.ParentProjectId != Guid.Empty);
|
|
}
|
|
|
|
private string GetTeamNames(Guid projectId)
|
|
{
|
|
var teams = DbContext.Team2Project.Where(x => x.ProjectId == projectId).Select(x => x.Team.Name).ToList();
|
|
|
|
string rt = "";
|
|
string sep = "";
|
|
if (teams.Count == 0)
|
|
return rt;
|
|
// var teamnames = this.DbContext.Teams.Where(x => teams.Contains(x.Id)).Select(x => x.Name).ToList();
|
|
foreach (var teamname in teams)
|
|
{
|
|
rt += sep + teamname;
|
|
sep = ";";
|
|
}
|
|
return rt;
|
|
}
|
|
private IList<ProjectListModel> GetProjects(int startIndex,
|
|
int pageSize,
|
|
ReadOnlyCollection<SortedColumn> sortedColumns,
|
|
out int totalRecordCount,
|
|
out int searchRecordCount,
|
|
string searchString)
|
|
{
|
|
var userId = SecurityManager.GetUserPrincipal();
|
|
var groupByTeam = UserManager.GetPagePreferencesValue<bool>(Url.Action("Index", "Project"), "projectsTable", "groupByTeam", userId);
|
|
var projectsToDisplay = ProjectManager.GetProjects4User(userId, groupByTeam, sortedColumns[0], startIndex, pageSize, searchString, out totalRecordCount, out searchRecordCount);
|
|
|
|
var projectsIds = projectsToDisplay.Select(x => x.Id);
|
|
var partsIds = projectsToDisplay.Where(x => x.ProjectParts != null).SelectMany(x => x.ProjectParts).Where(x => x != null).Select(x => x.Id);
|
|
var projectsWithPartsIds = projectsIds.Union(partsIds).ToList();
|
|
|
|
var inactiveScenarios =
|
|
DbContext.Scenarios.AsNoTracking()
|
|
.Where(s => s.Type == (int)ScenarioType.Portfolio &&
|
|
s.Status == (int)ScenarioStatus.Inactive &&
|
|
s.ParentId.HasValue &&
|
|
projectsWithPartsIds.Contains(s.ParentId.Value))
|
|
.Select(x => new
|
|
{
|
|
ProjectId = x.ParentId.Value,
|
|
ScenarioId = x.Id,
|
|
ScenarioName = x.Name,
|
|
ScenarioStartDate = x.StartDate,
|
|
ScenarioEndDate = x.EndDate,
|
|
})
|
|
.AsEnumerable()
|
|
.GroupBy(x => x.ProjectId)
|
|
.ToDictionary(x => x.Key, g => g.Select(x => new InactiveScenarioInProjectModel()
|
|
{
|
|
Id = x.ScenarioId,
|
|
Name = x.ScenarioName,
|
|
StartDate = x.ScenarioStartDate.HasValue ? Utils.ConvertToUnixDate(x.ScenarioStartDate.Value) : (long?)null,
|
|
EndDate = x.ScenarioEndDate.HasValue ? Utils.ConvertToUnixDate(x.ScenarioEndDate.Value) : (long?)null,
|
|
}).ToList());
|
|
|
|
foreach (var projItem in projectsToDisplay)
|
|
{
|
|
if (inactiveScenarios.ContainsKey(projItem.Id))
|
|
projItem.InactiveScenarios = inactiveScenarios[projItem.Id];
|
|
|
|
if ((projItem.ProjectParts != null) && projItem.ProjectParts.Count > 0)
|
|
{
|
|
foreach (var projPartItem in projItem.ProjectParts)
|
|
{
|
|
if (inactiveScenarios.ContainsKey(projPartItem.Id))
|
|
projPartItem.InactiveScenarios = inactiveScenarios[projPartItem.Id];
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
return projectsToDisplay;
|
|
}
|
|
|
|
private List<ContactModel> LoadContacts(Guid? parentId)
|
|
{
|
|
if (parentId == null || parentId == Guid.Empty)
|
|
return new List<ContactModel>();
|
|
|
|
return DbContext.Contacts.Where(c => c.ParentId == parentId).OrderBy(c => c.LastName).Select(c => new ContactModel
|
|
{
|
|
Id = c.Id,
|
|
ParentId = c.ParentId ?? Guid.Empty,
|
|
FirstName = c.FirstName,
|
|
LastName = c.LastName,
|
|
Type = (ContactType)c.Type,
|
|
Email = c.Email,
|
|
}).ToList();
|
|
}
|
|
private Guid ImportProject(IntegrationConnectionModel m)
|
|
{
|
|
var importMan = new IntegrationManager(DbContext);
|
|
var model2Save = importMan.ImportProjectFromAPI(IntergrationAccessType.ProjectImport, m, m.ImportRecordId);
|
|
var pman = new ProjectManager(DbContext);
|
|
var newProject = pman.Save(model2Save);
|
|
DbContext.SaveChanges();
|
|
|
|
var partIds = DbContext.Projects.Where(t => t.ParentProjectId.HasValue && t.ParentProjectId.Value == newProject.Id).Select(t => t.Id).ToArray();
|
|
//Give user Full Access permissions to the new project
|
|
var teamIds = new List<Guid>();
|
|
|
|
foreach (var part in model2Save.Parts)
|
|
{
|
|
if (part.AssignedTeams != null)
|
|
teamIds.AddRange(part.AssignedTeams);
|
|
}
|
|
|
|
var existingUsersPermissions =
|
|
DbContext.ProjectAccesses.Where(t => partIds.Contains(t.ProjectId) || t.ProjectId == newProject.Id)
|
|
.Select(t => new { t.ProjectId, t.PrincipalId }).ToList();
|
|
|
|
var users = DbContext.User2Team.Where(c => teamIds.Contains(c.TeamId)).Select(c => c.UserId).Distinct().ToList();
|
|
|
|
if (!users.Contains(User.Identity.GetID(), StringComparer.OrdinalIgnoreCase))
|
|
users.Add(User.Identity.GetID());
|
|
|
|
foreach (var contributor in users)
|
|
{
|
|
if (!existingUsersPermissions.Any(t => t.PrincipalId == new Guid(contributor) && t.ProjectId == newProject.Id))
|
|
{
|
|
DbContext.ProjectAccesses.Add(new ProjectAccess()
|
|
{
|
|
PrincipalId = new Guid(contributor),
|
|
ProjectId = newProject.Id,
|
|
Read = 1,
|
|
Write = 1
|
|
});
|
|
}
|
|
foreach (var partId in partIds)
|
|
{
|
|
if (!existingUsersPermissions.Any(t => t.PrincipalId == new Guid(contributor) && t.ProjectId == partId))
|
|
{
|
|
DbContext.ProjectAccesses.Add(new ProjectAccess()
|
|
{
|
|
PrincipalId = new Guid(contributor),
|
|
ProjectId = partId,
|
|
Read = 1,
|
|
Write = 1
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
return newProject.Id;
|
|
}
|
|
|
|
private void DoWorkFlowAction(WorkFlowCommandModel cmd, Guid scenarioId, Guid userid)
|
|
{
|
|
|
|
if (cmd != null)
|
|
{
|
|
WorkFlowManager wfman = new WorkFlowManager(DbContext);
|
|
wfman.ExecuteCommand(scenarioId, cmd.CommandName, userid);
|
|
}
|
|
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
} |