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 (HtmlHelpers.CheckSecurityObjectPermission(null, Areas.Vacations, AccessLevel.Read)) model.Vacations = VacationManager.GetVacations(model.Id); if (HtmlHelpers.CheckSecurityObjectPermission(null, Areas.Trainings, AccessLevel.Read)) model.Trainings = TrainingManager.GetTrainings(model.Id); model.Training.Resources = new List() { resourceId.Value }; return View(model); } [HttpGet] //[ValidateAntiForgeryToken] [AreaSecurityAttribute(area = Areas.Trainings, level = AccessLevel.Write)] public ActionResult LoadTraining(Guid? Id, Guid resourceId) { if (Id.HasValue) { var manager = new TrainingManager(DbContext); TrainingModel model = (TrainingModel)manager.Load(Id, false); return PartialView("_scheduleTraining", model); } else { return PartialView("_scheduleTraining", new TrainingModel() { TrainingStartDate = DateTime.Now, TrainingEndDate = DateTime.Now.AddDays(14), Resources = new List() { resourceId }, TrainingCost = 0, TrainingTimeAllocated = 0 }); } } [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 categoies. Try again later."); } } catch (Exception exception) // handle any unexpected error { LogException(exception); //SetErrorScript(); ModelState.AddModelError(string.Empty, "Cannot save expedenture categoies. Try again later."); } } HttpContext.Response.StatusCode = 500; HttpContext.Response.Clear(); //return Redirect(HttpContext.Request.UrlReferrer.AbsoluteUri); return PartialView("_scheduleTraining", model); } //[HttpPost] //[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 // { // //TrainingModel training = new TrainingModel() // //{ // // Id = Guid.Empty, // // Name = model.TrainingName, // // StartDate = model.TrainingStartDate, // // EndDate = model.TrainingEndDate, // // Cost = model.TrainingCost, // // TypeId = model.TrainingTypeID, // // PeopleResourceTrainings = model.Resources.Select(x => new PeopleResourceTrainingModel() { Id = x}).ToList() // //}; // 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 = model.Id }); // } // catch (BLLException blEx) // { // if (blEx.DisplayError) // SetErrorScript(message: blEx.Message); // else // { // LogException(blEx); // SetErrorScript(); // } // } // catch (Exception exception) // { // LogException(exception); // SetErrorScript(); // } // } // return View(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 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) { if(!resourceId.HasValue) return new HttpStatusCodeResult(HttpStatusCode.BadRequest); var model = new PeopleResourceModel(); if (resourceId != Guid.Empty) model = (PeopleResourceModel)Manager.Load(resourceId); 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.FullTimeResource = true; ViewBag.TeamsList = Utils.GetTeamsList(resourceId); 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 { bool statuschanged = true; bool teamchanged = false; PeopleResourceModel oldModel = null; if (model.Id != Guid.Empty) { oldModel = (PeopleResourceModel)Manager.Load(model.Id); statuschanged = model.IsActiveEmployee != oldModel.IsActiveEmployee; teamchanged = model.TeamId != oldModel.TeamId; } if (model.FullTimeResource) { var maxdate = (from c in DbContext.FiscalCalendars where c.Type == 0 orderby c.StartDate descending select c.EndDate).FirstOrDefault(); model.EndDate = maxdate; } if ((model.ChangeCapacity && model.Id != Guid.Empty && !model.IsActiveEmployee) || (teamchanged && model.ChangeCapacity)) { RemoveCapacity(oldModel); } Manager.Save(model); if ((statuschanged && model.ChangeCapacity && model.IsActiveEmployee) || (teamchanged && model.ChangeCapacity)) AddCapacity(model); DbContext.SaveChanges(); ContentLocker.RemoveLock("PeopleResource", model.Id.ToString(), User.Identity.Name); if (model.AddMore) return RedirectToAction("Edit", "PeopleResource", new { @resourceId = Guid.Empty.ToString() }); else return RedirectToAction("Board", "Team"); } catch (BLLException blEx) { if (blEx.DisplayError) SetErrorScript(message: blEx.Message); else { LogException(blEx); SetErrorScript(); } } catch (Exception exception) { LogException(exception); SetErrorScript(); } } ViewBag.TeamsList = Utils.GetTeamsList(model.Id); ViewBag.ExpendituresList = Utils.GetResourceExpendituresList(model.ExpenditureCategory != null ? model.ExpenditureCategory.Id : Guid.Empty); return View(model); } private void AddCapacity(PeopleResourceModel model) { var weekendings = (from c in DbContext.FiscalCalendars where c.Type == 0 && c.StartDate >= model.StartDate orderby c.StartDate select c.EndDate).ToArray(); var teamManager = new TeamManager(DbContext); var team = teamManager.Load(model.TeamId); var parentId = team.PlannedCapacityScenarioId; var sds = (from sd in DbContext.ScenarioDetail where sd.ParentID == parentId && sd.ExpenditureCategoryId == model.ExpenditureCategoryId && weekendings.Contains(sd.WeekEndingDate.Value) select sd).ToList(); foreach (var week in weekendings) { var sd = (from s in sds where s.WeekEndingDate == week select s).FirstOrDefault(); var vc = (from w in model.WeeklyCapacities where w.Key == week select w.Value).FirstOrDefault(); if (vc == null) continue; if (sd != null) { sd.Quantity += vc.Quantity; sd.Cost += vc.Cost; DbContext.Entry(sd).State = System.Data.Entity.EntityState.Modified; } else { var newSd = new ScenarioDetail { Id = Guid.NewGuid(), ParentID = team.PlannedCapacityScenarioId, Quantity = vc.Quantity, Cost = vc.Cost, ExpenditureCategoryId = model.ExpenditureCategoryId, WeekEndingDate = week, WeekOrdinal = 0 }; DbContext.ScenarioDetail.Add(newSd); } } } private void RemoveCapacity(PeopleResourceModel model) { var weekendings = (from c in DbContext.FiscalCalendars where c.Type == 0 && c.StartDate >= model.StartDate orderby c.StartDate select c.EndDate).ToArray(); var teamManager = new TeamManager(DbContext); var team = teamManager.Load(model.TeamId); var ParentId = team.PlannedCapacityScenarioId; var sds = (from sd in DbContext.ScenarioDetail where sd.ParentID == ParentId && sd.ExpenditureCategoryId == model.ExpenditureCategoryId && weekendings.Contains(sd.WeekEndingDate.Value) select sd).ToList(); foreach (var week in weekendings) { var sd = (from s in sds where s.WeekEndingDate == week select s).FirstOrDefault(); var vc = (from w in model.WeeklyCapacities where w.Key == week select w.Value).FirstOrDefault(); if (vc == null) 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) { 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); Manager.DeleteResource(model.Id); ContentLocker.RemoveLock("PeopleResource", id.ToString(), User.Identity.Name); return RedirectToAction("Board", "Team"); } [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) { 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 RedirectToAction("Details", "PeopleResource", new {resourceId=model.PeopleResourceId}); } } }