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