using System.Data.Common; using GB5Shared.DTO.Framework.Login; using GB5Shared.QueryExecutor; using GB5Shared.ResponseStandard; using PIEDAL.DTO.Estimation; using PIEDAL.Query.Estimation; namespace PIEDAL.CustomCode.Estimation; public class PIEEstimationDAL : IPIEEstimationDAL { private readonly IQueryExecutor _QueryExecutor; public PIEEstimationDAL(IQueryExecutor queryExecutor) { _QueryExecutor = queryExecutor; } // ── Rule reads ──────────────────────────────────────────────────────────── public async Task GetPIEEstimationRuleAsync( Guid ruleId, LoginDTO login, CancellationToken ct) => await _QueryExecutor.QuerySingleAsync( login, PIEEstimationRuleQB.GET_BY_ID, new { RuleId = ruleId }, cancellationToken: ct).ConfigureAwait(false); public async Task> GetActiveRulesByModuleIdsAsync( Guid[] moduleIds, short engagementType, short complexityLevel, LoginDTO login, CancellationToken ct) { // ANY(@ModuleIds) — Npgsql resolves Guid[] automatically var param = new { ModuleIds = moduleIds, EngagementType = engagementType, ComplexityLevel = complexityLevel }; return await _QueryExecutor.QueryAsync( login, PIEEstimationRuleQB.GET_ACTIVE_RULES_BY_MODULE_IDS, param, cancellationToken: ct).ConfigureAwait(false) ?? Enumerable.Empty(); } // ── Snapshot reads ──────────────────────────────────────────────────────── public async Task GetSnapshotByEngagementAsync( string engagementRef, LoginDTO login, CancellationToken ct) => await _QueryExecutor.QuerySingleAsync( login, PIEEstimationRuleQB.GET_SNAPSHOT_BY_ENGAGEMENT, new { EngagementRef = engagementRef }, cancellationToken: ct).ConfigureAwait(false); // ── Rule writes ─────────────────────────────────────────────────────────── public async Task> SavePIEEstimationRuleAsync( PIEEstimationRuleDTO dto, LoginDTO login, DbTransaction tx, CancellationToken ct) { dto.CreatedBy = login.UserId; dto.CreatedAt = DateTime.UtcNow; dto.UpdatedBy = login.UserId; dto.UpdatedAt = DateTime.UtcNow; int rows = await _QueryExecutor.ExecuteAsync( login, PIEEstimationRuleQB.INSERT, dto, tx, cancellationToken: ct).ConfigureAwait(false); return rows > 0 ? Result.Success("PIE estimation rule saved.") : Result.Failure("Failed to save PIE estimation rule."); } public async Task> UpdatePIEEstimationRuleAsync( PIEEstimationRuleDTO dto, LoginDTO login, DbTransaction tx, CancellationToken ct) { dto.UpdatedBy = login.UserId; dto.UpdatedAt = DateTime.UtcNow; int rows = await _QueryExecutor.ExecuteAsync( login, PIEEstimationRuleQB.UPDATE, dto, tx, cancellationToken: ct).ConfigureAwait(false); return rows > 0 ? Result.Success("PIE estimation rule updated.") : Result.Failure("PIE estimation rule not found or not updated."); } public async Task> SoftDeletePIEEstimationRuleAsync( Guid ruleId, LoginDTO login, DbTransaction tx, CancellationToken ct) { var param = new { RuleId = ruleId, UpdatedAt = DateTime.UtcNow, UpdatedBy = login.UserId }; int rows = await _QueryExecutor.ExecuteAsync( login, PIEEstimationRuleQB.SOFT_DELETE, param, tx, cancellationToken: ct).ConfigureAwait(false); return rows > 0 ? Result.Success("PIE estimation rule deactivated.") : Result.Failure("PIE estimation rule not found or already inactive."); } // ── Snapshot writes (insert-only) ───────────────────────────────────────── public async Task> InsertSnapshotAsync( PIEEstimationSnapshotDTO dto, LoginDTO login, DbTransaction tx, CancellationToken ct) { dto.CreatedBy = login.UserId; dto.CreatedAt = DateTime.UtcNow; int rows = await _QueryExecutor.ExecuteAsync( login, PIEEstimationRuleQB.INSERT_SNAPSHOT, dto, tx, cancellationToken: ct).ConfigureAwait(false); return rows > 0 ? Result.Success("PIE estimation snapshot recorded.") : Result.Failure("Failed to record PIE estimation snapshot."); } }