EnVisageOnline/Main-RMO/Source/EnVisage/Controllers/PeopleResourceController.cs

561 lines
24 KiB
C#

using EnVisage.App_Start;
using EnVisage.Code.BLL;
using EnVisage.Code.HtmlHelpers;
using EnVisage.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using EnVisage.Code;
using System.Net;
using jQuery.DataTables.Mvc;
using Microsoft.AspNet.Identity;
namespace EnVisage.Controllers
{
public class PeopleResourceController : BaseController
{
private PeopleResourcesManager _manager = null;
public PeopleResourcesManager Manager
{
get { return _manager ?? (_manager = new PeopleResourcesManager(DbContext)); }
}
// GET: Resource
[AreaSecurityAttribute(area = Areas.Resources, level = AccessLevel.Read)]
public ActionResult Index()
{
return View(DbContext.Teams.AsNoTracking().ToList());
}
[HttpPost]
[AreaSecurityAttribute(area = Areas.Resources, level = AccessLevel.Read)]
public JsonResult Index(JQueryDataTablesModel jQueryDataTablesModel)
{
var resources = Manager.GetResources();
return this.DataTablesJson(items: resources,
totalRecords: resources.Count,
totalDisplayRecords: resources.Count,
sEcho: jQueryDataTablesModel.sEcho);
}
[AreaSecurityAttribute(area = Areas.Resources, level = AccessLevel.Read)]
public ActionResult Details(Guid? resourceId)
{
if (!resourceId.HasValue)
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
var model = (PeopleResourceModel)Manager.Load(resourceId);
if (SecurityManager.CheckSecurityObjectPermission(Areas.Vacations, AccessLevel.Read))
model.Vacations = VacationManager.GetVacations(model.Id);
if (SecurityManager.CheckSecurityObjectPermission(Areas.Trainings, AccessLevel.Read))
model.Trainings = TrainingManager.GetTrainings(model.Id);
model.Training.Resources = new List<Guid>() { resourceId.Value };
var maxdate = (from c in DbContext.FiscalCalendars where c.Type == 0 orderby c.StartDate descending select c.EndDate).FirstOrDefault();
if (model.EndDate == maxdate)
model.PermanentResource = true;
return View(model);
}
[HttpGet]
//[ValidateAntiForgeryToken]
[AreaSecurityAttribute(area = Areas.Trainings, level = AccessLevel.Write)]
public ActionResult LoadTraining(Guid? Id, Guid resourceId)
{
#region Week Ending Day system setting
var weekEndingSetting = DbContext.SystemSettings.FirstOrDefault(t => t.Type == (int)SystemSettingType.FiscalCalendarWeekEnding);
var weekEndingDay = weekEndingSetting != null
? (DayOfWeek)Convert.ToInt16(weekEndingSetting.Value)
: DayOfWeek.Saturday;
#endregion
if (Id.HasValue)
{
var manager = new TrainingManager(DbContext);
TrainingModel model = (TrainingModel)manager.Load(Id, false);
model.WeekendingDay = (short)weekEndingDay;
return PartialView("_scheduleTraining", model);
}
else {
return PartialView("_scheduleTraining", new TrainingModel() {
TrainingStartDate = DateTime.Now,
TrainingEndDate = DateTime.Now.AddDays(14),
Resources = new List<Guid>() { resourceId },
TrainingCost = 0,
TrainingTimeAllocated = 0,
WeekendingDay = (short)weekEndingDay
});
}
}
[HttpPost]
[ValidateAntiForgeryToken]
[AreaSecurityAttribute(area = Areas.Trainings, level = AccessLevel.Write)]
public ActionResult DeleteTraining(Guid deleteTrainingId, Guid Id)
{
if (ContentLocker.IsLock("Trainings", deleteTrainingId.ToString(), User.Identity.Name))
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
var manager = new TrainingManager(DbContext);
var dbObj = manager.Load(deleteTrainingId, false);
if (dbObj == null)
return HttpNotFound();
DbContext.PeopleResourceTrainings.RemoveRange(DbContext.PeopleResourceTrainings.Where(t => t.TrainingId == dbObj.Id));
DbContext.Trainings.Remove(dbObj);
DbContext.SaveChanges();
ContentLocker.RemoveLock("Trainings", dbObj.Id.ToString(), User.Identity.Name);
return RedirectToAction("Details", "PeopleResource", new { resourceId = Id });
}
[HttpPost]
[ValidateAntiForgeryToken]
[AreaSecurityAttribute(area = Areas.Trainings, level = AccessLevel.Write)]
public ActionResult ScheduleTraining(TrainingModel model)
{
if (model == null || ContentLocker.IsLock("Trainings", model.Id.ToString(), User.Identity.Name))
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
model.TrimStringProperties();
if (ModelState.IsValid)
{
try
{
//var redirectId = model.Id;
//model.Id = Guid.Empty;
//model.PeopleResourceTrainings = model.Resources.Select(x => new PeopleResourceTrainingModel() { Id = x }).ToList();
var manager = new TrainingManager(DbContext);
manager.Save(model);
DbContext.SaveChanges();
ContentLocker.RemoveLock("Trainings", model.Id.ToString(), User.Identity.Name);
//return RedirectToAction("Details", "PeopleResource", new { resourceId = redirectId });
//return Redirect(HttpContext.Request.UrlReferrer.AbsoluteUri);
return PartialView("_scheduleTraining", 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();
ModelState.AddModelError(string.Empty, "Cannot save expedenture categories. Try again later.");
}
}
catch (Exception exception) // handle any unexpected error
{
LogException(exception);
//SetErrorScript();
ModelState.AddModelError(string.Empty, "Cannot save expedenture categories. Try again later.");
}
}
HttpContext.Response.StatusCode = 500;
HttpContext.Response.Clear();
//return Redirect(HttpContext.Request.UrlReferrer.AbsoluteUri);
return PartialView("_scheduleTraining", model);
}
[HttpGet]
[AreaSecurityAttribute(area = Areas.Vacations, level = AccessLevel.Write)]
public ActionResult EditVacation(Guid? id, Guid? peopleResourceId)
{
if ((id == null || id == Guid.Empty) && (peopleResourceId == null || peopleResourceId == Guid.Empty))
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
var manager = new VacationManager(DbContext);
var model = id == null || Guid.Empty.Equals(id) ? new VacationModel() : (VacationModel)manager.Load(id) ?? new VacationModel();
if (Guid.Empty.Equals(model.Id) && peopleResourceId != null)
model.PeopleResourceId = peopleResourceId.Value;
#region Load Unit of Measure Value
var uomRecord = (from p in DbContext.PeopleResources
join ec in DbContext.ExpenditureCategory on p.ExpenditureCategoryId equals ec.Id
join uom in DbContext.UOMs on ec.UOMId equals uom.Id
where p.Id == model.PeopleResourceId
select new { uom.Id, uom.UOMValue }).FirstOrDefault();
if (uomRecord == null || uomRecord.UOMValue == 0)
throw new UOMNotExistsException();
if (Guid.Empty.Equals(model.Id) && peopleResourceId != null)
model.HoursOff = 100;
model.UOMValue = uomRecord.UOMValue;
#endregion
#region Week Ending Day system setting
var weekEndingSetting = DbContext.SystemSettings.FirstOrDefault(t => t.Type == (int)SystemSettingType.FiscalCalendarWeekEnding);
var weekEndingDay = weekEndingSetting != null
? (DayOfWeek)Convert.ToInt16(weekEndingSetting.Value)
: DayOfWeek.Saturday;
model.WeekendingDay = (short)weekEndingDay;
#endregion
return View(model);
}
[HttpPost]
[AreaSecurityAttribute(area = Areas.Resources, level = AccessLevel.Write)]
public ActionResult EditVacation(VacationModel model)
{
if (model == null || ContentLocker.IsLock("Vacations", model.Id.ToString(), User.Identity.Name))
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
model.TrimStringProperties();
if (ModelState.IsValid)
{
try
{
var manager = new VacationManager(DbContext);
manager.Save(model);
DbContext.SaveChanges();
ContentLocker.RemoveLock("Vacations", model.Id.ToString(), User.Identity.Name);
return model.ParentViewId.HasValue ? RedirectToAction("Details", "PeopleResource", new { resourceId = model.PeopleResourceId, viewId = model.ParentViewId.Value }) : RedirectToAction("Details", "PeopleResource", new { resourceId = model.PeopleResourceId });
}
catch (BLLException blEx)
{
if (blEx.DisplayError)
SetErrorScript(message: blEx.Message);
else
{
LogException(blEx);
SetErrorScript();
}
}
catch (Exception exception)
{
LogException(exception);
SetErrorScript();
}
}
return View(model);
}
[HttpPost]
[AreaSecurityAttribute(area = Areas.Resources, level = AccessLevel.Write)]
public ActionResult Details(PeopleResourceModel model)
{
model.TrimStringProperties();
if (ModelState.IsValid)
{
try
{
Manager.Save(model);
DbContext.SaveChanges();
return RedirectToAction("Index");
}
catch (BLLException blEx)
{
if (blEx.DisplayError)
SetErrorScript(message: blEx.Message);
else
{
LogException(blEx);
SetErrorScript();
}
}
catch (Exception exception)
{
LogException(exception);
SetErrorScript();
}
}
return View(model);
}
[AreaSecurityAttribute(area = Areas.Resources, level = AccessLevel.Write)]
public ActionResult Edit(Guid? resourceId, Guid? teamId, Guid? categoryId, bool? noAdjust)
{
var model = new PeopleResourceModel();
if (resourceId.HasValue && (resourceId != Guid.Empty))
model = (PeopleResourceModel)Manager.Load(resourceId);
else
{
if (teamId.HasValue && teamId.Value != Guid.Empty)
model.TeamId = teamId.Value;
if (categoryId.HasValue && categoryId.Value != Guid.Empty)
model.ExpenditureCategoryId = categoryId.Value;
if(noAdjust.HasValue && noAdjust.Value == true)
model.ChangeCapacity = false;
else
model.ChangeCapacity = true;
}
var maxdate = (from c in DbContext.FiscalCalendars where c.Type == 0 orderby c.StartDate descending select c.EndDate).FirstOrDefault();
if (model.EndDate == maxdate)
model.PermanentResource = true;
ViewBag.TeamsList = Utils.GetTeamsAvailableForUser(Guid.Parse(User.Identity.GetID()));
ViewBag.ExpendituresList = Utils.GetResourceExpendituresList(model.ExpenditureCategory != null ? model.ExpenditureCategory.Id : Guid.Empty);
return View(model);
}
[HttpPost]
[AreaSecurityAttribute(area = Areas.Resources, level = AccessLevel.Write)]
public ActionResult Edit(PeopleResourceModel model, Guid[] expCatId, string[] expCatName, string[] expCatGroup,
bool[] expCatChecked)
{
if (model == null || ContentLocker.IsLock("PeopleResource", model.Id.ToString(), User.Identity.Name))
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
model.TrimStringProperties();
if (ModelState.IsValid)
{
try
{
if (model.PermanentResource)
{
var maxdate = (from c in DbContext.FiscalCalendars where c.Type == 0 orderby c.StartDate descending select c.EndDate).FirstOrDefault();
model.EndDate = maxdate;
}
//Actual capacity change cases: 1. New resource, 2. Resource status change (active/inactive), 3. Resource category change, 4. Resource team change, 5. Start/End date change
//Planned capacity change cases: when actual capacity is changed AND [model.ChangeCapacity] is set
bool newresource = model.Id == Guid.Empty;
bool statuschanged = false;
bool categorychanged = false;
bool teamchanged = false;
bool dateschanged = false;
PeopleResourceModel oldModel = null;
if (model.Id != Guid.Empty)
{
oldModel = (PeopleResourceModel)Manager.Load(model.Id);
statuschanged = model.IsActiveEmployee != oldModel.IsActiveEmployee;
categorychanged = model.ExpenditureCategoryId != oldModel.ExpenditureCategoryId;
teamchanged = model.TeamId != oldModel.TeamId;
dateschanged = model.StartDate != oldModel.StartDate || model.EndDate != oldModel.EndDate;
}
if (oldModel != null && oldModel.IsActiveEmployee)
{
if (teamchanged || categorychanged || dateschanged || statuschanged)
{
RemoveCapacity(oldModel, false);
if(model.ChangeCapacity)
RemoveCapacity(oldModel, true);
}
}
Manager.Save(model);
if (model.IsActiveEmployee)
{
if (newresource || statuschanged || categorychanged || teamchanged || dateschanged)
{
AddCapacity(model, false);
if(model.ChangeCapacity)
AddCapacity(model, true);
}
}
if (statuschanged && !model.IsActiveEmployee && !model.ReassignOnDeactivation)
{
var allocations = DbContext.PeopleResourceAllocations.Where(x => x.PeopleResourceId == model.Id).ToList();
DbContext.PeopleResourceAllocations.RemoveRange(allocations);
}
DbContext.SaveChanges();
ContentLocker.RemoveLock("PeopleResource", model.Id.ToString(), User.Identity.Name);
if (model.AddMore)
return RedirectToAction("Edit", "PeopleResource", new { @resourceId = Guid.Empty.ToString(), @teamId = model.TeamId });
else
return RedirectToAction("Board", "Team", new { @teamId = model.TeamId });
}
catch (BLLException blEx)
{
if (blEx.DisplayError)
SetErrorScript(message: blEx.Message);
else
{
LogException(blEx);
SetErrorScript();
}
}
catch (Exception exception)
{
LogException(exception);
SetErrorScript();
}
}
ViewBag.TeamsList = Utils.GetTeamsAvailableForUser(Guid.Parse(User.Identity.GetID()));
ViewBag.ExpendituresList = Utils.GetResourceExpendituresList(model.ExpenditureCategory != null ? model.ExpenditureCategory.Id : Guid.Empty);
return View(model);
}
public void AddCapacity(PeopleResourceModel model, bool isPlanned)
{
var weekendings = (from c in DbContext.FiscalCalendars.AsNoTracking() where c.Type == 0 && c.StartDate >= model.StartDate && c.AdjustingPeriod == false && c.NonWorking == 0 orderby c.StartDate select c.EndDate).ToArray();
var teamManager = new TeamManager(DbContext);
var team = teamManager.Load(model.TeamId);
Guid? parentId = isPlanned ? team.PlannedCapacityScenarioId : team.ActualCapacityScenarioId;
var capacityDetails = (from sd in DbContext.ScenarioDetail where sd.ParentID == parentId && sd.ExpenditureCategoryId == model.ExpenditureCategoryId && weekendings.Contains(sd.WeekEndingDate.Value) select sd).ToDictionary(x => x.WeekEndingDate, x => x);
foreach (var week in weekendings)
{
PeopleResourceModel.CapacityValues vc;
if (model.WeeklyCapacities.ContainsKey(week))
vc = model.WeeklyCapacities[week];
else
continue;
var capacityWeek = capacityDetails.ContainsKey(week) ? capacityDetails[week] : null;
if (capacityWeek != null)
{
capacityWeek.Quantity += vc.Quantity;
capacityWeek.Cost += vc.Cost;
DbContext.Entry(capacityWeek).State = System.Data.Entity.EntityState.Modified;
}
else
{
var newSd = new ScenarioDetail
{
Id = Guid.NewGuid(),
ParentID = (isPlanned) ? team.PlannedCapacityScenarioId : team.ActualCapacityScenarioId,
Quantity = vc.Quantity,
Cost = vc.Cost,
ExpenditureCategoryId = model.ExpenditureCategoryId,
WeekEndingDate = week,
WeekOrdinal = 0
};
DbContext.ScenarioDetail.Add(newSd);
}
}
DbContext.SaveChanges();
}
public void RemoveCapacity(PeopleResourceModel model, bool IsPlanned)
{
var weekendings = (from c in DbContext.FiscalCalendars.AsNoTracking() where c.Type == 0 && c.StartDate >= model.StartDate && c.AdjustingPeriod == false && c.NonWorking == 0 orderby c.StartDate select c.EndDate).ToArray();
var teamManager = new TeamManager(DbContext);
var team = teamManager.Load(model.TeamId);
Guid? ParentId;
if (IsPlanned) ParentId = team.PlannedCapacityScenarioId;
else ParentId = team.ActualCapacityScenarioId;
var sds = (from sd in DbContext.ScenarioDetail where sd.ParentID == ParentId && sd.ExpenditureCategoryId == model.ExpenditureCategoryId && weekendings.Contains(sd.WeekEndingDate.Value) select sd).ToDictionary(x => x.WeekEndingDate, x => x);
foreach (var week in weekendings)
{
if (!sds.ContainsKey(week)) continue;
var sd = sds[week];
PeopleResourceModel.CapacityValues vc = null;
if (model.WeeklyCapacities.ContainsKey(week))
vc = model.WeeklyCapacities[week];
else continue;
if (sd != null)
{
sd.Quantity -= vc.Quantity;
if (sd.Quantity < 0) sd.Quantity = 0;
sd.Cost -= vc.Cost;
if (sd.Cost < 0) sd.Cost = 0;
DbContext.Entry(sd).State = System.Data.Entity.EntityState.Modified;
}
}
DbContext.SaveChanges();
}
[AreaSecurityAttribute(area = Areas.Resources, level = AccessLevel.Write)]
public JsonResult Reassign(PeopleResourceModel model)
{
var projectIds = Request.Form.AllKeys.Where(x => x.Length > 30).Select(x => new Guid(x)).ToArray();
foreach (var projId in projectIds)
{
var scenarioIds = DbContext.Scenarios.Where(x => x.ParentId == projId).Select(x => x.Id).ToList();
var allocations = DbContext.PeopleResourceAllocations.Where(x => scenarioIds.Contains(x.ScenarioId) && x.PeopleResourceId == model.Id).ToList();
if (string.IsNullOrEmpty(Request.Form[projId.ToString()])) continue;
var newResourceId = new Guid(Request.Form[projId.ToString()]);
foreach (var alloc in allocations)
{
alloc.PeopleResourceId = newResourceId;
DbContext.Entry(alloc).State = System.Data.Entity.EntityState.Modified;
}
}
DbContext.SaveChanges();
return Json(new { Result = true, data = "" }, JsonRequestBehavior.AllowGet);
}
[AreaSecurityAttribute(area = Areas.Resources, level = AccessLevel.Write)]
public ActionResult Delete(Guid? resourceId)
{
var model = (PeopleResourceModel)Manager.Load(resourceId);
model.ChangeCapacity = true;
return View(model);
}
[HttpPost]
[AreaSecurityAttribute(area = Areas.Resources, level = AccessLevel.Write)]
public ActionResult Delete(PeopleResourceModel model, Guid? teamId)
{
if (ContentLocker.IsLock("PeopleResource", model.Id.ToString(), User.Identity.Name))
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
var resource = (PeopleResourceModel)Manager.Load(model.Id);
var id = resource.Id;
RemoveCapacity(resource, false);
if (model.ChangeCapacity)
RemoveCapacity(resource, true);
Manager.DeleteResource(model.Id);
ContentLocker.RemoveLock("PeopleResource", id.ToString(), User.Identity.Name);
return RedirectToAction("Board", "Team", new { @teamId = teamId.Value });
}
[HttpGet]
[AreaSecurityAttribute(area = Areas.Vacations, level = AccessLevel.Write)]
public ActionResult DeleteVacation(Guid? id)
{
if (id == null || id == Guid.Empty)
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
var model = new VacationModel();
try
{
var manager = new VacationManager(DbContext);
model = (VacationModel)manager.Load(id);
if (model == null)
return HttpNotFound();
}
catch (BLLException blEx)
{
if (blEx.DisplayError)
SetErrorScript(message: blEx.Message);
else
{
LogException(blEx);
SetErrorScript();
}
}
catch (Exception exception)
{
LogException(exception);
SetErrorScript();
}
return View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
[AreaSecurityAttribute(area = Areas.Vacations, level = AccessLevel.Write)]
public ActionResult DeleteVacation(VacationModel model, string viewId)
{
if (ContentLocker.IsLock("Vacations", model.Id.ToString(), User.Identity.Name))
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
var manager = new VacationManager(DbContext);
var dbObj = manager.Load(model.Id, false);
if (dbObj == null)
return HttpNotFound();
DbContext.PeopleResourceVacations.RemoveRange(DbContext.PeopleResourceVacations.Where(t => t.VacationId == dbObj.Id));
DbContext.Vacations.Remove(dbObj);
DbContext.SaveChanges();
ContentLocker.RemoveLock("Vacations", dbObj.Id.ToString(), User.Identity.Name);
return !string.IsNullOrEmpty(viewId) ? RedirectToAction("Details", "PeopleResource", new { resourceId = model.PeopleResourceId, viewId = viewId }) : RedirectToAction("Details", "PeopleResource", new { resourceId = model.PeopleResourceId });
}
}
}