Skip to content

Module — Training

Lets staff raise a Training Request (course, provider, dates, cost, project charge) and routes it through a fixed five-step approval chain, and provides a project-level dashboard of training activity. It is the smallest module — a single controller, a single BAL class and a single entity.

Source: NKO.Main/NKO.Main/Controllers/TrainingController .cs (note the trailing space in the file name), NKO.Main/NKO.Main/BAL/BTraining.cs, NKO.Lib/NKO.Shared/ViewModels/Training/TrainingStatus.cs.

Purpose & scope

  • In scope: the TrainingRequest record, its five-step approval, and the training dashboard.
  • Out of scope: the training-certificate documents attached to an employee (HR archive) and the budget the request charges against (Grant).
  • Database: NKO_DB (core), context NKO_DBEntities1.

Key features

  • Training request capture — title, training date, trainer organisation, description, transportation + training cost, currency, project, location, planned / unplanned, training-need category (TrainingNeedTypes), an "attended a similar course in the last 6 months" flag, and an other-costs detail field.
  • Fixed linear approval (TrainingStatus) — Draft (0) → WaitingForManager (1) → WaitingForHR (2) → WaitingForFinance (3) → WaitingForCountryDirector (4) → Accepted (5); plus Refused (6) and Cancelled (7). The next approver is resolved by NextUserHelper.GetTrainingNextUser.
  • Visibility — the global CommonSharedPermission(SharedPermissions.TrainingRequests = 5) grants all rows; otherwise a user sees their staff's non-draft requests plus any request where they fill a role slot (NextUserId / RefuseId / CreatedBy / ManagerId / HRId / FinanceId / CountryId).
  • Index filters — year, month, status, project, planned, training-need, user.
  • Dashboard — the count of training requests grouped by project (GetDashboardInfo), a Data grid, and a JSON endpoint.
  • Notifications — e-mail + in-app notification on every hop (NotificationTypesConstants.TRAININGREQUEST_*).
  • PDF — request details export via ?pdf=1.

Screens

TrainingController — /Training/*, views in NKO.Main/NKO.Main/Views/Training/.

Feature Route HTTP View Permission key
Training requests list /Training/Index GET Index.cshtml TrainingIndex
Request detail (+ sign strip) /Training/Details/{id} GET Details.cshtml TrainingDetails
Edit request /Training/Edit POST — TrainingEdit
Workflow transition /Training/ContextActions POST — TrainingDetails
Create request /Training/Create GET / POST Create.cshtml TrainingCreate
Delete request /Training/DeleteTraining/{id} GET / POST _DeleteTraining.cshtml TrainingIndex
Dashboard (count by project) /Training/Dashboard GET Dashboard.cshtml TrainingDashboard
Dashboard data /Training/GetDashboardInfo GET JSON TrainingDashboard
Data grid /Training/Data GET Data.cshtml TrainingData

ContextActions dispatches on TrainingUserTypes × TrainingOpTypes → SetSent / SetManagerAccepted / SetManagerRefused / SetHRAccepted / SetHRRefused / SetFinanceAccepted / SetFinanceRefused / SetcountryDirectorAccepted / SetCountryDirectoreRefused.

Business logic

Class File Responsibility & notable logic
BTraining NKO.Main/NKO.Main/BAL/BTraining.cs (~690 ln) Create(TrainingRequest) — new GUID, StatusId = Draft, ReqSign / ManagerSign = false, NextUserId = CreatedBy. GetAll(...) / GetMyTrainings(userId) — the visibility logic above. Edit — only the editable fields (description, location, planned, training-need, 6-months flag, other costs, project, name, costs, trainer org, date, transport cost). Workflow methods — each guards NextUserId == currentUser + exact StatusId + prior sign flags, then sets …SignDate / …Sign / …Note / …Id, advances StatusId, resolves NextUserId, notifies + e-mails; refusals set IsRefused, StatusId = Refused and notify the creator plus all prior approvers; SetcountryDirectorAccepted → Accepted, NextUserId = null. GetDashboardInfo(...) — groups GetAll by ProjectId, joins Project.ProjectName, returns List<KeyValuePair<string, double>>.

Data

TrainingRequest (NKO.Lib/NKO.DataAccess/DbModel/TrainingRequest.cs, extends BaseEntity): Name, TrainingDate, TrainerOrgName, Description, TransCost, TrainingCost, ProjectId, Location, Planned, TrainingNeed, IsAttendIn6Months, DetailsOfOtherCosts, Currency; the Req / Manager / HR / Finance / Country sign blocks (…Id, …Sign, …SignDate, …Note); RefuseId / IsRefused / RefuseDate / RefuseNote; NextUserId, StatusId. Related enums in TrainingStatus.cs: TrainingStatus, PlannedTypes (Planned = 0, NotPlanned = 1), TrainingNeedTypes (PerformanceEvaluation, JobRequirement, TNA, PersonalRequest, ManagersRequest).

Full column detail: Training database.

Permissions

Distinct keys: TrainingIndex, TrainingDetails, TrainingEdit, TrainingCreate, TrainingDashboard, TrainingData. Workflow area Areas.Training = 7; data scoping SharedPermissions.TrainingRequests = 5. TrainingUserTypes = Requester / Manager / HR / Finance / CountryDirector; TrainingOpTypes = Send + each role's Accept / Refuse.

Screenshots

Training Requests — /Training (year / month / status / project filters):

Training request list

Training Dashboard — /Training/Dashboard (request count by project):

Training dashboard — part 1 Training dashboard — part 2

Training Request detail — /Training/Details/{guid} (the five-step sign strip; requester name masked):

Training request detail