using FrameworkDAL.DTO.EIPConversation; using FrameworkDAL.Query.EIPConversation.EIPCapabilityAdmin; using GB5Shared.DTO.Framework.Login; using GB5Shared.GenerateAutoNumber; using GB5Shared.QueryExecutor; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using static GB5Shared.GB5Constant.Constant; namespace FrameworkDAL.CustomCode.EIPConversation.EIPCapabilityAdmin { public class EIPCapabilityAdminDAL : IEIPCapabilityAdminDAL { private readonly IQueryExecutor _qe; private readonly AutoNumber _autoNumber; private readonly ILogger _logger; public EIPCapabilityAdminDAL(IQueryExecutor qe, AutoNumber autoNumber, ILogger logger) { _qe = qe ?? throw new ArgumentNullException(nameof(qe)); _autoNumber = autoNumber ?? throw new ArgumentNullException(nameof(autoNumber)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } public async Task> GetCapabilityListAsync( string? search, LoginDTO login, CancellationToken ct = default) { ct.ThrowIfCancellationRequested(); try { _logger.LogInformation( "DAL | GetCapabilityList | Tenant={TenantId} | Search={Search}", login.ClientId, search); var result = await _qe.QueryAsync( login, EIPCapabilityAdminQB.GET_CAPABILITY_LIST, new { TenantId = login.ClientId, Search = search }, cancellationToken: ct).ConfigureAwait(false); return result ?? []; } catch (OperationCanceledException) { _logger.LogWarning("DAL | GetCapabilityList | Cancelled | Tenant={TenantId}", login.ClientId); throw; } catch (Exception ex) { _logger.LogError(ex, "DAL | GetCapabilityList | Error | Tenant={TenantId}", login.ClientId); throw; } } public async Task GetCapabilityAsync( int capabilityId, LoginDTO login, CancellationToken ct = default) { ct.ThrowIfCancellationRequested(); try { _logger.LogInformation( "DAL | GetCapability | Tenant={TenantId} | CapabilityId={CapabilityId}", login.ClientId, capabilityId); return await _qe.QuerySingleAsync( login, EIPCapabilityAdminQB.GET_CAPABILITY, new { CapabilityId = capabilityId, TenantId = login.ClientId }, cancellationToken: ct).ConfigureAwait(false); } catch (OperationCanceledException) { _logger.LogWarning("DAL | GetCapability | Cancelled | CapabilityId={Id}", capabilityId); throw; } catch (Exception ex) { _logger.LogError(ex, "DAL | GetCapability | Error | CapabilityId={Id}", capabilityId); throw; } } public async Task InsertCapabilityAsync( EIPCapabilityAdminDTO dto, LoginDTO login, CancellationToken ct = default) { ct.ThrowIfCancellationRequested(); try { _logger.LogInformation( "DAL | InsertCapability | Tenant={TenantId} | CapabilityCode={CapabilityCode}", login.ClientId, dto.CapabilityCode); // CAPABILITYID is a plain INT PK (not IDENTITY) — must be generated here. var auto = await _autoNumber.GetNumberAsync(1, AUTONUMBERCONSTANT.EIPCAPABILITY, login) .ConfigureAwait(false); var newId = auto.StartNumber; await _qe.ExecuteAsync( login, EIPCapabilityAdminQB.INSERT_CAPABILITY, new { CapabilityId = newId, TenantId = login.ClientId, dto.CapabilityCode, dto.CapabilityName, dto.Description, dto.RiskLevel, dto.RequiresOtp, dto.RequiresApproval, dto.AuditRequired, dto.CapabilityVersion, dto.IsActive, dto.Version, CreatedById = login.UserId }, cancellationToken: ct).ConfigureAwait(false); _logger.LogInformation("DAL | InsertCapability | Completed | NewId={NewId}", newId); return newId; } catch (OperationCanceledException) { _logger.LogWarning("DAL | InsertCapability | Cancelled | CapabilityCode={Code}", dto.CapabilityCode); throw; } catch (Exception ex) { _logger.LogError(ex, "DAL | InsertCapability | Error | CapabilityCode={Code}", dto.CapabilityCode); throw; } } public async Task UpdateCapabilityAsync( EIPCapabilityAdminDTO dto, LoginDTO login, CancellationToken ct = default) { ct.ThrowIfCancellationRequested(); try { _logger.LogInformation( "DAL | UpdateCapability | Tenant={TenantId} | CapabilityId={CapabilityId}", login.ClientId, dto.CapabilityId); await _qe.ExecuteAsync( login, EIPCapabilityAdminQB.UPDATE_CAPABILITY, new { dto.CapabilityId, TenantId = login.ClientId, dto.CapabilityCode, dto.CapabilityName, dto.Description, dto.RiskLevel, dto.RequiresOtp, dto.RequiresApproval, dto.AuditRequired, dto.CapabilityVersion, dto.IsActive, dto.Version, ModifiedById = login.UserId }, cancellationToken: ct).ConfigureAwait(false); } catch (OperationCanceledException) { _logger.LogWarning("DAL | UpdateCapability | Cancelled | CapabilityId={Id}", dto.CapabilityId); throw; } catch (Exception ex) { _logger.LogError(ex, "DAL | UpdateCapability | Error | CapabilityId={Id}", dto.CapabilityId); throw; } } public async Task DeleteCapabilityAsync( int capabilityId, LoginDTO login, CancellationToken ct = default) { ct.ThrowIfCancellationRequested(); try { _logger.LogInformation( "DAL | DeleteCapability | Tenant={TenantId} | CapabilityId={CapabilityId}", login.ClientId, capabilityId); await _qe.ExecuteAsync( login, EIPCapabilityAdminQB.DELETE_CAPABILITY, new { CapabilityId = capabilityId, TenantId = login.ClientId, ModifiedById = login.UserId }, cancellationToken: ct).ConfigureAwait(false); } catch (OperationCanceledException) { _logger.LogWarning("DAL | DeleteCapability | Cancelled | CapabilityId={Id}", capabilityId); throw; } catch (Exception ex) { _logger.LogError(ex, "DAL | DeleteCapability | Error | CapabilityId={Id}", capabilityId); throw; } } public async Task CapabilityCodeExistsAsync( string capabilityCode, int excludeCapabilityId, LoginDTO login, CancellationToken ct = default) { ct.ThrowIfCancellationRequested(); var count = await _qe.ExecuteScalarAsync( login, EIPCapabilityAdminQB.EXISTS_CAPABILITYCODE, new { CapabilityCode = capabilityCode, CapabilityId = excludeCapabilityId }, cancellationToken: ct).ConfigureAwait(false); return count == 1; } } }