using FrameworkDAL.DTO.Project; using FrameworkDAL.DTO.Region; using FrameworkDAL.Query.Region; using GB5Shared.DTO.Framework.Criteria; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using GB5Shared.QueryExecutor; using FrameworkDAL.Query.Module; using GB5Shared.DTO.Framework.Login; using GB5Shared.ResponseStandard; using GB5Shared.Telemetry; using Newtonsoft.Json; using System.Data.Common; namespace FrameworkDAL.CustomCode.Module { public class ModuleDAL : IModuleDAL { private readonly IQueryExecutor _queryExecutor; public ModuleDAL(IQueryExecutor queryExecutor) { _queryExecutor = queryExecutor; } public async Task GetModuleList(LoginDTO LoginDTO, string? module = null) { string Json = ""; try { string Sql = ModuleQB.GET_MODULE_LIST; var parameter = new { roleid = LoginDTO.RoleId, userid = LoginDTO.UserId, languageid = LoginDTO.LanguageId, partnerproductid = LoginDTO.PartnerProductId }; List ModuleLoadingDTOS = (await _queryExecutor.QueryAsync(LoginDTO, Sql, parameter,null!,true)).ToList(); var (filtered, strategy) = FilterByModule(ModuleLoadingDTOS, module); // Full detail of the module-filter decision as a searchable tag + timeline step, // visible in Zipkin on the same span/trace as the db.statement/db.params tags. GB5Trace.Tag("gb5.module.filter.strategy", strategy); GB5Trace.Step("filter-module-list", new { module, strategy, totalModules = ModuleLoadingDTOS.Count, matchedModules = filtered.Count }); Json = JsonConvert.SerializeObject(filtered); return Json; } catch (Exception) { throw; } } // Narrows the module list to whatever the caller's subdomain (e.g. "hrms", "crm", "costing") // resolves to, by name first then by code. Falls back to the full unfiltered list whenever // "module" is null/blank or matches nothing, so existing callers/behaviour are unaffected. private static (List Result, string Strategy) FilterByModule(List modules, string? module) { if (string.IsNullOrWhiteSpace(module)) return (modules, "no-module-unfiltered"); var byName = modules.Where(m => !string.IsNullOrEmpty(m.ModuleName) && m.ModuleName.IndexOf(module, StringComparison.OrdinalIgnoreCase) >= 0).ToList(); if (byName.Count > 0) return (byName, "matched-by-name"); var byCode = modules.Where(m => !string.IsNullOrEmpty(m.ModuleCode) && m.ModuleCode.IndexOf(module, StringComparison.OrdinalIgnoreCase) >= 0).ToList(); if (byCode.Count > 0) return (byCode, "matched-by-code"); return (modules, "no-match-fallback-unfiltered"); } public async Task GetSelectListModule(CriteriaDTO CriteriaDTO, LoginDTO LoginDTO) { try { string SQL = ModuleQB.GET_SELECTLIST_MODULE; var Result = await _queryExecutor.QueryAsync(LoginDTO, SQL, null!); string Json = JsonConvert.SerializeObject(Result); return Json; } catch (Exception) { throw; } } public async Task> SaveModule(ModuleDTO ModuleDTO, LoginDTO LoginDTO, DbTransaction Transaction) { try { ModuleDTO.ModuleCreatedById = LoginDTO.UserId; ModuleDTO.ModuleCreatedOn = DateTime.UtcNow; ModuleDTO.ModuleModifiedById = LoginDTO.UserId; ModuleDTO.ModuleModifiedOn = DateTime.UtcNow; string Sql = ModuleQB.SAVE_MODULE; int result = await _queryExecutor.ExecuteAsync(LoginDTO, Sql, ModuleDTO, Transaction); if (result > 0) { return Result.Success("Module saved successfully."); } else { return Result.Failure("Failed to save module."); } } catch (Exception) { throw; } } public async Task> UpdateModule(ModuleDTO ModuleDTO, LoginDTO LoginDTO, DbTransaction Transaction) { try { ModuleDTO.ModuleModifiedById = LoginDTO.UserId; ModuleDTO.ModuleModifiedOn = DateTime.UtcNow; string Sql = ModuleQB.UPDATE_MODULE; int result = await _queryExecutor.ExecuteAsync(LoginDTO, Sql, ModuleDTO, Transaction); if (result > 0) { return Result.Success("Module updated successfully."); } else { return Result.Failure("Failed to update module."); } } catch (Exception) { throw; } } public async Task GetModule(int ModuleId, LoginDTO LoginDTO) { string Json = ""; try { string Sql = ModuleQB.GET_MODULE; var parameter = new { ModuleId = ModuleId }; var Result = await _queryExecutor.QuerySingleAsync(LoginDTO, Sql, parameter); Json = JsonConvert.SerializeObject(Result); return Json; } catch (Exception) { throw; } } public async Task> DeleteModule(int ModuleId, LoginDTO LoginDTO) { try { string Sql = ModuleQB.DELETE_MODULE; var parameter = new { ModuleId = ModuleId }; var result = await _queryExecutor.ExecuteAsync(LoginDTO, Sql, parameter); if (result > 0) { return Result.Success("Module deleted successfully."); } else { return Result.Failure("Module not found or could not be deleted."); } } catch (Exception ex) { throw new Exception("Error while deleting Module Details", ex); } } } }