SHA256
Compare commits
28
Commits
0de4e1ba10
...
main
| Author | SHA256 | Date | |
|---|---|---|---|
|
|
0ab3957efa | ||
|
|
fbe1750510 | ||
|
|
23c8d490d8 | ||
|
|
c5d8487046 | ||
|
|
491ecc4cd1 | ||
|
|
a1a55aa396 | ||
|
|
dc85319da5 | ||
|
|
0abdfcd683 | ||
|
|
ae2ea51060 | ||
|
|
dcd5bb2aad | ||
|
|
fb2e00f06c | ||
|
|
9ec87d56da | ||
|
|
7b8020879b | ||
|
|
dc5293bdf7 | ||
|
|
4b72e3b3d3 | ||
|
|
6fe5a5e5a3 | ||
|
|
058352b7f3 | ||
|
|
313a714a99 | ||
|
|
cf31cbc414 | ||
|
|
b318f2415c | ||
|
|
c24faedee5 | ||
|
|
7052ec734c | ||
|
|
887c3d787a | ||
|
|
a01eed82e1 | ||
|
|
b08aaf2d7b | ||
|
|
4f22cd4541 | ||
|
|
b18bd7caa6 | ||
|
|
511bd023f2 |
Vendored
+9
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"files.associations": {
|
||||||
|
"appsettings*.json": "jsonc",
|
||||||
|
"*_config.json": "jsonc",
|
||||||
|
"*_config.json.sample": "jsonc"
|
||||||
|
},
|
||||||
|
"editor.formatOnSave": true,
|
||||||
|
"editor.formatOnSaveMode": "modificationsIfAvailable",
|
||||||
|
}
|
||||||
Vendored
+36
@@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||||
|
// for the documentation about the tasks.json format
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"type": "dotnet",
|
||||||
|
"task": "build",
|
||||||
|
"group": "build",
|
||||||
|
"problemMatcher": [],
|
||||||
|
"label": "Build Somnia.GuestLog"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Publish Container Image",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "dotnet",
|
||||||
|
"args": [
|
||||||
|
"publish",
|
||||||
|
"-c",
|
||||||
|
"Release",
|
||||||
|
"--os",
|
||||||
|
"linux",
|
||||||
|
"--arch",
|
||||||
|
"x64",
|
||||||
|
"-p:PublishProfile=DefaultContainer"
|
||||||
|
],
|
||||||
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}/src/Somnia.GuestLog"
|
||||||
|
},
|
||||||
|
"group": "build",
|
||||||
|
"presentation": {
|
||||||
|
"reveal": "always"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
# Somnia.GuestLog Deployment
|
||||||
|
|
||||||
|
## Deploy using docker-compose
|
||||||
|
|
||||||
|
Use [docker-compose file](docker-compose.yaml) as example. Configure required enviroment variables.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
- By default, HTTP-only is deploy. Uncomment required sections to enable HTTPS (and mount required certs).
|
||||||
|
- Reverse-proxies should work?
|
||||||
|
|
||||||
|
[To-Be-Improved]
|
||||||
|
|
||||||
|
## Manually update registry
|
||||||
|
|
||||||
|
Container images are built by CI/CD pipelines and uploaded to the registry (**not yet!**).
|
||||||
|
|
||||||
|
If required, a image can be manually built and uploaded to the registry (for testing or development purposes):
|
||||||
|
```sh
|
||||||
|
podman push [IMAGE_ID] [REGISTRY]/somnia/somnia-guestlog:[TAG]
|
||||||
|
|
||||||
|
# Example:
|
||||||
|
podman push localhost/somnia-guestlog:latest gitea.uberelectronnetwork.cc/somnia/somnia-guestlog:devbuild
|
||||||
|
```
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
services:
|
||||||
|
database:
|
||||||
|
environment:
|
||||||
|
POSTGRES_DB: ${POSTGRES_DB:-SomniaGuestLog}
|
||||||
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-NotAStrongPassword}
|
||||||
|
POSTGRES_USER: ${POSTGRES_USER:-somnia}
|
||||||
|
healthcheck:
|
||||||
|
retries: 5
|
||||||
|
start_period: 60s
|
||||||
|
test:
|
||||||
|
- CMD
|
||||||
|
- pg_isready
|
||||||
|
timeout: 5s
|
||||||
|
image: postgres:18-alpine
|
||||||
|
volumes:
|
||||||
|
- somniaguestlog_database_data:/var/lib/postgresql:rw
|
||||||
|
somnia-guestlog:
|
||||||
|
depends_on:
|
||||||
|
- database
|
||||||
|
environment:
|
||||||
|
SOMNIA_ConnectionStrings__DbSomniaGuestLog: Host=database;Port=5432;Username=${POSTGRES_USER:-somnia};Password=${POSTGRES_PASSWORD:-NotAStrongPassword};Database=${POSTGRES_DB:-SomniaGuestLog}
|
||||||
|
# Configure path for data protection keys. This path must persists between container restarts (use a mount or a volume).
|
||||||
|
SOMNIA_DataProtectionDir: /SomniaGuestLog/dataprotection
|
||||||
|
ASPNETCORE_URLS: "http://+:8080"
|
||||||
|
# Somnia AddressQuery Service - START
|
||||||
|
SOMNIA_AddressQuery__Provider: "Nominatim"
|
||||||
|
# Override if required.
|
||||||
|
# SOMNIA_AddressQuery__ServiceURL: ""
|
||||||
|
# SOMNIA_AddressQuery__ApiKey: ""
|
||||||
|
SOMNIA_AddressQuery__UserAgent: Somnia-GuestLog-Dev-Container
|
||||||
|
SOMNIA_AddressQuery__ResultLang: es
|
||||||
|
# Somnia AddressQuery Service - END
|
||||||
|
SOMNIA_StayExport__ExportStorageConnectionString: disk://path=/SomniaGuestLog/StayExportFiles
|
||||||
|
# Somnia StayExport - SpainParteViajeros Provider - START
|
||||||
|
# Override vars if required
|
||||||
|
# SOMNIA_StayExportSpainParteViajeros__InternetAvailable: true
|
||||||
|
# SOMNIA_StayExportSpainParteViajeros__CodigoEstablecimiento: 123123123
|
||||||
|
# Somnia StayExport - SpainParteViajeros Provider - END
|
||||||
|
|
||||||
|
# Enable for HTTPS - START
|
||||||
|
# ASPNETCORE_URLS: "https://+:8090;http://+:8080"
|
||||||
|
# ASPNETCORE_HTTPS_PORTS: 8090
|
||||||
|
# ASPNETCORE_Kestrel__Certificates__Default__Password: ${CERTIFICATE_CREDENTIAL:-}
|
||||||
|
# ASPNETCORE_Kestrel__Certificates__Default__Path: /https/aspnetapp.pfx
|
||||||
|
# Enable for HTTPS - END
|
||||||
|
|
||||||
|
image: localhost/somnia-guestlog:latest
|
||||||
|
# image: gitea.uberelectronnetwork.cc/somnia/somnia-guestlog:devbuild
|
||||||
|
|
||||||
|
ports:
|
||||||
|
- protocol: tcp
|
||||||
|
published: 8080
|
||||||
|
target: 8080
|
||||||
|
# Enable for HTTPS
|
||||||
|
# - protocol: tcp
|
||||||
|
# published: 8090
|
||||||
|
# target: 8090
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- somniaguestlog_app_data:/SomniaGuestLog
|
||||||
|
# Enable for HTTPS and configure path to your certificate.
|
||||||
|
# - ${HOME}/.aspnet/https:/https/
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
somniaguestlog_database_data: Null
|
||||||
|
somniaguestlog_app_data: Null
|
||||||
@@ -6,24 +6,34 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageVersion Include="Extensions.MudBlazor.StaticInput" Version="4.1.0" />
|
<PackageVersion Include="Extensions.MudBlazor.StaticInput" Version="4.1.0" />
|
||||||
|
<PackageVersion Include="FluentStorage" Version="8.0.22" />
|
||||||
|
<PackageVersion Include="FluentStorage.AWS" Version="8.0.21" />
|
||||||
<PackageVersion Include="FluentValidation" Version="12.1.1" />
|
<PackageVersion Include="FluentValidation" Version="12.1.1" />
|
||||||
<PackageVersion Include="Grpc.AspNetCore" Version="2.64.0" />
|
<PackageVersion Include="Grpc.AspNetCore" Version="2.64.0" />
|
||||||
<PackageVersion Include="Microsoft.Extensions.Localization" Version="10.0.9" />
|
<PackageVersion Include="Microsoft.Extensions.Localization" Version="10.0.9" />
|
||||||
<PackageVersion Include="MudBlazor" Version="9.4.0" />
|
<PackageVersion Include="MudBlazor" Version="9.10.0" />
|
||||||
|
<PackageVersion Include="MudBlazor.Translations" Version="3.6.0" />
|
||||||
|
<PackageVersion Include="Serilog" Version="4.4.0" />
|
||||||
|
<PackageVersion Include="Serilog.Enrichers.Process" Version="3.0.0" />
|
||||||
|
<PackageVersion Include="Serilog.Enrichers.Thread" Version="4.0.0" />
|
||||||
|
<PackageVersion Include="Serilog.Extensions.Hosting" Version="10.0.0" />
|
||||||
|
<PackageVersion Include="Serilog.Settings.Configuration" Version="10.0.1" />
|
||||||
|
<PackageVersion Include="Serilog.Sinks.Console" Version="6.1.1" />
|
||||||
|
<PackageVersion Include="Serilog.Sinks.File" Version="7.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageVersion Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="10.0.7" />
|
<PackageVersion Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="10.0.12" />
|
||||||
<PackageVersion Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="10.0.7" />
|
<PackageVersion Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="10.0.7" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="10.0.7" />
|
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="10.0.12" />
|
||||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.7">
|
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.12">
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageVersion>
|
</PackageVersion>
|
||||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.7" />
|
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.12" />
|
||||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="10.0.7" />
|
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="10.0.12" />
|
||||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Proxies" Version="10.0.7" />
|
<PackageVersion Include="Microsoft.EntityFrameworkCore.Proxies" Version="10.0.12" />
|
||||||
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.1" />
|
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.3" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Somnia.GuestLog;
|
||||||
|
|
||||||
|
public static class AppSettings
|
||||||
|
{
|
||||||
|
public const string AppName = "Somnia-GuestLog-dev";
|
||||||
|
|
||||||
|
public const string AppVersion = "v0.0.0-dev"; //2026-09-08
|
||||||
|
}
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
<ReconnectModal />
|
<ReconnectModal />
|
||||||
<script src="@Assets["_framework/blazor.web.js"]"></script>
|
<script src="@Assets["_framework/blazor.web.js"]"></script>
|
||||||
<script src="@Assets["_content/MudBlazor/MudBlazor.min.js"]"></script>
|
<script src="@Assets["_content/MudBlazor/MudBlazor.min.js"]"></script>
|
||||||
|
<script src="js/App.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
@using Somnia.GuestLog.Models.DTOs;
|
@using Somnia.GuestLog.Models.DTOs;
|
||||||
|
@using Somnia.GuestLog.Services
|
||||||
@using Somnia.GuestLog.Services.AddressQuery;
|
@using Somnia.GuestLog.Services.AddressQuery;
|
||||||
|
|
||||||
@inject ILogger<AddressQueryDialog> logger;
|
@inject ILogger<AddressQueryDialog> logger;
|
||||||
@inject IAddressQueryFactory addressQueryFactory;
|
@inject IAddressQueryFactory addressQueryFactory;
|
||||||
@inject ISnackbar Snackbar
|
@inject IUserMessageService userMessage
|
||||||
|
|
||||||
<MudDialog @ref="@DialogRef">
|
<MudDialog @ref="@DialogRef">
|
||||||
<TitleContent>
|
<TitleContent>
|
||||||
@@ -16,13 +17,22 @@
|
|||||||
<MudStack row>
|
<MudStack row>
|
||||||
<MudTextField @bind-Value="SearchText" Label="@LanguageLocale.control_AddressQueryDialog_searchText"
|
<MudTextField @bind-Value="SearchText" Label="@LanguageLocale.control_AddressQueryDialog_searchText"
|
||||||
Required />
|
Required />
|
||||||
<MudIconButton Icon="@Icons.Material.Filled.Search" OnClick="btnSearchAddress" />
|
<MudIconButton Icon="@Icons.Material.Filled.Search" OnClick="btnSearchAddress" Disabled="@_isDataLoading" />
|
||||||
</MudStack>
|
</MudStack>
|
||||||
|
|
||||||
<MudPaper Class="mt-4 pa-2">
|
<MudPaper Class="mt-4 pa-2">
|
||||||
@if (addressResults.Count == 0)
|
@if (addressResults.Count == 0 && !_isDataLoading)
|
||||||
{
|
{
|
||||||
<MudText Typo="Typo.body1">@LanguageLocale.general_noResults</MudText>
|
<MudElement Style="width: 100%; height: 100px;" HtmlTag="div">
|
||||||
|
<MudText Typo="Typo.body1" Align="Align.Center">
|
||||||
|
@LanguageLocale.general_noResults
|
||||||
|
</MudText>
|
||||||
|
</MudElement>
|
||||||
|
}
|
||||||
|
|
||||||
|
@if (_isDataLoading)
|
||||||
|
{
|
||||||
|
<MudSkeleton Width="100%" Height="100px" />
|
||||||
}
|
}
|
||||||
|
|
||||||
<MudList T="AddressResultDTO" @bind-SelectedValue="SelectedAddressResult"
|
<MudList T="AddressResultDTO" @bind-SelectedValue="SelectedAddressResult"
|
||||||
@@ -80,6 +90,9 @@
|
|||||||
private List<AddressResultDTO> addressResults = [];
|
private List<AddressResultDTO> addressResults = [];
|
||||||
private AddressResultDTO? SelectedAddressResult { get; set; }
|
private AddressResultDTO? SelectedAddressResult { get; set; }
|
||||||
|
|
||||||
|
private bool _isDataLoading = false;
|
||||||
|
private string _lastSearchText = "";
|
||||||
|
|
||||||
|
|
||||||
private void Cancel()
|
private void Cancel()
|
||||||
{
|
{
|
||||||
@@ -98,21 +111,25 @@
|
|||||||
|
|
||||||
private async Task btnSearchAddress()
|
private async Task btnSearchAddress()
|
||||||
{
|
{
|
||||||
if (SearchText.Length == 0)
|
if (SearchText.Length == 0 || SearchText == _lastSearchText)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var queryService = addressQueryFactory.GetService();
|
_isDataLoading = true;
|
||||||
|
|
||||||
|
var queryService = addressQueryFactory.GetService();
|
||||||
addressResults = await queryService.SearchAddressAsync(SearchText);
|
addressResults = await queryService.SearchAddressAsync(SearchText);
|
||||||
|
_lastSearchText = SearchText;
|
||||||
|
|
||||||
|
_isDataLoading = false;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
logger.LogError(ex, "SearchAddress returned an error!");
|
logger.LogError(ex, "SearchAddress returned an error!");
|
||||||
Snackbar.Add($"Error searching address: {ex.Message}", Severity.Error);
|
userMessage.ShowMessage($"Error searching address: {ex.Message}", MessageKind.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,7 +137,7 @@
|
|||||||
{
|
{
|
||||||
if (SelectedAddressResult is null)
|
if (SelectedAddressResult is null)
|
||||||
{
|
{
|
||||||
Snackbar.Add("Select an address", Severity.Warning);
|
userMessage.ShowMessage("Select an address", MessageKind.Warning);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
@using Somnia.GuestLog.Models.DTOs;
|
@using Somnia.GuestLog.Models.DTOs;
|
||||||
@using Somnia.GuestLog.Services
|
@using Somnia.GuestLog.Services
|
||||||
|
@using Somnia.GuestLog.Services.Entity
|
||||||
|
|
||||||
@inject ILogger<AddressQueryDialog> logger;
|
@inject ILogger<AddressQueryDialog> logger;
|
||||||
@inject ISnackbar Snackbar
|
@inject IUserMessageService userMessage
|
||||||
@inject IGuestDocumentService guestDocumentService;
|
@inject IGuestDocumentEntityService guestDocumentService;
|
||||||
|
|
||||||
|
|
||||||
<MudDialog Style="max-height: 90%;">
|
<MudDialog Style="max-height: 90%;">
|
||||||
@@ -77,7 +78,10 @@
|
|||||||
private IMudDialogInstance MudDialog { get; set; } = null!;
|
private IMudDialogInstance MudDialog { get; set; } = null!;
|
||||||
|
|
||||||
|
|
||||||
private GuestDocFilterDTO filter { get; set; } = new();
|
private GuestDocFilterDTO filter { get; set; } = new()
|
||||||
|
{
|
||||||
|
OnlyLastVersion = true
|
||||||
|
};
|
||||||
private IEnumerable<GuestDocumentDTO> results = [];
|
private IEnumerable<GuestDocumentDTO> results = [];
|
||||||
private GuestDocumentDTO? SelectedResult { get; set; }
|
private GuestDocumentDTO? SelectedResult { get; set; }
|
||||||
|
|
||||||
@@ -108,7 +112,7 @@
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
logger.LogError(ex, "GuestDocument Search returned an error!");
|
logger.LogError(ex, "GuestDocument Search returned an error!");
|
||||||
Snackbar.Add($"Error searching: {ex.Message}", Severity.Error);
|
userMessage.ShowMessage($"Error searching: {ex.Message}", MessageKind.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,7 +123,7 @@
|
|||||||
{
|
{
|
||||||
if (filter.IsEmpty)
|
if (filter.IsEmpty)
|
||||||
{
|
{
|
||||||
Snackbar.Add("Add some search!", Severity.Warning);
|
userMessage.ShowMessage("Search can't be empty!", MessageKind.Warning);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +135,7 @@
|
|||||||
{
|
{
|
||||||
if (SelectedResult is null)
|
if (SelectedResult is null)
|
||||||
{
|
{
|
||||||
Snackbar.Add("Select a guest document", Severity.Warning);
|
userMessage.ShowMessage("A guest document must be selected", MessageKind.Warning);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
@using System.Globalization
|
||||||
|
@using Microsoft.AspNetCore.Localization
|
||||||
|
|
||||||
|
@inject IJSRuntime JS
|
||||||
|
@inject NavigationManager Navigation
|
||||||
|
|
||||||
|
<MudItem>
|
||||||
|
<MudIconButton Icon="@Icons.Material.Outlined.Translate" Color="Color.Primary" DropShadow="false"
|
||||||
|
OnClick="@BtnToggleOpen" />
|
||||||
|
<MudPopover Open="_open" AnchorOrigin="Origin.BottomCenter" TransformOrigin="Origin.TopLeft" Paper="false">
|
||||||
|
<MudPaper Outlined="true" Class="px-4 py-8">
|
||||||
|
<MudSelect Value="currentCulture" T="CultureInfo" Label="@LanguageLocale.general_languageSelector" FullWidth="true"
|
||||||
|
ValueChanged="(culture) => CmbSelectedCultureChanged(culture)">
|
||||||
|
@foreach (CultureInfo culture in supportedCultures)
|
||||||
|
{
|
||||||
|
<MudSelectItem Value="culture">
|
||||||
|
@culture.DisplayName
|
||||||
|
</MudSelectItem>
|
||||||
|
}
|
||||||
|
</MudSelect>
|
||||||
|
</MudPaper>
|
||||||
|
</MudPopover>
|
||||||
|
</MudItem>
|
||||||
|
|
||||||
|
|
||||||
|
@code {
|
||||||
|
|
||||||
|
private bool _open;
|
||||||
|
|
||||||
|
private CultureInfo? currentCulture;
|
||||||
|
private List<CultureInfo> supportedCultures = [
|
||||||
|
new CultureInfo("en-US"),
|
||||||
|
new CultureInfo("es-ES"),
|
||||||
|
];
|
||||||
|
|
||||||
|
protected override void OnInitialized()
|
||||||
|
{
|
||||||
|
currentCulture = CultureInfo.CurrentCulture;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void BtnToggleOpen() => _open = !_open;
|
||||||
|
private async Task CmbSelectedCultureChanged(CultureInfo? newCulture)
|
||||||
|
{
|
||||||
|
if (newCulture is null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string cookieValue = CookieRequestCultureProvider.MakeCookieValue(
|
||||||
|
new RequestCulture(newCulture, newCulture));
|
||||||
|
|
||||||
|
await JS.InvokeVoidAsync("setBlazorCultureCookie", cookieValue);
|
||||||
|
Navigation.NavigateTo(Navigation.Uri, forceLoad: true);
|
||||||
|
|
||||||
|
//Close Popover.
|
||||||
|
_open = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -6,53 +6,61 @@
|
|||||||
|
|
||||||
@inject IDataListService dataListService;
|
@inject IDataListService dataListService;
|
||||||
@inject IValidator<GuestDocumentDTO> guestDocValidator;
|
@inject IValidator<GuestDocumentDTO> guestDocValidator;
|
||||||
|
@inject IUserMessageService userMessage;
|
||||||
|
|
||||||
|
|
||||||
<MudForm @ref="@_form" Model="@Model" Validation="@((guestDocValidator as GuestDocumentDTOValidator)!.ValidateValue)" ValidationDelay="0"
|
<MudForm @ref="@_form" Model="@Model" Validation="@((guestDocValidator as GuestDocumentDTOValidator)!.ValidateValue)"
|
||||||
ReadOnly="@ReadOnly">
|
ValidationDelay="0" ReadOnly="@ReadOnly">
|
||||||
<MudGrid>
|
<MudGrid>
|
||||||
<MudItem xs="12" md="6">
|
<MudItem xs="12" md="6">
|
||||||
<MudPaper Class="pa-4" Elevation="3" Height="100%">
|
<MudPaper Class="pa-4" Elevation="3" Height="100%">
|
||||||
<MudText Typo="Typo.subtitle1" Align="Align.Center">@LanguageLocale.control_GuestDocForm_sectionDocument</MudText>
|
<MudText Typo="Typo.subtitle1" Align="Align.Center">
|
||||||
|
@LanguageLocale.control_GuestDocForm_sectionDocument
|
||||||
|
</MudText>
|
||||||
<MudDivider DividerType="DividerType.Middle" Class="mb-4" />
|
<MudDivider DividerType="DividerType.Middle" Class="mb-4" />
|
||||||
<MudStack Row style="@FieldMarginY">
|
<MudStack Row style="@FieldMarginY">
|
||||||
<MudSelect @bind-Value="Model.DocumentType" For="@(() => Model.DocumentType)" Label="@LanguageLocale.dto_GuestDocument_DocumentType"
|
<MudSelect @bind-Value="Model.DocumentType" For="@(() => Model.DocumentType)"
|
||||||
Required ReadOnly="@ReadOnlyDocId">
|
Label="@LanguageLocale.dto_GuestDocument_DocumentType" Required ReadOnly="@ReadOnlyDocId">
|
||||||
@foreach (string docType in dataListService.GetDataListByName(GuestConsts.DataList_DocumentTypes))
|
@foreach (string docType in
|
||||||
|
dataListService.GetDataListByName(GuestConsts.DataList_DocumentTypes))
|
||||||
{
|
{
|
||||||
<MudSelectItem Value="docType">
|
<MudSelectItem Value="docType">
|
||||||
@dataListService.GetLocalizedValue(GuestConsts.DataList_DocumentTypes, docType)
|
@dataListService.GetLocalizedValue(GuestConsts.DataList_DocumentTypes, docType)
|
||||||
</MudSelectItem>
|
</MudSelectItem>
|
||||||
}
|
}
|
||||||
</MudSelect>
|
</MudSelect>
|
||||||
<MudTextField @bind-Value="Model.DocumentNum" For="@(() => Model.DocumentNum)" Label="@LanguageLocale.dto_GuestDocument_DocumentNum"
|
<MudTextField @bind-Value="Model.DocumentNum" For="@(() => Model.DocumentNum)"
|
||||||
Required ReadOnly="@ReadOnlyDocId" />
|
Label="@LanguageLocale.dto_GuestDocument_DocumentNum" Required ReadOnly="@ReadOnlyDocId" />
|
||||||
</MudStack>
|
</MudStack>
|
||||||
|
|
||||||
<MudStack Row style="@FieldMarginY">
|
<MudStack Row style="@FieldMarginY">
|
||||||
<MudDatePicker @bind-Date="Model.IssueDate" For="@(() => Model.IssueDate)" Label="@LanguageLocale.dto_GuestDocument_IssueDate"
|
<MudDatePicker @bind-Date="Model.IssueDate" For="@(() => Model.IssueDate)"
|
||||||
Clearable OpenTo="OpenTo.Year" Editable />
|
Label="@LanguageLocale.dto_GuestDocument_IssueDate" Clearable OpenTo="OpenTo.Year" Editable />
|
||||||
|
|
||||||
<MudTextField @bind-Value="Model.SupportNum" For="@(() => Model.SupportNum)" Label="@LanguageLocale.dto_GuestDocument_SupportNum"
|
<MudTextField @bind-Value="Model.SupportNum" For="@(() => Model.SupportNum)"
|
||||||
Required="@isSuportNumberRequired" Mask="@(new PatternMask("aaa000000"))"
|
Label="@LanguageLocale.dto_GuestDocument_SupportNum" Required="@isSuportNumberRequired"
|
||||||
|
Mask="SuportNumberPatternMask"
|
||||||
OnBlur="@(() => Model.SupportNum = Model.SupportNum?.ToUpper())" />
|
OnBlur="@(() => Model.SupportNum = Model.SupportNum?.ToUpper())" />
|
||||||
</MudStack>
|
</MudStack>
|
||||||
|
|
||||||
<MudAutocomplete T="string" @bind-Value="Model.Nationality" For="@(() => Model.Nationality)" Label="@LanguageLocale.dto_GuestDocument_Nationality"
|
<MudAutocomplete T="string" @bind-Value="Model.Nationality" For="@(() => Model.Nationality)"
|
||||||
SearchFunc="@SearchCountryCodes" ToStringFunc="@(e=> string.IsNullOrEmpty(e) ? "" : @dataListService.GetLocalizedValue(GuestConsts.DataList_CountryCodes, e))"
|
Label="@LanguageLocale.dto_GuestDocument_Nationality" SearchFunc="@SearchCountryCodes"
|
||||||
SelectValueOnTab="true" AdornmentIcon="@Icons.Material.Filled.Search"
|
ToStringFunc="@(e=> string.IsNullOrEmpty(e) ? "" : @dataListService.GetLocalizedValue(GuestConsts.DataList_CountryCodes, e))"
|
||||||
style="@FieldMarginY" />
|
SelectValueOnTab="true" AdornmentIcon="@Icons.Material.Filled.Search" style="@FieldMarginY"
|
||||||
|
Required />
|
||||||
</MudPaper>
|
</MudPaper>
|
||||||
</MudItem>
|
</MudItem>
|
||||||
<MudItem xs="12" md="6">
|
<MudItem xs="12" md="6">
|
||||||
<MudPaper Class="pa-4" Elevation="3" Height="100%">
|
<MudPaper Class="pa-4" Elevation="3" Height="100%">
|
||||||
<MudText Typo="Typo.subtitle1" Align="Align.Center">@LanguageLocale.control_GuestDocForm_sectionGuest</MudText>
|
<MudText Typo="Typo.subtitle1" Align="Align.Center">
|
||||||
|
@LanguageLocale.control_GuestDocForm_sectionGuest
|
||||||
|
</MudText>
|
||||||
<MudDivider DividerType="DividerType.Middle" Class="mb-4" />
|
<MudDivider DividerType="DividerType.Middle" Class="mb-4" />
|
||||||
|
|
||||||
<MudTextField @bind-Value="Model.Name" For="@(() => Model.Name)"
|
<MudTextField @bind-Value="Model.Name" For="@(() => Model.Name)" Required
|
||||||
Label="@LanguageLocale.dto_GuestDocument_Name"
|
Label="@LanguageLocale.dto_GuestDocument_Name"
|
||||||
OnBlur="@(() => Model.Name = Model.Name?.ToUpper())" />
|
OnBlur="@(() => Model.Name = Model.Name?.ToUpper())" />
|
||||||
<MudTextField @bind-Value="Model.Surname" For="@(() => Model.Surname)"
|
<MudTextField @bind-Value="Model.Surname" For="@(() => Model.Surname)" Required
|
||||||
Label="@LanguageLocale.dto_GuestDocument_Surname"
|
Label="@LanguageLocale.dto_GuestDocument_Surname"
|
||||||
OnBlur="@(() => Model.Surname = Model.Surname?.ToUpper())" />
|
OnBlur="@(() => Model.Surname = Model.Surname?.ToUpper())" />
|
||||||
<MudTextField @bind-Value="Model.Surname2" For="@(() => Model.Surname2)"
|
<MudTextField @bind-Value="Model.Surname2" For="@(() => Model.Surname2)"
|
||||||
@@ -60,11 +68,14 @@
|
|||||||
OnBlur="@(() => Model.Surname2 = Model.Surname2?.ToUpper())" />
|
OnBlur="@(() => Model.Surname2 = Model.Surname2?.ToUpper())" />
|
||||||
|
|
||||||
<MudStack Row style="@FieldMarginY">
|
<MudStack Row style="@FieldMarginY">
|
||||||
<MudDatePicker @bind-Date="Model.BirthDate" For="@(() => Model.BirthDate)" Label="@LanguageLocale.dto_GuestDocument_BirthDate"
|
<MudDatePicker @bind-Date="Model.BirthDate" For="@(() => Model.BirthDate)"
|
||||||
Clearable OpenTo="OpenTo.Year" Editable />
|
Label="@LanguageLocale.dto_GuestDocument_BirthDate" OpenTo="OpenTo.Year" Clearable Required
|
||||||
|
Editable />
|
||||||
|
|
||||||
<MudSelect @bind-Value="Model.Gender" For="@(() => Model.Gender)" Label="@LanguageLocale.dto_GuestDocument_Gender">
|
<MudSelect @bind-Value="Model.Gender" For="@(() => Model.Gender)"
|
||||||
@foreach (string gender in dataListService.GetDataListByName(GuestConsts.DataList_GenderOptions))
|
Label="@LanguageLocale.dto_GuestDocument_Gender">
|
||||||
|
@foreach (string gender in
|
||||||
|
dataListService.GetDataListByName(GuestConsts.DataList_GenderOptions))
|
||||||
{
|
{
|
||||||
<MudSelectItem Value="gender">
|
<MudSelectItem Value="gender">
|
||||||
@dataListService.GetLocalizedValue(GuestConsts.DataList_GenderOptions, gender)
|
@dataListService.GetLocalizedValue(GuestConsts.DataList_GenderOptions, gender)
|
||||||
@@ -77,30 +88,37 @@
|
|||||||
|
|
||||||
<MudItem xs="12" md="6">
|
<MudItem xs="12" md="6">
|
||||||
<MudPaper Class="pa-4" Elevation="3" Height="100%">
|
<MudPaper Class="pa-4" Elevation="3" Height="100%">
|
||||||
<MudText Typo="Typo.subtitle1" Align="Align.Center">@LanguageLocale.control_GuestDocForm_sectionContact</MudText>
|
<MudText Typo="Typo.subtitle1" Align="Align.Center">
|
||||||
|
@LanguageLocale.control_GuestDocForm_sectionContact
|
||||||
|
</MudText>
|
||||||
<MudDivider DividerType="DividerType.Middle" Class="mb-4" />
|
<MudDivider DividerType="DividerType.Middle" Class="mb-4" />
|
||||||
|
|
||||||
<MudStack Row>
|
<MudStack Row>
|
||||||
<MudTextField @bind-Value="Model.PhoneNumber" For="@(() => Model.PhoneNumber)"
|
<MudTextField @bind-Value="Model.PhoneNumber" For="@(() => Model.PhoneNumber)"
|
||||||
Label="@LanguageLocale.dto_GuestDocument_PhoneNumber"
|
Label="@LanguageLocale.dto_GuestDocument_PhoneNumber" InputType="InputType.Telephone" />
|
||||||
InputType="InputType.Telephone" />
|
|
||||||
<MudTextField @bind-Value="Model.EmailAddress" For="@(() => Model.EmailAddress)"
|
<MudTextField @bind-Value="Model.EmailAddress" For="@(() => Model.EmailAddress)"
|
||||||
Label="@LanguageLocale.dto_GuestDocument_EmailAddress"
|
Label="@LanguageLocale.dto_GuestDocument_EmailAddress" InputType="InputType.Email" />
|
||||||
InputType="InputType.Email" />
|
|
||||||
</MudStack>
|
</MudStack>
|
||||||
</MudPaper>
|
</MudPaper>
|
||||||
</MudItem>
|
</MudItem>
|
||||||
|
|
||||||
<MudItem xs="12" md="6">
|
<MudItem xs="12" md="6">
|
||||||
<MudPaper Class="pa-4" Elevation="3" Height="100%">
|
<MudPaper Class="pa-4" Elevation="3" Height="100%">
|
||||||
<MudText Typo="Typo.subtitle1" Align="Align.Center">@LanguageLocale.control_GuestDocForm_sectionAddress</MudText>
|
<MudText Typo="Typo.subtitle1" Align="Align.Center">
|
||||||
|
@LanguageLocale.control_GuestDocForm_sectionAddress
|
||||||
|
</MudText>
|
||||||
<MudDivider DividerType="DividerType.Middle" Class="mb-4" />
|
<MudDivider DividerType="DividerType.Middle" Class="mb-4" />
|
||||||
|
|
||||||
@if (!ReadOnly)
|
@if (!ReadOnly)
|
||||||
{
|
{
|
||||||
<MudButton OnClick="BtnOpenAddressSearchDialog" Variant="Variant.Outlined" FullWidth="true" Class="mb-2">
|
<MudStack Row>
|
||||||
|
<MudButton OnClick="BtnOpenAddressSearchDialog" Variant="Variant.Outlined" FullWidth="true"
|
||||||
|
Class="mb-2">
|
||||||
@LanguageLocale.control_GuestDocForm_btnSearchAddress
|
@LanguageLocale.control_GuestDocForm_btnSearchAddress
|
||||||
</MudButton>
|
</MudButton>
|
||||||
|
<MudIconButton OnClick="BtnSkipAddressSearch" Variant="Variant.Outlined" Disabled="!ReadOnlyAddress"
|
||||||
|
Icon="@Icons.Material.Filled.SkipNext" Class="mb-2" />
|
||||||
|
</MudStack>
|
||||||
}
|
}
|
||||||
|
|
||||||
<MudTextField @bind-Value="Model.Address" For="@(() => Model.Address)"
|
<MudTextField @bind-Value="Model.Address" For="@(() => Model.Address)"
|
||||||
@@ -116,7 +134,8 @@
|
|||||||
<MudStack Row style="@FieldMarginY">
|
<MudStack Row style="@FieldMarginY">
|
||||||
<MudAutocomplete T="string" @bind-Value="Model.AddressCountry" For="@(() => Model.AddressCountry)"
|
<MudAutocomplete T="string" @bind-Value="Model.AddressCountry" For="@(() => Model.AddressCountry)"
|
||||||
Label="@LanguageLocale.general_address_country" ReadOnly="@ReadOnlyAddress"
|
Label="@LanguageLocale.general_address_country" ReadOnly="@ReadOnlyAddress"
|
||||||
SearchFunc="@SearchCountryCodes" ToStringFunc="@(e=> string.IsNullOrEmpty(e) ? "" : @dataListService.GetLocalizedValue(GuestConsts.DataList_CountryCodes, e))"
|
SearchFunc="@SearchCountryCodes"
|
||||||
|
ToStringFunc="@(e=> string.IsNullOrEmpty(e) ? "" : @dataListService.GetLocalizedValue(GuestConsts.DataList_CountryCodes, e))"
|
||||||
SelectValueOnTab="true" AdornmentIcon="@Icons.Material.Filled.Search" />
|
SelectValueOnTab="true" AdornmentIcon="@Icons.Material.Filled.Search" />
|
||||||
|
|
||||||
<MudTextField @bind-Value="Model.ZipCode" For="@(() => Model.ZipCode)"
|
<MudTextField @bind-Value="Model.ZipCode" For="@(() => Model.ZipCode)"
|
||||||
@@ -155,7 +174,20 @@
|
|||||||
|
|
||||||
private Dictionary<string, string>? countryDict = null;
|
private Dictionary<string, string>? countryDict = null;
|
||||||
|
|
||||||
private bool isSuportNumberRequired { get => Model?.Nationality == GuestConsts.CountryCode_ESP; }
|
private bool isSuportNumberRequired
|
||||||
|
{
|
||||||
|
get => Model?.DocumentType == GuestConsts.DocumentType_DNI
|
||||||
|
|| Model?.DocumentType == GuestConsts.DocumentType_NIE;
|
||||||
|
}
|
||||||
|
private PatternMask SuportNumberPatternMask
|
||||||
|
{
|
||||||
|
get => Model?.DocumentType switch
|
||||||
|
{
|
||||||
|
GuestConsts.DocumentType_DNI => new PatternMask("aaa000000"),
|
||||||
|
GuestConsts.DocumentType_NIE => new PatternMask("a00000000"),
|
||||||
|
_ => new PatternMask("")
|
||||||
|
};
|
||||||
|
}
|
||||||
private string CreateTimeString
|
private string CreateTimeString
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -237,6 +269,14 @@
|
|||||||
ReadOnlyAddress = ReadOnly;
|
ReadOnlyAddress = ReadOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task BtnSkipAddressSearch()
|
||||||
|
{
|
||||||
|
userMessage.ShowMessage("Address search skipped! Address is editable now", MessageKind.Info);
|
||||||
|
|
||||||
|
//Make Address editable (if the form is editable).
|
||||||
|
ReadOnlyAddress = ReadOnly;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
@inject IDataListService dataListService;
|
@inject IDataListService dataListService;
|
||||||
@inject IValidator<StayEntryDTO> stayValidator;
|
@inject IValidator<StayEntryDTO> stayValidator;
|
||||||
@inject IDialogService dialogService;
|
@inject IDialogService dialogService;
|
||||||
@inject ISnackbar snackbar
|
@inject IUserMessageService userMessage
|
||||||
|
|
||||||
|
|
||||||
<MudForm @ref="@_form" Model="@Model" Validation="@((stayValidator as StayEntryDTOValidator)!.ValidateValue)"
|
<MudForm @ref="@_form" Model="@Model" Validation="@((stayValidator as StayEntryDTOValidator)!.ValidateValue)"
|
||||||
@@ -21,12 +21,18 @@
|
|||||||
<MudDivider DividerType="DividerType.Middle" Class="mb-4" />
|
<MudDivider DividerType="DividerType.Middle" Class="mb-4" />
|
||||||
|
|
||||||
<MudStack Row style="@FieldMarginY">
|
<MudStack Row style="@FieldMarginY">
|
||||||
<MudDatePicker @bind-Date="Model.DateIn" For="@(() => Model.DateIn)"
|
<MudDatePicker Date="Model.DateIn" For="@(() => Model.DateIn)"
|
||||||
Label="@LanguageLocale.dto_StayEntry_DateIn" Clearable OpenTo="OpenTo.Date" Editable />
|
DateChanged="@((newVal) => Model.DateIn = GetDateTimeFromDateAndTime(newVal, Model.DateIn?.TimeOfDay))"
|
||||||
<MudTimePicker @bind-Time="TimeIn" Label=" " Editable />
|
Label="@LanguageLocale.dto_StayEntry_DateIn" Clearable OpenTo="OpenTo.Date" Editable
|
||||||
<MudDatePicker @bind-Date="Model.DateOut" For="@(() => Model.DateOut)"
|
AutoClose="true" />
|
||||||
Label="@LanguageLocale.dto_StayEntry_DateOut" Clearable OpenTo="OpenTo.Date" Editable />
|
<MudTimePicker Time="Model.DateIn?.TimeOfDay" Label=" " Editable
|
||||||
<MudTimePicker @bind-Time="TimeOut" Label=" " Editable />
|
TimeChanged="@((newVal) => Model.DateIn = GetDateTimeFromDateAndTime(Model.DateIn, newVal))" />
|
||||||
|
<MudDatePicker Date="Model.DateOut" For="@(() => Model.DateOut)"
|
||||||
|
DateChanged="@((newVal) => Model.DateOut = GetDateTimeFromDateAndTime(newVal, Model.DateOut?.TimeOfDay))"
|
||||||
|
Label="@LanguageLocale.dto_StayEntry_DateOut" Clearable OpenTo="OpenTo.Date" Editable
|
||||||
|
AutoClose="true" />
|
||||||
|
<MudTimePicker Time="Model.DateOut?.TimeOfDay" Label=" " Editable
|
||||||
|
TimeChanged="@((newVal) => Model.DateOut = GetDateTimeFromDateAndTime(Model.DateOut, newVal))" />
|
||||||
</MudStack>
|
</MudStack>
|
||||||
<MudStack Row style="@FieldMarginY">
|
<MudStack Row style="@FieldMarginY">
|
||||||
<MudTextField @bind-Value="Model.RoomCount" For="@(() => Model.RoomCount)"
|
<MudTextField @bind-Value="Model.RoomCount" For="@(() => Model.RoomCount)"
|
||||||
@@ -91,7 +97,7 @@
|
|||||||
{
|
{
|
||||||
<MudTd DataLabel="@LanguageLocale.general_actions">
|
<MudTd DataLabel="@LanguageLocale.general_actions">
|
||||||
<MudIconButton Icon="@Icons.Material.Filled.Delete"
|
<MudIconButton Icon="@Icons.Material.Filled.Delete"
|
||||||
OnClick="@(() => BtnDeleteGuest(context.DocumentType!, context.DocumentNum!))" />
|
OnClick="@(() => BtnDeleteGuest(context.Id!.Value, context.Version!.Value))" />
|
||||||
</MudTd>
|
</MudTd>
|
||||||
}
|
}
|
||||||
@if (ReadOnly)
|
@if (ReadOnly)
|
||||||
@@ -113,11 +119,11 @@
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public StayEntryDTO Model { private get; set; } = new();
|
public StayEntryDTO Model { private get; set; } = new();
|
||||||
|
|
||||||
[Parameter]
|
[Parameter, EditorRequired]
|
||||||
public bool ReadOnly { get; set; } = false;
|
public FormMode FormMode { get; set; }
|
||||||
|
|
||||||
private TimeSpan? TimeIn = DateTime.Now.TimeOfDay;
|
|
||||||
private TimeSpan? TimeOut = new(hours: 12, minutes: 0, seconds: 0);
|
private bool ReadOnly => FormMode == FormMode.ReadOnly;
|
||||||
|
|
||||||
|
|
||||||
private MudForm _form = null!;
|
private MudForm _form = null!;
|
||||||
@@ -138,7 +144,20 @@
|
|||||||
|
|
||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
Model.DateIn = DateTime.Today;
|
//Initialize values when not ReadOnly.
|
||||||
|
if (FormMode == FormMode.Create)
|
||||||
|
{
|
||||||
|
Model.DateIn = DateTime.Now;
|
||||||
|
|
||||||
|
DateTime dateOut = DateTime.Today.AddDays(1);
|
||||||
|
Model.DateOut = new(
|
||||||
|
year: dateOut.Year, month: dateOut.Month, day: dateOut.Day,
|
||||||
|
hour: 12, minute: 0, second: 0
|
||||||
|
);
|
||||||
|
|
||||||
|
//Init Guest List
|
||||||
|
Model.GuestDocuments = [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Public Methods
|
#region Public Methods
|
||||||
@@ -149,7 +168,7 @@
|
|||||||
|
|
||||||
if (Model.GuestDocuments is null || Model.GuestDocuments.Count == 0)
|
if (Model.GuestDocuments is null || Model.GuestDocuments.Count == 0)
|
||||||
{
|
{
|
||||||
snackbar.Add("At least 1 guest is required!", MudBlazor.Severity.Warning);
|
userMessage.ShowMessage("At least 1 guest is required!", MessageKind.Warning);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,10 +177,6 @@
|
|||||||
|
|
||||||
public StayEntryDTO GetModel()
|
public StayEntryDTO GetModel()
|
||||||
{
|
{
|
||||||
//Update model times.
|
|
||||||
Model.DateIn = GetDateTimeFromDateAndTime(Model.DateIn, TimeIn);
|
|
||||||
Model.DateOut = GetDateTimeFromDateAndTime(Model.DateOut, TimeOut);
|
|
||||||
|
|
||||||
return Model;
|
return Model;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,6 +200,8 @@
|
|||||||
|
|
||||||
private async Task BtnAddGuest()
|
private async Task BtnAddGuest()
|
||||||
{
|
{
|
||||||
|
Debug.Assert(Model.GuestDocuments != null);
|
||||||
|
|
||||||
DialogOptions dialogOptions = new()
|
DialogOptions dialogOptions = new()
|
||||||
{
|
{
|
||||||
MaxWidth = MaxWidth.Medium,
|
MaxWidth = MaxWidth.Medium,
|
||||||
@@ -205,38 +222,31 @@
|
|||||||
|
|
||||||
if (resultData is null)
|
if (resultData is null)
|
||||||
{
|
{
|
||||||
snackbar.Add("Error! No Guest Document selected!", MudBlazor.Severity.Error);
|
userMessage.ShowMessage("Error! No Guest Document selected!", MessageKind.Error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Check if this guest is already added.
|
//Check if this guest is already added.
|
||||||
if (Model.GuestDocuments is not null && Model.GuestDocuments.Count > 0)
|
if (Model.GuestDocuments.Count > 0)
|
||||||
{
|
{
|
||||||
bool alreadyAdded = Model.GuestDocuments.Any(e => e.DocumentType == resultData.DocumentType
|
bool alreadyAdded = Model.GuestDocuments.Any(e => e.Id == resultData.Id);
|
||||||
&& e.DocumentNum == resultData.DocumentNum);
|
|
||||||
if (alreadyAdded)
|
if (alreadyAdded)
|
||||||
{
|
{
|
||||||
snackbar.Add("GuestDocument already added!", MudBlazor.Severity.Warning);
|
userMessage.ShowMessage("GuestDocument already added!", MessageKind.Warning);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Init List.
|
|
||||||
if (Model.GuestDocuments is null)
|
|
||||||
{
|
|
||||||
Model.GuestDocuments = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
Model.GuestDocuments.Add(resultData);
|
Model.GuestDocuments.Add(resultData);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BtnDeleteGuest(string docType, string docNum)
|
private void BtnDeleteGuest(long guestDocId, int version)
|
||||||
{
|
{
|
||||||
Debug.Assert(Model.GuestDocuments is not null);
|
Debug.Assert(Model.GuestDocuments is not null);
|
||||||
|
|
||||||
//Filter out given GuestDocument from model.
|
//Filter out given GuestDocument from model.
|
||||||
Model.GuestDocuments = Model.GuestDocuments
|
Model.GuestDocuments = Model.GuestDocuments
|
||||||
.Where(e => !(e.DocumentType == docType && e.DocumentNum == docNum))
|
.Where(e => !(e.Id == guestDocId && e.Version == version))
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,9 +19,14 @@
|
|||||||
<MudToggleIconButton Class="ml-auto" Icon="@Icons.Material.Outlined.LightMode"
|
<MudToggleIconButton Class="ml-auto" Icon="@Icons.Material.Outlined.LightMode"
|
||||||
ToggledIcon="@Icons.Material.Outlined.DarkMode" ToggledColor="Color.Primary" Color="Color.Primary"
|
ToggledIcon="@Icons.Material.Outlined.DarkMode" ToggledColor="Color.Primary" Color="Color.Primary"
|
||||||
Toggled="@_isDarkMode" ToggledChanged="@DarkModeToggle" />
|
Toggled="@_isDarkMode" ToggledChanged="@DarkModeToggle" />
|
||||||
|
<LanguageSelector />
|
||||||
</MudAppBar>
|
</MudAppBar>
|
||||||
<MudDrawer id="nav-drawer" @bind-Open="_drawerOpen" ClipMode="DrawerClipMode.Docked" Elevation="2">
|
<MudDrawer id="nav-drawer" @bind-Open="_drawerOpen" ClipMode="DrawerClipMode.Docked" Elevation="2">
|
||||||
<NavMenu />
|
<NavMenu />
|
||||||
|
<MudSpacer />
|
||||||
|
<MudText Typo="Typo.caption" Class="mx-2" GutterBottom>
|
||||||
|
@AppSettings.AppName - @AppSettings.AppVersion
|
||||||
|
</MudText>
|
||||||
</MudDrawer>
|
</MudDrawer>
|
||||||
<MudMainContent Class="pt-16 pa-4">
|
<MudMainContent Class="pt-16 pa-4">
|
||||||
@Body
|
@Body
|
||||||
|
|||||||
@@ -13,4 +13,7 @@
|
|||||||
<MudNavLink Href="@GuestConsts.Page_StayEntry_List" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.Book">
|
<MudNavLink Href="@GuestConsts.Page_StayEntry_List" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.Book">
|
||||||
@LanguageLocale.navMenu_StayEntryList
|
@LanguageLocale.navMenu_StayEntryList
|
||||||
</MudNavLink>
|
</MudNavLink>
|
||||||
|
<MudNavLink Href="@GuestConsts.Page_StayExport_List" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.ImportExport">
|
||||||
|
@LanguageLocale.navMenu_StayExport
|
||||||
|
</MudNavLink>
|
||||||
</MudNavMenu>
|
</MudNavMenu>
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
@page "/debug/addrSearch"
|
@page "/debug/addrSearch"
|
||||||
|
|
||||||
@using Somnia.GuestLog.Models.DTOs;
|
@using Somnia.GuestLog.Models.DTOs;
|
||||||
|
@using Somnia.GuestLog.Services;
|
||||||
@using Somnia.GuestLog.Services.AddressQuery;
|
@using Somnia.GuestLog.Services.AddressQuery;
|
||||||
|
|
||||||
@inject ILogger<AddressQuery> logger;
|
@inject ILogger<AddressQuery> logger;
|
||||||
@inject IAddressQueryFactory addressQueryFactory;
|
@inject IAddressQueryFactory addressQueryFactory;
|
||||||
@inject ISnackbar Snackbar
|
@inject IUserMessageService userMessage
|
||||||
@inject IDialogService DialogService
|
@inject IDialogService DialogService
|
||||||
|
|
||||||
<PageTitle>DEBUG - Address Query</PageTitle>
|
<PageTitle>DEBUG - Address Query</PageTitle>
|
||||||
@@ -89,7 +90,7 @@
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
logger.LogError(ex, "SearchAddress returned an error!");
|
logger.LogError(ex, "SearchAddress returned an error!");
|
||||||
Snackbar.Add($"Error searching address: {ex.Message}", Severity.Error);
|
userMessage.ShowMessage($"Error searching address: {ex.Message}", MessageKind.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
@page "/debug/empty"
|
@page "/debug/empty"
|
||||||
|
|
||||||
|
@using Somnia.GuestLog.Services
|
||||||
|
|
||||||
|
|
||||||
@inject ILogger<Empty> logger;
|
@inject ILogger<Empty> logger;
|
||||||
@inject ISnackbar Snackbar
|
@inject IUserMessageService userMessage
|
||||||
@inject IDialogService DialogService
|
@inject IDialogService DialogService
|
||||||
|
|
||||||
<PageTitle>DEBUG - Empty</PageTitle>
|
<PageTitle>DEBUG - Empty</PageTitle>
|
||||||
|
|||||||
@@ -4,26 +4,41 @@
|
|||||||
@using Somnia.GuestLog.Services;
|
@using Somnia.GuestLog.Services;
|
||||||
@using Microsoft.AspNetCore.WebUtilities;
|
@using Microsoft.AspNetCore.WebUtilities;
|
||||||
|
|
||||||
@inject ISnackbar Snackbar
|
@inject IUserMessageService userMessage
|
||||||
@inject IDialogService DialogService
|
@inject IDialogService DialogService
|
||||||
@inject NavigationManager Navigation
|
@inject NavigationManager Navigation
|
||||||
@inject IGuestDocumentService guestDocService
|
@inject IGuestDocumentEntityService guestDocService
|
||||||
@inject IStayEntryService stayService
|
@inject IStayEntryEntityService stayService
|
||||||
|
@inject IDialogService DialogService
|
||||||
|
|
||||||
|
|
||||||
<PageTitle>Somnia - Guest Docs - Details</PageTitle>
|
<PageTitle>Somnia - Guest Docs - Details</PageTitle>
|
||||||
|
|
||||||
<MudStack Row="true" Class="my-4">
|
<MudStack Row="true" Class="my-4">
|
||||||
<MudText Typo="Typo.h4" GutterBottom="true">Guest Document - "@docId"</MudText>
|
<MudText Typo="Typo.h4" GutterBottom="true">Guest Document: @docId - @documentModel?.FullDocument</MudText>
|
||||||
<MudSpacer />
|
<MudSpacer />
|
||||||
|
@if (_isEditMode)
|
||||||
|
{
|
||||||
|
<MudButton Variant="Variant.Filled" Color="Color.Error" Size="Size.Small" StartIcon="@Icons.Material.Filled.Cancel"
|
||||||
|
OnClick="() => BtnCancelEdit()" Disabled="!_isEditMode">
|
||||||
|
@LanguageLocale.general_btnCancel
|
||||||
|
</MudButton>
|
||||||
|
<MudButton Variant="Variant.Filled" Color="Color.Success" Size="Size.Small" StartIcon="@Icons.Material.Filled.Save"
|
||||||
|
OnClick="() => BtnSaveEdit()" Disabled="!_isEditMode">
|
||||||
|
@LanguageLocale.general_btnSave
|
||||||
|
</MudButton>
|
||||||
|
}
|
||||||
|
@if (!_isEditMode)
|
||||||
|
{
|
||||||
<MudButton Variant="Variant.Filled" Color="Color.Success" Size="Size.Small" StartIcon="@Icons.Material.Filled.Edit"
|
<MudButton Variant="Variant.Filled" Color="Color.Success" Size="Size.Small" StartIcon="@Icons.Material.Filled.Edit"
|
||||||
OnClick="() => BtnEdit()" Disabled>
|
OnClick="() => BtnEnableEdit()" Disabled="_isEditMode">
|
||||||
@LanguageLocale.general_btnEdit
|
@LanguageLocale.general_btnEdit
|
||||||
</MudButton>
|
</MudButton>
|
||||||
<MudButton Variant="Variant.Filled" Color="Color.Default" Size="Size.Small"
|
<MudButton Variant="Variant.Filled" Color="Color.Default" Size="Size.Small"
|
||||||
StartIcon="@Icons.Material.Filled.ArrowBack" OnClick="() => BtnReturn()">
|
StartIcon="@Icons.Material.Filled.ArrowBack" OnClick="() => BtnReturn()">
|
||||||
@LanguageLocale.general_btnReturn
|
@LanguageLocale.general_btnReturn
|
||||||
</MudButton>
|
</MudButton>
|
||||||
|
}
|
||||||
</MudStack>
|
</MudStack>
|
||||||
|
|
||||||
@if (documentModel is not null)
|
@if (documentModel is not null)
|
||||||
@@ -32,10 +47,11 @@
|
|||||||
Centered>
|
Centered>
|
||||||
|
|
||||||
<MudTabPanel Text="Details" Icon="@Icons.Material.Filled.Info">
|
<MudTabPanel Text="Details" Icon="@Icons.Material.Filled.Info">
|
||||||
<GuestDocForm @ref="_form" Model="documentModel" ReadOnly="true" />
|
<GuestDocForm @ref="_form" Model="documentModel" ReadOnly="!_isEditMode" />
|
||||||
</MudTabPanel>
|
</MudTabPanel>
|
||||||
|
|
||||||
<MudTabPanel Text="Stays" ToolTip="Guest stays" OnClick="LoadTabGuestStays" Icon="@Icons.Material.Filled.Bed">
|
<MudTabPanel Text="Stays" ToolTip="Guest stays" Icon="@Icons.Material.Filled.Bed" OnClick="LoadTabGuestStays"
|
||||||
|
Disabled="_isEditMode">
|
||||||
<MudText>Total Stays: @(guestStaysLoading ? "Loading..." : guestStayList.Count())</MudText>
|
<MudText>Total Stays: @(guestStaysLoading ? "Loading..." : guestStayList.Count())</MudText>
|
||||||
<MudTable Items="@guestStayList" Hover="true" Loading="@guestStaysLoading" Class="mt-2" Elevation="2">
|
<MudTable Items="@guestStayList" Hover="true" Loading="@guestStaysLoading" Class="mt-2" Elevation="2">
|
||||||
<HeaderContent>
|
<HeaderContent>
|
||||||
@@ -77,7 +93,7 @@
|
|||||||
@code {
|
@code {
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public string? docId { get; set; }
|
public long docId { get; set; }
|
||||||
|
|
||||||
GuestDocForm _form = null!;
|
GuestDocForm _form = null!;
|
||||||
|
|
||||||
@@ -87,29 +103,22 @@
|
|||||||
IEnumerable<StayEntryDTO> guestStayList = [];
|
IEnumerable<StayEntryDTO> guestStayList = [];
|
||||||
bool guestStaysLoading = true;
|
bool guestStaysLoading = true;
|
||||||
|
|
||||||
|
private bool _isEditMode = false;
|
||||||
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
if (docId is null)
|
|
||||||
{
|
|
||||||
Snackbar.Add("No GuestDocument provided!!", Severity.Error);
|
|
||||||
Navigation.NotFound();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
GuestDocIdDTO? docIdModel = GuestDocIdDTO.DecodeFromString(docId);
|
|
||||||
if (docIdModel is null)
|
|
||||||
{
|
|
||||||
Snackbar.Add($"Provided GuestDocId can't be decoded: '{docId}'", Severity.Error);
|
|
||||||
Navigation.NotFound();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Get model from db.
|
//Get model from db.
|
||||||
documentModel = await guestDocService.GetDtoByIdAsync(docIdModel.DocumentType, docIdModel.DocumentNum);
|
await LoadGuestDocumentAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task LoadGuestDocumentAsync()
|
||||||
|
{
|
||||||
|
//Get model from db.
|
||||||
|
documentModel = await guestDocService.GetLastVersionDtoByIdAsync(docId);
|
||||||
if (documentModel is null)
|
if (documentModel is null)
|
||||||
{
|
{
|
||||||
Snackbar.Add($"GuestDocument not found with ID: '{docId}'", Severity.Error);
|
userMessage.ShowMessage($"GuestDocument not found with ID: '{docId}'", MessageKind.Error);
|
||||||
Navigation.NotFound();
|
Navigation.NotFound();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -123,22 +132,81 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (documentModel is null || documentModel.DocumentType is null || documentModel.DocumentNum is null)
|
if (documentModel is null || documentModel.Id is null || documentModel.Version is null)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
guestStaysLoading = true;
|
guestStaysLoading = true;
|
||||||
guestStayList = await stayService.GetStaysWithGuest(documentModel.DocumentType, documentModel.DocumentNum);
|
guestStayList = await stayService.GetStaysWithGuest(documentModel.Id.Value);
|
||||||
guestStaysLoading = false;
|
guestStaysLoading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#region Event Handlers
|
#region Event Handlers
|
||||||
|
|
||||||
private void BtnEdit()
|
private void BtnEnableEdit()
|
||||||
{
|
{
|
||||||
Snackbar.Add("Not implemented yet!", Severity.Info);
|
Debug.Assert(_isEditMode == false);
|
||||||
|
|
||||||
|
userMessage.ShowMessage(LanguageLocale.page_GuestDocDetail_msgEditEnabled, MessageKind.Normal);
|
||||||
|
_isEditMode = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task BtnCancelEdit()
|
||||||
|
{
|
||||||
|
Debug.Assert(_isEditMode == true);
|
||||||
|
|
||||||
|
var result = await DialogService.ShowMessageBoxAsync(
|
||||||
|
LanguageLocale.general_confirmTitle, LanguageLocale.page_GuestDocDetail_msgConfirmCancelEdit,
|
||||||
|
yesText: "OK", cancelText: LanguageLocale.general_btnCancel);
|
||||||
|
|
||||||
|
if (result == null || result.Value == false)
|
||||||
|
{
|
||||||
|
// Cancel cancel -> Continue with edit.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Cancel edit -> Reload data from DB.
|
||||||
|
await LoadGuestDocumentAsync();
|
||||||
|
|
||||||
|
userMessage.ShowMessage(LanguageLocale.general_msgEditCanceled, MessageKind.Normal);
|
||||||
|
_isEditMode = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task BtnSaveEdit()
|
||||||
|
{
|
||||||
|
Debug.Assert(_isEditMode == true && documentModel is not null);
|
||||||
|
|
||||||
|
var confirmResult = await DialogService.ShowMessageBoxAsync(
|
||||||
|
LanguageLocale.general_confirmTitle, LanguageLocale.page_GuestDocDetail_msgConfirmSaveEdit,
|
||||||
|
yesText: "OK", cancelText: LanguageLocale.general_btnCancel);
|
||||||
|
|
||||||
|
if (confirmResult == null || confirmResult.Value == false)
|
||||||
|
{
|
||||||
|
// Cancel save -> Continue with edit.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Show Loading dialog...
|
||||||
|
var loadingDialog = await DialogService.ShowAsync<LoadingDialog>();
|
||||||
|
|
||||||
|
//Save edit.
|
||||||
|
Result updateResult = await guestDocService.UpdateDocumentAsync(documentModel);
|
||||||
|
if (!updateResult.IsSuccess)
|
||||||
|
{
|
||||||
|
string errorMsg = string.Format(LanguageLocale.page_GuestDocDetail_msgEditError, documentModel.FullDocument);
|
||||||
|
userMessage.ShowResultWithMessage(updateResult, errorMsg);
|
||||||
|
loadingDialog.Close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Reload data from DB.
|
||||||
|
await LoadGuestDocumentAsync();
|
||||||
|
loadingDialog.Close();
|
||||||
|
userMessage.ShowMessage(LanguageLocale.general_msgEditSaved, MessageKind.Success);
|
||||||
|
|
||||||
|
_isEditMode = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BtnReturn()
|
private void BtnReturn()
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
@using Somnia.GuestLog.Models.DTOs;
|
@using Somnia.GuestLog.Models.DTOs;
|
||||||
@using Somnia.GuestLog.Services;
|
@using Somnia.GuestLog.Services;
|
||||||
|
|
||||||
@inject IGuestDocumentService GuestDocService
|
@inject IGuestDocumentEntityService GuestDocService
|
||||||
@inject NavigationManager Navigation
|
@inject NavigationManager Navigation
|
||||||
@inject ISnackbar Snackbar
|
@inject IUserMessageService userMessage
|
||||||
@inject IDialogService DialogService
|
@inject IDialogService DialogService
|
||||||
@inject IDataListService dataListService;
|
@inject IDataListService dataListService;
|
||||||
|
|
||||||
@@ -43,6 +43,9 @@
|
|||||||
</MudStack>
|
</MudStack>
|
||||||
</ToolBarContent>
|
</ToolBarContent>
|
||||||
<Columns>
|
<Columns>
|
||||||
|
<PropertyColumn Property="x => x.Id" Title="@LanguageLocale.dto_GuestDocument_Id" Hideable="false" />
|
||||||
|
<PropertyColumn Property="x => x.Version" Title="@LanguageLocale.dto_GuestDocument_Version" Hidden
|
||||||
|
Hideable="true" />
|
||||||
<PropertyColumn Title="@LanguageLocale.dto_GuestDocument_DocumentType"
|
<PropertyColumn Title="@LanguageLocale.dto_GuestDocument_DocumentType"
|
||||||
Property="x => dataListService.GetLocalizedValue(GuestConsts.DataList_DocumentTypes, x.DocumentType)"
|
Property="x => dataListService.GetLocalizedValue(GuestConsts.DataList_DocumentTypes, x.DocumentType)"
|
||||||
Hideable="false" />
|
Hideable="false" />
|
||||||
@@ -50,6 +53,7 @@
|
|||||||
Title="@LanguageLocale.dto_GuestDocument_DocumentNum" />
|
Title="@LanguageLocale.dto_GuestDocument_DocumentNum" />
|
||||||
<PropertyColumn Property="x => x.Name" Title="@LanguageLocale.dto_GuestDocument_Name" />
|
<PropertyColumn Property="x => x.Name" Title="@LanguageLocale.dto_GuestDocument_Name" />
|
||||||
<PropertyColumn Property="x => x.Surname" Title="@LanguageLocale.dto_GuestDocument_Surname" />
|
<PropertyColumn Property="x => x.Surname" Title="@LanguageLocale.dto_GuestDocument_Surname" />
|
||||||
|
<PropertyColumn Property="x => x.Surname2" Title="@LanguageLocale.dto_GuestDocument_Surname2" />
|
||||||
<PropertyColumn Title="@LanguageLocale.dto_GuestDocument_Nationality"
|
<PropertyColumn Title="@LanguageLocale.dto_GuestDocument_Nationality"
|
||||||
Property="x => dataListService.GetLocalizedValue(GuestConsts.DataList_CountryCodes, x.Nationality)" />
|
Property="x => dataListService.GetLocalizedValue(GuestConsts.DataList_CountryCodes, x.Nationality)" />
|
||||||
<PropertyColumn Property="x => x.UpdateTime" Title="@LanguageLocale.dto_GuestDocument_UpdateTime" />
|
<PropertyColumn Property="x => x.UpdateTime" Title="@LanguageLocale.dto_GuestDocument_UpdateTime" />
|
||||||
@@ -101,7 +105,7 @@
|
|||||||
|
|
||||||
if (showMsg)
|
if (showMsg)
|
||||||
{
|
{
|
||||||
Snackbar.Add("Data loaded from DB", Severity.Info, o => o.VisibleStateDuration = 1000);
|
userMessage.ShowMessage("Data loaded from DB", MessageKind.Info);
|
||||||
}
|
}
|
||||||
_dataLoading = false;
|
_dataLoading = false;
|
||||||
}
|
}
|
||||||
@@ -126,10 +130,9 @@
|
|||||||
|
|
||||||
private async Task BtnViewDetails(GuestDocumentDTO item)
|
private async Task BtnViewDetails(GuestDocumentDTO item)
|
||||||
{
|
{
|
||||||
GuestDocIdDTO idDto = GuestDocIdDTO.BuildFromDto(item) ?? throw new InvalidOperationException();
|
string strId = item.Id?.ToString() ?? throw new InvalidOperationException();
|
||||||
|
|
||||||
string itemId = GuestDocIdDTO.EncodeAsString(idDto);
|
string uri = GuestConsts.Page_GuestDocs_Detail.Replace(GuestConsts.Page_GuestDocs_Detail_Param_DocId, strId);
|
||||||
string uri = GuestConsts.Page_GuestDocs_Detail.Replace(GuestConsts.Page_GuestDocs_Detail_Param_DocId, itemId);
|
|
||||||
Navigation.NavigateTo(uri);
|
Navigation.NavigateTo(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,15 +145,16 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool deleted = await GuestDocService.DeleteDocumentAsync(item);
|
Result deleteResult = await GuestDocService.DeleteDocumentAsync(item);
|
||||||
if (!deleted)
|
if (!deleteResult.IsSuccess)
|
||||||
{
|
{
|
||||||
Snackbar.Add($"Error deleting document {item.DocumentType}-{item.DocumentNum}", Severity.Error);
|
string errorMsg = $"Error deleting document {item.DocumentType}-{item.DocumentNum}";
|
||||||
|
userMessage.ShowResultWithMessage(deleteResult, errorMsg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Snackbar.Add($"Document {item.DocumentType}-{item.DocumentNum} deleted!", Severity.Success);
|
userMessage.ShowMessage($"Document {item.DocumentType}-{item.DocumentNum} deleted!", MessageKind.Success);
|
||||||
await LoadDataAsync();
|
await LoadDataAsync(showMsg: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BtnNewGuest()
|
private void BtnNewGuest()
|
||||||
|
|||||||
@@ -4,10 +4,10 @@
|
|||||||
@using Somnia.GuestLog.Services;
|
@using Somnia.GuestLog.Services;
|
||||||
@using Somnia.GuestLog.Validators;
|
@using Somnia.GuestLog.Validators;
|
||||||
|
|
||||||
@inject ISnackbar Snackbar
|
@inject IUserMessageService userMessage
|
||||||
@inject IDialogService DialogService
|
@inject IDialogService DialogService
|
||||||
@inject NavigationManager Navigation
|
@inject NavigationManager Navigation
|
||||||
@inject IGuestDocumentService guestDocService
|
@inject IGuestDocumentEntityService guestDocService
|
||||||
@inject IDataListService dataListService;
|
@inject IDataListService dataListService;
|
||||||
|
|
||||||
@inject FluentValidation.IValidator<GuestDocIdDTO> docIdValidator;
|
@inject FluentValidation.IValidator<GuestDocIdDTO> docIdValidator;
|
||||||
@@ -18,10 +18,13 @@
|
|||||||
<MudStack Row="true" Class="my-4">
|
<MudStack Row="true" Class="my-4">
|
||||||
<MudText Typo="Typo.h4" GutterBottom="true">New Guest Document</MudText>
|
<MudText Typo="Typo.h4" GutterBottom="true">New Guest Document</MudText>
|
||||||
<MudSpacer />
|
<MudSpacer />
|
||||||
|
@if (currentPageMode == ePageMode.createNew)
|
||||||
|
{
|
||||||
<MudButton Variant="Variant.Filled" Color="Color.Success" Size="Size.Small" StartIcon="@Icons.Material.Filled.Add"
|
<MudButton Variant="Variant.Filled" Color="Color.Success" Size="Size.Small" StartIcon="@Icons.Material.Filled.Add"
|
||||||
OnClick="() => BtnSaveNewGuest()">
|
OnClick="() => BtnSaveNewGuest()">
|
||||||
@LanguageLocale.general_btnCreate
|
@LanguageLocale.general_btnCreate
|
||||||
</MudButton>
|
</MudButton>
|
||||||
|
}
|
||||||
<MudButton Variant="Variant.Filled" Color="Color.Default" Size="Size.Small"
|
<MudButton Variant="Variant.Filled" Color="Color.Default" Size="Size.Small"
|
||||||
StartIcon="@Icons.Material.Filled.ArrowBack" OnClick="() => BtnReturn()">
|
StartIcon="@Icons.Material.Filled.ArrowBack" OnClick="() => BtnReturn()">
|
||||||
@LanguageLocale.general_btnReturn
|
@LanguageLocale.general_btnReturn
|
||||||
@@ -82,6 +85,7 @@
|
|||||||
|
|
||||||
ePageMode currentPageMode = ePageMode.selectDocId;
|
ePageMode currentPageMode = ePageMode.selectDocId;
|
||||||
GuestDocIdDTO currentDocId = new() { DocumentNum = "", DocumentType = "" };
|
GuestDocIdDTO currentDocId = new() { DocumentNum = "", DocumentType = "" };
|
||||||
|
long? alreadyExistDocId = null;
|
||||||
GuestDocumentDTO newDocumentModel = new();
|
GuestDocumentDTO newDocumentModel = new();
|
||||||
|
|
||||||
bool loadingDocId = false;
|
bool loadingDocId = false;
|
||||||
@@ -100,7 +104,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
loadingDocId = true;
|
loadingDocId = true;
|
||||||
GuestDocumentDTO? dto = await guestDocService.GetDtoByIdAsync(currentDocId.DocumentType, currentDocId.DocumentNum);
|
GuestDocumentDTO? dto =
|
||||||
|
await guestDocService.GetLastVersionDtoByDocumentAsync(currentDocId.DocumentType, currentDocId.DocumentNum);
|
||||||
loadingDocId = false;
|
loadingDocId = false;
|
||||||
|
|
||||||
if (dto is null)
|
if (dto is null)
|
||||||
@@ -117,6 +122,7 @@
|
|||||||
|
|
||||||
//GuestDoc already exists!
|
//GuestDoc already exists!
|
||||||
currentPageMode = ePageMode.alreadyExistDoc;
|
currentPageMode = ePageMode.alreadyExistDoc;
|
||||||
|
alreadyExistDocId = dto.Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BtnReturn()
|
private void BtnReturn()
|
||||||
@@ -126,42 +132,44 @@
|
|||||||
|
|
||||||
private async Task BtnSaveNewGuest()
|
private async Task BtnSaveNewGuest()
|
||||||
{
|
{
|
||||||
|
Debug.Assert(currentPageMode == ePageMode.createNew && _form != null);
|
||||||
|
|
||||||
bool isFormValid = await _form.ValidateForm();
|
bool isFormValid = await _form.ValidateForm();
|
||||||
if (!isFormValid)
|
if (!isFormValid)
|
||||||
{
|
{
|
||||||
Snackbar.Add("Invalid Form!", Severity.Error);
|
userMessage.ShowMessage("Invalid Form!", MessageKind.Warning);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GuestDocumentDTO model = _form.Model;
|
GuestDocumentDTO model = _form.Model;
|
||||||
|
|
||||||
Snackbar.Add($"Document '{model.DocumentNum}' creating...", Severity.Info);
|
|
||||||
|
|
||||||
//Show Loading dialog...
|
//Show Loading dialog...
|
||||||
var loadingDialog = await DialogService.ShowAsync<LoadingDialog>();
|
var loadingDialog = await DialogService.ShowAsync<LoadingDialog>();
|
||||||
|
|
||||||
bool isCreated = await guestDocService.CreateDocumentAsync(model);
|
Result createResult = await guestDocService.CreateDocumentAsync(model);
|
||||||
if (!isCreated)
|
if (!createResult.IsSuccess)
|
||||||
{
|
{
|
||||||
Snackbar.Add($"Error creating Document '{model.DocumentNum}'", Severity.Error);
|
string errorMsg = $"Error creating Document '{model.FullDocument}'";
|
||||||
|
userMessage.ShowResultWithMessage(createResult, errorMsg);
|
||||||
loadingDialog.Close();
|
loadingDialog.Close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Snackbar.Add($"Document '{model.DocumentNum}' Created!", Severity.Success);
|
userMessage.ShowMessage($"Document '{model.FullDocument}' Created!", MessageKind.Success);
|
||||||
Navigation.NavigateTo(GuestConsts.Page_GuestDocs_List);
|
Navigation.NavigateTo(GuestConsts.Page_GuestDocs_List);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BtnGoToDocument()
|
private void BtnGoToDocument()
|
||||||
{
|
{
|
||||||
if (currentPageMode != ePageMode.alreadyExistDoc)
|
if (currentPageMode != ePageMode.alreadyExistDoc || alreadyExistDocId is null)
|
||||||
{
|
{
|
||||||
Snackbar.Add("Invalid operation!", Severity.Error);
|
userMessage.ShowMessage("Invalid operation!", MessageKind.Error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
string docId = GuestDocIdDTO.EncodeAsString(currentDocId);
|
|
||||||
string uri = GuestConsts.Page_GuestDocs_Detail.Replace("{docId}", docId);
|
string strId = alreadyExistDocId.Value.ToString();
|
||||||
|
string uri = GuestConsts.Page_GuestDocs_Detail.Replace(GuestConsts.Page_GuestDocs_Detail_Param_DocId, strId);
|
||||||
Navigation.NavigateTo(uri);
|
Navigation.NavigateTo(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,11 @@
|
|||||||
@using Somnia.GuestLog.Models.DTOs;
|
@using Somnia.GuestLog.Models.DTOs;
|
||||||
@using Somnia.GuestLog.Services;
|
@using Somnia.GuestLog.Services;
|
||||||
|
|
||||||
@inject ISnackbar Snackbar
|
@inject IUserMessageService userMessage
|
||||||
@inject IDialogService DialogService
|
@inject IDialogService DialogService
|
||||||
@inject NavigationManager Navigation
|
@inject NavigationManager Navigation
|
||||||
@inject IGuestDocumentService guestDocService
|
@inject IGuestDocumentEntityService guestDocService
|
||||||
@inject IStayEntryService stayService
|
@inject IStayEntryEntityService stayService
|
||||||
|
|
||||||
|
|
||||||
<PageTitle>Somnia - Guest Docs - Details</PageTitle>
|
<PageTitle>Somnia - Guest Docs - Details</PageTitle>
|
||||||
@@ -27,7 +27,8 @@
|
|||||||
|
|
||||||
@if (stayModel is not null)
|
@if (stayModel is not null)
|
||||||
{
|
{
|
||||||
<StayEntryForm Model="stayModel" ReadOnly="true" />
|
<StayEntryForm Model="stayModel" FormMode="FormMode.ReadOnly" />
|
||||||
|
<MudText Class="mt-4">@CreateTimeString</MudText>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -41,6 +42,22 @@
|
|||||||
|
|
||||||
StayEntryDTO? stayModel = null;
|
StayEntryDTO? stayModel = null;
|
||||||
|
|
||||||
|
private string? CreateTimeString
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (stayModel is null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<string> textList = [];
|
||||||
|
textList.Add($"Created at: {stayModel.CreateTime?.ToString() ?? "???"}");
|
||||||
|
textList.Add($"Last Update Time: {stayModel.UpdateTime?.ToString() ?? "???"}");
|
||||||
|
return string.Join("; ", textList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
@* if (StayId is default)
|
@* if (StayId is default)
|
||||||
@@ -54,7 +71,7 @@
|
|||||||
stayModel = await stayService.GetDtoByIdAsync(StayId, queryConfig: new(IncludeGuests: true));
|
stayModel = await stayService.GetDtoByIdAsync(StayId, queryConfig: new(IncludeGuests: true));
|
||||||
if (stayModel is null)
|
if (stayModel is null)
|
||||||
{
|
{
|
||||||
Snackbar.Add($"Stay not found with ID: '{StayId}'", Severity.Error);
|
userMessage.ShowMessage($"Stay not found with ID: '{StayId}'", MessageKind.Error);
|
||||||
Navigation.NotFound();
|
Navigation.NotFound();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -62,7 +79,7 @@
|
|||||||
|
|
||||||
private void BtnEdit()
|
private void BtnEdit()
|
||||||
{
|
{
|
||||||
Snackbar.Add("Not implemented yet!", Severity.Info);
|
userMessage.ShowMessage("Not implemented yet!", MessageKind.Info);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BtnReturn()
|
private void BtnReturn()
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
@using Somnia.GuestLog.Models.DTOs;
|
@using Somnia.GuestLog.Models.DTOs;
|
||||||
@using Somnia.GuestLog.Services;
|
@using Somnia.GuestLog.Services;
|
||||||
|
|
||||||
@inject IStayEntryService StayEntryService
|
@inject IStayEntryEntityService StayEntryService
|
||||||
@inject NavigationManager Navigation
|
@inject NavigationManager Navigation
|
||||||
@inject ISnackbar Snackbar
|
@inject IUserMessageService userMessage
|
||||||
@inject IDialogService DialogService
|
@inject IDialogService DialogService
|
||||||
@inject IDataListService dataListService;
|
@inject IDataListService dataListService;
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@
|
|||||||
private StayEntryFilterDTO stayFilter = new StayEntryFilterDTO()
|
private StayEntryFilterDTO stayFilter = new StayEntryFilterDTO()
|
||||||
{
|
{
|
||||||
DateInStart = DateTime.Today.AddDays(-14),
|
DateInStart = DateTime.Today.AddDays(-14),
|
||||||
DateInEnd = DateTime.Today,
|
DateInEnd = DateTime.Today.AddDays(1),
|
||||||
};
|
};
|
||||||
|
|
||||||
private IEnumerable<StayEntryDTO> stayEntryList = [];
|
private IEnumerable<StayEntryDTO> stayEntryList = [];
|
||||||
@@ -96,7 +96,7 @@
|
|||||||
|
|
||||||
if (showMsg)
|
if (showMsg)
|
||||||
{
|
{
|
||||||
Snackbar.Add("Data loaded from DB", Severity.Info, o => o.VisibleStateDuration = 1000);
|
userMessage.ShowMessage("Data loaded from DB", MessageKind.Info);
|
||||||
}
|
}
|
||||||
_dataLoading = false;
|
_dataLoading = false;
|
||||||
}
|
}
|
||||||
@@ -117,7 +117,7 @@
|
|||||||
|
|
||||||
private async Task BtnViewDetails(StayEntryDTO item)
|
private async Task BtnViewDetails(StayEntryDTO item)
|
||||||
{
|
{
|
||||||
string itemId = $"{item.Id ?? -1}";
|
string itemId = item.Id?.ToString() ?? throw new InvalidOperationException();
|
||||||
string uri = GuestConsts.Page_StayEntry_Detail.Replace(GuestConsts.Page_StayEntry_Detail_Param_Id, itemId);
|
string uri = GuestConsts.Page_StayEntry_Detail.Replace(GuestConsts.Page_StayEntry_Detail_Param_Id, itemId);
|
||||||
Navigation.NavigateTo(uri);
|
Navigation.NavigateTo(uri);
|
||||||
}
|
}
|
||||||
@@ -131,14 +131,15 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool deleted = await StayEntryService.DeleteEntryAsync(item);
|
Result deleteResult = await StayEntryService.DeleteEntryAsync(item);
|
||||||
if (!deleted)
|
if (!deleteResult.IsSuccess)
|
||||||
{
|
{
|
||||||
Snackbar.Add($"Error deleting Stay {item.Id}", Severity.Error);
|
string errorMsg = $"Error deleting Stay {item.Id}";
|
||||||
|
userMessage.ShowResultWithMessage(deleteResult, errorMsg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Snackbar.Add($"Stay {item.Id} deleted!", Severity.Success);
|
userMessage.ShowMessage($"Stay {item.Id} deleted!", MessageKind.Success);
|
||||||
await LoadDataAsync();
|
await LoadDataAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,10 @@
|
|||||||
@using Somnia.GuestLog.Services;
|
@using Somnia.GuestLog.Services;
|
||||||
|
|
||||||
|
|
||||||
@inject ISnackbar Snackbar
|
@inject IUserMessageService userMessage
|
||||||
@inject IDialogService DialogService
|
@inject IDialogService DialogService
|
||||||
@inject NavigationManager Navigation
|
@inject NavigationManager Navigation
|
||||||
@inject IStayEntryService stayService
|
@inject IStayEntryEntityService stayService
|
||||||
@inject IDataListService dataListService;
|
@inject IDataListService dataListService;
|
||||||
|
|
||||||
<PageTitle>Somnia - Stay Entries - New</PageTitle>
|
<PageTitle>Somnia - Stay Entries - New</PageTitle>
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
</MudButton>
|
</MudButton>
|
||||||
</MudStack>
|
</MudStack>
|
||||||
|
|
||||||
<StayEntryForm @ref="_form" Model="@newStayModel" />
|
<StayEntryForm @ref="_form" Model="@newStayModel" FormMode="FormMode.Create" />
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
StayEntryForm _form = null!;
|
StayEntryForm _form = null!;
|
||||||
@@ -45,22 +45,22 @@
|
|||||||
bool isFormValid = await _form.ValidateForm();
|
bool isFormValid = await _form.ValidateForm();
|
||||||
if (!isFormValid)
|
if (!isFormValid)
|
||||||
{
|
{
|
||||||
Snackbar.Add("Invalid Form!", Severity.Warning);
|
userMessage.ShowMessage("Invalid Form!", MessageKind.Warning);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var loadingDialog = await DialogService.ShowAsync<LoadingDialog>();
|
var loadingDialog = await DialogService.ShowAsync<LoadingDialog>();
|
||||||
|
|
||||||
StayEntryDTO model = _form.GetModel();
|
StayEntryDTO model = _form.GetModel();
|
||||||
bool isCreated = await stayService.CreateEntryAsync(model);
|
Result createResult = await stayService.CreateEntryAsync(model);
|
||||||
if (!isCreated)
|
if (!createResult.IsSuccess)
|
||||||
{
|
{
|
||||||
Snackbar.Add($"Error creating StayEntry", Severity.Error);
|
userMessage.ShowResultWithMessage(createResult, $"Error creating StayEntry");
|
||||||
loadingDialog.Close();
|
loadingDialog.Close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Snackbar.Add($"StayEntry Created!", Severity.Success);
|
userMessage.ShowMessage("StayEntry Created: (Id: {0})", MessageKind.Success, createResult.Context ?? ["???"]);
|
||||||
Navigation.NavigateTo(GuestConsts.Page_StayEntry_List);
|
Navigation.NavigateTo(GuestConsts.Page_StayEntry_List);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,197 @@
|
|||||||
|
@attribute [Route($"{GuestConsts.Page_StayExport_List}")]
|
||||||
|
|
||||||
|
@using System.Text.Json;
|
||||||
|
@using Somnia.GuestLog.Models.DTOs;
|
||||||
|
@using Somnia.GuestLog.Services;
|
||||||
|
@using Somnia.GuestLog.Services.StayExport;
|
||||||
|
|
||||||
|
@inject IStayExportFileEntityService stayExportEntityService
|
||||||
|
@inject NavigationManager Navigation
|
||||||
|
@inject IUserMessageService userMessage
|
||||||
|
@inject IDialogService DialogService
|
||||||
|
@inject IDataListService dataListService;
|
||||||
|
@inject ILocalizerService Localizer;
|
||||||
|
|
||||||
|
@inject IStayExportService ExportService;
|
||||||
|
@inject IJSRuntime JS
|
||||||
|
|
||||||
|
|
||||||
|
<PageTitle>Somnia - Stay Export Files</PageTitle>
|
||||||
|
|
||||||
|
<MudStack Row="true" Class="my-4">
|
||||||
|
<MudText Typo="Typo.h4" GutterBottom="true">@LanguageLocale.page_StayExportList_pageTitle</MudText>
|
||||||
|
<MudSpacer />
|
||||||
|
<MudButton Variant="Variant.Filled" Color="Color.Primary" Size="Size.Small"
|
||||||
|
StartIcon="@Icons.Material.Filled.Search" OnClick="() => BtnSearchDataAsync()">
|
||||||
|
@LanguageLocale.general_btnSearch
|
||||||
|
</MudButton>
|
||||||
|
<MudButton Variant="Variant.Filled" Color="Color.Primary" Size="Size.Small" StartIcon="@Icons.Material.Filled.Add"
|
||||||
|
OnClick="() => BtnNewExport()">
|
||||||
|
@LanguageLocale.page_StayExportList_btnNewExport
|
||||||
|
</MudButton>
|
||||||
|
</MudStack>
|
||||||
|
|
||||||
|
@* <MudPaper Class="pa-4 my-4" Elevation="2" Height="100%">
|
||||||
|
FILTER
|
||||||
|
</MudPaper> *@
|
||||||
|
|
||||||
|
<MudDataGrid @ref="_dataGrid" T="StayExportFileDTO" Items="@stayExportList" Loading="@_dataLoading" ReadOnly="true"
|
||||||
|
Elevation="2">
|
||||||
|
<ToolBarContent>
|
||||||
|
<MudText Typo="Typo.subtitle1">@LanguageLocale.page_StayExportList_exportList</MudText>
|
||||||
|
</ToolBarContent>
|
||||||
|
<Columns>
|
||||||
|
<PropertyColumn Property="x => x.Id" Hideable="false" Title="@LanguageLocale.dto_StayExportFile_Id" />
|
||||||
|
<PropertyColumn Property="x => Localizer.GetEnumValue(x.ExportFormat)"
|
||||||
|
Title="@LanguageLocale.dto_StayExportFile_ExportFormat" />
|
||||||
|
<TemplateColumn Title="@LanguageLocale.dto_StayExportFile_ExportParams">
|
||||||
|
<CellTemplate>
|
||||||
|
<MudIconButton Size="@Size.Small" Icon="@Icons.Material.Outlined.Info"
|
||||||
|
OnClick="() => ShowExportParams(context.Item)" />
|
||||||
|
</CellTemplate>
|
||||||
|
</TemplateColumn>
|
||||||
|
<PropertyColumn Property="x => Localizer.GetEnumValue(x.ExportResult)"
|
||||||
|
Title="@LanguageLocale.dto_StayExportFile_ExportResult" />
|
||||||
|
<PropertyColumn Property="x => x.ExportTime" Title="@LanguageLocale.dto_StayExportFile_ExportTime" />
|
||||||
|
<TemplateColumn Title="@LanguageLocale.dto_StayExportFile_ExportDetails">
|
||||||
|
<CellTemplate>
|
||||||
|
<MudIconButton Size="@Size.Small" Icon="@Icons.Material.Outlined.Info"
|
||||||
|
OnClick="() => ShowExportDetails(context.Item)" />
|
||||||
|
</CellTemplate>
|
||||||
|
</TemplateColumn>
|
||||||
|
|
||||||
|
<TemplateColumn CellClass="d-flex justify-between" Title="Options" StickyRight Hideable="false"
|
||||||
|
ShowColumnOptions="false">
|
||||||
|
<CellTemplate>
|
||||||
|
<MudIconButton Size="@Size.Small" Icon="@Icons.Material.Outlined.Download"
|
||||||
|
OnClick="() => BtnDownloadFile(context.Item)" />
|
||||||
|
<MudIconButton Size="@Size.Small" Icon="@Icons.Material.Outlined.Delete"
|
||||||
|
OnClick="() => BtnDeleteItem(context.Item)" />
|
||||||
|
</CellTemplate>
|
||||||
|
</TemplateColumn>
|
||||||
|
</Columns>
|
||||||
|
<PagerContent>
|
||||||
|
<MudDataGridPager T="StayExportFileDTO" />
|
||||||
|
</PagerContent>
|
||||||
|
</MudDataGrid>
|
||||||
|
|
||||||
|
<ConfirmDeleteMsgBox @ref="_confirmDeleteMsgBox" />
|
||||||
|
|
||||||
|
@code {
|
||||||
|
private bool _dataLoading = true;
|
||||||
|
private const int resultLimit = 200;
|
||||||
|
|
||||||
|
private IEnumerable<StayExportFileDTO> stayExportList = [];
|
||||||
|
|
||||||
|
private MudDataGrid<StayExportFileDTO> _dataGrid = null!;
|
||||||
|
private ConfirmDeleteMsgBox _confirmDeleteMsgBox = null!;
|
||||||
|
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
await LoadDataAsync(showMsg: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task LoadDataAsync(bool showMsg = true)
|
||||||
|
{
|
||||||
|
_dataLoading = true;
|
||||||
|
|
||||||
|
stayExportList = await stayExportEntityService.GetDtoListAsync(limit: resultLimit);
|
||||||
|
|
||||||
|
if (showMsg)
|
||||||
|
{
|
||||||
|
userMessage.ShowMessage("Data loaded from DB", MessageKind.Info);
|
||||||
|
}
|
||||||
|
_dataLoading = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#region Event Handlers
|
||||||
|
|
||||||
|
private async Task BtnSearchDataAsync()
|
||||||
|
{
|
||||||
|
await LoadDataAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BtnNewExport()
|
||||||
|
{
|
||||||
|
Navigation.NavigateTo(GuestConsts.Page_StayExport_New);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private async Task ShowExportParams(StayExportFileDTO dto)
|
||||||
|
{
|
||||||
|
string jsonParams = JsonSerializer.Serialize(dto.ExportParams, options: new() { WriteIndented = true });
|
||||||
|
|
||||||
|
await DialogService.ShowMessageBoxAsync("Details", (MarkupString)$"<pre>{jsonParams}</pre>");
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ShowExportDetails(StayExportFileDTO dto)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(dto.ExportDetails))
|
||||||
|
{
|
||||||
|
userMessage.ShowMessage("This ExportFile doesn't have any export details", MessageKind.Info);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
using var jDoc = JsonDocument.Parse(dto.ExportDetails);
|
||||||
|
string jsonDetails = JsonSerializer.Serialize(jDoc, new JsonSerializerOptions { WriteIndented = true });
|
||||||
|
|
||||||
|
await DialogService.ShowMessageBoxAsync("Details", (MarkupString)$"<pre>{jsonDetails}</pre>");
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task BtnDownloadFile(StayExportFileDTO item)
|
||||||
|
{
|
||||||
|
if (item.ExportResult == Enums.Models.StayExportFileResult.NoData)
|
||||||
|
{
|
||||||
|
userMessage.ShowMessage("A Export without data can't be downloaded!", MessageKind.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(item.ExportedPath))
|
||||||
|
{
|
||||||
|
userMessage.ShowMessage("File can't be downloaded: no path found!", MessageKind.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
using Stream objectStream = new MemoryStream();
|
||||||
|
Result loadResult = await ExportService.GetExportedFileAsync(item, objectStream);
|
||||||
|
if (!loadResult.IsSuccess)
|
||||||
|
{
|
||||||
|
userMessage.ShowResultWithMessage(loadResult, "Exported File can't be downloaded");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
objectStream.Seek(0, SeekOrigin.Begin);
|
||||||
|
|
||||||
|
using var streamRef = new DotNetStreamReference(stream: objectStream);
|
||||||
|
|
||||||
|
var fileName = Path.GetFileName(item.ExportedPath);
|
||||||
|
await JS.InvokeVoidAsync("downloadFileFromStream", fileName, streamRef);
|
||||||
|
userMessage.ShowMessage("Exported File downloaded!", MessageKind.Success);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task BtnDeleteItem(StayExportFileDTO item)
|
||||||
|
{
|
||||||
|
bool? confirmDelete = await _confirmDeleteMsgBox.MsgBox.ShowAsync();
|
||||||
|
|
||||||
|
if (confirmDelete is null || confirmDelete.Value == false)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result deleteResult = await ExportService.DeleteExportedFileAsync(item);
|
||||||
|
if (!deleteResult.IsSuccess)
|
||||||
|
{
|
||||||
|
string errorMsg = $"Error deleting Export file {item.Id}";
|
||||||
|
userMessage.ShowResultWithMessage(deleteResult, errorMsg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
userMessage.ShowMessage($"Export file {item.Id} deleted!", MessageKind.Success);
|
||||||
|
await LoadDataAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,162 @@
|
|||||||
|
@attribute [Route($"{GuestConsts.Page_StayExport_New}")]
|
||||||
|
|
||||||
|
@using FluentValidation;
|
||||||
|
@using Somnia.GuestLog.Models.DTOs;
|
||||||
|
@using Somnia.GuestLog.Enums.Models;
|
||||||
|
@using Somnia.GuestLog.Services;
|
||||||
|
@using Somnia.GuestLog.Validators;
|
||||||
|
@using Somnia.GuestLog.Services.StayExport;
|
||||||
|
|
||||||
|
|
||||||
|
@inject IUserMessageService userMessage
|
||||||
|
@inject IDialogService DialogService
|
||||||
|
@inject NavigationManager Navigation
|
||||||
|
@inject IValidator<StayExportParamsDTO> ExportParamsValidator;
|
||||||
|
@inject ILocalizerService Localizer;
|
||||||
|
@inject IStayExportService ExportService;
|
||||||
|
|
||||||
|
@inject IJSRuntime JS
|
||||||
|
|
||||||
|
|
||||||
|
<PageTitle>Somnia - Stay Export - New</PageTitle>
|
||||||
|
|
||||||
|
<MudStack Row="true" Class="my-4">
|
||||||
|
<MudText Typo="Typo.h4" GutterBottom="true">
|
||||||
|
@LanguageLocale.page_StayExportNew_pageTitle
|
||||||
|
</MudText>
|
||||||
|
<MudSpacer />
|
||||||
|
<MudButton Variant="Variant.Filled" Color="Color.Success" Size="Size.Small" StartIcon="@Icons.Material.Filled.Add"
|
||||||
|
OnClick="() => BtnCreateExport()" Disabled="@_isExported">
|
||||||
|
@LanguageLocale.general_btnCreate
|
||||||
|
</MudButton>
|
||||||
|
<MudButton Variant="Variant.Filled" Color="Color.Default" Size="Size.Small"
|
||||||
|
StartIcon="@Icons.Material.Filled.ArrowBack" OnClick="() => BtnReturn()">
|
||||||
|
@LanguageLocale.general_btnReturn
|
||||||
|
</MudButton>
|
||||||
|
</MudStack>
|
||||||
|
|
||||||
|
<MudForm @ref="@_form" Model="@exportParams"
|
||||||
|
Validation="@((ExportParamsValidator as StayExportParamsDTOValidator)!.ValidateValue)" ReadOnly="@_isExported">
|
||||||
|
<MudPaper Class="pa-4 my-4" Elevation="3" Height="100%">
|
||||||
|
<MudStack Row style="margin-block: 0.2em;">
|
||||||
|
<MudSelect @bind-Value="exportFormat" Label="@LanguageLocale.dto_StayExportFile_ExportFormat" FullWidth
|
||||||
|
Clearable>
|
||||||
|
@foreach (StayExportFormat option in Enum.GetValues<StayExportFormat>())
|
||||||
|
{
|
||||||
|
<MudSelectItem Value="new Nullable<StayExportFormat>(option)">
|
||||||
|
@Localizer.GetEnumValue(option)
|
||||||
|
</MudSelectItem>
|
||||||
|
}
|
||||||
|
</MudSelect>
|
||||||
|
<MudSelect @bind-Value="exportParams.ExportType" For="@(() => exportParams.ExportType)"
|
||||||
|
Label="@LanguageLocale.dto_StayExportParams_ExportType" FullWidth Clearable>
|
||||||
|
@foreach (StayExportParamType option in Enum.GetValues<StayExportParamType>())
|
||||||
|
{
|
||||||
|
<MudSelectItem Value="new Nullable<StayExportParamType>(option)">
|
||||||
|
@Localizer.GetEnumValue(option)
|
||||||
|
</MudSelectItem>
|
||||||
|
}
|
||||||
|
</MudSelect>
|
||||||
|
</MudStack>
|
||||||
|
</MudPaper>
|
||||||
|
@if (_showPeriodFields)
|
||||||
|
{
|
||||||
|
<MudPaper Class="pa-4" Elevation="3" Height="100%">
|
||||||
|
<MudStack Row>
|
||||||
|
<MudDatePicker @bind-Date="exportParams.ExportPeriodStart" For="@(() => exportParams.ExportPeriodStart)"
|
||||||
|
Label="@LanguageLocale.dto_StayExportParams_ExportPeriodStart" Clearable OpenTo="OpenTo.Date" Editable
|
||||||
|
AutoClose="true" />
|
||||||
|
<MudDatePicker @bind-Date="exportParams.ExportPeriodEnd" For="@(() => exportParams.ExportPeriodEnd)"
|
||||||
|
Label="@LanguageLocale.dto_StayExportParams_ExportPeriodEnd" Clearable OpenTo="OpenTo.Date" Editable
|
||||||
|
AutoClose="true" />
|
||||||
|
</MudStack>
|
||||||
|
</MudPaper>
|
||||||
|
}
|
||||||
|
|
||||||
|
</MudForm>
|
||||||
|
|
||||||
|
@if (_isExported && exportedFile != null)
|
||||||
|
{
|
||||||
|
<MudPaper Class="pa-4 my-6" Elevation="3" Height="100%">
|
||||||
|
<MudStack>
|
||||||
|
<MudText Typo="Typo.h4">File Exported!</MudText>
|
||||||
|
<MudTextField Value="@Localizer.GetEnumValue(exportedFile.ExportResult)"
|
||||||
|
Label="@LanguageLocale.dto_StayExportFile_ExportResult" FullWidth ReadOnly="true" />
|
||||||
|
<MudTextField Value="@Localizer.GetEnumValue(exportedFile.ExportFormat)"
|
||||||
|
Label="@LanguageLocale.dto_StayExportFile_ExportFormat" FullWidth ReadOnly="true" />
|
||||||
|
<MudButton OnClick="BtnDownloadExportedFile">Download Exported File</MudButton>
|
||||||
|
</MudStack>
|
||||||
|
</MudPaper>
|
||||||
|
}
|
||||||
|
|
||||||
|
@code {
|
||||||
|
MudForm _form = null!;
|
||||||
|
|
||||||
|
StayExportFormat? exportFormat = null;
|
||||||
|
StayExportParamsDTO exportParams = new();
|
||||||
|
StayExportFileDTO? exportedFile = null;
|
||||||
|
|
||||||
|
bool _showPeriodFields => exportParams.ExportType == StayExportParamType.PeriodDateIn;
|
||||||
|
bool _isExported => exportedFile != null;
|
||||||
|
|
||||||
|
|
||||||
|
private void BtnReturn()
|
||||||
|
{
|
||||||
|
Navigation.NavigateTo(GuestConsts.Page_StayExport_List);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task BtnCreateExport()
|
||||||
|
{
|
||||||
|
await _form.ValidateAsync();
|
||||||
|
if (!_form.IsValid || exportFormat == null)
|
||||||
|
{
|
||||||
|
userMessage.ShowMessage("Invalid Form!", MessageKind.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var loadingDialog = await DialogService.ShowAsync<LoadingDialog>();
|
||||||
|
|
||||||
|
var exportResult = await ExportService.ExportStaysByParamsAsync(exportFormat.Value, exportParams);
|
||||||
|
exportedFile = exportResult.Value;
|
||||||
|
loadingDialog.Close();
|
||||||
|
|
||||||
|
if (!exportResult.IsSuccess)
|
||||||
|
{
|
||||||
|
userMessage.ShowResultWithMessage(exportResult, $"Error exporting stays");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
userMessage.ShowMessage(
|
||||||
|
$"Stay exported: {exportResult.ResultCode} with export result: {exportedFile?.ExportResult}",
|
||||||
|
MessageKind.Success);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task BtnDownloadExportedFile()
|
||||||
|
{
|
||||||
|
Debug.Assert(exportedFile != null);
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(exportedFile.ExportedPath))
|
||||||
|
{
|
||||||
|
userMessage.ShowMessage("Exported File can't be downloaded as no file was saved", MessageKind.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
using Stream dataStream = new MemoryStream();
|
||||||
|
|
||||||
|
Result loadResult = await ExportService.GetExportedFileAsync(exportedFile, dataStream);
|
||||||
|
if (!loadResult.IsSuccess)
|
||||||
|
{
|
||||||
|
userMessage.ShowResultWithMessage(loadResult, "Exported File can't be downloaded");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dataStream.Seek(0, SeekOrigin.Begin);
|
||||||
|
using var streamRef = new DotNetStreamReference(stream: dataStream);
|
||||||
|
|
||||||
|
var fileName = Path.GetFileName(exportedFile.ExportedPath);
|
||||||
|
await JS.InvokeVoidAsync("downloadFileFromStream", fileName, streamRef);
|
||||||
|
|
||||||
|
userMessage.ShowMessage("Exported File downloaded!", MessageKind.Success);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1 +1,3 @@
|
|||||||
@using Somnia.GuestLog.Components.Controls
|
@using Somnia.GuestLog.Components.Controls
|
||||||
|
@using Somnia.GuestLog.Services.Entity;
|
||||||
|
@using System.Diagnostics;
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
@using System.Net.Http
|
@using System.Net.Http
|
||||||
@using System.Net.Http.Json
|
@using System.Net.Http.Json
|
||||||
|
@using System.Linq;
|
||||||
@using Microsoft.AspNetCore.Components.Forms
|
@using Microsoft.AspNetCore.Components.Forms
|
||||||
@using Microsoft.AspNetCore.Components.Routing
|
@using Microsoft.AspNetCore.Components.Routing
|
||||||
@using Microsoft.AspNetCore.Components.Web
|
@using Microsoft.AspNetCore.Components.Web
|
||||||
@@ -15,4 +16,4 @@
|
|||||||
@using Somnia.GuestLog.Components.Forms
|
@using Somnia.GuestLog.Components.Forms
|
||||||
@using Somnia.GuestLog.Components.Controls
|
@using Somnia.GuestLog.Components.Controls
|
||||||
@using Somnia.GuestLog.Resources
|
@using Somnia.GuestLog.Resources
|
||||||
@using System.Linq;
|
@using Somnia.GuestLog.Enums.UI
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Serilog": {
|
||||||
|
"Using": [
|
||||||
|
"Serilog.Sinks.Console",
|
||||||
|
"Serilog.Sinks.File"
|
||||||
|
],
|
||||||
|
"MinimumLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Override": {
|
||||||
|
"Microsoft": "Warning",
|
||||||
|
"Microsoft.EntityFrameworkCore.Database.Command": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Enrich": [
|
||||||
|
"FromLogContext",
|
||||||
|
"WithThreadId",
|
||||||
|
"WithProcessId"
|
||||||
|
],
|
||||||
|
"Properties": {
|
||||||
|
"ApplicationName": "Somnia-GuestLog"
|
||||||
|
},
|
||||||
|
"WriteTo": [
|
||||||
|
{
|
||||||
|
"Name": "Console",
|
||||||
|
"Args": {
|
||||||
|
"restrictedToMinimumLevel": "Information"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "File",
|
||||||
|
"Args": {
|
||||||
|
// Logs data path
|
||||||
|
"path": "/SomniaGuestLog/logs/log_.log",
|
||||||
|
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{ProcessId}-{ThreadId}] [{Level}] {JobKey}{Message}{NewLine}{Exception}",
|
||||||
|
"rollingInterval": "Day",
|
||||||
|
"rollOnFileSizeLimit": true,
|
||||||
|
"fileSizeLimitBytes": 1073741824,
|
||||||
|
"retainedFileCountLimit": 30,
|
||||||
|
"restrictedToMinimumLevel": "Information"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
namespace Somnia.GuestLog.Enums.Models;
|
||||||
|
|
||||||
|
public enum StayExportFileResult
|
||||||
|
{
|
||||||
|
OK = 0,
|
||||||
|
NoData = 1,
|
||||||
|
ExportError = 2,
|
||||||
|
UploadError = 3,
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
namespace Somnia.GuestLog.Enums.Models;
|
||||||
|
|
||||||
|
public enum StayExportFormat
|
||||||
|
{
|
||||||
|
GuestLogJson = 0,
|
||||||
|
SpainParteViajeros = 1,
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
namespace Somnia.GuestLog.Enums.Models;
|
||||||
|
|
||||||
|
public enum StayExportParamType
|
||||||
|
{
|
||||||
|
PeriodDateIn = 0,
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
namespace Somnia.GuestLog.Enums.Services;
|
||||||
|
|
||||||
|
public enum AddressQueryProvider
|
||||||
|
{
|
||||||
|
Nominatim,
|
||||||
|
GoogleApiV4
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
namespace Somnia.GuestLog.Enums.Services;
|
||||||
|
|
||||||
|
public enum ResultCode
|
||||||
|
{
|
||||||
|
//Common Codes
|
||||||
|
Ok,
|
||||||
|
UnknownError,
|
||||||
|
FailedValidation,
|
||||||
|
NotFound,
|
||||||
|
FileStorageError,
|
||||||
|
|
||||||
|
//Specific Codes
|
||||||
|
GuestInStay,
|
||||||
|
GuestCurrentlyInStay,
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
namespace Somnia.GuestLog.Enums.UI;
|
||||||
|
|
||||||
|
public enum FormMode
|
||||||
|
{
|
||||||
|
Create, ReadOnly, Edit
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
namespace Somnia.GuestLog.Enums.UI;
|
||||||
|
|
||||||
|
public enum MessageKind
|
||||||
|
{
|
||||||
|
Info, Warning, Error, Success, Normal
|
||||||
|
}
|
||||||
@@ -6,13 +6,16 @@ public static class GuestConsts
|
|||||||
public const string Page_GuestDocs_List = "/guest-documents";
|
public const string Page_GuestDocs_List = "/guest-documents";
|
||||||
public const string Page_GuestDocs_New = "/guest-documents/new";
|
public const string Page_GuestDocs_New = "/guest-documents/new";
|
||||||
public const string Page_GuestDocs_Detail = $"/guest-documents/d/{Page_GuestDocs_Detail_Param_DocId}";
|
public const string Page_GuestDocs_Detail = $"/guest-documents/d/{Page_GuestDocs_Detail_Param_DocId}";
|
||||||
public const string Page_GuestDocs_Detail_Param_DocId = "{docId}";
|
public const string Page_GuestDocs_Detail_Param_DocId = "{docId:long}";
|
||||||
|
|
||||||
public const string Page_StayEntry_List = "/stayEntries";
|
public const string Page_StayEntry_List = "/stayEntries";
|
||||||
public const string Page_StayEntry_New = "/stayEntries/new";
|
public const string Page_StayEntry_New = "/stayEntries/new";
|
||||||
public const string Page_StayEntry_Detail = $"/stayEntries/d/{Page_StayEntry_Detail_Param_Id}";
|
public const string Page_StayEntry_Detail = $"/stayEntries/d/{Page_StayEntry_Detail_Param_Id}";
|
||||||
public const string Page_StayEntry_Detail_Param_Id = "{StayId:long}";
|
public const string Page_StayEntry_Detail_Param_Id = "{StayId:long}";
|
||||||
|
|
||||||
|
public const string Page_StayExport_List = "/stayExport";
|
||||||
|
public const string Page_StayExport_New = "/stayExport/new";
|
||||||
|
|
||||||
|
|
||||||
public const string QueryParam_ReturnUrl = "returnUrl";
|
public const string QueryParam_ReturnUrl = "returnUrl";
|
||||||
|
|
||||||
@@ -28,4 +31,13 @@ public static class GuestConsts
|
|||||||
public const string DocumentType_DNI = "DNI";
|
public const string DocumentType_DNI = "DNI";
|
||||||
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 string EmptyField = "-";
|
||||||
}
|
}
|
||||||
@@ -5,4 +5,8 @@ public static class DbConsts
|
|||||||
public const string DbType_Timestamptz = "timestamp with time zone";
|
public const string DbType_Timestamptz = "timestamp with time zone";
|
||||||
public const string DbType_Timestamptz_0 = "timestamp(0) with time zone";
|
public const string DbType_Timestamptz_0 = "timestamp(0) with time zone";
|
||||||
public const string DbType_Timestamptz_3 = "timestamp(3) with time zone";
|
public const string DbType_Timestamptz_3 = "timestamp(3) with time zone";
|
||||||
|
|
||||||
|
public const string DbType_jsonb = "jsonb";
|
||||||
|
|
||||||
|
public const string PK_NotApply = "N/A";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,13 @@ public class GuestDocumentEntityConfig : IEntityTypeConfiguration<GuestDocument>
|
|||||||
builder.ToTable("GuestDocument");
|
builder.ToTable("GuestDocument");
|
||||||
|
|
||||||
//PK
|
//PK
|
||||||
builder.HasKey(e => new { e.DocumentType, e.DocumentNum });
|
builder.HasKey(e => new { e.Id, e.Version });
|
||||||
|
|
||||||
|
builder.Property(e => e.Id)
|
||||||
|
.UseIdentityByDefaultColumn();
|
||||||
|
|
||||||
|
builder.Property(e => e.Version)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
builder.Property(e => e.DocumentType)
|
builder.Property(e => e.DocumentType)
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
@@ -48,6 +54,15 @@ public class GuestDocumentEntityConfig : IEntityTypeConfiguration<GuestDocument>
|
|||||||
builder.Property(e => e.EmailAddress)
|
builder.Property(e => e.EmailAddress)
|
||||||
.HasMaxLength(256);
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
builder.Property(e => e.CreateTime)
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType(DbConsts.DbType_Timestamptz_3);
|
||||||
|
builder.Property(e => e.UpdateTime)
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType(DbConsts.DbType_Timestamptz_3);
|
||||||
|
builder.Property(e => e.IsLastVersion)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
|
||||||
var addressBuilder = builder.ComplexProperty(e => e.AddressDetails);
|
var addressBuilder = builder.ComplexProperty(e => e.AddressDetails);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||||
|
using Somnia.GuestLog.Models.Entities;
|
||||||
|
|
||||||
|
namespace Somnia.GuestLog.Infrastructure.EntityConfigs;
|
||||||
|
|
||||||
|
public class StayExportFileEntityConfig : IEntityTypeConfiguration<StayExportFile>
|
||||||
|
{
|
||||||
|
public void Configure(EntityTypeBuilder<StayExportFile> builder)
|
||||||
|
{
|
||||||
|
builder.ToTable("StayExportFile");
|
||||||
|
|
||||||
|
//PK
|
||||||
|
builder.HasKey(e => e.Id);
|
||||||
|
|
||||||
|
builder.Property(e => e.Id)
|
||||||
|
.IsRequired()
|
||||||
|
.UseIdentityByDefaultColumn();
|
||||||
|
|
||||||
|
builder.ComplexProperty(e => e.ExportParams, e =>
|
||||||
|
{
|
||||||
|
e.ToJson();
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Property(e => e.ExportedPath)
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
builder.Property(e => e.ExportDetails)
|
||||||
|
.HasColumnType(DbConsts.DbType_jsonb);
|
||||||
|
|
||||||
|
|
||||||
|
builder.Property(e => e.ExportTime)
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType(DbConsts.DbType_Timestamptz);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,11 +13,14 @@ public partial class GuestLogContext : DbContext
|
|||||||
public DbSet<GuestDocument> GuestDocuments { get; set; }
|
public DbSet<GuestDocument> GuestDocuments { get; set; }
|
||||||
public DbSet<StayEntry> StayEntries { get; set; }
|
public DbSet<StayEntry> StayEntries { get; set; }
|
||||||
|
|
||||||
|
public DbSet<StayExportFile> StayExportFiles { get; set; }
|
||||||
|
|
||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
{
|
{
|
||||||
modelBuilder.ApplyConfiguration<GuestDocument>(new GuestDocumentEntityConfig());
|
modelBuilder.ApplyConfiguration<GuestDocument>(new GuestDocumentEntityConfig());
|
||||||
modelBuilder.ApplyConfiguration<StayEntry>(new StayEntryEntityConfig());
|
modelBuilder.ApplyConfiguration<StayEntry>(new StayEntryEntityConfig());
|
||||||
|
modelBuilder.ApplyConfiguration<StayExportFile>(new StayExportFileEntityConfig());
|
||||||
|
|
||||||
OnModelCreatingPartial(modelBuilder);
|
OnModelCreatingPartial(modelBuilder);
|
||||||
base.OnModelCreating(modelBuilder);
|
base.OnModelCreating(modelBuilder);
|
||||||
|
|||||||
+205
@@ -0,0 +1,205 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
using Somnia.GuestLog.Infrastructure;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Somnia.GuestLog.Infrastructure.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(GuestLogContext))]
|
||||||
|
[Migration("20260830201743_GuestDocument_ChangePKToIdAndVersion")]
|
||||||
|
partial class GuestDocument_ChangePKToIdAndVersion
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "10.0.7")
|
||||||
|
.HasAnnotation("Proxies:ChangeTracking", false)
|
||||||
|
.HasAnnotation("Proxies:CheckEquality", false)
|
||||||
|
.HasAnnotation("Proxies:LazyLoading", true)
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||||
|
|
||||||
|
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("GuestDocumentStayEntry", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("StayEntryId")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<long>("GuestDocumentsId")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<int>("GuestDocumentsVersion")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.HasKey("StayEntryId", "GuestDocumentsId", "GuestDocumentsVersion");
|
||||||
|
|
||||||
|
b.HasIndex("GuestDocumentsId", "GuestDocumentsVersion");
|
||||||
|
|
||||||
|
b.ToTable("GuestDocumentStayEntry");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Somnia.GuestLog.Models.Entities.GuestDocument", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||||
|
|
||||||
|
b.Property<int>("Version")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<DateOnly>("BirthDate")
|
||||||
|
.HasColumnType("date");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreateTime")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("DocumentNum")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)");
|
||||||
|
|
||||||
|
b.Property<string>("DocumentType")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(8)
|
||||||
|
.HasColumnType("character varying(8)");
|
||||||
|
|
||||||
|
b.Property<string>("EmailAddress")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)");
|
||||||
|
|
||||||
|
b.Property<string>("Gender")
|
||||||
|
.HasMaxLength(1)
|
||||||
|
.HasColumnType("character varying(1)");
|
||||||
|
|
||||||
|
b.Property<DateOnly>("IssueDate")
|
||||||
|
.HasColumnType("date");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)");
|
||||||
|
|
||||||
|
b.Property<string>("Nationality")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(3)
|
||||||
|
.HasColumnType("character varying(3)");
|
||||||
|
|
||||||
|
b.Property<string>("PhoneNumber")
|
||||||
|
.HasMaxLength(32)
|
||||||
|
.HasColumnType("character varying(32)");
|
||||||
|
|
||||||
|
b.Property<string>("SupportNum")
|
||||||
|
.HasMaxLength(10)
|
||||||
|
.HasColumnType("character varying(10)");
|
||||||
|
|
||||||
|
b.Property<string>("Surname")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)");
|
||||||
|
|
||||||
|
b.Property<string>("Surname2")
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdateTime")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.ComplexProperty(typeof(Dictionary<string, object>), "AddressDetails", "Somnia.GuestLog.Models.Entities.GuestDocument.AddressDetails#GuestAddress", b1 =>
|
||||||
|
{
|
||||||
|
b1.Property<string>("Address")
|
||||||
|
.HasMaxLength(128)
|
||||||
|
.HasColumnType("character varying(128)");
|
||||||
|
|
||||||
|
b1.Property<string>("AddressCity")
|
||||||
|
.HasMaxLength(128)
|
||||||
|
.HasColumnType("character varying(128)");
|
||||||
|
|
||||||
|
b1.Property<string>("AddressCountry")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(3)
|
||||||
|
.HasColumnType("character varying(3)");
|
||||||
|
|
||||||
|
b1.Property<string>("AddressProvince")
|
||||||
|
.HasMaxLength(128)
|
||||||
|
.HasColumnType("character varying(128)");
|
||||||
|
|
||||||
|
b1.Property<string>("AddressState")
|
||||||
|
.HasMaxLength(128)
|
||||||
|
.HasColumnType("character varying(128)");
|
||||||
|
|
||||||
|
b1.Property<string>("ZipCode")
|
||||||
|
.HasMaxLength(12)
|
||||||
|
.HasColumnType("character varying(12)");
|
||||||
|
});
|
||||||
|
|
||||||
|
b.HasKey("Id", "Version");
|
||||||
|
|
||||||
|
b.ToTable("GuestDocument", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Somnia.GuestLog.Models.Entities.StayEntry", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreateTime")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<DateTime>("DateIn")
|
||||||
|
.HasColumnType("timestamp(0) with time zone");
|
||||||
|
|
||||||
|
b.Property<DateTime>("DateOut")
|
||||||
|
.HasColumnType("timestamp(0) with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("PaymentMethod")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(5)
|
||||||
|
.HasColumnType("character varying(5)");
|
||||||
|
|
||||||
|
b.Property<int>("RoomCount")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<string>("RoomNumber")
|
||||||
|
.HasMaxLength(32)
|
||||||
|
.HasColumnType("character varying(32)");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdateTime")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("StayEntry", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("GuestDocumentStayEntry", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Somnia.GuestLog.Models.Entities.StayEntry", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("StayEntryId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Somnia.GuestLog.Models.Entities.GuestDocument", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("GuestDocumentsId", "GuestDocumentsVersion")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+101
@@ -0,0 +1,101 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Somnia.GuestLog.Infrastructure.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class GuestDocument_ChangePKToIdAndVersion : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
//Data don't really matter right now. Just get it working good.
|
||||||
|
//This migration will destry all data, but it's fine.
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "GuestDocumentStayEntry"
|
||||||
|
);
|
||||||
|
|
||||||
|
migrationBuilder.Sql("""DELETE FROM "StayEntry";""");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "GuestDocument"
|
||||||
|
);
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "GuestDocument",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<long>(type: "bigint", nullable: false)
|
||||||
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||||
|
Version = table.Column<int>(type: "integer", nullable: false),
|
||||||
|
DocumentType = table.Column<string>(type: "character varying(8)", maxLength: 8, nullable: false),
|
||||||
|
DocumentNum = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: false),
|
||||||
|
IssueDate = table.Column<DateOnly>(type: "date", nullable: false),
|
||||||
|
SupportNum = table.Column<string>(type: "character varying(10)", maxLength: 10, nullable: true),
|
||||||
|
Nationality = table.Column<string>(type: "character varying(3)", maxLength: 3, nullable: false),
|
||||||
|
Name = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: false),
|
||||||
|
Surname = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: false),
|
||||||
|
Surname2 = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
||||||
|
BirthDate = table.Column<DateOnly>(type: "date", nullable: false),
|
||||||
|
Gender = table.Column<string>(type: "character varying(1)", maxLength: 1, nullable: true),
|
||||||
|
PhoneNumber = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
||||||
|
EmailAddress = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
|
||||||
|
CreateTime = table.Column<DateTime>(type: "timestamp(3) with time zone", nullable: false),
|
||||||
|
UpdateTime = table.Column<DateTime>(type: "timestamp(3) with time zone", nullable: false),
|
||||||
|
IsLastVersion = table.Column<bool>(type: "boolean", nullable: false),
|
||||||
|
AddressDetails_Address = table.Column<string>(type: "character varying(128)", maxLength: 128, nullable: true),
|
||||||
|
AddressDetails_AddressCity = table.Column<string>(type: "character varying(128)", maxLength: 128, nullable: true),
|
||||||
|
AddressDetails_AddressCountry = table.Column<string>(type: "character varying(3)", maxLength: 3, nullable: true),
|
||||||
|
AddressDetails_AddressProvince = table.Column<string>(type: "character varying(128)", maxLength: 128, nullable: true),
|
||||||
|
AddressDetails_AddressState = table.Column<string>(type: "character varying(128)", maxLength: 128, nullable: true),
|
||||||
|
AddressDetails_ZipCode = table.Column<string>(type: "character varying(12)", maxLength: 12, nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_GuestDocument", x => new { x.Id, x.Version });
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//Existing index for "DocType" and "DocNum" can be useful, so let's keep it.
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "GuestDocumentStayEntry",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
StayEntryId = table.Column<long>(type: "bigint", nullable: false),
|
||||||
|
GuestDocumentsId = table.Column<long>(type: "bigint", nullable: false),
|
||||||
|
GuestDocumentsVersion = table.Column<int>(type: "integer", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_GuestDocumentStayEntry", x => new { x.StayEntryId, x.GuestDocumentsId, x.GuestDocumentsVersion });
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_GuestDocumentStayEntry_GuestDocument_GuestDocumentsId_Guest~",
|
||||||
|
columns: x => new { x.GuestDocumentsId, x.GuestDocumentsVersion },
|
||||||
|
principalTable: "GuestDocument",
|
||||||
|
principalColumns: new[] { "Id", "Version" },
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_GuestDocumentStayEntry_StayEntry_StayEntryId",
|
||||||
|
column: x => x.StayEntryId,
|
||||||
|
principalTable: "StayEntry",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_GuestDocumentStayEntry_GuestDocumentsId_GuestDocumentsVersi~",
|
||||||
|
table: "GuestDocumentStayEntry",
|
||||||
|
columns: new[] { "GuestDocumentsId", "GuestDocumentsVersion" });
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException("Rollback is not supported for this migration!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Generated
+249
@@ -0,0 +1,249 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
using Somnia.GuestLog.Infrastructure;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Somnia.GuestLog.Infrastructure.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(GuestLogContext))]
|
||||||
|
[Migration("20260901161146_AddTable_StayExportFile")]
|
||||||
|
partial class AddTable_StayExportFile
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "10.0.7")
|
||||||
|
.HasAnnotation("Proxies:ChangeTracking", false)
|
||||||
|
.HasAnnotation("Proxies:CheckEquality", false)
|
||||||
|
.HasAnnotation("Proxies:LazyLoading", true)
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||||
|
|
||||||
|
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("GuestDocumentStayEntry", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("StayEntryId")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<long>("GuestDocumentsId")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<int>("GuestDocumentsVersion")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.HasKey("StayEntryId", "GuestDocumentsId", "GuestDocumentsVersion");
|
||||||
|
|
||||||
|
b.HasIndex("GuestDocumentsId", "GuestDocumentsVersion");
|
||||||
|
|
||||||
|
b.ToTable("GuestDocumentStayEntry");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Somnia.GuestLog.Models.Entities.GuestDocument", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||||
|
|
||||||
|
b.Property<int>("Version")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<DateOnly>("BirthDate")
|
||||||
|
.HasColumnType("date");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreateTime")
|
||||||
|
.HasColumnType("timestamp(3) with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("DocumentNum")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)");
|
||||||
|
|
||||||
|
b.Property<string>("DocumentType")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(8)
|
||||||
|
.HasColumnType("character varying(8)");
|
||||||
|
|
||||||
|
b.Property<string>("EmailAddress")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)");
|
||||||
|
|
||||||
|
b.Property<string>("Gender")
|
||||||
|
.HasMaxLength(1)
|
||||||
|
.HasColumnType("character varying(1)");
|
||||||
|
|
||||||
|
b.Property<bool>("IsLastVersion")
|
||||||
|
.HasColumnType("boolean");
|
||||||
|
|
||||||
|
b.Property<DateOnly>("IssueDate")
|
||||||
|
.HasColumnType("date");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)");
|
||||||
|
|
||||||
|
b.Property<string>("Nationality")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(3)
|
||||||
|
.HasColumnType("character varying(3)");
|
||||||
|
|
||||||
|
b.Property<string>("PhoneNumber")
|
||||||
|
.HasMaxLength(32)
|
||||||
|
.HasColumnType("character varying(32)");
|
||||||
|
|
||||||
|
b.Property<string>("SupportNum")
|
||||||
|
.HasMaxLength(10)
|
||||||
|
.HasColumnType("character varying(10)");
|
||||||
|
|
||||||
|
b.Property<string>("Surname")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)");
|
||||||
|
|
||||||
|
b.Property<string>("Surname2")
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdateTime")
|
||||||
|
.HasColumnType("timestamp(3) with time zone");
|
||||||
|
|
||||||
|
b.ComplexProperty(typeof(Dictionary<string, object>), "AddressDetails", "Somnia.GuestLog.Models.Entities.GuestDocument.AddressDetails#GuestAddress", b1 =>
|
||||||
|
{
|
||||||
|
b1.Property<string>("Address")
|
||||||
|
.HasMaxLength(128)
|
||||||
|
.HasColumnType("character varying(128)");
|
||||||
|
|
||||||
|
b1.Property<string>("AddressCity")
|
||||||
|
.HasMaxLength(128)
|
||||||
|
.HasColumnType("character varying(128)");
|
||||||
|
|
||||||
|
b1.Property<string>("AddressCountry")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(3)
|
||||||
|
.HasColumnType("character varying(3)");
|
||||||
|
|
||||||
|
b1.Property<string>("AddressProvince")
|
||||||
|
.HasMaxLength(128)
|
||||||
|
.HasColumnType("character varying(128)");
|
||||||
|
|
||||||
|
b1.Property<string>("AddressState")
|
||||||
|
.HasMaxLength(128)
|
||||||
|
.HasColumnType("character varying(128)");
|
||||||
|
|
||||||
|
b1.Property<string>("ZipCode")
|
||||||
|
.HasMaxLength(12)
|
||||||
|
.HasColumnType("character varying(12)");
|
||||||
|
});
|
||||||
|
|
||||||
|
b.HasKey("Id", "Version");
|
||||||
|
|
||||||
|
b.ToTable("GuestDocument", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Somnia.GuestLog.Models.Entities.StayEntry", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreateTime")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<DateTime>("DateIn")
|
||||||
|
.HasColumnType("timestamp(0) with time zone");
|
||||||
|
|
||||||
|
b.Property<DateTime>("DateOut")
|
||||||
|
.HasColumnType("timestamp(0) with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("PaymentMethod")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(5)
|
||||||
|
.HasColumnType("character varying(5)");
|
||||||
|
|
||||||
|
b.Property<int>("RoomCount")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<string>("RoomNumber")
|
||||||
|
.HasMaxLength(32)
|
||||||
|
.HasColumnType("character varying(32)");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdateTime")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("StayEntry", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Somnia.GuestLog.Models.Entities.StayExportFile", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||||
|
|
||||||
|
b.Property<int>("ExportFormat")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<int>("ExportResult")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<DateTime>("ExportTime")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("ExportedPath")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)");
|
||||||
|
|
||||||
|
b.ComplexProperty(typeof(Dictionary<string, object>), "ExportParams", "Somnia.GuestLog.Models.Entities.StayExportFile.ExportParams#StayExportParams", b1 =>
|
||||||
|
{
|
||||||
|
b1.IsRequired();
|
||||||
|
|
||||||
|
b1.Property<DateTime?>("ExportPeriodEnd");
|
||||||
|
|
||||||
|
b1.Property<DateTime?>("ExportPeriodStart");
|
||||||
|
|
||||||
|
b1.Property<int>("ExportType");
|
||||||
|
|
||||||
|
b1
|
||||||
|
.ToJson("ExportParams")
|
||||||
|
.HasColumnType("jsonb");
|
||||||
|
});
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("StayExportFile", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("GuestDocumentStayEntry", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Somnia.GuestLog.Models.Entities.StayEntry", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("StayEntryId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Somnia.GuestLog.Models.Entities.GuestDocument", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("GuestDocumentsId", "GuestDocumentsVersion")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Somnia.GuestLog.Infrastructure.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class AddTable_StayExportFile : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "StayExportFile",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<long>(type: "bigint", nullable: false)
|
||||||
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||||
|
ExportFormat = table.Column<int>(type: "integer", nullable: false),
|
||||||
|
ExportResult = table.Column<int>(type: "integer", nullable: false),
|
||||||
|
ExportedPath = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
|
||||||
|
ExportTime = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||||
|
ExportParams = table.Column<string>(type: "jsonb", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_StayExportFile", x => x.Id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "StayExportFile");
|
||||||
|
}
|
||||||
|
|||||||