SHA256
Compare commits
3
Commits
3e0ef34f66
...
0de4e1ba10
| Author | SHA256 | Date | |
|---|---|---|---|
|
|
0de4e1ba10 | ||
|
|
340bc583b7 | ||
|
|
67845e250f |
@@ -23,6 +23,7 @@
|
|||||||
</PackageVersion>
|
</PackageVersion>
|
||||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.7" />
|
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.7" />
|
||||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="10.0.7" />
|
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="10.0.7" />
|
||||||
|
<PackageVersion Include="Microsoft.EntityFrameworkCore.Proxies" Version="10.0.7" />
|
||||||
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.1" />
|
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<MudMessageBox @ref="_msgBox" Title="@LanguageLocale.general_confirmTitle"
|
||||||
|
CancelText="@LanguageLocale.general_btnCancel">
|
||||||
|
<MessageContent>
|
||||||
|
@LanguageLocale.general_confirmDeleteMsg
|
||||||
|
</MessageContent>
|
||||||
|
<YesButton>
|
||||||
|
<MudButton Variant="Variant.Filled" Color="Color.Error" StartIcon="@Icons.Material.Filled.DeleteForever">
|
||||||
|
@LanguageLocale.general_btnDelete
|
||||||
|
</MudButton>
|
||||||
|
</YesButton>
|
||||||
|
</MudMessageBox>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
public MudMessageBox MsgBox => _msgBox;
|
||||||
|
|
||||||
|
MudMessageBox _msgBox = null!;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -34,6 +34,14 @@
|
|||||||
|
|
||||||
@if (!isLoading)
|
@if (!isLoading)
|
||||||
{
|
{
|
||||||
|
@* Only show on first load *@
|
||||||
|
@if (loadCount == 1)
|
||||||
|
{
|
||||||
|
<MudText Align="Align.Center" GutterBottom>
|
||||||
|
@LanguageLocale.control_GuestDocumentSearchDialog_txtSuggestedGuests
|
||||||
|
</MudText>
|
||||||
|
}
|
||||||
|
|
||||||
<MudList T="GuestDocumentDTO" @bind-SelectedValue="SelectedResult"
|
<MudList T="GuestDocumentDTO" @bind-SelectedValue="SelectedResult"
|
||||||
SelectionMode="SelectionMode.SingleSelection" Color="Color.Info">
|
SelectionMode="SelectionMode.SingleSelection" Color="Color.Info">
|
||||||
@foreach (GuestDocumentDTO result in results)
|
@foreach (GuestDocumentDTO result in results)
|
||||||
@@ -74,10 +82,39 @@
|
|||||||
private GuestDocumentDTO? SelectedResult { get; set; }
|
private GuestDocumentDTO? SelectedResult { get; set; }
|
||||||
|
|
||||||
private bool isLoading = false;
|
private bool isLoading = false;
|
||||||
|
private int loadCount = 0;
|
||||||
|
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
//Load last 5 guests.
|
||||||
|
await LoadGuests(limit: 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void Cancel() => MudDialog.Cancel();
|
private void Cancel() => MudDialog.Cancel();
|
||||||
|
|
||||||
|
|
||||||
|
private async Task LoadGuests(int limit = 25)
|
||||||
|
{
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
isLoading = true;
|
||||||
|
results = await guestDocumentService.GetDtoListByFilterAsync(filter);
|
||||||
|
isLoading = false;
|
||||||
|
loadCount++;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.LogError(ex, "GuestDocument Search returned an error!");
|
||||||
|
Snackbar.Add($"Error searching: {ex.Message}", Severity.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#region Event Handlers
|
||||||
|
|
||||||
private async Task BtnSearchGuestDocuments()
|
private async Task BtnSearchGuestDocuments()
|
||||||
{
|
{
|
||||||
if (filter.IsEmpty)
|
if (filter.IsEmpty)
|
||||||
@@ -86,17 +123,8 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
//Load unlimited guests using current filter.
|
||||||
{
|
await LoadGuests();
|
||||||
isLoading = true;
|
|
||||||
results = await guestDocumentService.GetDtoListByFilterAsync(filter);
|
|
||||||
isLoading = false;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
logger.LogError(ex, "GuestDocument Search returned an error!");
|
|
||||||
Snackbar.Add($"Error searching: {ex.Message}", Severity.Error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task btnSelectGuest()
|
private async Task btnSelectGuest()
|
||||||
@@ -114,4 +142,7 @@
|
|||||||
MudDialog.Close(dialogResult);
|
MudDialog.Close(dialogResult);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
@using System.ComponentModel
|
||||||
|
@using Somnia.GuestLog.Models.DTOs
|
||||||
|
@using Somnia.GuestLog.Services
|
||||||
|
|
||||||
|
@inject IDataListService dataListService;
|
||||||
|
|
||||||
|
<MudForm Model="@Filter" IsTouchedChanged="@(() => FilterChanged.InvokeAsync(Filter))">
|
||||||
|
<MudStack Row Breakpoint="Breakpoint.LgAndDown" StretchItems="StretchItems.All">
|
||||||
|
<MudStack Row style="margin-block: 0.2em;">
|
||||||
|
<MudDatePicker @bind-Date="Filter.DateInStart" For="@(() => Filter.DateInStart)"
|
||||||
|
Label="@LanguageLocale.general_dateStart" OpenTo="OpenTo.Date" Editable Required="@DateRequired" />
|
||||||
|
<MudDatePicker @bind-Date="Filter.DateInEnd" For="@(() => Filter.DateInEnd)"
|
||||||
|
Label="@LanguageLocale.general_dateEnd" OpenTo="OpenTo.Date" Editable Required="@DateRequired" />
|
||||||
|
</MudStack>
|
||||||
|
|
||||||
|
<MudStack Row style="margin-block: 0.2em;">
|
||||||
|
<MudTextField @bind-Value="Filter.RoomNumber" For="@(() => Filter.RoomNumber)"
|
||||||
|
Label="@LanguageLocale.dto_StayEntry_RoomNumber" FullWidth Clearable />
|
||||||
|
<MudSelect @bind-Value="Filter.PaymentMethod" For="@(() => Filter.PaymentMethod)"
|
||||||
|
Label="@LanguageLocale.dto_StayEntry_PaymentMethod" FullWidth Clearable>
|
||||||
|
@foreach (string paymentType in
|
||||||
|
dataListService.GetDataListByName(GuestConsts.DataList_PaymentMethods))
|
||||||
|
{
|
||||||
|
<MudSelectItem Value="paymentType">
|
||||||
|
@dataListService.GetLocalizedValue(GuestConsts.DataList_PaymentMethods, paymentType)
|
||||||
|
</MudSelectItem>
|
||||||
|
}
|
||||||
|
</MudSelect>
|
||||||
|
</MudStack>
|
||||||
|
</MudStack>
|
||||||
|
</MudForm>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
|
||||||
|
[Parameter, Bindable(true)]
|
||||||
|
public StayEntryFilterDTO Filter { get; set; } = new();
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public EventCallback<StayEntryFilterDTO> FilterChanged { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public bool DateRequired { get; set; } = true;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
|
@using System.Diagnostics
|
||||||
@using FluentValidation;
|
@using FluentValidation;
|
||||||
@using Microsoft.AspNetCore.SignalR
|
|
||||||
@using Somnia.GuestLog.Models.DTOs;
|
@using Somnia.GuestLog.Models.DTOs;
|
||||||
@using Somnia.GuestLog.Services;
|
@using Somnia.GuestLog.Services;
|
||||||
@using Somnia.GuestLog.Validators;
|
@using Somnia.GuestLog.Validators;
|
||||||
@@ -69,10 +69,7 @@
|
|||||||
<MudTh>@LanguageLocale.dto_GuestDocument_Name</MudTh>
|
<MudTh>@LanguageLocale.dto_GuestDocument_Name</MudTh>
|
||||||
<MudTh>@LanguageLocale.dto_GuestDocument_Surname</MudTh>
|
<MudTh>@LanguageLocale.dto_GuestDocument_Surname</MudTh>
|
||||||
<MudTh>@LanguageLocale.dto_GuestDocument_Surname2</MudTh>
|
<MudTh>@LanguageLocale.dto_GuestDocument_Surname2</MudTh>
|
||||||
@if (!ReadOnly)
|
<MudTh>@LanguageLocale.general_actions</MudTh>
|
||||||
{
|
|
||||||
<MudTh>@LanguageLocale.general_actions</MudTh>
|
|
||||||
}
|
|
||||||
</HeaderContent>
|
</HeaderContent>
|
||||||
<RowTemplate>
|
<RowTemplate>
|
||||||
<MudTd DataLabel="@LanguageLocale.dto_GuestDocument_DocumentType">
|
<MudTd DataLabel="@LanguageLocale.dto_GuestDocument_DocumentType">
|
||||||
@@ -97,6 +94,13 @@
|
|||||||
OnClick="@(() => BtnDeleteGuest(context.DocumentType!, context.DocumentNum!))" />
|
OnClick="@(() => BtnDeleteGuest(context.DocumentType!, context.DocumentNum!))" />
|
||||||
</MudTd>
|
</MudTd>
|
||||||
}
|
}
|
||||||
|
@if (ReadOnly)
|
||||||
|
{
|
||||||
|
<MudTd DataLabel="@LanguageLocale.general_actions">
|
||||||
|
<MudIconButton Icon="@Icons.Material.Filled.Info"
|
||||||
|
OnClick="@(() => BtnViewGuestDetails(context))" />
|
||||||
|
</MudTd>
|
||||||
|
}
|
||||||
</RowTemplate>
|
</RowTemplate>
|
||||||
</MudTable>
|
</MudTable>
|
||||||
|
|
||||||
@@ -143,7 +147,7 @@
|
|||||||
{
|
{
|
||||||
await _form.ValidateAsync();
|
await _form.ValidateAsync();
|
||||||
|
|
||||||
if (Model.GuestDocuments.Count == 0)
|
if (Model.GuestDocuments is null || Model.GuestDocuments.Count == 0)
|
||||||
{
|
{
|
||||||
snackbar.Add("At least 1 guest is required!", MudBlazor.Severity.Warning);
|
snackbar.Add("At least 1 guest is required!", MudBlazor.Severity.Warning);
|
||||||
return false;
|
return false;
|
||||||
@@ -181,7 +185,15 @@
|
|||||||
|
|
||||||
private async Task BtnAddGuest()
|
private async Task BtnAddGuest()
|
||||||
{
|
{
|
||||||
var dialog = await dialogService.ShowAsync<GuestDocumentSearchDialog>();
|
DialogOptions dialogOptions = new()
|
||||||
|
{
|
||||||
|
MaxWidth = MaxWidth.Medium,
|
||||||
|
FullWidth = true,
|
||||||
|
BackdropClick = false,
|
||||||
|
CloseOnEscapeKey = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
var dialog = await dialogService.ShowAsync<GuestDocumentSearchDialog>(title: "", options: dialogOptions);
|
||||||
DialogResult? result = await dialog.Result;
|
DialogResult? result = await dialog.Result;
|
||||||
|
|
||||||
if (result is null || result.Canceled)
|
if (result is null || result.Canceled)
|
||||||
@@ -198,12 +210,21 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Check if this guest is already added.
|
//Check if this guest is already added.
|
||||||
bool alreadyAdded = Model.GuestDocuments.Any(e => e.DocumentType == resultData.DocumentType
|
if (Model.GuestDocuments is not null && Model.GuestDocuments.Count > 0)
|
||||||
&& e.DocumentNum == resultData.DocumentNum);
|
|
||||||
if (alreadyAdded)
|
|
||||||
{
|
{
|
||||||
snackbar.Add("GuestDocument already added!", MudBlazor.Severity.Warning);
|
bool alreadyAdded = Model.GuestDocuments.Any(e => e.DocumentType == resultData.DocumentType
|
||||||
return;
|
&& e.DocumentNum == resultData.DocumentNum);
|
||||||
|
if (alreadyAdded)
|
||||||
|
{
|
||||||
|
snackbar.Add("GuestDocument already added!", MudBlazor.Severity.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Init List.
|
||||||
|
if (Model.GuestDocuments is null)
|
||||||
|
{
|
||||||
|
Model.GuestDocuments = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
Model.GuestDocuments.Add(resultData);
|
Model.GuestDocuments.Add(resultData);
|
||||||
@@ -211,8 +232,27 @@
|
|||||||
|
|
||||||
private void BtnDeleteGuest(string docType, string docNum)
|
private void BtnDeleteGuest(string docType, string docNum)
|
||||||
{
|
{
|
||||||
|
Debug.Assert(Model.GuestDocuments is not null);
|
||||||
|
|
||||||
//Filter out given GuestDocument from model.
|
//Filter out given GuestDocument from model.
|
||||||
Model.GuestDocuments = Model.GuestDocuments.Where(e => !(e.DocumentType == docType && e.DocumentNum == docNum)).ToList();
|
Model.GuestDocuments = Model.GuestDocuments
|
||||||
|
.Where(e => !(e.DocumentType == docType && e.DocumentNum == docNum))
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private async Task BtnViewGuestDetails(GuestDocumentDTO item)
|
||||||
|
{
|
||||||
|
var parameters =
|
||||||
|
new DialogParameters<GuestDocDetailsDialog> { { x => x.DocumentDTO, item } };
|
||||||
|
var options = new DialogOptions()
|
||||||
|
{
|
||||||
|
FullScreen = true,
|
||||||
|
CloseButton = true,
|
||||||
|
CloseOnEscapeKey = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
await dialogService.ShowAsync<GuestDocDetailsDialog>("GuestDoc Details", parameters, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
|
<MudNavMenu>
|
||||||
<MudNavMenu>
|
|
||||||
<MudNavLink Href="" Match="NavLinkMatch.All" Icon="@Icons.Material.Filled.Home">Home</MudNavLink>
|
<MudNavLink Href="" Match="NavLinkMatch.All" Icon="@Icons.Material.Filled.Home">Home</MudNavLink>
|
||||||
|
|
||||||
|
@*
|
||||||
<MudNavLink Href="counter" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.Add">Counter</MudNavLink>
|
<MudNavLink Href="counter" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.Add">Counter</MudNavLink>
|
||||||
|
|
||||||
<MudNavLink Href="weather" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.List">Weather</MudNavLink>
|
<MudNavLink Href="weather" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.List">Weather</MudNavLink>
|
||||||
|
*@
|
||||||
|
|
||||||
<MudNavLink Href="@GuestConsts.Page_GuestDocs_List" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.DocumentScanner">Guests</MudNavLink>
|
<MudNavLink Href="@GuestConsts.Page_GuestDocs_List" Match="NavLinkMatch.Prefix"
|
||||||
<MudNavLink Href="@GuestConsts.Page_StayEntry_List" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.Book">Stays</MudNavLink>
|
Icon="@Icons.Material.Filled.DocumentScanner">
|
||||||
|
@LanguageLocale.navMenu_GuestDocumentList
|
||||||
|
</MudNavLink>
|
||||||
|
<MudNavLink Href="@GuestConsts.Page_StayEntry_List" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.Book">
|
||||||
|
@LanguageLocale.navMenu_StayEntryList
|
||||||
|
</MudNavLink>
|
||||||
</MudNavMenu>
|
</MudNavMenu>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
@using Somnia.GuestLog.Models.DTOs;
|
@using Somnia.GuestLog.Models.DTOs;
|
||||||
@using Somnia.GuestLog.Services;
|
@using Somnia.GuestLog.Services;
|
||||||
|
@using Microsoft.AspNetCore.WebUtilities;
|
||||||
|
|
||||||
@inject ISnackbar Snackbar
|
@inject ISnackbar Snackbar
|
||||||
@inject IDialogService DialogService
|
@inject IDialogService DialogService
|
||||||
@@ -42,6 +43,7 @@
|
|||||||
<MudTh>@LanguageLocale.dto_StayEntry_DateOut</MudTh>
|
<MudTh>@LanguageLocale.dto_StayEntry_DateOut</MudTh>
|
||||||
<MudTh>@LanguageLocale.dto_StayEntry_RoomCount</MudTh>
|
<MudTh>@LanguageLocale.dto_StayEntry_RoomCount</MudTh>
|
||||||
<MudTh>@LanguageLocale.dto_StayEntry_RoomNumber</MudTh>
|
<MudTh>@LanguageLocale.dto_StayEntry_RoomNumber</MudTh>
|
||||||
|
<MudTh>@LanguageLocale.general_actions</MudTh>
|
||||||
</HeaderContent>
|
</HeaderContent>
|
||||||
<RowTemplate>
|
<RowTemplate>
|
||||||
<MudTd DataLabel="@LanguageLocale.dto_StayEntry_DateIn">
|
<MudTd DataLabel="@LanguageLocale.dto_StayEntry_DateIn">
|
||||||
@@ -56,6 +58,9 @@
|
|||||||
<MudTd DataLabel="@LanguageLocale.dto_StayEntry_RoomNumber">
|
<MudTd DataLabel="@LanguageLocale.dto_StayEntry_RoomNumber">
|
||||||
@context.RoomNumber
|
@context.RoomNumber
|
||||||
</MudTd>
|
</MudTd>
|
||||||
|
<MudTd DataLabel="@LanguageLocale.general_actions">
|
||||||
|
<MudIconButton Icon="@Icons.Material.Filled.Info" OnClick="@(() => BtnViewStayDetails(context))" />
|
||||||
|
</MudTd>
|
||||||
</RowTemplate>
|
</RowTemplate>
|
||||||
<NoRecordsContent>
|
<NoRecordsContent>
|
||||||
<MudText>@LanguageLocale.general_noResults</MudText>
|
<MudText>@LanguageLocale.general_noResults</MudText>
|
||||||
@@ -110,16 +115,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BtnEdit()
|
|
||||||
{
|
|
||||||
Snackbar.Add("Not implemented yet!", Severity.Info);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void BtnReturn()
|
|
||||||
{
|
|
||||||
Navigation.NavigateTo(GuestConsts.Page_GuestDocs_List);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task LoadTabGuestStays()
|
private async Task LoadTabGuestStays()
|
||||||
{
|
{
|
||||||
//Only load when there is no data.
|
//Only load when there is no data.
|
||||||
@@ -137,4 +132,33 @@
|
|||||||
guestStayList = await stayService.GetStaysWithGuest(documentModel.DocumentType, documentModel.DocumentNum);
|
guestStayList = await stayService.GetStaysWithGuest(documentModel.DocumentType, documentModel.DocumentNum);
|
||||||
guestStaysLoading = false;
|
guestStaysLoading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#region Event Handlers
|
||||||
|
|
||||||
|
private void BtnEdit()
|
||||||
|
{
|
||||||
|
Snackbar.Add("Not implemented yet!", Severity.Info);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BtnReturn()
|
||||||
|
{
|
||||||
|
Navigation.NavigateTo(GuestConsts.Page_GuestDocs_List);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void BtnViewStayDetails(StayEntryDTO item)
|
||||||
|
{
|
||||||
|
string itemId = $"{item.Id ?? -1}";
|
||||||
|
string uri = GuestConsts.Page_StayEntry_Detail.Replace(GuestConsts.Page_StayEntry_Detail_Param_Id, itemId);
|
||||||
|
|
||||||
|
string relativeUri = Navigation.ToBaseRelativePath(Navigation.Uri);
|
||||||
|
uri = QueryHelpers.AddQueryString(uri, [
|
||||||
|
new KeyValuePair<string, string?>(GuestConsts.QueryParam_ReturnUrl, relativeUri)
|
||||||
|
]);
|
||||||
|
Navigation.NavigateTo(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -69,17 +69,7 @@
|
|||||||
</PagerContent>
|
</PagerContent>
|
||||||
</MudDataGrid>
|
</MudDataGrid>
|
||||||
|
|
||||||
<MudMessageBox @ref="_msgBoxConfirmDelete" Title="@LanguageLocale.general_confirmTitle"
|
<ConfirmDeleteMsgBox @ref="_msgBoxConfirmDelete" />
|
||||||
CancelText="@LanguageLocale.general_btnCancel">
|
|
||||||
<MessageContent>
|
|
||||||
@LanguageLocale.general_confirmDeleteMsg
|
|
||||||
</MessageContent>
|
|
||||||
<YesButton>
|
|
||||||
<MudButton Variant="Variant.Filled" Color="Color.Error" StartIcon="@Icons.Material.Filled.DeleteForever">
|
|
||||||
@LanguageLocale.general_btnDelete
|
|
||||||
</MudButton>
|
|
||||||
</YesButton>
|
|
||||||
</MudMessageBox>
|
|
||||||
|
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
@@ -92,7 +82,7 @@
|
|||||||
private GuestDocFilterDTO docFilter = new GuestDocFilterDTO();
|
private GuestDocFilterDTO docFilter = new GuestDocFilterDTO();
|
||||||
|
|
||||||
private MudDataGrid<GuestDocumentDTO> _dataGrid = null!;
|
private MudDataGrid<GuestDocumentDTO> _dataGrid = null!;
|
||||||
private MudMessageBox _msgBoxConfirmDelete = null!;
|
private ConfirmDeleteMsgBox _msgBoxConfirmDelete = null!;
|
||||||
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
@@ -145,7 +135,7 @@
|
|||||||
|
|
||||||
private async Task BtnDeleteItem(GuestDocumentDTO item)
|
private async Task BtnDeleteItem(GuestDocumentDTO item)
|
||||||
{
|
{
|
||||||
bool? confirmDelete = await _msgBoxConfirmDelete.ShowAsync();
|
bool? confirmDelete = await _msgBoxConfirmDelete.MsgBox.ShowAsync();
|
||||||
|
|
||||||
if (confirmDelete is null || confirmDelete.Value == false)
|
if (confirmDelete is null || confirmDelete.Value == false)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
@attribute [Route($"{GuestConsts.Page_StayEntry_Detail}")]
|
||||||
|
|
||||||
|
@using Somnia.GuestLog.Models.DTOs;
|
||||||
|
@using Somnia.GuestLog.Services;
|
||||||
|
|
||||||
|
@inject ISnackbar Snackbar
|
||||||
|
@inject IDialogService DialogService
|
||||||
|
@inject NavigationManager Navigation
|
||||||
|
@inject IGuestDocumentService guestDocService
|
||||||
|
@inject IStayEntryService stayService
|
||||||
|
|
||||||
|
|
||||||
|
<PageTitle>Somnia - Guest Docs - Details</PageTitle>
|
||||||
|
|
||||||
|
<MudStack Row="true" Class="my-4">
|
||||||
|
<MudText Typo="Typo.h4" GutterBottom="true">Stay Entry - "@StayId"</MudText>
|
||||||
|
<MudSpacer />
|
||||||
|
<MudButton Variant="Variant.Filled" Color="Color.Success" Size="Size.Small" StartIcon="@Icons.Material.Filled.Edit"
|
||||||
|
OnClick="() => BtnEdit()" Disabled>
|
||||||
|
@LanguageLocale.general_btnEdit
|
||||||
|
</MudButton>
|
||||||
|
<MudButton Variant="Variant.Filled" Color="Color.Default" Size="Size.Small"
|
||||||
|
StartIcon="@Icons.Material.Filled.ArrowBack" OnClick="() => BtnReturn()">
|
||||||
|
@LanguageLocale.general_btnReturn
|
||||||
|
</MudButton>
|
||||||
|
</MudStack>
|
||||||
|
|
||||||
|
@if (stayModel is not null)
|
||||||
|
{
|
||||||
|
<StayEntryForm Model="stayModel" ReadOnly="true" />
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@code {
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public long StayId { get; set; }
|
||||||
|
|
||||||
|
[SupplyParameterFromQuery(Name = GuestConsts.QueryParam_ReturnUrl)]
|
||||||
|
public string? ReturnUrl { get; set; }
|
||||||
|
|
||||||
|
StayEntryDTO? stayModel = null;
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
@* if (StayId is default)
|
||||||
|
{
|
||||||
|
Snackbar.Add("No Id provided!!", Severity.Error);
|
||||||
|
Navigation.NotFound();
|
||||||
|
return;
|
||||||
|
} *@
|
||||||
|
|
||||||
|
//Get model from db.
|
||||||
|
stayModel = await stayService.GetDtoByIdAsync(StayId, queryConfig: new(IncludeGuests: true));
|
||||||
|
if (stayModel is null)
|
||||||
|
{
|
||||||
|
Snackbar.Add($"Stay not found with ID: '{StayId}'", Severity.Error);
|
||||||
|
Navigation.NotFound();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BtnEdit()
|
||||||
|
{
|
||||||
|
Snackbar.Add("Not implemented yet!", Severity.Info);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BtnReturn()
|
||||||
|
{
|
||||||
|
string uri = ReturnUrl ?? GuestConsts.Page_StayEntry_List;
|
||||||
|
Navigation.NavigateTo(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -24,6 +24,10 @@
|
|||||||
</MudButton>
|
</MudButton>
|
||||||
</MudStack>
|
</MudStack>
|
||||||
|
|
||||||
|
<MudPaper Class="pa-4 my-4" Elevation="2" Height="100%">
|
||||||
|
<StayEntryFilterForm @bind-Filter="stayFilter" />
|
||||||
|
</MudPaper>
|
||||||
|
|
||||||
<MudDataGrid @ref="_dataGrid" T="StayEntryDTO" Items="@stayEntryList" Loading="@_dataLoading" ReadOnly="true"
|
<MudDataGrid @ref="_dataGrid" T="StayEntryDTO" Items="@stayEntryList" Loading="@_dataLoading" ReadOnly="true"
|
||||||
Elevation="2">
|
Elevation="2">
|
||||||
<ToolBarContent>
|
<ToolBarContent>
|
||||||
@@ -43,7 +47,7 @@
|
|||||||
|
|
||||||
<PropertyColumn Property="x => x.UpdateTime" Title="@LanguageLocale.dto_GuestDocument_UpdateTime" />
|
<PropertyColumn Property="x => x.UpdateTime" Title="@LanguageLocale.dto_GuestDocument_UpdateTime" />
|
||||||
|
|
||||||
@* <TemplateColumn CellClass="d-flex justify-between" Title="Options" StickyRight Hideable="false"
|
<TemplateColumn CellClass="d-flex justify-between" Title="Options" StickyRight Hideable="false"
|
||||||
ShowColumnOptions="false">
|
ShowColumnOptions="false">
|
||||||
<CellTemplate>
|
<CellTemplate>
|
||||||
<MudIconButton Size="@Size.Small" Icon="@Icons.Material.Outlined.Info"
|
<MudIconButton Size="@Size.Small" Icon="@Icons.Material.Outlined.Info"
|
||||||
@@ -51,22 +55,31 @@
|
|||||||
<MudIconButton Size="@Size.Small" Icon="@Icons.Material.Outlined.Delete"
|
<MudIconButton Size="@Size.Small" Icon="@Icons.Material.Outlined.Delete"
|
||||||
OnClick="() => BtnDeleteItem(context.Item)" />
|
OnClick="() => BtnDeleteItem(context.Item)" />
|
||||||
</CellTemplate>
|
</CellTemplate>
|
||||||
</TemplateColumn> *@
|
</TemplateColumn>
|
||||||
</Columns>
|
</Columns>
|
||||||
<PagerContent>
|
<PagerContent>
|
||||||
<MudDataGridPager T="StayEntryDTO" />
|
<MudDataGridPager T="StayEntryDTO" />
|
||||||
</PagerContent>
|
</PagerContent>
|
||||||
</MudDataGrid>
|
</MudDataGrid>
|
||||||
|
|
||||||
|
<ConfirmDeleteMsgBox @ref="_confirmDeleteMsgBox" />
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
|
||||||
private bool _dataLoading = true;
|
private bool _dataLoading = true;
|
||||||
private bool _showAllData = false;
|
private bool _showAllData = false;
|
||||||
private const int resultLimit = 200;
|
private const int resultLimit = 200;
|
||||||
|
|
||||||
|
private StayEntryFilterDTO stayFilter = new StayEntryFilterDTO()
|
||||||
|
{
|
||||||
|
DateInStart = DateTime.Today.AddDays(-14),
|
||||||
|
DateInEnd = DateTime.Today,
|
||||||
|
};
|
||||||
|
|
||||||
private IEnumerable<StayEntryDTO> stayEntryList = [];
|
private IEnumerable<StayEntryDTO> stayEntryList = [];
|
||||||
|
|
||||||
private MudDataGrid<StayEntryDTO> _dataGrid = null!;
|
private MudDataGrid<StayEntryDTO> _dataGrid = null!;
|
||||||
|
private ConfirmDeleteMsgBox _confirmDeleteMsgBox = null!;
|
||||||
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
@@ -79,8 +92,7 @@
|
|||||||
_dataLoading = true;
|
_dataLoading = true;
|
||||||
|
|
||||||
int dataLimit = _showAllData ? 0 : resultLimit;
|
int dataLimit = _showAllData ? 0 : resultLimit;
|
||||||
stayEntryList = await StayEntryService.GetDtoListAsync();
|
stayEntryList = await StayEntryService.GetDtoListByFilterAsync(filter: stayFilter, limit: dataLimit);
|
||||||
//stayEntryList = await StayEntryService.GetDtoListAsync(filter: filter, limit: dataLimit);
|
|
||||||
|
|
||||||
if (showMsg)
|
if (showMsg)
|
||||||
{
|
{
|
||||||
@@ -102,6 +114,34 @@
|
|||||||
Navigation.NavigateTo(GuestConsts.Page_StayEntry_New);
|
Navigation.NavigateTo(GuestConsts.Page_StayEntry_New);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private async Task BtnViewDetails(StayEntryDTO item)
|
||||||
|
{
|
||||||
|
string itemId = $"{item.Id ?? -1}";
|
||||||
|
string uri = GuestConsts.Page_StayEntry_Detail.Replace(GuestConsts.Page_StayEntry_Detail_Param_Id, itemId);
|
||||||
|
Navigation.NavigateTo(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task BtnDeleteItem(StayEntryDTO item)
|
||||||
|
{
|
||||||
|
bool? confirmDelete = await _confirmDeleteMsgBox.MsgBox.ShowAsync();
|
||||||
|
|
||||||
|
if (confirmDelete is null || confirmDelete.Value == false)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool deleted = await StayEntryService.DeleteEntryAsync(item);
|
||||||
|
if (!deleted)
|
||||||
|
{
|
||||||
|
Snackbar.Add($"Error deleting Stay {item.Id}", Severity.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Snackbar.Add($"Stay {item.Id} deleted!", Severity.Success);
|
||||||
|
await LoadDataAsync();
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -10,6 +10,11 @@ public static class GuestConsts
|
|||||||
|
|
||||||
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_Param_Id = "{StayId:long}";
|
||||||
|
|
||||||
|
|
||||||
|
public const string QueryParam_ReturnUrl = "returnUrl";
|
||||||
|
|
||||||
|
|
||||||
public const string DataList_DocumentTypes = "DocumentType";
|
public const string DataList_DocumentTypes = "DocumentType";
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ public class StayEntryDTO
|
|||||||
public string? PaymentMethod { get; set; }
|
public string? PaymentMethod { get; set; }
|
||||||
|
|
||||||
|
|
||||||
public List<GuestDocumentDTO> GuestDocuments { get; set; } = [];
|
public List<GuestDocumentDTO>? GuestDocuments { get; set; } = null;
|
||||||
|
|
||||||
|
|
||||||
public DateTime? CreateTime { get; set; }
|
public DateTime? CreateTime { get; set; }
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
namespace Somnia.GuestLog.Models.DTOs;
|
||||||
|
|
||||||
|
public class StayEntryFilterDTO
|
||||||
|
{
|
||||||
|
public DateTime? DateInStart { get; set; }
|
||||||
|
public DateTime? DateInEnd { get; set; }
|
||||||
|
|
||||||
|
public string? RoomNumber { get; set; }
|
||||||
|
public string? PaymentMethod { get; set; }
|
||||||
|
}
|
||||||
@@ -33,7 +33,7 @@ internal static class EntityMapping
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static StayEntryDTO MapStayEntryEntityToDTO(StayEntry entity)
|
public static StayEntryDTO MapStayEntryEntityToDTO(StayEntry entity, bool includeGuests)
|
||||||
{
|
{
|
||||||
return new()
|
return new()
|
||||||
{
|
{
|
||||||
@@ -45,7 +45,7 @@ internal static class EntityMapping
|
|||||||
PaymentMethod = entity.PaymentMethod,
|
PaymentMethod = entity.PaymentMethod,
|
||||||
CreateTime = entity.CreateTime,
|
CreateTime = entity.CreateTime,
|
||||||
UpdateTime = entity.UpdateTime,
|
UpdateTime = entity.UpdateTime,
|
||||||
GuestDocuments = [.. entity.GuestDocuments.Select(e => MapGuestDocumentEntityToDTO(e))],
|
GuestDocuments = includeGuests ? [.. entity.GuestDocuments.Select(e => MapGuestDocumentEntityToDTO(e))] : null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Somnia.GuestLog.Models.Entities;
|
||||||
|
|
||||||
|
namespace Somnia.GuestLog.Models.QueryConfigs;
|
||||||
|
|
||||||
|
public record StayEntryQueryConfig(bool IncludeGuests = false, bool UseSplitQueries = true, bool DisableTracking = false)
|
||||||
|
{
|
||||||
|
public readonly static StayEntryQueryConfig DefaultQueryConfig = new();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class StayEntryQueryExtensions
|
||||||
|
{
|
||||||
|
public static IQueryable<StayEntry> AddQueryConfig(this IQueryable<StayEntry> query, StayEntryQueryConfig? config)
|
||||||
|
{
|
||||||
|
config ??= StayEntryQueryConfig.DefaultQueryConfig;
|
||||||
|
|
||||||
|
if (config.IncludeGuests)
|
||||||
|
{
|
||||||
|
query = query.Include(e => e.GuestDocuments);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.UseSplitQueries)
|
||||||
|
{
|
||||||
|
query = query.AsSplitQuery();
|
||||||
|
}
|
||||||
|
if (config.DisableTracking)
|
||||||
|
{
|
||||||
|
query = query.AsNoTracking();
|
||||||
|
}
|
||||||
|
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
using FluentValidation;
|
using FluentValidation;
|
||||||
using Microsoft.AspNetCore.Localization;
|
using Microsoft.AspNetCore.Localization;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Diagnostics;
|
||||||
using MudBlazor.Services;
|
using MudBlazor.Services;
|
||||||
using Somnia.GuestLog.Components;
|
using Somnia.GuestLog.Components;
|
||||||
using Somnia.GuestLog.Infrastructure;
|
using Somnia.GuestLog.Infrastructure;
|
||||||
@@ -17,7 +18,17 @@ var connectionStringGuestLog = builder.Configuration.GetConnectionString("DbSomn
|
|||||||
?? throw new InvalidOperationException("Connection string 'DbSomniaGuestLog' not found.");
|
?? throw new InvalidOperationException("Connection string 'DbSomniaGuestLog' not found.");
|
||||||
builder.Services.AddDbContextFactory<GuestLogContext>(options =>
|
builder.Services.AddDbContextFactory<GuestLogContext>(options =>
|
||||||
{
|
{
|
||||||
options.UseNpgsql(connectionStringGuestLog);
|
options.UseNpgsql(connectionStringGuestLog)
|
||||||
|
.UseLazyLoadingProxies()
|
||||||
|
.ConfigureWarnings(w => w.Log((CoreEventId.NavigationLazyLoading, LogLevel.Warning)));
|
||||||
|
|
||||||
|
// The following options help with debugging, but should
|
||||||
|
// be changed or removed for production.
|
||||||
|
if (builder.Environment.IsDevelopment())
|
||||||
|
{
|
||||||
|
options.EnableSensitiveDataLogging()
|
||||||
|
.EnableDetailedErrors();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
|
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
|
||||||
|
|||||||
@@ -166,6 +166,8 @@
|
|||||||
<data name="general.noResults" xml:space="preserve"><value>No Results!</value></data>
|
<data name="general.noResults" xml:space="preserve"><value>No Results!</value></data>
|
||||||
<data name="general.showAllElements" xml:space="preserve"><value>Show all elements</value></data>
|
<data name="general.showAllElements" xml:space="preserve"><value>Show all elements</value></data>
|
||||||
<data name="general.wildcardHelperText" xml:space="preserve"><value>Use '%' as wildcard</value></data>
|
<data name="general.wildcardHelperText" xml:space="preserve"><value>Use '%' as wildcard</value></data>
|
||||||
|
<data name="general.dateStart" xml:space="preserve"><value>Date Start</value></data>
|
||||||
|
<data name="general.dateEnd" xml:space="preserve"><value>Date End</value></data>
|
||||||
|
|
||||||
<data name="general.address.address" xml:space="preserve"><value>Address</value></data>
|
<data name="general.address.address" xml:space="preserve"><value>Address</value></data>
|
||||||
<data name="general.address.city" xml:space="preserve"><value>City</value></data>
|
<data name="general.address.city" xml:space="preserve"><value>City</value></data>
|
||||||
@@ -174,6 +176,10 @@
|
|||||||
<data name="general.address.country" xml:space="preserve"><value>Country</value></data>
|
<data name="general.address.country" xml:space="preserve"><value>Country</value></data>
|
||||||
<data name="general.address.zipCode" xml:space="preserve"><value>Zip Code</value></data>
|
<data name="general.address.zipCode" xml:space="preserve"><value>Zip Code</value></data>
|
||||||
|
|
||||||
|
<data name="navMenu.GuestDocumentList" xml:space="preserve"><value>Guests</value></data>
|
||||||
|
<data name="navMenu.StayEntryList" xml:space="preserve"><value>Stays</value></data>
|
||||||
|
|
||||||
|
|
||||||
<data name="page.GuestDocList.pageTitle" xml:space="preserve"><value>Guest Documents</value></data>
|
<data name="page.GuestDocList.pageTitle" xml:space="preserve"><value>Guest Documents</value></data>
|
||||||
<data name="page.GuestDocList.documentList" xml:space="preserve"><value>Document List</value></data>
|
<data name="page.GuestDocList.documentList" xml:space="preserve"><value>Document List</value></data>
|
||||||
<data name="page.GuestDocList.btnNewGuest" xml:space="preserve"><value>New Guest</value></data>
|
<data name="page.GuestDocList.btnNewGuest" xml:space="preserve"><value>New Guest</value></data>
|
||||||
@@ -204,5 +210,6 @@
|
|||||||
|
|
||||||
<data name="control.GuestDocumentSearchDialog.dialogTitle" xml:space="preserve"><value>Search Guest Document</value></data>
|
<data name="control.GuestDocumentSearchDialog.dialogTitle" xml:space="preserve"><value>Search Guest Document</value></data>
|
||||||
<data name="control.GuestDocumentSearchDialog.btnSelectDocument" xml:space="preserve"><value>Use Guest</value></data>
|
<data name="control.GuestDocumentSearchDialog.btnSelectDocument" xml:space="preserve"><value>Use Guest</value></data>
|
||||||
|
<data name="control.GuestDocumentSearchDialog.txtSuggestedGuests" xml:space="preserve"><value>Suggested Guests</value></data>
|
||||||
|
|
||||||
</root>
|
</root>
|
||||||
@@ -43,7 +43,7 @@ public class NominatimAddressQueryService(
|
|||||||
{
|
{
|
||||||
HouseNumber = result.Address.House_number,
|
HouseNumber = result.Address.House_number,
|
||||||
AddressRoad = result.Address.Road ?? result.Address.Square,
|
AddressRoad = result.Address.Road ?? result.Address.Square,
|
||||||
AddressCity = result.Address.City ?? result.Address.Municipality ?? result.Address.Village ?? result.Address.Village,
|
AddressCity = result.Address.City ?? result.Address.Municipality ?? result.Address.Town ?? result.Address.Village,
|
||||||
AddressProvince = result.Address.Province,
|
AddressProvince = result.Address.Province,
|
||||||
AddressState = result.Address.State,
|
AddressState = result.Address.State,
|
||||||
AddressCountry = result.Address.Country,
|
AddressCountry = result.Address.Country,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Somnia.GuestLog.Models.DTOs;
|
using Somnia.GuestLog.Models.DTOs;
|
||||||
|
using Somnia.GuestLog.Models.QueryConfigs;
|
||||||
|
|
||||||
namespace Somnia.GuestLog.Services;
|
namespace Somnia.GuestLog.Services;
|
||||||
|
|
||||||
@@ -9,11 +10,12 @@ public interface IStayEntryService
|
|||||||
public Task<bool> DeleteEntryAsync(StayEntryDTO dto);
|
public Task<bool> DeleteEntryAsync(StayEntryDTO dto);
|
||||||
public Task<bool> DeleteEntryAsync(long id);
|
public Task<bool> DeleteEntryAsync(long id);
|
||||||
|
|
||||||
public Task<StayEntryDTO?> GetDtoByIdAsync(long id);
|
public Task<StayEntryDTO?> GetDtoByIdAsync(long id, StayEntryQueryConfig? queryConfig = null);
|
||||||
public Task<IEnumerable<StayEntryDTO>> GetDtoListAsync();
|
public Task<IEnumerable<StayEntryDTO>> GetDtoListAsync(StayEntryQueryConfig? queryConfig = null);
|
||||||
|
public Task<IEnumerable<StayEntryDTO>> GetDtoListByFilterAsync(StayEntryFilterDTO filter, int limit = 0, StayEntryQueryConfig? queryConfig = null);
|
||||||
|
|
||||||
|
|
||||||
public Task<bool> IsGuestInStayInPeriod(string docType, string docNum, DateTime startTime, DateTime endTime);
|
public Task<bool> IsGuestInStayInPeriod(string docType, string docNum, DateTime startTime, DateTime endTime);
|
||||||
public Task<IEnumerable<StayEntryDTO>> GetStaysWithGuest(string docType, string docNum);
|
public Task<IEnumerable<StayEntryDTO>> GetStaysWithGuest(string docType, string docNum, StayEntryQueryConfig? queryConfig = null);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,8 @@ using Somnia.GuestLog.Infrastructure;
|
|||||||
using Somnia.GuestLog.Models;
|
using Somnia.GuestLog.Models;
|
||||||
using Somnia.GuestLog.Models.DTOs;
|
using Somnia.GuestLog.Models.DTOs;
|
||||||
using Somnia.GuestLog.Models.Entities;
|
using Somnia.GuestLog.Models.Entities;
|
||||||
|
using Somnia.GuestLog.Models.QueryConfigs;
|
||||||
|
using Somnia.GuestLog.Utils;
|
||||||
|
|
||||||
namespace Somnia.GuestLog.Services;
|
namespace Somnia.GuestLog.Services;
|
||||||
|
|
||||||
@@ -41,7 +43,7 @@ public class StayEntryService(
|
|||||||
using var dbContext = contextFactory.CreateDbContext();
|
using var dbContext = contextFactory.CreateDbContext();
|
||||||
|
|
||||||
//Check and add GuestDocuments
|
//Check and add GuestDocuments
|
||||||
foreach (GuestDocumentDTO guestDto in dto.GuestDocuments)
|
foreach (GuestDocumentDTO guestDto in dto.GuestDocuments!)
|
||||||
{
|
{
|
||||||
//Get it from db.
|
//Get it from db.
|
||||||
GuestDocument? dbGuest = await dbContext.GuestDocuments.FindAsync(guestDto.DocumentType, guestDto.DocumentNum)
|
GuestDocument? dbGuest = await dbContext.GuestDocuments.FindAsync(guestDto.DocumentType, guestDto.DocumentNum)
|
||||||
@@ -111,21 +113,53 @@ public class StayEntryService(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<StayEntryDTO?> GetDtoByIdAsync(long id)
|
public async Task<StayEntryDTO?> GetDtoByIdAsync(long id, StayEntryQueryConfig? queryConfig = null)
|
||||||
{
|
{
|
||||||
using var dbContext = contextFactory.CreateDbContext();
|
using var dbContext = contextFactory.CreateDbContext();
|
||||||
StayEntry? dbItem = await dbContext.StayEntries.FindAsync(id);
|
StayEntry? dbItem = await dbContext.StayEntries
|
||||||
return dbItem is not null ? GetDtoFromDb(dbItem) : null;
|
.Where(e => e.Id == id)
|
||||||
|
.AddQueryConfig(queryConfig)
|
||||||
|
.FirstOrDefaultAsync();
|
||||||
|
|
||||||
|
return dbItem is not null ? GetDtoFromDb(dbItem, queryConfig) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<StayEntryDTO>> GetDtoListAsync()
|
public async Task<IEnumerable<StayEntryDTO>> GetDtoListAsync(StayEntryQueryConfig? queryConfig = null)
|
||||||
{
|
{
|
||||||
using var dbContext = contextFactory.CreateDbContext();
|
using var dbContext = contextFactory.CreateDbContext();
|
||||||
|
|
||||||
var dbList = await dbContext.StayEntries
|
var dbList = await dbContext.StayEntries
|
||||||
|
.AddQueryConfig(queryConfig)
|
||||||
.OrderByDescending(e => e.UpdateTime)
|
.OrderByDescending(e => e.UpdateTime)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
return dbList.Select(GetDtoFromDb);
|
return dbList.Select(e => GetDtoFromDb(e, queryConfig));
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<StayEntryDTO>> GetDtoListByFilterAsync(StayEntryFilterDTO filter, int limit = 0, StayEntryQueryConfig? queryConfig = null)
|
||||||
|
{
|
||||||
|
using var dbContext = contextFactory.CreateDbContext();
|
||||||
|
|
||||||
|
var query = dbContext.StayEntries
|
||||||
|
.AddQueryConfig(queryConfig)
|
||||||
|
.AsQueryable();
|
||||||
|
|
||||||
|
query = query.WhereIf(filter.DateInStart is not null && filter.DateInEnd is not null,
|
||||||
|
e => e.DateIn >= filter.DateInStart!.Value.ToUniversalTime()
|
||||||
|
&& e.DateIn < filter.DateInEnd!.Value.ToUniversalTime());
|
||||||
|
query = query.WhereIf(!string.IsNullOrEmpty(filter.RoomNumber),
|
||||||
|
e => EF.Functions.Like(e.RoomNumber, $"%{filter.RoomNumber}%"));
|
||||||
|
query = query.WhereIf(!string.IsNullOrEmpty(filter.PaymentMethod),
|
||||||
|
e => e.PaymentMethod == filter.PaymentMethod);
|
||||||
|
|
||||||
|
if (limit > 0)
|
||||||
|
{
|
||||||
|
query = query.Take(limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
var dbList = await query.ToListAsync();
|
||||||
|
|
||||||
|
return dbList.Select(x => GetDtoFromDb(x, queryConfig));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -133,29 +167,33 @@ public class StayEntryService(
|
|||||||
{
|
{
|
||||||
using var dbContext = contextFactory.CreateDbContext();
|
using var dbContext = contextFactory.CreateDbContext();
|
||||||
|
|
||||||
bool rs = await dbContext.StayEntries.AnyAsync(
|
bool rs = await dbContext.StayEntries
|
||||||
s => s.DateIn < endTime && s.DateOut > startTime
|
.AnyAsync(s => s.DateIn < endTime && s.DateOut > startTime
|
||||||
&& s.GuestDocuments.Any(g => g.DocumentType == docType && g.DocumentNum == docNum));
|
&& s.GuestDocuments.Any(g => g.DocumentType == docType && g.DocumentNum == docNum)
|
||||||
|
);
|
||||||
|
|
||||||
return rs;
|
return rs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<StayEntryDTO>> GetStaysWithGuest(string docType, string docNum)
|
public async Task<IEnumerable<StayEntryDTO>> GetStaysWithGuest(string docType, string docNum, StayEntryQueryConfig? queryConfig = null)
|
||||||
{
|
{
|
||||||
using var dbContext = contextFactory.CreateDbContext();
|
using var dbContext = contextFactory.CreateDbContext();
|
||||||
|
|
||||||
var rs = await dbContext.StayEntries.Where(
|
var rs = await dbContext.StayEntries
|
||||||
s => s.GuestDocuments.Any(g => g.DocumentType == docType && g.DocumentNum == docNum))
|
.Where(s => s.GuestDocuments.Any(g => g.DocumentType == docType && g.DocumentNum == docNum))
|
||||||
|
.AddQueryConfig(queryConfig)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
return rs.Select(GetDtoFromDb);
|
return rs.Select(e => GetDtoFromDb(e, queryConfig));
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Internal Methods
|
#region Internal Methods
|
||||||
|
|
||||||
private static StayEntryDTO GetDtoFromDb(StayEntry dbItem)
|
private static StayEntryDTO GetDtoFromDb(StayEntry dbItem, StayEntryQueryConfig? queryConfig)
|
||||||
{
|
{
|
||||||
return EntityMapping.MapStayEntryEntityToDTO(dbItem);
|
queryConfig ??= StayEntryQueryConfig.DefaultQueryConfig;
|
||||||
|
|
||||||
|
return EntityMapping.MapStayEntryEntityToDTO(dbItem, queryConfig.IncludeGuests);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" />
|
||||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" />
|
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ public class StayEntryDTOValidator : ValueValidator<StayEntryDTO>
|
|||||||
.Must(val => val != null && dataListService.IsValueInList(GuestConsts.DataList_PaymentMethods, val));
|
.Must(val => val != null && dataListService.IsValueInList(GuestConsts.DataList_PaymentMethods, val));
|
||||||
|
|
||||||
RuleFor(e => e.GuestDocuments)
|
RuleFor(e => e.GuestDocuments)
|
||||||
|
.NotNull()
|
||||||
.NotEmpty();
|
.NotEmpty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user