using System; using System.ComponentModel.DataAnnotations; using System.Threading; using System.Threading.Tasks; using RecruitmentDAL.DTO.JobPosition; using GB5Shared.DaprCache; using GB5Shared.DTO.Framework.AutoNumber; using GB5Shared.DTO.Framework.Criteria; using GB5Shared.DTO.Framework.Login; using GB5Shared.EntityHandler; using GB5Shared.GenerateAutoNumber; using GB5Shared.Resource.Response; using GB5Shared.Telemetry; using GB5Shared.Validation; using Microsoft.Extensions.Logging; using RecruitmentDAL.CustomeCode.JobPosition; using static GB5Shared.GB5Constant.Constant; namespace RecruitmentBLL.JobPosition { public class JobPositionBLL : IJobPositionBLL { private readonly IJobPositionDAL _JobPositionDAL; private readonly AutoNumber _AutoNumber; private readonly IValidation _Validation; private readonly KeyInvalidate _KeyInvalidate; private readonly BaseEntityAppService _BaseEntityAppService; private readonly ILogger _Logger; public JobPositionBLL( IJobPositionDAL jobPositionDAL, AutoNumber autoNumber, IValidation validation, KeyInvalidate keyInvalidate, BaseEntityAppService baseEntityAppService, ILogger logger) { _JobPositionDAL = jobPositionDAL; _AutoNumber = autoNumber; _Validation = validation; _KeyInvalidate = keyInvalidate; _BaseEntityAppService = baseEntityAppService; _Logger = logger; } public async Task GetJobPosition(int JobPositionId, LoginDTO LoginDTO, CancellationToken ct) { try { return await _JobPositionDAL.GetJobPosition(JobPositionId, LoginDTO, ct) .ConfigureAwait(false); } catch (Exception ex) { GB5Trace.MarkFailed("get-jobposition-failed", ex); _Logger.LogError(ex, "GetJobPosition failed for JobPositionId {JobPositionId}", JobPositionId); throw; } } public async Task SaveJobPosition(JobPositionDTO JobPositionDTO, LoginDTO LoginDTO, CancellationToken ct) { if (JobPositionDTO == null) throw new ArgumentNullException(nameof(JobPositionDTO)); AutoNumberDTO? autoNumberDTO = null; try { GB5Trace.Step("validate-jobposition", new { JobPositionDTO.JobPositionId }); await _Validation.NotEmpty( JobPositionDTO.PositionTitle, nameof(JobPositionDTO.PositionTitle)); JobPositionDTO.ModifiedById = LoginDTO.UserId; JobPositionDTO.ModifiedOn = DateTime.UtcNow; bool isNew = JobPositionDTO.JobPositionId == 0; if (isNew) { autoNumberDTO = await _AutoNumber.GetNumberAsync( 1, "JOBPOSITION", LoginDTO).ConfigureAwait(false); JobPositionDTO.JobPositionId = autoNumberDTO.StartNumber; JobPositionDTO.CreatedById = LoginDTO.UserId; JobPositionDTO.CreatedOn = DateTime.UtcNow; JobPositionDTO.TenantId = LoginDTO.ClientId; } GB5Trace.Step("save-jobposition", new { JobPositionDTO.JobPositionId, isNew }); await _BaseEntityAppService.ExecuteSaveAsync( EntityConstant.OBJECTRECRUITMENTJOBPOSITION, isNew ? EventTypeConstant.SAVERECRUITMENTJOBPOSITIONEVENTTYPEID : EventTypeConstant.UPDATERECRUITMENTJOBPOSITIONEVENTTYPEID, JobPositionDTO, LoginDTO, async tx => { _ = isNew ? await _JobPositionDAL.SaveJobPosition(JobPositionDTO, LoginDTO, tx, ct).ConfigureAwait(false) : await _JobPositionDAL.UpdateJobPosition(JobPositionDTO, LoginDTO, tx, ct).ConfigureAwait(false); return JobPositionDTO.JobPositionId; }, null, -1, -1, null, isNew).ConfigureAwait(false); GB5Trace.Step("event-publish", new { EventTypeId = isNew ? EventTypeConstant.SAVERECRUITMENTJOBPOSITIONEVENTTYPEID : EventTypeConstant.UPDATERECRUITMENTJOBPOSITIONEVENTTYPEID }); var cacheKey = new CacheKeyGeneration().KeyGeneration( JobPositionDTO.JobPositionId, EntityConstant.OBJECTRECRUITMENTJOBPOSITION, CacheKeyLevel.CLIENT_LEVEL, LoginDTO); await _KeyInvalidate.AllInvalidateCache(cacheKey).ConfigureAwait(false); _Logger.LogInformation( "JobPosition {JobPositionId} {Action} by user {UserId}", JobPositionDTO.JobPositionId, isNew ? "saved" : "updated", LoginDTO.UserId); return isNew ? $"{SuccessResponse.SaveSuccessMessage} {JobPositionDTO.JobPositionId}" : $"{SuccessResponse.UpdateSuccessMessage} {JobPositionDTO.JobPositionId}"; } catch (ValidationException vex) { GB5Trace.MarkFailed("save-jobposition-failed", vex); if (autoNumberDTO != null && JobPositionDTO.JobPositionId > 0) await _AutoNumber.RollbackAutoNumber("JOBPOSITION", JobPositionDTO.JobPositionId, LoginDTO).ConfigureAwait(false); throw new Exception(vex.Message); } catch (Exception ex) { GB5Trace.MarkFailed("save-jobposition-failed", ex); _Logger.LogError(ex, "SaveJobPosition failed for JobPositionId {JobPositionId}", JobPositionDTO.JobPositionId); if (autoNumberDTO != null && JobPositionDTO.JobPositionId > 0) { await _AutoNumber.RollbackAutoNumber( "JOBPOSITION", JobPositionDTO.JobPositionId, LoginDTO).ConfigureAwait(false); } throw; } } public async Task GetSelectListJobPosition(CriteriaDTO criteriaDTO, LoginDTO LoginDTO, CancellationToken ct) { try { return await _JobPositionDAL.GetSelectListJobPosition(criteriaDTO, LoginDTO, ct) .ConfigureAwait(false); } catch (Exception ex) { GB5Trace.MarkFailed("get-selectlist-jobposition-failed", ex); _Logger.LogError(ex, "GetSelectListJobPosition failed"); throw; } } public async Task DeleteJobPosition(int JobPositionId, LoginDTO LoginDTO, CancellationToken ct) { try { GB5Trace.Step("delete-jobposition", new { JobPositionId }); var result = await _JobPositionDAL.DeleteJobPosition(JobPositionId, LoginDTO, ct) .ConfigureAwait(false); var cacheKey = new CacheKeyGeneration().KeyGeneration( JobPositionId, EntityConstant.OBJECTRECRUITMENTJOBPOSITION, CacheKeyLevel.CLIENT_LEVEL, LoginDTO); await _KeyInvalidate.AllInvalidateCache(cacheKey).ConfigureAwait(false); _Logger.LogInformation("JobPosition {JobPositionId} deleted by user {UserId}", JobPositionId, LoginDTO.UserId); return result; } catch (Exception ex) { GB5Trace.MarkFailed("delete-jobposition-failed", ex); _Logger.LogError(ex, "DeleteJobPosition failed for JobPositionId {JobPositionId}", JobPositionId); throw; } } } }