EnVisageOnline/Main/Source/EnVisage/Controllers/CapacityManagementControlle...

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
}
}