using EAIAdminDAL.DTO; using EAIAdminDAL.Query; 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 EAIAdminDAL.CustomCode { public class EAIInitiativeAdminDAL : IEAIInitiativeAdminDAL { private readonly IQueryExecutor _qe; private readonly AutoNumber _autoNumber; private readonly ILogger _logger; public EAIInitiativeAdminDAL(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> GetInitiativeListAsync( string? search, LoginDTO login, CancellationToken ct = default) { ct.ThrowIfCancellationRequested(); try { var searchPattern = string.IsNullOrWhiteSpace(search) ? null : $"%{search}%"; var result = await _qe.QueryAsync( login, EAIInitiativeAdminQB.GET_INITIATIVE_LIST, new { TenantId = login.ClientId, SearchPattern = searchPattern }, cancellationToken: ct).ConfigureAwait(false); return result ?? []; } catch (OperationCanceledException) { _logger.LogWarning("DAL | GetInitiativeList | Cancelled | Tenant={TenantId}", login.ClientId); throw; } catch (Exception ex) { _logger.LogError(ex, "DAL | GetInitiativeList | Error | Tenant={TenantId}", login.ClientId); throw; } } public async Task GetInitiativeAsync( int initiativeId, LoginDTO login, CancellationToken ct = default) { ct.ThrowIfCancellationRequested(); try { return await _qe.QuerySingleAsync( login, EAIInitiativeAdminQB.GET_INITIATIVE, new { InitiativeId = initiativeId, TenantId = login.ClientId }, cancellationToken: ct).ConfigureAwait(false); } catch (OperationCanceledException) { _logger.LogWarning("DAL | GetInitiative | Cancelled | InitiativeId={Id}", initiativeId); throw; } catch (Exception ex) { _logger.LogError(ex, "DAL | GetInitiative | Error | InitiativeId={Id}", initiativeId); throw; } } public async Task InsertInitiativeAsync( EAIInitiativeAdminDTO dto, LoginDTO login, CancellationToken ct = default) { ct.ThrowIfCancellationRequested(); try { // AIINITIATIVEID is a plain INT PK (not IDENTITY) — must be generated here. var auto = await _autoNumber.GetNumberAsync(1, AUTONUMBERCONSTANT.EAIINITIATIVE, login) .ConfigureAwait(false); var newId = auto.StartNumber; var now = DateTime.UtcNow; await _qe.ExecuteAsync( login, EAIInitiativeAdminQB.INSERT_INITIATIVE, new { InitiativeId = newId, TenantId = login.ClientId, dto.InitiativeCode, dto.InitiativeName, dto.MaturityLevel, dto.EAIRemoteId, dto.Version, CreatedById = login.UserId, CreatedOn = now }, cancellationToken: ct).ConfigureAwait(false); _logger.LogInformation("DAL | InsertInitiative | Completed | NewId={NewId}", newId); return newId; } catch (OperationCanceledException) { _logger.LogWarning("DAL | InsertInitiative | Cancelled | InitiativeCode={Code}", dto.InitiativeCode); throw; } catch (Exception ex) { _logger.LogError(ex, "DAL | InsertInitiative | Error | InitiativeCode={Code}", dto.InitiativeCode); throw; } } public async Task UpdateInitiativeAsync( EAIInitiativeAdminDTO dto, LoginDTO login, CancellationToken ct = default) { ct.ThrowIfCancellationRequested(); try { await _qe.ExecuteAsync( login, EAIInitiativeAdminQB.UPDATE_INITIATIVE, new { dto.InitiativeId, TenantId = login.ClientId, dto.InitiativeName, dto.MaturityLevel, dto.EAIRemoteId, dto.Version, ModifiedById = login.UserId, ModifiedOn = DateTime.UtcNow }, cancellationToken: ct).ConfigureAwait(false); } catch (OperationCanceledException) { _logger.LogWarning("DAL | UpdateInitiative | Cancelled | InitiativeId={Id}", dto.InitiativeId); throw; } catch (Exception ex) { _logger.LogError(ex, "DAL | UpdateInitiative | Error | InitiativeId={Id}", dto.InitiativeId); throw; } } public async Task UpdateEAIRemoteIdAsync( int initiativeId, long eaiRemoteId, LoginDTO login, CancellationToken ct = default) { ct.ThrowIfCancellationRequested(); await _qe.ExecuteAsync( login, EAIInitiativeAdminQB.UPDATE_EAIREMOTEID, new { InitiativeId = initiativeId, TenantId = login.ClientId, EAIRemoteId = eaiRemoteId }, cancellationToken: ct).ConfigureAwait(false); } public async Task DeleteInitiativeAsync( int initiativeId, LoginDTO login, CancellationToken ct = default) { ct.ThrowIfCancellationRequested(); try { await _qe.ExecuteAsync( login, EAIInitiativeAdminQB.DELETE_INITIATIVE, new { InitiativeId = initiativeId, TenantId = login.ClientId, ModifiedById = login.UserId, ModifiedOn = DateTime.UtcNow }, cancellationToken: ct).ConfigureAwait(false); } catch (OperationCanceledException) { _logger.LogWarning("DAL | DeleteInitiative | Cancelled | InitiativeId={Id}", initiativeId); throw; } catch (Exception ex) { _logger.LogError(ex, "DAL | DeleteInitiative | Error | InitiativeId={Id}", initiativeId); throw; } } public async Task InitiativeCodeExistsAsync( string initiativeCode, int excludeInitiativeId, LoginDTO login, CancellationToken ct = default) { ct.ThrowIfCancellationRequested(); var count = await _qe.ExecuteScalarAsync( login, EAIInitiativeAdminQB.EXISTS_INITIATIVECODE, new { InitiativeCode = initiativeCode, InitiativeId = excludeInitiativeId }, cancellationToken: ct).ConfigureAwait(false); return count == 1; } } }