using System.ComponentModel.DataAnnotations; using GB5Shared.DTO.Framework.Login; using GB5Shared.Resource.Response; using GB5Shared.Telemetry; using GB5Shared.Validation; using Microsoft.Extensions.Logging; using PartnerBLL.PartnerTerm; using PartnerDAL.CustomCode.PartnerTerm; using PartnerDAL.DTO.PartnerTerm; namespace PartnerBLL.Implementations { public class PartnerTermBLL : IPartnerTermBLL { private readonly IPartnerTermDAL _partnerTermDAL; private readonly IValidation _validation; private readonly ILogger _logger; public PartnerTermBLL(IPartnerTermDAL partnerTermDAL, IValidation validation, ILogger logger) { _partnerTermDAL = partnerTermDAL; _validation = validation; _logger = logger; } // TPARTNERTERM.LANGUAGEID stays INT (no schema change) even though MUSER.LANGUAGEID // is a real code ('EN', 'TN', ...) — there is no numeric language master table in // this framework, so this fixed map is the only place the code<->id relationship // is recorded. Add a new entry here whenever a new MUSER.LANGUAGEID code needs its // own PartnerTerm rows; anything unmapped falls back to English (1). private static readonly Dictionary LanguageCodeToId = new(StringComparer.OrdinalIgnoreCase) { ["EN"] = 1, // English — confirmed in live MUSER data ["TN"] = 2, // Tamil — confirmed in live MUSER data // Add further codes here as MUSER starts using them — MUSER.LANGUAGEID is // NVARCHAR(2), so any new code must also fit two characters, e.g.: // ["HI"] = 3, // Hindi // ["TE"] = 4, // Telugu // ["KN"] = 5, // Kannada // ["ML"] = 6, // Malayalam }; private const int DEFAULT_LANGUAGE_ID = 1; // EN private static int ResolveLanguageId(string? languageCode) => !string.IsNullOrWhiteSpace(languageCode) && LanguageCodeToId.TryGetValue(languageCode.Trim(), out var id) ? id : DEFAULT_LANGUAGE_ID; public async Task GetTerminologyBundle(LoginDTO loginDTO) { try { int languageId = ResolveLanguageId(loginDTO.LanguageId); return await _partnerTermDAL.GetTerminologyBundle( loginDTO.ClientId, languageId, loginDTO).ConfigureAwait(false); } catch (Exception) { throw; } } public async Task GetPartnerTerm(int partnerProductId, string languageId, LoginDTO loginDTO) { try { int lang = ResolveLanguageId(languageId); return await _partnerTermDAL.GetPartnerTerm(partnerProductId, lang, loginDTO).ConfigureAwait(false); } catch (Exception) { throw; } } public async Task SavePartnerTerm(PartnerTermDTO dto, LoginDTO loginDTO) { if (dto == null) throw new ArgumentNullException(nameof(dto)); try { GB5Trace.Step("validate-partner-term", new { dto.PartnerProductId, dto.TermKey }); if (dto.PartnerProductId == 0) throw new ValidationException("PartnerProductId is required."); await _validation.NotEmpty(dto.TermKey, nameof(dto.TermKey)); await _validation.NotEmpty(dto.TermValue, nameof(dto.TermValue)); bool isNew = dto.PartnerTermId == 0; dto.ModifiedById = loginDTO.UserId; dto.ModifiedOn = DateTime.UtcNow; GB5Trace.Step("save-partner-term", new { dto.PartnerTermId, isNew }); if (isNew) { dto.CreatedById = loginDTO.UserId; dto.CreatedOn = DateTime.UtcNow; int newId = await _partnerTermDAL.SavePartnerTerm(dto, loginDTO).ConfigureAwait(false); return $"{SuccessResponse.SaveSuccessMessage} {newId}"; } else { await _partnerTermDAL.UpdatePartnerTerm(dto, loginDTO).ConfigureAwait(false); return $"{SuccessResponse.UpdateSuccessMessage} {dto.PartnerTermId}"; } } catch (ValidationException vex) { throw new Exception(vex.Message); } catch (Exception ex) { GB5Trace.MarkFailed("save-partner-term-failed", ex); _logger.LogError(ex, "SavePartnerTerm failed for PartnerProductId {PartnerProductId} TermKey {TermKey}", dto.PartnerProductId, dto.TermKey); throw; } } public async Task DeletePartnerTerm(int partnerTermId, LoginDTO loginDTO) { try { int rows = await _partnerTermDAL.DeletePartnerTerm(partnerTermId, loginDTO).ConfigureAwait(false); return rows > 0 ? SuccessResponse.DeleteSuccessMessage : ErrorResponse.DeleteNotFoundMessage; } catch (Exception ex) { GB5Trace.MarkFailed("delete-partner-term-failed", ex); _logger.LogError(ex, "DeletePartnerTerm failed for PartnerTermId {PartnerTermId}", partnerTermId); throw; } } } }