using GB5Shared.DTO.Framework.Criteria; using GB5Shared.DTO.Framework.Login; using GB5Shared.QueryExecutor; using GB5Shared.Resource.Response; using GB5Shared.Validation; using Newtonsoft.Json; using TMSDAL.CustomCode.EvaluationPlan; using TMSDAL.DTO.Evaluation.TMSDAL.DTO.EvaluationPlan; using TMSDAL.DTO.EvaluationTemplate; using TMSDAL.Query.EvaluationPlan; namespace TMSDAL.CustomCode.EvaluationPlan { public class EvaluationPlanDAL : IEvaluationPlanDAL { private readonly IQueryExecutor _QueryExecutor; private readonly IValidation _Validation; public EvaluationPlanDAL(IQueryExecutor queryExecutor, IValidation validation) { _QueryExecutor = queryExecutor; _Validation = validation; } // ═══════════════════════════════════════════════════════════════════════ // PLAN — GET SINGLE // ═══════════════════════════════════════════════════════════════════════ public async Task GetEvaluationPlan(int evaluationPlanId, LoginDTO loginDTO) { try { // Step 1: Fetch plan header var plan = await _QueryExecutor.QuerySingleAsync( loginDTO, EvaluationPlanQB.GET_EVALUATIONPLAN, new { EvaluationPlanId = evaluationPlanId, TenantId = loginDTO.ClientId }); if (plan == null) return JsonConvert.SerializeObject(null); // Step 2: Fetch templates for this plan plan.Templates = (await _QueryExecutor.QueryAsync( loginDTO, EvaluationPlanQB.GET_TEMPLATES_BY_PLAN, new { EvaluationPlanId = evaluationPlanId })).ToList(); return JsonConvert.SerializeObject(plan); } catch (Exception) { throw; } } // ═══════════════════════════════════════════════════════════════════════ // PLAN — GET LIST // ═══════════════════════════════════════════════════════════════════════ public async Task GetEvaluationPlanList(LoginDTO loginDTO) { try { // Step 1: Fetch all plans var plans = (await _QueryExecutor.QueryAsync( loginDTO, EvaluationPlanQB.GET_EVALUATIONPLAN_LIST, new { TenantId = loginDTO.ClientId })).ToList(); if (!plans.Any()) return JsonConvert.SerializeObject(plans); // Step 2: Fetch all templates in one shot using IN @PlanIds var planIds = plans.Select(p => p.EvaluationPlanId).ToList(); var templates = (await _QueryExecutor.QueryAsync( loginDTO, EvaluationPlanQB.GET_TEMPLATES_BY_PLAN_IDS, new { EvaluationPlanIds = planIds })).ToList(); // Step 3: Group templates and map into plans var templateMap = templates .GroupBy(t => t.EvaluationPlanId) .ToDictionary(g => g.Key, g => g.ToList()); foreach (var plan in plans) plan.Templates = templateMap.GetValueOrDefault(plan.EvaluationPlanId); return JsonConvert.SerializeObject(plans); } catch (Exception) { throw; } } // ═══════════════════════════════════════════════════════════════════════ // PLAN — GET SELECTLIST // ═══════════════════════════════════════════════════════════════════════ public async Task GetSelectListEvaluationPlan(CriteriaDTO criteriaDTO, LoginDTO loginDTO) { var result = await _QueryExecutor.QueryWithCriteriaAsync( loginDTO, EvaluationPlanQB.GET_SELECTLIST_EVALUATIONPLAN, new { TenantId = loginDTO.ClientId }, criteriaDTO); return JsonConvert.SerializeObject(result); } // ═══════════════════════════════════════════════════════════════════════ // PLAN — SAVE // ═══════════════════════════════════════════════════════════════════════ public async Task SaveEvaluationPlan(EvaluationPlanDTO dto, LoginDTO loginDTO) { try { return await _QueryExecutor.ExecuteAsync( loginDTO, EvaluationPlanQB.SAVE_EVALUATIONPLAN, dto); } catch (Exception ex) { string error = await _Validation.HandleException(ex, ErrorResponse.SaveErrorMessage); throw new Exception(error); } } // ═══════════════════════════════════════════════════════════════════════ // PLAN — UPDATE // ═══════════════════════════════════════════════════════════════════════ public async Task UpdateEvaluationPlan(EvaluationPlanDTO dto, LoginDTO loginDTO) { try { return await _QueryExecutor.ExecuteAsync( loginDTO, EvaluationPlanQB.UPDATE_EVALUATIONPLAN, dto); } catch (Exception ex) { string error = await _Validation.HandleException(ex, ErrorResponse.UpdateErrorMessage); throw new Exception(error); } } // ═══════════════════════════════════════════════════════════════════════ // PLAN — DELETE // ═══════════════════════════════════════════════════════════════════════ public async Task DeleteEvaluationPlan(int evaluationPlanId, LoginDTO loginDTO) { try { // Step 1: Delete all templates first (FK constraint) await _QueryExecutor.ExecuteAsync( loginDTO, EvaluationPlanQB.DELETE_TEMPLATES_BY_PLAN, new { EvaluationPlanId = evaluationPlanId }); // Step 2: Delete plan header int rowsAffected = await _QueryExecutor.ExecuteAsync( loginDTO, EvaluationPlanQB.DELETE_EVALUATIONPLAN, new { EvaluationPlanId = evaluationPlanId, TenantId = loginDTO.ClientId }); return rowsAffected > 0 ? SuccessResponse.DeleteSuccessMessage : ErrorResponse.DeleteNotFoundMessage; } catch (Exception ex) { string error = await _Validation.HandleException(ex, ErrorResponse.DeleteErrorMessage); throw new Exception(error); } } // ═══════════════════════════════════════════════════════════════════════ // TEMPLATE — GET SINGLE // ═══════════════════════════════════════════════════════════════════════ public async Task GetEvaluationTemplate(int evaluationTemplateId, LoginDTO loginDTO) { try { var result = await _QueryExecutor.QuerySingleAsync( loginDTO, EvaluationPlanQB.GET_EVALUATIONTEMPLATE, new { EvaluationTemplateId = evaluationTemplateId }); return JsonConvert.SerializeObject(result); } catch (Exception) { throw; } } // ═══════════════════════════════════════════════════════════════════════ // TEMPLATE — SAVE // ═══════════════════════════════════════════════════════════════════════ public async Task SaveEvaluationTemplate(EvaluationTemplateDTO dto, LoginDTO loginDTO) { try { return await _QueryExecutor.ExecuteAsync( loginDTO, EvaluationPlanQB.SAVE_EVALUATIONTEMPLATE, dto); } catch (Exception ex) { string error = await _Validation.HandleException(ex, ErrorResponse.SaveErrorMessage); throw new Exception(error); } } // ═══════════════════════════════════════════════════════════════════════ // TEMPLATE — UPDATE // ═══════════════════════════════════════════════════════════════════════ public async Task UpdateEvaluationTemplate(EvaluationTemplateDTO dto, LoginDTO loginDTO) { try { return await _QueryExecutor.ExecuteAsync( loginDTO, EvaluationPlanQB.UPDATE_EVALUATIONTEMPLATE, dto); } catch (Exception ex) { string error = await _Validation.HandleException(ex, ErrorResponse.UpdateErrorMessage); throw new Exception(error); } } // ═══════════════════════════════════════════════════════════════════════ // TEMPLATE — DELETE SINGLE // ═══════════════════════════════════════════════════════════════════════ public async Task DeleteEvaluationTemplate(int evaluationTemplateId, LoginDTO loginDTO) { try { int rowsAffected = await _QueryExecutor.ExecuteAsync( loginDTO, EvaluationPlanQB.DELETE_EVALUATIONTEMPLATE, new { EvaluationTemplateId = evaluationTemplateId }); return rowsAffected > 0 ? SuccessResponse.DeleteSuccessMessage : ErrorResponse.DeleteNotFoundMessage; } catch (Exception ex) { string error = await _Validation.HandleException(ex, ErrorResponse.DeleteErrorMessage); throw new Exception(error); } } // ═══════════════════════════════════════════════════════════════════════ // TEMPLATE — DELETE ALL BY PLAN // ═══════════════════════════════════════════════════════════════════════ public async Task DeleteTemplatesByPlan(int evaluationPlanId, LoginDTO loginDTO) { try { return await _QueryExecutor.ExecuteAsync( loginDTO, EvaluationPlanQB.DELETE_TEMPLATES_BY_PLAN, new { EvaluationPlanId = evaluationPlanId }); } catch (Exception ex) { string error = await _Validation.HandleException(ex, ErrorResponse.DeleteErrorMessage); throw new Exception(error); } } } }