SHA256
feat StayExport - StayExportProvider SpainParteViejeros - Initial implementation
- Added initial implementation to export stays in "SpainParteViajeros" format. - Added required configurations.
This commit is contained in:
@@ -32,6 +32,10 @@ public static class GuestConsts
|
|||||||
public const string DocumentType_NIE = "NIE";
|
public const string DocumentType_NIE = "NIE";
|
||||||
public const string DocumentType_PASSPORT = "PASSPORT";
|
public const string DocumentType_PASSPORT = "PASSPORT";
|
||||||
|
|
||||||
|
public const string GenderOptions_MALE = "M";
|
||||||
|
public const string GenderOptions_FEMALE = "F";
|
||||||
|
public const string GenderOptions_OTHER = "O";
|
||||||
|
|
||||||
public const int GuestDocument_FirstVersion = 1;
|
public const int GuestDocument_FirstVersion = 1;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
namespace Somnia.GuestLog.Models.Configuration;
|
||||||
|
|
||||||
|
public class StayExportSpainParteViajerosConfig
|
||||||
|
{
|
||||||
|
public const string SectionName = "StayExportSpainParteViajeros";
|
||||||
|
|
||||||
|
public bool InternetAvailable { get; set; } = false;
|
||||||
|
public string? CodigoEstablecimiento { get; set; }
|
||||||
|
}
|
||||||
@@ -79,6 +79,8 @@ builder.Services.AddOptions<AddressQueryConfig>()
|
|||||||
.Bind(builder.Configuration.GetSection(AddressQueryConfig.SectionName));
|
.Bind(builder.Configuration.GetSection(AddressQueryConfig.SectionName));
|
||||||
builder.Services.AddOptions<StayExportConfig>()
|
builder.Services.AddOptions<StayExportConfig>()
|
||||||
.Bind(builder.Configuration.GetSection(StayExportConfig.SectionName));
|
.Bind(builder.Configuration.GetSection(StayExportConfig.SectionName));
|
||||||
|
builder.Services.AddOptions<StayExportSpainParteViajerosConfig>()
|
||||||
|
.Bind(builder.Configuration.GetSection(StayExportSpainParteViajerosConfig.SectionName));
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
|
|||||||
+19
-2
@@ -13,12 +13,26 @@ public class SpainCodigoMunicipioCatastroService(
|
|||||||
private const string Api_Param_Provincia = "Provincia";
|
private const string Api_Param_Provincia = "Provincia";
|
||||||
private const string Api_Param_Municipio = "Municipio";
|
private const string Api_Param_Municipio = "Municipio";
|
||||||
|
|
||||||
|
|
||||||
|
//Result Cache.
|
||||||
|
readonly Dictionary<(string provincia, string municipio), string> codigoMunicipioCache = [];
|
||||||
|
|
||||||
|
|
||||||
public async Task<string?> GetCodigoMunicipioAsync(string municipio, string province)
|
public async Task<string?> GetCodigoMunicipioAsync(string municipio, string province)
|
||||||
{
|
{
|
||||||
|
var cacheKey = (province.ToUpper(), municipio.ToUpper());
|
||||||
|
|
||||||
|
//Try get from cache.
|
||||||
|
if (codigoMunicipioCache.TryGetValue(cacheKey, out string? cacheCode))
|
||||||
|
{
|
||||||
|
logger.LogInformation("SpainCodigoMunicipioCatastroService - Municipio found in cache for: '{key}'", cacheKey);
|
||||||
|
return cacheCode;
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string uri = GetRequestUri(municipio, province);
|
string uri = GetRequestUri(municipio, province);
|
||||||
logger.LogInformation("SpainCodigoMunicipioCatastroService - Getting municipios with query: '{addr}'", uri);
|
logger.LogInformation("SpainCodigoMunicipioCatastroService - Getting municipios from API with query: '{addr}'", uri);
|
||||||
|
|
||||||
var httpClient = httpFactory.CreateClient();
|
var httpClient = httpFactory.CreateClient();
|
||||||
using var rsStream = await httpClient.GetStreamAsync(uri);
|
using var rsStream = await httpClient.GetStreamAsync(uri);
|
||||||
@@ -49,7 +63,10 @@ public class SpainCodigoMunicipioCatastroService(
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $"{codIne.codigoProvincia}{codIne.codigoMunicipio}";
|
string finalCode = $"{codIne.codigoProvincia}{codIne.codigoMunicipio}";
|
||||||
|
|
||||||
|
codigoMunicipioCache.Add(cacheKey, finalCode);
|
||||||
|
return finalCode;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,20 +1,399 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
using FluentValidation;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
using Somnia.GuestLog.Enums.Models;
|
using Somnia.GuestLog.Enums.Models;
|
||||||
|
using Somnia.GuestLog.Models.Configuration;
|
||||||
using Somnia.GuestLog.Models.DTOs;
|
using Somnia.GuestLog.Models.DTOs;
|
||||||
|
using Somnia.GuestLog.Services.SpainCodigoMunicipio;
|
||||||
|
|
||||||
namespace Somnia.GuestLog.Services.StayExport;
|
namespace Somnia.GuestLog.Services.StayExport;
|
||||||
|
|
||||||
public class StayExportProviderSpainParteViajeros(
|
public class StayExportProviderSpainParteViajeros(
|
||||||
|
ILogger<StayExportProviderSpainParteViajeros> logger,
|
||||||
|
ISpainCodigoMunicipioService codigoMunicipioService,
|
||||||
|
IOptions<StayExportSpainParteViajerosConfig> configOptions
|
||||||
) : IStayExportFormatProvider
|
) : IStayExportFormatProvider
|
||||||
{
|
{
|
||||||
private const string fileExtension = "xml";
|
private const string fileExtension = "xml";
|
||||||
|
|
||||||
|
private const string PersonRole = "VI";
|
||||||
|
private const string PersonRelation = "OT";
|
||||||
|
|
||||||
|
private const string PersonTipoDoc_NIF = "NIF";
|
||||||
|
private const string PersonTipoDoc_NIE = "NIE";
|
||||||
|
private const string PersonTipoDoc_PAS = "PAS";
|
||||||
|
private const string PersonTipoDoc_OTRO = "OTRO";
|
||||||
|
|
||||||
|
private const string PersonDireccionPais_ESP = "ESP";
|
||||||
|
|
||||||
|
private const string XmlNamespace_Peticion = "http://www.neg.hospedajes.mir.es/altaParteHospedaje";
|
||||||
|
|
||||||
|
private readonly StayExportSpainParteViajerosConfig config = configOptions.Value;
|
||||||
|
|
||||||
public StayExportFormat GetFormat() => StayExportFormat.SpainParteViajeros;
|
public StayExportFormat GetFormat() => StayExportFormat.SpainParteViajeros;
|
||||||
public string GetFilename(DateTime exportTime)
|
public string GetFilename(DateTime exportTime)
|
||||||
=> $"{Enum.GetName(GetFormat())}_{exportTime.ToFileTimeUtc()}.{fileExtension}";
|
=> $"{Enum.GetName(GetFormat())}_{exportTime.ToFileTimeUtc()}.{fileExtension}";
|
||||||
|
|
||||||
public Task<StayExportFileResult> ExportDataAsync(IEnumerable<StayEntryDTO> stayList, Stream dataStream)
|
public async Task<StayExportFileResult> ExportDataAsync(IEnumerable<StayEntryDTO> stayList, Stream dataStream)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
if (string.IsNullOrEmpty(config.CodigoEstablecimiento))
|
||||||
|
{
|
||||||
|
logger.LogError("StayExportProviderSpainParteViajeros - Config error: CodigoEstablecimiento is not configured!");
|
||||||
|
return StayExportFileResult.ExportError;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stayList.Any())
|
||||||
|
{
|
||||||
|
return StayExportFileResult.NoData;
|
||||||
|
}
|
||||||
|
|
||||||
|
ComunicacionValidator comunicacionValidator = new();
|
||||||
|
|
||||||
|
List<Comunicacion> comunicacionsList = [];
|
||||||
|
foreach (StayEntryDTO stay in stayList)
|
||||||
|
{
|
||||||
|
(Comunicacion? comunicacion, string code) = await GetComunicacionFromStay(stay);
|
||||||
|
if (comunicacion == null)
|
||||||
|
{
|
||||||
|
logger.LogWarning("StayExportProviderSpainParteViajeros - Stay (ID: {id}) can't be exported: Code: {code}", stay.Id, code);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var errors = comunicacionValidator.Validate(comunicacion);
|
||||||
|
if (!errors.IsValid)
|
||||||
|
{
|
||||||
|
logger.LogWarning("StayExportProviderSpainParteViajeros - Stay (ID: {id}) is invalid: Errors: {errors}", stay.Id, errors.Errors);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
comunicacionsList.Add(comunicacion);
|
||||||
|
logger.LogInformation("StayExportProviderSpainParteViajeros - Stay (ID: {id}) Exported OK", stay.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
Peticion peticion = new()
|
||||||
|
{
|
||||||
|
solicitud = new()
|
||||||
|
{
|
||||||
|
codigoEstablecimiento = config.CodigoEstablecimiento,
|
||||||
|
comunicacion = comunicacionsList,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
XmlSerializer serializer = new(typeof(Peticion));
|
||||||
|
serializer.Serialize(dataStream, peticion);
|
||||||
|
|
||||||
|
return StayExportFileResult.OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Internal Methods
|
||||||
|
|
||||||
|
private async Task<(Comunicacion? comunicacion, string code)> GetComunicacionFromStay(StayEntryDTO stay)
|
||||||
|
{
|
||||||
|
Debug.Assert(stay.Id != null
|
||||||
|
&& stay.DateIn != null
|
||||||
|
&& stay.DateOut != null
|
||||||
|
&& stay.GuestDocuments != null
|
||||||
|
);
|
||||||
|
|
||||||
|
//Call Fn to validate Stay.
|
||||||
|
|
||||||
|
Contrato contrato = new()
|
||||||
|
{
|
||||||
|
referencia = stay.Id.Value.ToString(),
|
||||||
|
fechaContrato = stay.DateIn.Value.Date,
|
||||||
|
fechaEntrada = stay.DateIn.Value,
|
||||||
|
fechaSalida = stay.DateOut.Value,
|
||||||
|
internet = config.InternetAvailable,
|
||||||
|
numHabitaciones = stay.RoomCount ?? -1,
|
||||||
|
numPersonas = stay.GuestDocuments.Count,
|
||||||
|
pago = new()
|
||||||
|
{
|
||||||
|
tipoPago = GetTipoPagoFromStay(stay)!
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
List<Persona> personasList = [];
|
||||||
|
foreach (GuestDocumentDTO doc in stay.GuestDocuments)
|
||||||
|
{
|
||||||
|
Direccion dir = new()
|
||||||
|
{
|
||||||
|
direccion = doc.Address!,
|
||||||
|
codigoPostal = doc.ZipCode!,
|
||||||
|
pais = doc.AddressCountry!,
|
||||||
|
};
|
||||||
|
|
||||||
|
//Get Municipio given current country.
|
||||||
|
if (doc.AddressCountry != PersonDireccionPais_ESP)
|
||||||
|
{
|
||||||
|
List<string?> addressParts = [doc.AddressCity, doc.AddressProvince, doc.AddressState];
|
||||||
|
dir.nombreMunicipio = string.Join(", ", addressParts.Where(p => !string.IsNullOrEmpty(p)));
|
||||||
|
}
|
||||||
|
if (doc.AddressCountry == PersonDireccionPais_ESP)
|
||||||
|
{
|
||||||
|
dir.codigoMunicipio = await GetMunicipioFromGuestAddressAsync(doc);
|
||||||
|
if (dir.codigoMunicipio == null)
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
comunicacion: null,
|
||||||
|
code: "NoCodigoMunicipio"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Persona persona = new()
|
||||||
|
{
|
||||||
|
rol = PersonRole,
|
||||||
|
nombre = doc.Name!,
|
||||||
|
apellido1 = doc.Surname!,
|
||||||
|
apellido2 = doc.Surname2,
|
||||||
|
tipoDocumento = GetTipoDocumentoFromGuest(doc)!,
|
||||||
|
numeroDocumento = doc.DocumentNum!,
|
||||||
|
soporteDocumento = doc.SupportNum,
|
||||||
|
fechaNacimiento = doc.BirthDate?.Date ?? DateTime.MaxValue,
|
||||||
|
nacionalidad = doc.Nationality!,
|
||||||
|
sexo = GetSexoFromGuest(doc)!,
|
||||||
|
telefono = doc.PhoneNumber,
|
||||||
|
correo = doc.EmailAddress,
|
||||||
|
parentesco = PersonRelation,
|
||||||
|
direccion = dir,
|
||||||
|
};
|
||||||
|
personasList.Add(persona);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
comunicacion: new()
|
||||||
|
{
|
||||||
|
contrato = contrato,
|
||||||
|
persona = personasList
|
||||||
|
},
|
||||||
|
code: "OK");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string? GetTipoDocumentoFromGuest(GuestDocumentDTO doc)
|
||||||
|
{
|
||||||
|
return doc.DocumentType switch
|
||||||
|
{
|
||||||
|
GuestConsts.DocumentType_DNI => PersonTipoDoc_NIF,
|
||||||
|
GuestConsts.DocumentType_NIE => PersonTipoDoc_NIE,
|
||||||
|
GuestConsts.DocumentType_PASSPORT => PersonTipoDoc_PAS,
|
||||||
|
null => null,
|
||||||
|
_ => PersonTipoDoc_OTRO
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string? GetSexoFromGuest(GuestDocumentDTO doc)
|
||||||
|
{
|
||||||
|
return doc.Gender switch
|
||||||
|
{
|
||||||
|
GuestConsts.GenderOptions_MALE => "H",
|
||||||
|
GuestConsts.GenderOptions_FEMALE => "F",
|
||||||
|
null => null,
|
||||||
|
_ => "O"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string? GetTipoPagoFromStay(StayEntryDTO stay)
|
||||||
|
{
|
||||||
|
return stay.PaymentMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<string?> GetMunicipioFromGuestAddressAsync(GuestDocumentDTO doc)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(doc.AddressCity) || string.IsNullOrEmpty(doc.AddressProvince))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Get codMunicipio from API.
|
||||||
|
return await codigoMunicipioService.GetCodigoMunicipioAsync(doc.AddressCity, doc.AddressProvince);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Validator
|
||||||
|
|
||||||
|
private sealed class ComunicacionValidator : AbstractValidator<Comunicacion>
|
||||||
|
{
|
||||||
|
//TODO: Validate values in list for: Pago.tipoPago, Persona.sexo, Persona.tipoDocumento
|
||||||
|
|
||||||
|
public ComunicacionValidator()
|
||||||
|
{
|
||||||
|
RuleFor(comm => comm.contrato)
|
||||||
|
.NotNull()
|
||||||
|
.ChildRules(contrato =>
|
||||||
|
{
|
||||||
|
contrato.RuleFor(p => p.referencia)
|
||||||
|
.NotEmpty()
|
||||||
|
.MaximumLength(50);
|
||||||
|
|
||||||
|
contrato.RuleFor(p => p.fechaEntrada)
|
||||||
|
.LessThan(p => p.fechaSalida);
|
||||||
|
|
||||||
|
contrato.RuleFor(p => p.fechaSalida)
|
||||||
|
.GreaterThan(p => p.fechaEntrada);
|
||||||
|
|
||||||
|
contrato.RuleFor(p => p.numHabitaciones)
|
||||||
|
.GreaterThanOrEqualTo(0);
|
||||||
|
|
||||||
|
//BLOQUE PAGO
|
||||||
|
contrato.RuleFor(p => p.pago)
|
||||||
|
.ChildRules(e =>
|
||||||
|
{
|
||||||
|
e.RuleFor(p => p.tipoPago)
|
||||||
|
.NotEmpty();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
RuleForEach(comm => comm.persona)
|
||||||
|
.ChildRules(person =>
|
||||||
|
{
|
||||||
|
person.RuleFor(p => p.rol)
|
||||||
|
.Equal(PersonRole);
|
||||||
|
person.RuleFor(p => p.nombre)
|
||||||
|
.NotEmpty()
|
||||||
|
.MaximumLength(50);
|
||||||
|
person.RuleFor(p => p.apellido1)
|
||||||
|
.NotEmpty()
|
||||||
|
.MaximumLength(50);
|
||||||
|
person.RuleFor(p => p.apellido2)
|
||||||
|
.MaximumLength(50);
|
||||||
|
person.RuleFor(p => p.tipoDocumento)
|
||||||
|
.NotEmpty()
|
||||||
|
.MaximumLength(5);
|
||||||
|
person.RuleFor(p => p.numeroDocumento)
|
||||||
|
.NotEmpty()
|
||||||
|
.MaximumLength(15);
|
||||||
|
person.RuleFor(p => p.soporteDocumento)
|
||||||
|
.NotEmpty()
|
||||||
|
.When(p => p.tipoDocumento == PersonTipoDoc_NIF || p.tipoDocumento == PersonTipoDoc_NIE);
|
||||||
|
person.RuleFor(p => p.fechaNacimiento)
|
||||||
|
.NotEmpty();
|
||||||
|
person.RuleFor(p => p.sexo)
|
||||||
|
.MaximumLength(1);
|
||||||
|
person.RuleFor(p => p.telefono)
|
||||||
|
.MaximumLength(20);
|
||||||
|
person.RuleFor(p => p.correo)
|
||||||
|
.MaximumLength(250);
|
||||||
|
|
||||||
|
person.RuleFor(p => p.direccion)
|
||||||
|
.ChildRules(d =>
|
||||||
|
{
|
||||||
|
d.RuleFor(p => p.direccion)
|
||||||
|
.NotEmpty()
|
||||||
|
.MaximumLength(100);
|
||||||
|
d.RuleFor(p => p.codigoMunicipio)
|
||||||
|
.NotEmpty()
|
||||||
|
.When(p => p.pais == PersonDireccionPais_ESP)
|
||||||
|
.MaximumLength(5);
|
||||||
|
d.RuleFor(p => p.nombreMunicipio)
|
||||||
|
.NotEmpty()
|
||||||
|
.When(p => p.pais != PersonDireccionPais_ESP)
|
||||||
|
.MaximumLength(100);
|
||||||
|
d.RuleFor(p => p.codigoMunicipio)
|
||||||
|
.NotEmpty()
|
||||||
|
.MaximumLength(20);
|
||||||
|
d.RuleFor(p => p.pais)
|
||||||
|
.NotEmpty()
|
||||||
|
.Length(3);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
RuleForEach(comm => comm.persona)
|
||||||
|
.Must(p => !string.IsNullOrEmpty(p.telefono) || !string.IsNullOrEmpty(p.correo))
|
||||||
|
.WithMessage($"It's required to have at least one of the following fields: '{nameof(Persona.telefono)}', '{nameof(Persona.correo)}'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Export Data Classes
|
||||||
|
|
||||||
|
[XmlRoot(ElementName = "peticion", Namespace = XmlNamespace_Peticion)]
|
||||||
|
public class Peticion
|
||||||
|
{
|
||||||
|
public required Solicitud solicitud;
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlRoot(ElementName = "solicitud")]
|
||||||
|
public class Solicitud
|
||||||
|
{
|
||||||
|
public required string codigoEstablecimiento;
|
||||||
|
public required List<Comunicacion> comunicacion;
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlRoot(ElementName = "comunicacion")]
|
||||||
|
public class Comunicacion
|
||||||
|
{
|
||||||
|
public required Contrato contrato;
|
||||||
|
public required List<Persona> persona;
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlRoot(ElementName = "contrato")]
|
||||||
|
public class Contrato
|
||||||
|
{
|
||||||
|
public required string referencia;
|
||||||
|
|
||||||
|
[XmlElement(DataType = "date")]
|
||||||
|
public required DateTime fechaContrato;
|
||||||
|
|
||||||
|
[XmlElement(DataType = "dateTime")]
|
||||||
|
public required DateTime fechaEntrada;
|
||||||
|
|
||||||
|
[XmlElement(DataType = "dateTime")]
|
||||||
|
public required DateTime fechaSalida;
|
||||||
|
|
||||||
|
public required int numPersonas;
|
||||||
|
public int? numHabitaciones;
|
||||||
|
public bool? internet;
|
||||||
|
|
||||||
|
//BLOQUE PAGO
|
||||||
|
public required Pago pago;
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlRoot(ElementName = "persona")]
|
||||||
|
public class Persona
|
||||||
|
{
|
||||||
|
public required string rol;
|
||||||
|
public required string nombre;
|
||||||
|
public required string apellido1;
|
||||||
|
public string? apellido2;
|
||||||
|
public required string tipoDocumento;
|
||||||
|
public required string numeroDocumento;
|
||||||
|
public string? soporteDocumento;
|
||||||
|
|
||||||
|
[XmlElement(DataType = "date")]
|
||||||
|
public required DateTime fechaNacimiento;
|
||||||
|
public required string nacionalidad;
|
||||||
|
public required string sexo;
|
||||||
|
|
||||||
|
public string? telefono;
|
||||||
|
public string? correo;
|
||||||
|
public required string parentesco;
|
||||||
|
|
||||||
|
// BLOQUE DIRECCION
|
||||||
|
public required Direccion direccion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Pago
|
||||||
|
{
|
||||||
|
public required string tipoPago;
|
||||||
|
|
||||||
|
// [XmlElement(DataType = "date")]
|
||||||
|
// public required DateTime fechaPago;
|
||||||
|
public string? medioPago;
|
||||||
|
public string? titular;
|
||||||
|
public string? caducidadTarjeta;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Direccion
|
||||||
|
{
|
||||||
|
public required string direccion;
|
||||||
|
public string? codigoMunicipio;
|
||||||
|
public string? nombreMunicipio;
|
||||||
|
public required string codigoPostal;
|
||||||
|
public required string pais;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
@@ -25,5 +25,9 @@
|
|||||||
"EnableStayExport": true,
|
"EnableStayExport": true,
|
||||||
"ExportStorageConnectionString": "disk://path=/SomniaGuestLog/StayExportFiles",
|
"ExportStorageConnectionString": "disk://path=/SomniaGuestLog/StayExportFiles",
|
||||||
"UseSubdirectoryByFormat": true
|
"UseSubdirectoryByFormat": true
|
||||||
|
},
|
||||||
|
"StayExportSpainParteViajeros": {
|
||||||
|
"InternetAvailable": true,
|
||||||
|
"CodigoEstablecimiento": ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user