using System.Text.Json; using CMGMBLL.Interfaces; using CMGMDAL.DTOs; using CMGMDAL.Interfaces; using GB5Shared.DaprCache; using GB5Shared.DTO.Framework.Login; using GB5Shared.EventLogPublish; using GB5Shared.Resource.Response; using GB5Shared.Telemetry; using static GB5Shared.GB5Constant.Constant; using Microsoft.Extensions.Logging; namespace CMGMBLL.Implementations; public class CareerPathBLL : ICareerPathBLL { private readonly ICareerPathDAL _dal; private readonly KeyInvalidate _keyInvalidate; private readonly EventLogPublish _eventLog; private readonly ILogger _logger; public CareerPathBLL(ICareerPathDAL dal, KeyInvalidate keyInvalidate, EventLogPublish eventLog, ILogger logger) { _dal = dal; _keyInvalidate = keyInvalidate; _eventLog = eventLog; _logger = logger; } public async Task GetByIdAsync(int careerPathId, LoginDTO login, CancellationToken ct) { try { var dto = await _dal.GetByIdAsync(careerPathId, login, ct).ConfigureAwait(false); return JsonSerializer.Serialize(dto); } catch (Exception ex) { GB5Trace.MarkFailed("get-careerpath-failed", ex); _logger.LogError(ex, "GetCareerPath failed for CareerPathId {Id}", careerPathId); throw; } } public async Task GetListAsync(int frameworkId, short status, LoginDTO login, CancellationToken ct) { try { var list = await _dal.GetListAsync(frameworkId, status, login, ct).ConfigureAwait(false); return JsonSerializer.Serialize(list); } catch (Exception ex) { GB5Trace.MarkFailed("get-careerpath-list-failed", ex); _logger.LogError(ex, "GetCareerPathList failed for FrameworkId {FrameworkId}", frameworkId); throw; } } public async Task SaveAsync(CareerPathDTO dto, LoginDTO login, CancellationToken ct) { try { GB5Trace.Step("validate-careerpath", new { dto.CareerPathId }); if (string.IsNullOrWhiteSpace(dto.PathCode)) return "Path Code is required."; if (string.IsNullOrWhiteSpace(dto.PathName)) return "Path Name is required."; if (dto.FrameworkId <= 0) return "Framework is required."; if (dto.CurrentRoleId <= 0) return "Current Role is required."; if (dto.TargetRoleId <= 0) return "Target Role is required."; bool isNew = dto.CareerPathId == 0; GB5Trace.Step("save-careerpath", new { dto.CareerPathId, isNew }); int savedId = await _dal.SaveAsync(dto, isNew, login, ct).ConfigureAwait(false); GB5Trace.Step("event-publish", new { EventTypeId = EventTypeConstant.SAVECMGMCAREERPATHEVNTTYPEID }); await _eventLog.PublishEventLogAsync("Career Path Saved", dto, EventTypeConstant.SAVECMGMCAREERPATHEVNTTYPEID, savedId, login, ct: ct).ConfigureAwait(false); var cacheKey = new CacheKeyGeneration().KeyGeneration(savedId, EntityConstant.OBJECTCAREERPATH, CacheKeyLevel.CLIENT_LEVEL, login); await _keyInvalidate.AllInvalidateCache(cacheKey).ConfigureAwait(false); return isNew ? $"{SuccessResponse.SaveSuccessMessage} {savedId}" : SuccessResponse.UpdateSuccess; } catch (Exception ex) { GB5Trace.MarkFailed("save-careerpath-failed", ex); _logger.LogError(ex, "SaveCareerPath failed for Code {Code}", dto.PathCode); throw; } } public async Task DeleteAsync(int careerPathId, LoginDTO login, CancellationToken ct) { try { GB5Trace.Step("delete-careerpath", new { careerPathId }); await _dal.DeleteAsync(careerPathId, login, ct).ConfigureAwait(false); GB5Trace.Step("event-publish", new { EventTypeId = EventTypeConstant.SAVECMGMCAREERPATHEVNTTYPEID }); await _eventLog.PublishEventLogAsync("Career Path Deleted", new { CareerPathId = careerPathId }, EventTypeConstant.SAVECMGMCAREERPATHEVNTTYPEID, careerPathId, login, ct: ct).ConfigureAwait(false); var cacheKey = new CacheKeyGeneration().KeyGeneration(careerPathId, EntityConstant.OBJECTCAREERPATH, CacheKeyLevel.CLIENT_LEVEL, login); await _keyInvalidate.AllInvalidateCache(cacheKey).ConfigureAwait(false); return SuccessResponse.DeleteSuccessMessage; } catch (Exception ex) { GB5Trace.MarkFailed("delete-careerpath-failed", ex); _logger.LogError(ex, "DeleteCareerPath failed for Id {Id}", careerPathId); throw; } } public async Task GetRequirementsAsync(int careerPathId, LoginDTO login, CancellationToken ct) { try { var list = await _dal.GetRequirementsAsync(careerPathId, login, ct).ConfigureAwait(false); return JsonSerializer.Serialize(list); } catch (Exception ex) { GB5Trace.MarkFailed("get-careerpath-requirements-failed", ex); _logger.LogError(ex, "GetRequirements failed for CareerPathId {Id}", careerPathId); throw; } } public async Task SaveRequirementAsync(CareerPathRequirementDTO dto, LoginDTO login, CancellationToken ct) { try { GB5Trace.Step("validate-careerpath-requirement", new { dto.CareerPathReqId }); if (dto.CareerPathId <= 0) return "Career Path is required."; if (dto.SkillId <= 0) return "Skill is required."; bool isNew = dto.CareerPathReqId == 0; GB5Trace.Step("save-careerpath-requirement", new { dto.CareerPathReqId, isNew }); int savedId = await _dal.SaveRequirementAsync(dto, isNew, login, ct).ConfigureAwait(false); var cacheKey = new CacheKeyGeneration().KeyGeneration(dto.CareerPathId, EntityConstant.OBJECTCAREERPATH, CacheKeyLevel.CLIENT_LEVEL, login); await _keyInvalidate.AllInvalidateCache(cacheKey).ConfigureAwait(false); return isNew ? $"{SuccessResponse.SaveSuccessMessage} {savedId}" : SuccessResponse.UpdateSuccess; } catch (Exception ex) { GB5Trace.MarkFailed("save-careerpath-requirement-failed", ex); _logger.LogError(ex, "SaveRequirement failed for CareerPathId {Id}", dto.CareerPathId); throw; } } public async Task DeleteRequirementAsync(int careerPathReqId, LoginDTO login, CancellationToken ct) { try { GB5Trace.Step("delete-careerpath-requirement", new { careerPathReqId }); await _dal.DeleteRequirementAsync(careerPathReqId, login, ct).ConfigureAwait(false); var cacheKey = new CacheKeyGeneration().KeyGeneration(careerPathReqId, EntityConstant.OBJECTCAREERPATH, CacheKeyLevel.CLIENT_LEVEL, login); await _keyInvalidate.AllInvalidateCache(cacheKey).ConfigureAwait(false); return SuccessResponse.DeleteSuccessMessage; } catch (Exception ex) { GB5Trace.MarkFailed("delete-careerpath-requirement-failed", ex); _logger.LogError(ex, "DeleteRequirement failed for Id {Id}", careerPathReqId); throw; } } }