412 lines
13 KiB
C#
412 lines
13 KiB
C#
using EnVisage.Code;
|
|
using EnVisage.Code.BLL;
|
|
using EnVisage.Models;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Net;
|
|
using System.Web.Mvc;
|
|
using System.Data;
|
|
using System.Data.Entity;
|
|
using System.Linq;
|
|
|
|
namespace EnVisage.Controllers
|
|
{
|
|
[Authorize]
|
|
public class SkillsController : BaseController
|
|
{
|
|
[AreaSecurity(area = Areas.Skills, level = AccessLevel.Read)]
|
|
public ActionResult Index()
|
|
{
|
|
string userIdAsText = User.Identity.GetID();
|
|
SkillsMatrixPageLoadModel model = GetPageLoadModel(userIdAsText, ApplicationDashboards.None, this.DbContext);
|
|
model.ReadOnly = !SecurityManager.CheckSecurityObjectPermission(Areas.SkillsMatrix, AccessLevel.Write);
|
|
|
|
// Get Activity Calendar root URL
|
|
model.ActivityCalendarUrl = this.Url.Action("Index", "CapacityManagement");
|
|
// Open in special Skills Matrix page
|
|
model.OpenerType = ApplicationDashboards.None;
|
|
|
|
return View("Index", model);
|
|
}
|
|
public ActionResult ExportToPDF()
|
|
{
|
|
PDFExporter exporter = new PDFExporter();
|
|
exporter.BrowserWidth = 2560;
|
|
byte[] pdfBuffer = exporter.ExportPage(Url.Action("LoadMatrix", "Skills", null, this.Request.Url.Scheme), 20, true, Request.Cookies);
|
|
|
|
// send the PDF file to browser
|
|
FileResult fileResult = new FileContentResult(pdfBuffer, "application/pdf");
|
|
fileResult.FileDownloadName = "Prevu-Skills-" + DateTime.Today.Month + "-" + DateTime.Today.Day + ".pdf";
|
|
|
|
return fileResult;
|
|
}
|
|
|
|
#region Skills management
|
|
|
|
[HttpPost]
|
|
[AreaSecurity(area = Areas.Skills, level = AccessLevel.Read)]
|
|
[ValidateJsonAntiForgeryToken]
|
|
public ActionResult GetSkillTree(SkillsMatrixQueryModel model)
|
|
{
|
|
try
|
|
{
|
|
var manager = new SkillGroupManager(DbContext);
|
|
var items = manager.LoadSkillsTree();
|
|
return Json(items);
|
|
}
|
|
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 load skills tree. Try again later.");
|
|
}
|
|
}
|
|
catch (Exception exception) // handle any unexpected error
|
|
{
|
|
LogException(exception);
|
|
//SetErrorScript();
|
|
ModelState.AddModelError(string.Empty, "Cannot load skills tree. Try again later.");
|
|
}
|
|
return new HttpStatusCodeResult(HttpStatusCode.InternalServerError);
|
|
}
|
|
|
|
[HttpPost]
|
|
[AreaSecurity(area = Areas.Skills, level = AccessLevel.Write)]
|
|
[ValidateJsonAntiForgeryToken]
|
|
public ActionResult SaveSkillTree(EditSkillsModel model)
|
|
{
|
|
try
|
|
{
|
|
var manager = new SkillGroupManager(DbContext);
|
|
manager.Save(model);
|
|
DbContext.SaveChanges();
|
|
var items = manager.LoadSkillsTree();
|
|
return Json(items);
|
|
}
|
|
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 skills tree. Try again later.");
|
|
}
|
|
}
|
|
catch (Exception exception) // handle any unexpected error
|
|
{
|
|
LogException(exception);
|
|
//SetErrorScript();
|
|
ModelState.AddModelError(string.Empty, "Cannot save skills tree. Try again later.");
|
|
}
|
|
return new HttpStatusCodeResult(HttpStatusCode.InternalServerError);
|
|
}
|
|
|
|
#endregion
|
|
#region Skills matrix
|
|
|
|
/// <summary>
|
|
/// Returns Skills Matrix data
|
|
/// </summary>
|
|
/// <param name="model">Query params</param>
|
|
/// <returns></returns>
|
|
/// <remarks>SA. ENV-1328</remarks>
|
|
[HttpPost]
|
|
[ValidateJsonAntiForgeryToken]
|
|
public ActionResult GetSkillsMatrix(SkillsMatrixQueryModel model)
|
|
{
|
|
if (!SecurityManager.CheckSecurityObjectPermission(Areas.SkillsMatrix, AccessLevel.Read) &&
|
|
!SecurityManager.CheckSecurityObjectPermission(Areas.RD_ResourceSkills, AccessLevel.Read))
|
|
return new HttpStatusCodeResult(HttpStatusCode.Unauthorized);
|
|
|
|
try
|
|
{
|
|
// If DatePoint is not specified, data will be extracted for Now
|
|
DateTime datePoint = DateTime.UtcNow.Date;
|
|
Guid userId = SecurityManager.GetUserPrincipal();
|
|
|
|
if (model.DatePoint > 0)
|
|
datePoint = Utils.ConvertFromUnixDate(model.DatePoint).ToUniversalTime();
|
|
|
|
var manager = new SkillsMatrixManager(DbContext);
|
|
bool excludeChartData = (model.Filter != null) && (model.Filter.Resources != null) && (model.Filter.Resources.Count == 1);
|
|
SkillsMatrixSaveModel data = manager.LoadSkillMatrix(SkillMatrixTimeLayer.Present, model.DataType,
|
|
datePoint, userId, !excludeChartData, model.Filter);
|
|
return Json(data);
|
|
}
|
|
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 load skills matrix. Try again later.");
|
|
}
|
|
}
|
|
catch (Exception exception) // handle any unexpected error
|
|
{
|
|
LogException(exception);
|
|
//SetErrorScript();
|
|
ModelState.AddModelError(string.Empty, "Cannot load skills matrix. Try again later.");
|
|
}
|
|
return new HttpStatusCodeResult(HttpStatusCode.InternalServerError);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Saves Skills Matrix data
|
|
/// </summary>
|
|
/// <param name="model">Data to save</param>
|
|
/// <returns></returns>
|
|
/// <remarks>SA. ENV-1328</remarks>
|
|
[HttpPost]
|
|
[ValidateJsonAntiForgeryToken]
|
|
public ActionResult SaveSkillsMatrix(SkillsMatrixSaveModel model)
|
|
{
|
|
if (!SecurityManager.CheckSecurityObjectPermission(Areas.SkillsMatrix, AccessLevel.Write) &&
|
|
!SecurityManager.CheckSecurityObjectPermission(Areas.RD_ResourceSkills, AccessLevel.Write))
|
|
return new HttpStatusCodeResult(HttpStatusCode.Unauthorized);
|
|
|
|
try
|
|
{
|
|
if ((model != null) && (model.Values != null))
|
|
{
|
|
var manager = new SkillsMatrixManager(DbContext);
|
|
manager.Save(model);
|
|
DbContext.SaveChanges();
|
|
}
|
|
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();
|
|
ModelState.AddModelError(string.Empty, "Cannot save skill matrix. Try again later.");
|
|
}
|
|
}
|
|
catch (Exception exception) // handle any unexpected error
|
|
{
|
|
LogException(exception);
|
|
//SetErrorScript();
|
|
ModelState.AddModelError(string.Empty, "Cannot save skill matrix. Try again later.");
|
|
}
|
|
return new HttpStatusCodeResult(HttpStatusCode.InternalServerError);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initialized model for opening Skills page. Including filter options
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static SkillsMatrixPageLoadModel GetPageLoadModel(string userIdAsText, ApplicationDashboards openerType,
|
|
EnVisageEntities dbContext)
|
|
{
|
|
if (String.IsNullOrEmpty(userIdAsText))
|
|
throw new ArgumentNullException("userIdAsText");
|
|
|
|
if (dbContext == null)
|
|
throw new ArgumentNullException("dbContext");
|
|
|
|
SkillsMatrixPageLoadModel model = new SkillsMatrixPageLoadModel {
|
|
DataType = Skill2ResourceType.Actual
|
|
};
|
|
Guid userId = Guid.Parse(userIdAsText);
|
|
|
|
List<SelectListItem> options;
|
|
|
|
#region Teams
|
|
|
|
if (openerType != ApplicationDashboards.ResourceBoard)
|
|
{
|
|
TeamManager teamMngr = new TeamManager(dbContext);
|
|
var availableTeams = teamMngr.GetTeamsByUser(userId);
|
|
|
|
options = (availableTeams.OrderBy(x => x.Name).Select(x => new SelectListItem()
|
|
{
|
|
Text = x.Name,
|
|
Value = x.TeamId.ToString()
|
|
})).ToList();
|
|
|
|
model.FilterOptions.Teams = options;
|
|
}
|
|
|
|
#endregion
|
|
#region Views
|
|
|
|
if (openerType != ApplicationDashboards.ResourceBoard)
|
|
{
|
|
ViewManager viewMngr = new ViewManager(dbContext);
|
|
IList<ViewListModel> availableViews = viewMngr.GetViewsByOwner(userId);
|
|
|
|
options = (availableViews.OrderBy(x => x.Name).Select(x => new SelectListItem()
|
|
{
|
|
Text = x.Name,
|
|
Value = x.Id.ToString()
|
|
})).ToList();
|
|
|
|
model.FilterOptions.Views = options;
|
|
}
|
|
|
|
#endregion
|
|
#region Companies
|
|
|
|
if (openerType != ApplicationDashboards.ResourceBoard)
|
|
{
|
|
CompanyManager cmpnyMngr = new CompanyManager(dbContext);
|
|
|
|
// Uncomment below, the only visible to user companies must be displayed by permissions
|
|
// var availableCompanies = cmpnyMngr.GetCompaniesByUser4Display(userId);
|
|
|
|
var availableCompanies = cmpnyMngr.GetCompaniesByUser(null);
|
|
|
|
options = new List<SelectListItem>();
|
|
SelectListItem listItem;
|
|
|
|
var companiesRootLevel = availableCompanies.Where(x =>
|
|
!x.ParentCompanyId.HasValue || !availableCompanies.Any(z => z.Id.Equals(x.ParentCompanyId.Value)))
|
|
.OrderBy(x => x.Name).ToList();
|
|
|
|
foreach (var rootCompany in companiesRootLevel)
|
|
{
|
|
listItem = new SelectListItem()
|
|
{
|
|
Text = rootCompany.Name,
|
|
Value = rootCompany.Id.ToString(),
|
|
Group = null
|
|
};
|
|
options.Add(listItem);
|
|
|
|
// Get child companies
|
|
var childCompanies = availableCompanies.Where(x =>
|
|
x.ParentCompanyId.HasValue && x.ParentCompanyId.Value.Equals(rootCompany.Id))
|
|
.OrderBy(x => x.Name).ToList();
|
|
|
|
foreach (var childCompany in childCompanies)
|
|
{
|
|
listItem = new SelectListItem()
|
|
{
|
|
Text = childCompany.Name,
|
|
Value = childCompany.Id.ToString(),
|
|
Group = new SelectListGroup()
|
|
{
|
|
Name = rootCompany.Name
|
|
}
|
|
};
|
|
options.Add(listItem);
|
|
}
|
|
}
|
|
|
|
model.FilterOptions.Companies = options;
|
|
}
|
|
|
|
#endregion
|
|
#region Skill Groups and Skills
|
|
|
|
SkillManager skillMngr = new SkillManager(dbContext);
|
|
List<Skill> allSkills = skillMngr.DataTable.ToList();
|
|
|
|
Dictionary<Guid, string> skillGroups = allSkills.Where(x => !x.ParentId.HasValue)
|
|
.ToDictionary(k => k.Id, v => v.Name);
|
|
|
|
List<SelectListItem> skillGroupsOrdered = skillGroups.OrderBy(x => x.Value)
|
|
.Select(x => new SelectListItem()
|
|
{
|
|
Value = x.Key.ToString(),
|
|
Text = x.Value,
|
|
}).ToList();
|
|
|
|
model.FilterOptions.Skills = new List<SelectListItem>();
|
|
|
|
// SA: When creating Skills tree for Matrix filter in the page,
|
|
// we transform the tree to an ordered plain list, where Skills immediatelly follow
|
|
// their parent Skill Group. To make Skills and Groups manipulation easy,
|
|
// we store the amount of skills and marker of child skills existance to the Group property of
|
|
// any Skills Group SelectListItem. Where Group.Name contains amount of child skills, and
|
|
// Group.Disabled=true means the Skill Group has child skills
|
|
foreach (SelectListItem grp in skillGroupsOrdered)
|
|
{
|
|
SelectListItem grpCopy = grp.Clone();
|
|
model.FilterOptions.Skills.Add(grpCopy);
|
|
|
|
List<SelectListItem> grpSkills = allSkills.Where(s =>
|
|
s.ParentId.HasValue && s.ParentId.Value.Equals(new Guid(grpCopy.Value)))
|
|
.OrderBy(s => s.Name)
|
|
.Select(s => new SelectListItem()
|
|
{
|
|
Value = s.Id.ToString(),
|
|
Text = s.Name
|
|
}).ToList();
|
|
|
|
model.FilterOptions.Skills.AddRange(grpSkills);
|
|
grpCopy.Group = new SelectListGroup()
|
|
{
|
|
Name = grpSkills.Count().ToString(),
|
|
Disabled = grpSkills.Count() > 0
|
|
};
|
|
}
|
|
|
|
skillMngr = null;
|
|
|
|
#endregion
|
|
#region Skill Levels
|
|
|
|
if (openerType != ApplicationDashboards.ResourceBoard)
|
|
{
|
|
Dictionary<int, string> levelsReady = new Dictionary<int, string>();
|
|
Array levelIds = Enum.GetValues(typeof(SkillLevels));
|
|
|
|
foreach (object levelId in levelIds)
|
|
{
|
|
int levelCode = Convert.ToInt32(levelId);
|
|
string levelName = ((SkillLevels)levelId).ToDisplayValue();
|
|
levelsReady.Add(levelCode, levelName);
|
|
}
|
|
model.FilterOptions.SkillLevels = levelsReady.OrderBy(x => x.Key).Select(x => new SelectListItem()
|
|
{
|
|
Value = x.Key.ToString(),
|
|
Text = String.Format("{0} - {1}", x.Key.ToString(), x.Value)
|
|
}).ToList();
|
|
}
|
|
|
|
#endregion
|
|
#region Skill Interests
|
|
|
|
if (openerType != ApplicationDashboards.ResourceBoard)
|
|
{
|
|
Dictionary<int, string> interestesReady = new Dictionary<int, string>();
|
|
Array interestIds = Enum.GetValues(typeof(SkillInterests));
|
|
|
|
foreach (object interestId in interestIds)
|
|
{
|
|
int interestCode = Convert.ToInt32(interestId);
|
|
string interestName = ((SkillInterests)interestId).ToDisplayValue();
|
|
interestesReady.Add(interestCode, interestName);
|
|
}
|
|
model.FilterOptions.SkillInterests = interestesReady.OrderBy(x => x.Key).Select(x => new SelectListItem()
|
|
{
|
|
Value = x.Key.ToString(),
|
|
Text = x.Value
|
|
}).ToList();
|
|
}
|
|
|
|
#endregion
|
|
|
|
return model;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
} |