using SoapService.Models; namespace SoapService.Services; public class WsServicioDeInformacion : IWsServicioDeInformacion { private static readonly Dictionary _personasGeneradas = new(); private static readonly Random _random = new(); // Expanded lists of Uruguayan names and surnames private static readonly string[] _nombresHombre = { "Juan", "Carlos", "Martín", "Luis", "Diego", "Marcelo", "Alejandro", "Fernando", "Matías", "Pablo", "Eduardo", "Federico", "Gonzalo", "Sergio", "Daniel", "Raúl", "Gabriel", "Andrés", "Nicolás", "Roberto", "Sebastián", "Héctor", "Gustavo", "Leonardo", "Rodrigo", "Gerardo", "Ricardo", "Santiago", "Ignacio", "Emiliano", "Dante", "Agustín", "Julio", "Mario", "Alfredo", "Bruno", "Mauricio" }; private static readonly string[] _nombresMujer = { "María", "Ana", "Laura", "Sofía", "Lucía", "Valentina", "Natalia", "Andrea", "Gabriela", "Carolina", "Verónica", "Claudia", "Patricia", "Alejandra", "Victoria", "Soledad", "Carmen", "Isabel", "Cecilia", "Paula", "Florencia", "Silvia", "Leticia", "Jimena", "Romina", "Agustina", "Lorena", "Camila", "Valeria", "Daniela", "Mariana", "Eugenia", "Rosario", "Pilar", "Adriana", "Carla", "Micaela", "Magdalena", "Inés" }; private static readonly string[] _segundosNombres = { "José", "Pablo", "Elena", "Inés", "Alberto", "Miguel", "Beatriz", "Javier", "Alejandro", "Antonio", "Teresa", "Francisco", "Manuel", "Mercedes", "Rosario", "Ernesto", "Juana", "Felipe", "Jaime", "Clara", "Ignacio", "Ángel", "Joaquín", "Rafael", "Susana", "Héctor", "Alicia", "Marta", "Luciana", "Mateo", "Margarita" }; private static readonly string[] _apellidos = { "Rodríguez", "Fernández", "García", "Martínez", "López", "González", "Pérez", "Gómez", "Sánchez", "Romero", "Silva", "Castro", "Torres", "Álvarez", "Benítez", "Ramírez", "Flores", "Herrera", "Gutiérrez", "Suárez", "Rojas", "Vargas", "Acosta", "Morales", "Giménez", "Cardozo", "Méndez", "Delgado", "Díaz", "Pereyra", "Olivera", "Ferreira", "Núñez", "Castillo", "Aguirre", "Duarte", "Sosa", "Vázquez", "Techera", "Medina", "Hernández", "Cabrera", "Machado", "Bentancor", "Moreira", "Fagúndez", "Pintos" }; public ResultObtDocDigitalizado ObtDocDigitalizado(ParamObtDocDigitalizado param) { // Validate input parameters if (string.IsNullOrEmpty(param?.NroDocumento) || string.IsNullOrEmpty(param?.NroSerie) || string.IsNullOrEmpty(param?.Organismo) || string.IsNullOrEmpty(param?.ClaveAcceso1)) { return CreateErrorResult(ErrorCodes.ErroresGraves.ParametrosIncorrectos, ErrorCodes.ErroresGraves.ParametrosIncorrectosMensaje); } try { int seed = GetSeedFromCI(param.NroDocumento); Random randomCI = new(seed); var (errors, warnings) = CheckErrorsAndWarnings(param.NroDocumento); if (errors.Any()) { return new ResultObtDocDigitalizado { Errores = errors.ToArray() }; } ObjPersona persona = GeneratePerson(param, randomCI); var images = GenerateImages(seed); return new ResultObtDocDigitalizado { Persona = persona, Imagenes = images, Warnings = warnings.Any() ? warnings.ToArray() : null }; } catch (Exception ex) { return CreateErrorResult(ErrorCodes.ErroresGraves.ConsultaNoCompletada, $"Error inesperado: {ex.Message}", ex.StackTrace!); } } private (List Errors, List Warnings) CheckErrorsAndWarnings(string nroDocumento) { var errors = new List(); var warnings = new List(); // Extract digits for error/warning checking string digits = new string(nroDocumento.Where(char.IsDigit).ToArray()); if (string.IsNullOrEmpty(digits)) { errors.Add(CreateMensaje(ErrorCodes.ErroresGraves.ParametrosIncorrectos, ErrorCodes.ErroresGraves.ParametrosIncorrectosMensaje)); return (errors, warnings); } string firstTwoDigits = digits.Length >= 2 ? digits.Substring(0, 2) : digits.PadRight(2, '0'); switch (firstTwoDigits) { case "11": // Persona inexistente errors.Add(CreateMensaje(ErrorCodes.ErroresLeves.PersonaInexistente, ErrorCodes.ErroresLeves.PersonaInexistenteMensaje)); return (errors, warnings); case "12": // Límite excedido errors.Add(CreateMensaje(ErrorCodes.ErroresLeves.LimiteConsultasExcedido, ErrorCodes.ErroresLeves.LimiteConsultasExcedidoMensaje)); return (errors, warnings); case "13": // Cédula anulada errors.Add(CreateMensaje(ErrorCodes.ErroresLeves.NumeroCedulaAnulado, ErrorCodes.ErroresLeves.NumeroCedulaAnuladoMensaje)); return (errors, warnings); case "14": // Regularización needed warnings.Add(CreateMensaje(ErrorCodes.Warnings.DatosPersonaRegularizar, ErrorCodes.Warnings.DatosPersonaRegularizarMensaje)); break; case "15": // Documento hurtado warnings.Add(CreateMensaje(ErrorCodes.Warnings.DocumentoHurtadoExtraviado, ErrorCodes.Warnings.DocumentoHurtadoExtraviadoMensaje)); break; } return (errors, warnings); } private ObjPersona GeneratePerson(ParamObtDocDigitalizado param, Random randomCI) { // Return cached person if exists if (_personasGeneradas.TryGetValue(param.NroDocumento, out var existingPerson)) { return existingPerson; } // Generate deterministic person data int sexo = randomCI.Next(1, 3); // 1 = Masculino, 2 = Femenino string nombre1 = sexo == 1 ? _nombresHombre[randomCI.Next(_nombresHombre.Length)] : _nombresMujer[randomCI.Next(_nombresMujer.Length)]; string nombre2 = _segundosNombres[randomCI.Next(_segundosNombres.Length)]; string apellido1 = _apellidos[randomCI.Next(_apellidos.Length)]; string apellido2 = _apellidos[randomCI.Next(_apellidos.Length)]; // Optional adoptive surnames string? apellidoAdoptivo1 = randomCI.NextDouble() < 0.1 ? _apellidos[randomCI.Next(_apellidos.Length)] : null; string? apellidoAdoptivo2 = apellidoAdoptivo1 != null && randomCI.NextDouble() < 0.5 ? _apellidos[randomCI.Next(_apellidos.Length)] : null; // Extract last two digits of document number for age string digits = new string(param.NroDocumento.Where(char.IsDigit).ToArray()); string lastTwoDigits = digits.Length >= 2 ? digits[^2..] : digits.PadLeft(2, '0'); int edad = int.Parse(lastTwoDigits); // Ensure age is reasonable (e.g., 0-99); adjust if needed edad = Math.Clamp(edad, 0, 99); // Generate birth date based on age DateTime fechaNacimiento = DateTime.Now.AddYears(-edad).AddDays(-randomCI.Next(0, 365)); string fechaNacimientoStr = fechaNacimiento.ToString("yyyy-MM-dd"); // Build full name string nombreCompleto = $"{nombre1} {nombre2} {apellido1} {apellido2}"; if (apellidoAdoptivo1 != null) { nombreCompleto += $" {apellidoAdoptivo1}"; if (apellidoAdoptivo2 != null) nombreCompleto += $" {apellidoAdoptivo2}"; } // Create person var persona = new ObjPersona { CodTipoDocumento = param.TipoDocumento, NroDocumento = param.NroDocumento, Nombre1 = nombre1, Nombre2 = nombre2, PrimerApellido = apellido1, SegundoApellido = apellido2, ApellidoAdoptivo1 = apellidoAdoptivo1!, ApellidoAdoptivo2 = apellidoAdoptivo2!, Sexo = sexo, FechaNacimiento = fechaNacimientoStr, CodNacionalidad = randomCI.Next(1, 3), // 1 = Oriental, 2 = Extranjero NombreEnCedula = nombreCompleto, IdSolicitud = 10000 + (randomCI.Next(0, 90000)), IdRespuesta = 10000 + (randomCI.Next(0, 90000)) }; // Cache the person _personasGeneradas[param.NroDocumento] = persona; return persona; } private ImagenDigital[] GenerateImages(int seed) { Random randomImage = new(seed); int length1 = 100 + (randomImage.Next(0, 300)); // 100-399 bytes int length2 = 100 + (randomImage.Next(0, 300)); // 100-399 bytes return new[] { new ImagenDigital { Foto = "No Implementado...", LargoBytes = length1, TipoImagen = 1 }, new ImagenDigital { Foto = "No Implementado...", LargoBytes = length2, TipoImagen = 2 } }; } private int GetSeedFromCI(string nroDocumento) { string digits = new string(nroDocumento.Where(char.IsDigit).ToArray()); if (string.IsNullOrEmpty(digits)) { return 12345; } if (digits.Length > 8) { digits = digits[^8..]; } return int.TryParse(digits, out int seed) ? seed : 12345; } private ResultObtDocDigitalizado CreateErrorResult(int code, string message, string extraData = "Trace") { return new ResultObtDocDigitalizado { Errores = new[] { CreateMensaje(code, message, extraData) } }; } private Mensaje CreateMensaje(int code, string description, string extraData = "Trace") { return new Mensaje { CodMensaje = code, Descripcion = description, DatoExtra = extraData }; } }