automated dev commit
This commit is contained in:
commit
7551b4d824
18 changed files with 870 additions and 0 deletions
62
.dockerignore
Normal file
62
.dockerignore
Normal file
|
@ -0,0 +1,62 @@
|
|||
# Archivos y carpetas de desarrollo
|
||||
.vs/
|
||||
.vscode/
|
||||
.idea/
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# Carpetas de build
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Oo]ut/
|
||||
[Dd]ebug/
|
||||
[Rr]elease/
|
||||
x64/
|
||||
x86/
|
||||
build/
|
||||
msbuild.log
|
||||
msbuild.err
|
||||
msbuild.wrn
|
||||
|
||||
# Archivos temporales
|
||||
*.log
|
||||
*.logs
|
||||
*.tmp
|
||||
*.swp
|
||||
|
||||
# Archivos de Git y control de versiones
|
||||
.git/
|
||||
.gitignore
|
||||
.github/
|
||||
|
||||
# Archivos de Docker
|
||||
Dockerfile
|
||||
.dockerignore
|
||||
docker-compose*.yml
|
||||
|
||||
# Archivos de documentación y ejemplos
|
||||
README.md
|
||||
LICENSE
|
||||
*.md
|
||||
docs/
|
||||
examples/
|
||||
|
||||
# Archivos específicos de entorno
|
||||
.env
|
||||
*.env
|
||||
appsettings.*.json
|
||||
|
||||
# Archivos de pruebas
|
||||
[Tt]est*/
|
||||
*.Tests/
|
||||
TestResults/
|
||||
|
||||
# Paquetes NuGet
|
||||
*.nupkg
|
||||
packages/
|
||||
|
||||
# Archivos del sistema operativo
|
||||
.DS_Store
|
||||
Thumbs.db
|
161
.gitignore
vendored
Normal file
161
.gitignore
vendored
Normal file
|
@ -0,0 +1,161 @@
|
|||
# Visual Studio files
|
||||
.vs/
|
||||
.vscode/
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
build/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Oo]ut/
|
||||
msbuild.log
|
||||
msbuild.err
|
||||
msbuild.wrn
|
||||
|
||||
# ReSharper
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# Visual Studio cache/options directory
|
||||
.vs/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# DNX
|
||||
project.lock.json
|
||||
artifacts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/packages/repositories.config
|
||||
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# VS Code directories
|
||||
.vscode/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
# JetBrains Rider
|
||||
.idea/
|
||||
*.sln.iml
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
# Mac bundle stuff
|
||||
*.dmg
|
||||
*.app
|
||||
|
||||
# content below from: https://github.com/github/gitignore/blob/master/Global/macOS.gitignore
|
||||
# General
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
# content below from: https://github.com/github/gitignore/blob/master/Global/Windows.gitignore
|
||||
# Windows thumbnail cache files
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
ehthumbs_vista.db
|
||||
|
||||
# Dump file
|
||||
*.stackdump
|
||||
|
||||
# Folder config file
|
||||
[Dd]esktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
*.logs
|
0
Dockerfile
Normal file
0
Dockerfile
Normal file
46
Models/ErrorCodes.cs
Normal file
46
Models/ErrorCodes.cs
Normal file
|
@ -0,0 +1,46 @@
|
|||
namespace SoapService.Models;
|
||||
|
||||
public static class ErrorCodes
|
||||
{
|
||||
// Warnings (700-1000)
|
||||
public static class Warnings
|
||||
{
|
||||
public const int DatosPersonaRegularizar = 701;
|
||||
public const string DatosPersonaRegularizarMensaje = "Datos de Persona a regularizar";
|
||||
|
||||
public const int DocumentoHurtadoExtraviado = 702;
|
||||
public const string DocumentoHurtadoExtraviadoMensaje = "Documento Denunciado como Hurtado/Extraviado el ../../....";
|
||||
|
||||
public const int HojaInteriorHurtada = 703;
|
||||
public const string HojaInteriorHurtadaMensaje = "La Hoja interior Serie {0}, Número {1}, figura como hurtada";
|
||||
|
||||
public const int DocumentoNoUltimo = 704;
|
||||
public const string DocumentoNoUltimoMensaje = "El documento presentado no es el último gestionado";
|
||||
|
||||
public const int ValoresNoCoinciden = 705;
|
||||
public const string ValoresNoCoincidenMensaje = "Los valores del material no coinciden con el último documento digitalizado ingresado. Por favor, verifique los datos y digite nuevamente si corresponde.";
|
||||
}
|
||||
|
||||
// Errores Leves (> 1000)
|
||||
public static class ErroresLeves
|
||||
{
|
||||
public const int PersonaInexistente = 1001;
|
||||
public const string PersonaInexistenteMensaje = "Persona inexistente";
|
||||
|
||||
public const int LimiteConsultasExcedido = 1002;
|
||||
public const string LimiteConsultasExcedidoMensaje = "Límite de consultas excedido";
|
||||
|
||||
public const int NumeroCedulaAnulado = 1003;
|
||||
public const string NumeroCedulaAnuladoMensaje = "Número de cédula anulado";
|
||||
}
|
||||
|
||||
// Errores Graves (> 10000)
|
||||
public static class ErroresGraves
|
||||
{
|
||||
public const int ParametrosIncorrectos = 10001;
|
||||
public const string ParametrosIncorrectosMensaje = "Parámetros incorrectos";
|
||||
|
||||
public const int ConsultaNoCompletada = 10002;
|
||||
public const string ConsultaNoCompletadaMensaje = "No se pudo completar la consulta";
|
||||
}
|
||||
}
|
16
Models/ImagenDigital.cs
Normal file
16
Models/ImagenDigital.cs
Normal file
|
@ -0,0 +1,16 @@
|
|||
using System.Runtime.Serialization;
|
||||
|
||||
namespace SoapService.Models;
|
||||
|
||||
[DataContract(Namespace = "http://dnic.gub.uy/")]
|
||||
public class ImagenDigital
|
||||
{
|
||||
[DataMember(Order = 0)]
|
||||
public string Foto { get; set; }
|
||||
|
||||
[DataMember(Order = 1)]
|
||||
public int LargoBytes { get; set; }
|
||||
|
||||
[DataMember(Order = 2)]
|
||||
public int TipoImagen { get; set; }
|
||||
}
|
16
Models/Mensaje.cs
Normal file
16
Models/Mensaje.cs
Normal file
|
@ -0,0 +1,16 @@
|
|||
using System.Runtime.Serialization;
|
||||
|
||||
namespace SoapService.Models;
|
||||
|
||||
[DataContract(Namespace = "http://dnic.gub.uy/")]
|
||||
public class Mensaje
|
||||
{
|
||||
[DataMember(Order = 0)]
|
||||
public int CodMensaje { get; set; }
|
||||
|
||||
[DataMember(Order = 1)]
|
||||
public string Descripcion { get; set; }
|
||||
|
||||
[DataMember(Order = 2)]
|
||||
public string DatoExtra { get; set; }
|
||||
}
|
49
Models/ObjPersona.cs
Normal file
49
Models/ObjPersona.cs
Normal file
|
@ -0,0 +1,49 @@
|
|||
using System.Runtime.Serialization;
|
||||
|
||||
namespace SoapService.Models;
|
||||
|
||||
[DataContract(Namespace = "http://dnic.gub.uy/")]
|
||||
public class ObjPersona
|
||||
{
|
||||
[DataMember(Order = 0)]
|
||||
public string CodTipoDocumento { get; set; }
|
||||
|
||||
[DataMember(Order = 1)]
|
||||
public string NroDocumento { get; set; }
|
||||
|
||||
[DataMember(Order = 2)]
|
||||
public string Nombre1 { get; set; }
|
||||
|
||||
[DataMember(Order = 3)]
|
||||
public string Nombre2 { get; set; }
|
||||
|
||||
[DataMember(Order = 4)]
|
||||
public string PrimerApellido { get; set; }
|
||||
|
||||
[DataMember(Order = 5)]
|
||||
public string SegundoApellido { get; set; }
|
||||
|
||||
[DataMember(Order = 6)]
|
||||
public string ApellidoAdoptivo1 { get; set; }
|
||||
|
||||
[DataMember(Order = 7)]
|
||||
public string ApellidoAdoptivo2 { get; set; }
|
||||
|
||||
[DataMember(Order = 8)]
|
||||
public int Sexo { get; set; }
|
||||
|
||||
[DataMember(Order = 9)]
|
||||
public string FechaNacimiento { get; set; }
|
||||
|
||||
[DataMember(Order = 10)]
|
||||
public int CodNacionalidad { get; set; }
|
||||
|
||||
[DataMember(Order = 11)]
|
||||
public string NombreEnCedula { get; set; }
|
||||
|
||||
[DataMember(Order = 12)]
|
||||
public int IdSolicitud { get; set; }
|
||||
|
||||
[DataMember(Order = 13)]
|
||||
public int IdRespuesta { get; set; }
|
||||
}
|
28
Models/ParamObtDocDigitalizado.cs
Normal file
28
Models/ParamObtDocDigitalizado.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
using System.Runtime.Serialization;
|
||||
|
||||
namespace SoapService.Models;
|
||||
|
||||
[DataContract(Namespace = "http://dnic.gub.uy/")]
|
||||
public class ParamObtDocDigitalizado
|
||||
{
|
||||
[DataMember(Name = "ClaveAcceso1", Order = 0)]
|
||||
public string ClaveAcceso1 { get; set; }
|
||||
|
||||
[DataMember(Name = "ClaveAcceso2", Order = 1)]
|
||||
public string ClaveAcceso2 { get; set; }
|
||||
|
||||
[DataMember(Name = "NroDocumento", Order = 2)]
|
||||
public string NroDocumento { get; set; }
|
||||
|
||||
[DataMember(Name = "NroIdentificacion", Order = 3)]
|
||||
public int NroIdentificacion { get; set; }
|
||||
|
||||
[DataMember(Name = "NroSerie", Order = 4)]
|
||||
public string NroSerie { get; set; }
|
||||
|
||||
[DataMember(Name = "Organismo", Order = 5)]
|
||||
public string Organismo { get; set; }
|
||||
|
||||
[DataMember(Name = "TipoDocumento", Order = 6)]
|
||||
public string TipoDocumento { get; set; } = "DO";
|
||||
}
|
19
Models/ResultObtDocDigitalizado.cs
Normal file
19
Models/ResultObtDocDigitalizado.cs
Normal file
|
@ -0,0 +1,19 @@
|
|||
using System.Runtime.Serialization;
|
||||
|
||||
namespace SoapService.Models;
|
||||
|
||||
[DataContract(Namespace = "http://dnic.gub.uy/")]
|
||||
public class ResultObtDocDigitalizado
|
||||
{
|
||||
[DataMember(Order = 0)]
|
||||
public ObjPersona Persona { get; set; }
|
||||
|
||||
[DataMember(Order = 1)]
|
||||
public ImagenDigital[] Imagenes { get; set; }
|
||||
|
||||
[DataMember(Order = 2)]
|
||||
public Mensaje[]? Warnings { get; set; }
|
||||
|
||||
[DataMember(Order = 3)]
|
||||
public Mensaje[] Errores { get; set; }
|
||||
}
|
43
Program.cs
Normal file
43
Program.cs
Normal file
|
@ -0,0 +1,43 @@
|
|||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using SoapCore;
|
||||
using SoapService.Services;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Agregar servicios al contenedor
|
||||
builder.Services.AddSoapCore();
|
||||
builder.Services.TryAddSingleton<IWsServicioDeInformacion, WsServicioDeInformacion>();
|
||||
builder.Services.AddControllers();
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
|
||||
// Configurar Logging
|
||||
builder.Logging.AddConsole();
|
||||
builder.Logging.AddDebug();
|
||||
|
||||
// Configurar URL y Kestrel
|
||||
builder.WebHost.UseKestrel(options =>
|
||||
{
|
||||
options.ListenAnyIP(5050);
|
||||
});
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// Configurar el pipeline HTTP
|
||||
app.UseHttpsRedirection();
|
||||
app.UseRouting();
|
||||
|
||||
// Configurar endpoints SOAP
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.UseSoapEndpoint<IWsServicioDeInformacion>(
|
||||
"/WsServicioDeInformacion.svc",
|
||||
new SoapEncoderOptions(),
|
||||
SoapSerializer.DataContractSerializer);
|
||||
|
||||
endpoints.UseSoapEndpoint<IWsServicioDeInformacion>(
|
||||
"/WsServicioDeInformacion.asmx",
|
||||
new SoapEncoderOptions(),
|
||||
SoapSerializer.XmlSerializer);
|
||||
});
|
||||
|
||||
app.Run();
|
41
Properties/launchSettings.json
Normal file
41
Properties/launchSettings.json
Normal file
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:28336",
|
||||
"sslPort": 44394
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"http": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "swagger",
|
||||
"applicationUrl": "http://localhost:5032",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"https": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "swagger",
|
||||
"applicationUrl": "https://localhost:7249;http://localhost:5032",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "swagger",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
90
README.md
Normal file
90
README.md
Normal file
|
@ -0,0 +1,90 @@
|
|||
# Servicio de Simulación de Documentos Digitalizados
|
||||
|
||||
Este documento explica cómo utilizar el servicio de simulación de documentos digitalizados para fines educativos. El servicio genera información ficticia de personas basada en números de documentos de identidad (cédulas).
|
||||
|
||||
## Características principales
|
||||
|
||||
- Generación de datos personales ficticios deterministas (siempre los mismos para la misma cédula)
|
||||
- Simulación de errores y advertencias controladas mediante patrones en los números de cédula
|
||||
- Generación de edades específicas basadas en los últimos dígitos de la cédula
|
||||
|
||||
## Cómo generar errores y advertencias específicos
|
||||
|
||||
El servicio utiliza los **dos primeros dígitos** de la cédula para determinar si ocurre un error o una advertencia:
|
||||
|
||||
| Dos primeros dígitos | Resultado generado |
|
||||
| -------------------- | -------------------------------------------- |
|
||||
| 11 | Error - Persona inexistente |
|
||||
| 12 | Error - Límite de consultas excedido |
|
||||
| 13 | Error - Número de cédula anulado |
|
||||
| 14 | Advertencia - Datos de persona a regularizar |
|
||||
| 15 | Advertencia - Documento hurtado o extraviado |
|
||||
| Otros | Sin errores ni advertencias |
|
||||
|
||||
Por ejemplo, si consulta la cédula `11.234.567-8`, el servicio devolverá un error indicando que la persona no existe.
|
||||
|
||||
## Cómo obtener cédulas con edades específicas
|
||||
|
||||
La edad de la persona generada se determina por los **últimos dos dígitos** de la cédula:
|
||||
|
||||
- Para una persona de 25 años: use una cédula que termine en "25"
|
||||
- Para una persona de 18 años: use una cédula que termine en "18"
|
||||
- Para una persona de 65 años: use una cédula que termine en "65"
|
||||
|
||||
Por ejemplo, la cédula `4.321.025-9` generará una persona que tiene 25 años.
|
||||
|
||||
## Ejemplos de uso
|
||||
|
||||
### Ejemplos de cédulas que generan errores:
|
||||
|
||||
- `11.234.567-8`: Error - Persona inexistente
|
||||
- `12.345.678-9`: Error - Límite de consultas excedido
|
||||
- `13.456.789-0`: Error - Número de cédula anulado
|
||||
|
||||
### Ejemplos de cédulas que generan advertencias:
|
||||
|
||||
- `14.567.890-1`: Sin error, con advertencia - Datos a regularizar
|
||||
- `15.456.789-0`: Sin error, con advertencia - Documento hurtado/extraviado
|
||||
- `56.789.123-4`: Sin error, sin advertencia (no comienza con 11-15)
|
||||
|
||||
### Ejemplos de cédulas con edades específicas:
|
||||
|
||||
- `4.321.018-9`: Persona de 18 años
|
||||
- `5.678.930-3`: Persona de 30 años
|
||||
- `6.789.045-1`: Persona de 45 años
|
||||
- `7.890.175-8`: Persona de 75 años
|
||||
|
||||
### Combinando características:
|
||||
|
||||
- `15.467.825-7`: Persona de 25 años con advertencia de documento hurtado
|
||||
- `14.418.965-3`: Persona de 65 años con advertencia de datos a regularizar
|
||||
|
||||
## Otros datos generados
|
||||
|
||||
Además de la edad, el servicio genera determinísticamente para cada cédula:
|
||||
|
||||
- Nombres y apellidos
|
||||
- Sexo (basado en el número de cédula)
|
||||
- Fecha de nacimiento (basada en la edad)
|
||||
- Nacionalidad
|
||||
- Nombres completos para la cédula
|
||||
- Identificadores de solicitud y respuesta
|
||||
|
||||
## Notas importantes
|
||||
|
||||
1. Los datos generados son ficticios y no corresponden a personas reales.
|
||||
2. El servicio es determinista: la misma cédula siempre generará los mismos datos.
|
||||
3. Para edades de 0-9, asegúrese de incluir un cero delante (por ejemplo, "05" para 5 años).
|
||||
4. Para cédulas sin dígitos suficientes, el sistema puede comportarse de manera inesperada.
|
||||
|
||||
## Formato de parámetros requeridos
|
||||
|
||||
Para realizar una consulta válida, debe proporcionar los siguientes parámetros:
|
||||
|
||||
- `NroDocumento`: Número de cédula (requerido)
|
||||
- `NroSerie`: Número de serie del documento (requerido)
|
||||
- `Organismo`: Código del organismo solicitante (requerido)
|
||||
- `ClaveAcceso1`: Clave de acceso (requerida)
|
||||
- `TipoDocumento`: Tipo de documento (opcional)
|
||||
|
||||
La ausencia de cualquiera de los parámetros requeridos resultará en un error de "Parámetros incorrectos".
|
11
Services/IWsServicioDeInformacion.cs
Normal file
11
Services/IWsServicioDeInformacion.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
using SoapService.Models;
|
||||
using System.ServiceModel;
|
||||
|
||||
namespace SoapService.Services;
|
||||
|
||||
[ServiceContract(Namespace = "http://dnic.gub.uy/")]
|
||||
public interface IWsServicioDeInformacion
|
||||
{
|
||||
[OperationContract]
|
||||
ResultObtDocDigitalizado ObtDocDigitalizado(ParamObtDocDigitalizado param);
|
||||
}
|
250
Services/WsServicioDeInformacion.cs
Normal file
250
Services/WsServicioDeInformacion.cs
Normal file
|
@ -0,0 +1,250 @@
|
|||
using SoapService.Models;
|
||||
|
||||
namespace SoapService.Services;
|
||||
|
||||
public class WsServicioDeInformacion : IWsServicioDeInformacion
|
||||
{
|
||||
private static readonly Dictionary<string, ObjPersona> _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<Mensaje> Errors, List<Mensaje> Warnings) CheckErrorsAndWarnings(string nroDocumento)
|
||||
{
|
||||
var errors = new List<Mensaje>();
|
||||
var warnings = new List<Mensaje>();
|
||||
|
||||
// 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
|
||||
};
|
||||
}
|
||||
}
|
15
SoapService.csproj
Normal file
15
SoapService.csproj
Normal file
|
@ -0,0 +1,15 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.8" />
|
||||
<PackageReference Include="SoapCore" Version="1.2.1.8" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
6
SoapService.http
Normal file
6
SoapService.http
Normal file
|
@ -0,0 +1,6 @@
|
|||
@SoapService_HostAddress = http://localhost:5032
|
||||
|
||||
GET {{SoapService_HostAddress}}/weatherforecast/
|
||||
Accept: application/json
|
||||
|
||||
###
|
8
appsettings.Development.json
Normal file
8
appsettings.Development.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
9
appsettings.json
Normal file
9
appsettings.json
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue