351 lines
16 KiB
C#
351 lines
16 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Web.Mvc;
|
|
using EnVisage.Code;
|
|
using EnVisage.Code.BLL;
|
|
using EnVisage.Models;
|
|
using System.Text;
|
|
using Resources;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace EnVisage.Controllers
|
|
{
|
|
|
|
[Authorize]
|
|
public class CapacityManagementController : BaseController
|
|
{
|
|
#region Actions
|
|
public ActionResult ExportToPDF()
|
|
{
|
|
PDFExporter exporter = new PDFExporter { BrowserWidth = 2560 };
|
|
byte[] pdfBuffer = exporter.ExportPage(Url.Action("Index", "CapacityManagement", null, this.Request.Url.Scheme), 5, true, Request.Cookies);
|
|
|
|
// send the PDF file to browser
|
|
FileResult fileResult = new FileContentResult(pdfBuffer, "application/pdf");
|
|
fileResult.FileDownloadName = "Prevu-ActivityCalendar-" + DateTime.Today.Month + "-" + DateTime.Today.Day + ".pdf";
|
|
|
|
return fileResult;
|
|
}
|
|
|
|
[HttpGet]
|
|
[AreaSecurity(area = Areas.ActivityCalendar, level = AccessLevel.Read)]
|
|
public ActionResult Index(Guid? id)
|
|
{
|
|
var model = new CapacityPageInitOption();
|
|
if (id.HasValue && !Guid.Empty.Equals(id))
|
|
{
|
|
var foundEntity = DbContext.BLL_Objects.FirstOrDefault(x => x.Id.Equals(id.Value));
|
|
if (foundEntity != null)
|
|
{
|
|
// Get entity type
|
|
string entityTypeName = foundEntity.EntityName;
|
|
if (entityTypeName == "Company")
|
|
{
|
|
model.EntityType = CapacityPageInitOption.CalendarEntityType.Company;
|
|
model.EntityId = id.Value;
|
|
}
|
|
if (entityTypeName == "View")
|
|
{
|
|
model.EntityType = CapacityPageInitOption.CalendarEntityType.View;
|
|
model.EntityId = id.Value;
|
|
}
|
|
if (entityTypeName == "Team")
|
|
{
|
|
model.EntityType = CapacityPageInitOption.CalendarEntityType.Team;
|
|
model.EntityId = id.Value;
|
|
}
|
|
if (entityTypeName == "Resource")
|
|
{
|
|
model.EntityType = CapacityPageInitOption.CalendarEntityType.Resource;
|
|
model.EntityId = id.Value;
|
|
}
|
|
}
|
|
}
|
|
return View(model);
|
|
}
|
|
|
|
[HttpPost]
|
|
[ValidateJsonAntiForgeryToken]
|
|
public ActionResult SaveChanges(ActivityCalendarSaveModel model)
|
|
{
|
|
#if DEBUG
|
|
var watch1 = new System.Diagnostics.Stopwatch();
|
|
watch1.Start();
|
|
Logger.Debug("Start SaveChanges");
|
|
#endif
|
|
|
|
model.TrimStringProperties();
|
|
|
|
#region Debug and tracing
|
|
|
|
var sb = new StringBuilder();
|
|
sb.AppendLine("CapacityManagement.SaveChanges method. model:");
|
|
model.DebugObjectProperties(sb);
|
|
Logger.Debug(sb);
|
|
|
|
#endregion
|
|
|
|
#if DEBUG
|
|
watch1.Stop();
|
|
System.Diagnostics.Debug.WriteLine($"SaveChanges Start has taken {watch1.ElapsedMilliseconds} ms");
|
|
Logger.Debug($"Start SaveChanges {watch1.ElapsedMilliseconds} ms");
|
|
watch1 = new System.Diagnostics.Stopwatch();
|
|
watch1.Start();
|
|
#endif
|
|
|
|
if (ModelState.IsValid)
|
|
{
|
|
try
|
|
{
|
|
// Perform permissions check
|
|
var acManager = (new ActivityCalendarManager(DbContext));
|
|
if (!acManager.ActivityCalendarSavePermitted(model))
|
|
{
|
|
// AC is in Resource Calendar mode. Current user doesn't have necessary permissions
|
|
ModelState.AddModelError(string.Empty, Messages.Common_AccessDenied);
|
|
return new HttpStatusCodeResult(HttpStatusCode.InternalServerError);
|
|
}
|
|
|
|
// Validates incoming data and cleares incorrect data
|
|
var expenditureTypes = acManager.GetExpenditureTypesFromSaveDataModel(model);
|
|
var resourcesTeams = acManager.GetTeamsForResourcesFromSaveDataModel(model);
|
|
var newTeams = acManager.GetNewTeamsFromCalendar(model);
|
|
var modelValidated = acManager.ValidateCalendarSaveDataModel(model, expenditureTypes, resourcesTeams);
|
|
|
|
using (var transaction = DbContext.Database.BeginTransaction())
|
|
{
|
|
var transactionId = DbContext.GetClientConnectionId();
|
|
var userId = SecurityManager.GetUserPrincipal().ToString();
|
|
|
|
try
|
|
{
|
|
//create team add notifications
|
|
var addedTeams = new List<Guid>();
|
|
var wfMan = new WorkFlowManager(DbContext);
|
|
#if DEBUG
|
|
watch1.Stop();
|
|
System.Diagnostics.Debug.WriteLine($"SaveChanges model validation and load has taken {watch1.ElapsedMilliseconds} ms");
|
|
Logger.Debug($"SaveChanges model validation and load {watch1.ElapsedMilliseconds} ms");
|
|
watch1 = new System.Diagnostics.Stopwatch();
|
|
watch1.Start();
|
|
#endif
|
|
|
|
var projectIdScenarioIdDictionary = DbContext.Scenarios.Where(x => newTeams.Keys.Contains(x.Id)).ToDictionary(q => q.ParentId, q => q.Id);
|
|
foreach (var projectIdScenarioId in projectIdScenarioIdDictionary)
|
|
{
|
|
if (!projectIdScenarioId.Key.HasValue)
|
|
continue;
|
|
var wfStates = wfMan.GetProjectStates(projectIdScenarioId.Key.Value);
|
|
//seed state list with NUll so we can loop thru atleast one time and add any notifications that are
|
|
//not bound by state
|
|
wfStates.Add(null);
|
|
foreach (var wfState in wfStates)
|
|
{
|
|
var wfstate = wfState != null && string.IsNullOrEmpty(wfState.state) ? wfState.state : null;
|
|
var teams = newTeams[projectIdScenarioId.Value];
|
|
foreach (var t in teams)
|
|
{
|
|
if (addedTeams.Contains(t))
|
|
continue;
|
|
addedTeams.Add(t);
|
|
var who2 = wfMan.GetContactTeamDetails(t, WorkFlowContactNotificationType.TeamScenarioAdd, wfstate);
|
|
if (who2.Count > 0)
|
|
who2 = who2.Distinct().ToList();
|
|
new NotificationManager(DbContext).CreateTeamAddNotification(who2, projectIdScenarioId.Value, 0, true, wfstate);
|
|
}
|
|
}
|
|
}
|
|
#if DEBUG
|
|
watch1.Stop();
|
|
System.Diagnostics.Debug.WriteLine($"SaveChanges Team Add notificationsn has taken {watch1.ElapsedMilliseconds} ms");
|
|
Logger.Debug($"SaveChanges Team Add notificationsn {watch1.ElapsedMilliseconds} ms");
|
|
watch1 = new System.Diagnostics.Stopwatch();
|
|
watch1.Start();
|
|
#endif
|
|
if (model.SaveAction == SaveAsScenario.New)
|
|
{
|
|
// Make scenario copies
|
|
modelValidated = acManager.CopyScenarios(modelValidated, transactionId);
|
|
DbContext.BulkSaveChanges();
|
|
}
|
|
#if DEBUG
|
|
watch1.Stop();
|
|
System.Diagnostics.Debug.WriteLine($"SaveChanges Copy Scenarios has taken {watch1.ElapsedMilliseconds} ms");
|
|
Logger.Debug($"SaveChanges Copy Scenarios {watch1.ElapsedMilliseconds} ms");
|
|
watch1 = new System.Diagnostics.Stopwatch();
|
|
watch1.Start();
|
|
#endif
|
|
// Update scenarios
|
|
acManager.UpdateScenarios(modelValidated, expenditureTypes, resourcesTeams, transactionId);
|
|
DbContext.BulkSaveChanges();
|
|
#if DEBUG
|
|
watch1.Stop();
|
|
System.Diagnostics.Debug.WriteLine($"SaveChanges Update Scenarios has taken {watch1.ElapsedMilliseconds} ms");
|
|
Logger.Debug($"SaveChanges Update Scenarios All {watch1.ElapsedMilliseconds} ms");
|
|
watch1 = new System.Diagnostics.Stopwatch();
|
|
watch1.Start();
|
|
#endif
|
|
|
|
// Update non-project time
|
|
acManager.UpdateNonProjectTime(modelValidated);
|
|
DbContext.BulkSaveChanges();
|
|
#if DEBUG
|
|
watch1.Stop();
|
|
System.Diagnostics.Debug.WriteLine($"SaveChanges Update Non Project Time has taken {watch1.ElapsedMilliseconds} ms");
|
|
Logger.Debug($"SaveChanges Update Non Project Time {watch1.ElapsedMilliseconds} ms");
|
|
watch1 = new System.Diagnostics.Stopwatch();
|
|
watch1.Start();
|
|
#endif
|
|
transaction.Commit();
|
|
Task.Run(() => AuditProxy.CommitHistoryChanges(transactionId, userId));
|
|
#if DEBUG
|
|
watch1.Stop();
|
|
System.Diagnostics.Debug.WriteLine($"SaveChanges Commit has taken {watch1.ElapsedMilliseconds} ms");
|
|
Logger.Debug($"SaveChanges Commit {watch1.ElapsedMilliseconds} ms");
|
|
#endif
|
|
|
|
Task.Run(() => AuditProxy.CommitEventChanges(transactionId));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
transaction.Rollback();
|
|
AuditProxy.ClearHistoryChanges(transactionId);
|
|
AuditProxy.ClearEventChanges(transactionId);
|
|
LogException(ex);
|
|
|
|
return new HttpStatusCodeResult(HttpStatusCode.InternalServerError);
|
|
}
|
|
}
|
|
|
|
DoWorkFlowAction(model.WorkFlowActions, this.HttpContext.User.Identity.GetID());
|
|
//(new WorkFlowManager(this.DbContext).DoWorkFlowAction(model.WorkFlowActions, this.HttpContext.User.Identity.GetID());
|
|
return new HttpStatusCodeResult(HttpStatusCode.OK);
|
|
}
|
|
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();
|
|
}
|
|
}
|
|
|
|
return new HttpStatusCodeResult(HttpStatusCode.InternalServerError);
|
|
}
|
|
|
|
[HttpPost]
|
|
[ValidateJsonAntiForgeryToken]
|
|
public ActionResult GetActivityCalendar(ActivityCalendarRequestModel model)
|
|
{
|
|
if (model == null)
|
|
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
|
|
try
|
|
{
|
|
var acManager = (new ActivityCalendarManager(DbContext));
|
|
var acModel = acManager.GetActivityCalendarModel(model);
|
|
|
|
return BigJson(acModel);
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
LogException(exception);
|
|
}
|
|
|
|
return new HttpStatusCodeResult(HttpStatusCode.InternalServerError);
|
|
}
|
|
|
|
[HttpPost]
|
|
[ValidateJsonAntiForgeryToken]
|
|
[AreaSecurity(area = Areas.ActivityCalendar, level = AccessLevel.Read)]
|
|
public ActionResult GetFilterOptions()
|
|
{
|
|
try
|
|
{
|
|
string userIdAsText = User.Identity.GetID();
|
|
var userId = Guid.Parse(userIdAsText);
|
|
|
|
var acManager = new ActivityCalendarManager(DbContext);
|
|
var model = acManager.GetActivityCalendarFilterOptions(userId);
|
|
if (model == null)
|
|
throw new InvalidOperationException(Messages.Common_OperationWasTerminatedBecauseModelIsNull);
|
|
|
|
return BigJson(model);
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
LogException(exception);
|
|
}
|
|
|
|
return new HttpStatusCodeResult(HttpStatusCode.InternalServerError);
|
|
}
|
|
|
|
[HttpPost]
|
|
[ValidateJsonAntiForgeryToken]
|
|
public ActionResult GetResourceDetailsRights()
|
|
{
|
|
try
|
|
{
|
|
var model = new
|
|
{
|
|
Read = SecurityManager.CheckSecurityObjectPermission(Areas.RD_ResourceTimeAllocation, AccessLevel.Read),
|
|
Write = SecurityManager.CheckSecurityObjectPermission(Areas.RD_ResourceTimeAllocation, AccessLevel.Write),
|
|
ForecastRead = SecurityManager.CheckSecurityObjectPermission(Areas.RD_ResourceTimeAllocationProjected, AccessLevel.Read),
|
|
ForecastWrite = SecurityManager.CheckSecurityObjectPermission(Areas.RD_ResourceTimeAllocationProjected, AccessLevel.Write),
|
|
ActualsRead = SecurityManager.CheckSecurityObjectPermission(Areas.RD_ResourceTimeAllocationActual, AccessLevel.Read),
|
|
ActualsWrite = SecurityManager.CheckSecurityObjectPermission(Areas.RD_ResourceTimeAllocationActual, AccessLevel.Write),
|
|
};
|
|
|
|
return BigJson(model);
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
LogException(exception);
|
|
}
|
|
|
|
return new HttpStatusCodeResult(HttpStatusCode.InternalServerError);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Private Methods
|
|
|
|
private void DoWorkFlowAction(List<ActivityCalWorkFlowCommand> actions, string userid)
|
|
{
|
|
if (actions != null)
|
|
{
|
|
WorkFlowManager wfman = new WorkFlowManager(DbContext);
|
|
foreach (var wfActions in actions)
|
|
{
|
|
if (wfActions.HasChanges)
|
|
{
|
|
if (wfActions.ScenarioId.HasValue)
|
|
{
|
|
var documentId = wfActions.ScenarioId.Value;
|
|
var cmd = wfActions.Commands.FirstOrDefault(x => x.Selected);
|
|
if (cmd != null)
|
|
{
|
|
wfman.ExecuteCommand(documentId, cmd.command, Guid.Parse(userid));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
}
|