using GB5Shared.DTO.Framework.Criteria; using GB5Shared.DTO.Framework.Login; using GB5Shared.GenerateAutoNumber; using GB5Shared.Resource.Response; using SkillManagementDAL.CustomCode.RoleSkillRequirement; using SkillManagementDAL.DTO.RoleSkillRequirement; using System.Text.Json; namespace SkillManagementBLL.RoleSkillRequirement { public class RoleSkillRequirementBLL : IRoleSkillRequirementBLL { private readonly IRoleSkillRequirementDAL _dal; private readonly AutoNumber _autoNumber; public RoleSkillRequirementBLL(IRoleSkillRequirementDAL dal, AutoNumber autoNumber) { _dal = dal; _autoNumber = autoNumber; } public async Task GetByRole(int roleId, LoginDTO login, CancellationToken ct) => await _dal.GetByRole(roleId, login, ct); public async Task GetBySkill(int SkillId, LoginDTO login, CancellationToken ct) => await _dal.GetBySkill(SkillId, login, ct); public async Task GetByReq(int ReqId, LoginDTO login, CancellationToken ct) => await _dal.GetByReq(ReqId, login, ct); public async Task Save(IEnumerable reqs, int roleId, string? roleCode, string? roleName, LoginDTO login, CancellationToken ct) { var reqList = reqs.ToList(); if (reqList.Count == 0) throw new ArgumentException("At least one skill requirement is required."); foreach (var r in reqList) { if (r.SkillId == 0) throw new ArgumentException("SkillId is required for each requirement."); if (r.Category > 3) throw new ArgumentException("Category must be 0 (Core), 1 (Technical), 2 (Specialist), or 3 (Optional)."); if (r.MinLevNo < 1) throw new ArgumentException("MinLevNo must be at least 1."); } // RoleId == 0 means new role — generate an ID for the group int finalRoleId = roleId; if (finalRoleId == 0) { var roleAn = await _autoNumber.GetAutoNumber(1, "MJOBROLESKILL", login); finalRoleId = roleAn.StartNumber; } // Assign a fresh ReqId to each requirement that doesn't already have one foreach (var r in reqList.Where(x => x.ReqId == 0)) { var an = await _autoNumber.GetAutoNumber(1, "MJOBROLESKILL", login); r.ReqId = an.StartNumber; } // Stamp RoleId, RoleCode, RoleName on every row foreach (var r in reqList) { r.RoleId = finalRoleId; r.RoleCode = roleCode; r.RoleName = roleName; } await _dal.Save(reqList, finalRoleId, login, ct); return string.Format(SuccessResponse.SaveSuccessWithCodeAndName, roleCode, roleName); } public async Task GetSelectList(CriteriaDTO criteriaDTO, LoginDTO login, CancellationToken ct) => await _dal.GetSelectList(criteriaDTO, login, ct); public async Task DeleteById(int reqId, LoginDTO login, CancellationToken ct) { var rows = await _dal.DeleteById(reqId, login, ct); if (rows == 0) throw new Exception(ErrorResponse.DeleteNotFoundMessage); return SuccessResponse.DeleteSuccessMessage; } public async Task GetRoleSkillRequirementList(int firstNumber, int maxResult, CriteriaDTO criteriaDTO, LoginDTO login, CancellationToken ct = default) { // ── VALIDATION ─────────────────────────────────────────── if (firstNumber == -1 && maxResult != -1) throw new ArgumentException("MaxResult must also be -1 when FirstNumber is -1."); if (firstNumber != -1 && maxResult == -1) throw new ArgumentException("FirstNumber must also be -1 when MaxResult is -1."); if (firstNumber != -1 && firstNumber < 1) throw new ArgumentException($"FirstNumber must be >= 1 or -1. Got: {firstNumber}"); if (maxResult != -1 && maxResult < 1) throw new ArgumentException($"MaxResult must be >= 1 or -1. Got: {maxResult}"); // ── FETCH DATA ─────────────────────────────────────────── bool isAllData = firstNumber == -1 && maxResult == -1; List data = isAllData ? await _dal.GetAllList(login, ct) : await _dal.GetPagedList(firstNumber, maxResult, login, ct); // ── SERIALIZE (KEY CHANGE) ──────────────────────────────── var json = JsonSerializer.Serialize(data); return json; } } }