using System; using System.ComponentModel.DataAnnotations; using System.Threading; using System.Threading.Tasks; using RecruitmentDAL.DTO.InterviewPanel; using GB5Shared.DaprCache; using GB5Shared.DTO.Framework.AutoNumber; 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.InterviewPanel; using static GB5Shared.GB5Constant.Constant; namespace RecruitmentBLL.InterviewPanel { public class InterviewPanelBLL : IInterviewPanelBLL { private readonly IInterviewPanelDAL _InterviewPanelDAL; private readonly AutoNumber _AutoNumber; private readonly IValidation _Validation; private readonly KeyInvalidate _KeyInvalidate; private readonly BaseEntityAppService _BaseEntityAppService; private readonly ILogger _Logger; public InterviewPanelBLL( IInterviewPanelDAL interviewPanelDAL, AutoNumber autoNumber, IValidation validation, KeyInvalidate keyInvalidate, BaseEntityAppService baseEntityAppService, ILogger logger) { _InterviewPanelDAL = interviewPanelDAL; _AutoNumber = autoNumber; _Validation = validation; _KeyInvalidate = keyInvalidate; _BaseEntityAppService = baseEntityAppService; _Logger = logger; } public async Task GetInterviewPanel(int InterviewPanelId, LoginDTO LoginDTO, CancellationToken ct) { try { return await _InterviewPanelDAL.GetInterviewPanel(InterviewPanelId, LoginDTO, ct) .ConfigureAwait(false); } catch (Exception ex) { GB5Trace.MarkFailed("get-interviewpanel-failed", ex); _Logger.LogError(ex, "GetInterviewPanel failed for InterviewPanelId {InterviewPanelId}", InterviewPanelId); throw; } } public async Task GetInterviewPanelByInterview(int InterviewId, LoginDTO LoginDTO, CancellationToken ct) { try { return await _InterviewPanelDAL.GetInterviewPanelByInterview(InterviewId, LoginDTO, ct) .ConfigureAwait(false); } catch (Exception ex) { GB5Trace.MarkFailed("get-interviewpanel-by-interview-failed", ex); _Logger.LogError(ex, "GetInterviewPanelByInterview failed for InterviewId {InterviewId}", InterviewId); throw; } } public async Task SaveInterviewPanel(InterviewPanelDTO InterviewPanelDTO, LoginDTO LoginDTO, CancellationToken ct) { if (InterviewPanelDTO == null) throw new ArgumentNullException(nameof(InterviewPanelDTO)); AutoNumberDTO? autoNumberDTO = null; try { GB5Trace.Step("validate-interviewpanel", new { InterviewPanelDTO.InterviewPanelId }); if (InterviewPanelDTO.InterviewId <= 0) { throw new ValidationException( $"InterviewId is required. Received: {InterviewPanelDTO.InterviewId}."); } if (InterviewPanelDTO.InterviewerId <= 0) { throw new ValidationException( $"InterviewerId is required. Received: {InterviewPanelDTO.InterviewerId}."); } bool isNew = InterviewPanelDTO.InterviewPanelId == 0; InterviewPanelDTO.ModifiedById = LoginDTO.UserId; InterviewPanelDTO.ModifiedOn = DateTime.UtcNow; InterviewPanelDTO.TenantId = LoginDTO.ClientId; if (isNew) { autoNumberDTO = await _AutoNumber.GetNumberAsync( 1, "INTERVIEWPANEL", LoginDTO).ConfigureAwait(false); InterviewPanelDTO.InterviewPanelId = autoNumberDTO.StartNumber; InterviewPanelDTO.CreatedById = LoginDTO.UserId; InterviewPanelDTO.CreatedOn = DateTime.UtcNow; if (InterviewPanelDTO.Status == 0) InterviewPanelDTO.Status = 1; } GB5Trace.Step("save-interviewpanel", new { InterviewPanelDTO.InterviewPanelId, isNew }); await _BaseEntityAppService.ExecuteSaveAsync( EntityConstant.OBJECTRECRUITMENTINTERVIEWPANEL, isNew ? EventTypeConstant.SAVERECRUITMENTINTERVIEWPANELEVENTTYPEID : EventTypeConstant.UPDATERECRUITMENTINTERVIEWPANELEVENTTYPEID, InterviewPanelDTO, LoginDTO, async tx => { _ = isNew ? await _InterviewPanelDAL.SaveInterviewPanel(InterviewPanelDTO, LoginDTO, tx, ct).ConfigureAwait(false) : await _InterviewPanelDAL.UpdateInterviewPanel(InterviewPanelDTO, LoginDTO, tx, ct).ConfigureAwait(false); return InterviewPanelDTO.InterviewPanelId; }, null, -1, -1, null, isNew).ConfigureAwait(false); GB5Trace.Step("event-publish", new { EventTypeId = isNew ? EventTypeConstant.SAVERECRUITMENTINTERVIEWPANELEVENTTYPEID : EventTypeConstant.UPDATERECRUITMENTINTERVIEWPANELEVENTTYPEID }); var cacheKey = new CacheKeyGeneration().KeyGeneration( InterviewPanelDTO.InterviewPanelId, EntityConstant.OBJECTRECRUITMENTINTERVIEWPANEL, CacheKeyLevel.CLIENT_LEVEL, LoginDTO); await _KeyInvalidate.AllInvalidateCache(cacheKey).ConfigureAwait(false); _Logger.LogInformation( "InterviewPanel {InterviewPanelId} {Action} by user {UserId}", InterviewPanelDTO.InterviewPanelId, isNew ? "saved" : "updated", LoginDTO.UserId); return isNew ? $"{SuccessResponse.SaveSuccessMessage} {InterviewPanelDTO.InterviewPanelId}" : $"{SuccessResponse.UpdateSuccessMessage} {InterviewPanelDTO.InterviewPanelId}"; } catch (ValidationException vex) { GB5Trace.MarkFailed("save-interviewpanel-failed", vex); if (autoNumberDTO != null && InterviewPanelDTO.InterviewPanelId > 0) await _AutoNumber.RollbackAutoNumber("INTERVIEWPANEL", InterviewPanelDTO.InterviewPanelId, LoginDTO).ConfigureAwait(false); throw new Exception(vex.Message); } catch (Exception ex) { GB5Trace.MarkFailed("save-interviewpanel-failed", ex); _Logger.LogError(ex, "SaveInterviewPanel failed for InterviewPanelId {InterviewPanelId}", InterviewPanelDTO.InterviewPanelId); if (autoNumberDTO != null && InterviewPanelDTO.InterviewPanelId > 0) { await _AutoNumber.RollbackAutoNumber( "INTERVIEWPANEL", InterviewPanelDTO.InterviewPanelId, LoginDTO).ConfigureAwait(false); } throw; } } public async Task DeleteInterviewPanel(int InterviewPanelId, LoginDTO LoginDTO, CancellationToken ct) { try { GB5Trace.Step("delete-interviewpanel", new { InterviewPanelId }); var result = await _InterviewPanelDAL.DeleteInterviewPanel(InterviewPanelId, LoginDTO, ct) .ConfigureAwait(false); var cacheKey = new CacheKeyGeneration().KeyGeneration( InterviewPanelId, EntityConstant.OBJECTRECRUITMENTINTERVIEWPANEL, CacheKeyLevel.CLIENT_LEVEL, LoginDTO); await _KeyInvalidate.AllInvalidateCache(cacheKey).ConfigureAwait(false); _Logger.LogInformation("InterviewPanel {InterviewPanelId} deleted by user {UserId}", InterviewPanelId, LoginDTO.UserId); return result; } catch (Exception ex) { GB5Trace.MarkFailed("delete-interviewpanel-failed", ex); _Logger.LogError(ex, "DeleteInterviewPanel failed for InterviewPanelId {InterviewPanelId}", InterviewPanelId); throw; } } } }