From b18bd7caa668caf69c75a33e6fc4d0d6056c340bd1a985459c9a69dfcef5a726 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garc=C3=ADa?= <93217193+Daniel-Garmig@users.noreply.github.com> Date: Mon, 24 Aug 2026 20:50:38 +0200 Subject: [PATCH] GuestLog - StayEntry pages fixes - Details/New - Fixed time field binding. Now it binds directly to the Model instead of using temp TimeSpans. - New - Fixed StayEntry validation to allow creating Stays with a DateOut in the past. - List - Added ordering to db results so limit behaves in a deterministic way. Fixed default search so stays created today are shown. --- .../Components/Forms/FormMode.cs | 6 ++ .../Components/Forms/StayEntryForm.razor | 55 +++++++++++-------- .../Pages/StayEntries/StayEntryDetail.razor | 19 ++++++- .../Pages/StayEntries/StayEntryList.razor | 2 +- .../Pages/StayEntries/StayEntryNew.razor | 2 +- src/Somnia.GuestLog/Models/EntityMapping.cs | 4 +- .../Services/StayEntryService.cs | 6 +- .../Validators/StayEntryDTOValidator.cs | 2 +- 8 files changed, 67 insertions(+), 29 deletions(-) create mode 100644 src/Somnia.GuestLog/Components/Forms/FormMode.cs diff --git a/src/Somnia.GuestLog/Components/Forms/FormMode.cs b/src/Somnia.GuestLog/Components/Forms/FormMode.cs new file mode 100644 index 0000000..42e9d6c --- /dev/null +++ b/src/Somnia.GuestLog/Components/Forms/FormMode.cs @@ -0,0 +1,6 @@ +namespace Somnia.GuestLog.Components.Forms; + +public enum FormMode +{ + Create, ReadOnly, Edit +} \ No newline at end of file diff --git a/src/Somnia.GuestLog/Components/Forms/StayEntryForm.razor b/src/Somnia.GuestLog/Components/Forms/StayEntryForm.razor index 52f416c..9be90fe 100644 --- a/src/Somnia.GuestLog/Components/Forms/StayEntryForm.razor +++ b/src/Somnia.GuestLog/Components/Forms/StayEntryForm.razor @@ -21,12 +21,16 @@ - - - - + + + + FormMode == FormMode.ReadOnly; private MudForm _form = null!; + private MudDatePicker _datePickerDateIn = null!; + private MudDatePicker _datePickerDateOut = null!; private const string FieldMarginY = "margin-block: 0.5em"; private IEnumerable PaymentMethodSet @@ -138,7 +144,20 @@ 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 @@ -158,10 +177,6 @@ public StayEntryDTO GetModel() { - //Update model times. - Model.DateIn = GetDateTimeFromDateAndTime(Model.DateIn, TimeIn); - Model.DateOut = GetDateTimeFromDateAndTime(Model.DateOut, TimeOut); - return Model; } @@ -185,6 +200,8 @@ private async Task BtnAddGuest() { + Debug.Assert(Model.GuestDocuments != null); + DialogOptions dialogOptions = new() { MaxWidth = MaxWidth.Medium, @@ -210,7 +227,7 @@ } //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 && e.DocumentNum == resultData.DocumentNum); @@ -221,12 +238,6 @@ } } - //Init List. - if (Model.GuestDocuments is null) - { - Model.GuestDocuments = []; - } - Model.GuestDocuments.Add(resultData); } diff --git a/src/Somnia.GuestLog/Components/Pages/StayEntries/StayEntryDetail.razor b/src/Somnia.GuestLog/Components/Pages/StayEntries/StayEntryDetail.razor index 41bc2ff..4df0722 100644 --- a/src/Somnia.GuestLog/Components/Pages/StayEntries/StayEntryDetail.razor +++ b/src/Somnia.GuestLog/Components/Pages/StayEntries/StayEntryDetail.razor @@ -27,7 +27,8 @@ @if (stayModel is not null) { - + + @CreateTimeString } @@ -41,6 +42,22 @@ StayEntryDTO? stayModel = null; + private string? CreateTimeString + { + get + { + if (stayModel is null) + { + return null; + } + + List 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() { @* if (StayId is default) diff --git a/src/Somnia.GuestLog/Components/Pages/StayEntries/StayEntryList.razor b/src/Somnia.GuestLog/Components/Pages/StayEntries/StayEntryList.razor index cf2900f..1b31a44 100644 --- a/src/Somnia.GuestLog/Components/Pages/StayEntries/StayEntryList.razor +++ b/src/Somnia.GuestLog/Components/Pages/StayEntries/StayEntryList.razor @@ -73,7 +73,7 @@ private StayEntryFilterDTO stayFilter = new StayEntryFilterDTO() { DateInStart = DateTime.Today.AddDays(-14), - DateInEnd = DateTime.Today, + DateInEnd = DateTime.Today.AddDays(1), }; private IEnumerable stayEntryList = []; diff --git a/src/Somnia.GuestLog/Components/Pages/StayEntries/StayEntryNew.razor b/src/Somnia.GuestLog/Components/Pages/StayEntries/StayEntryNew.razor index 78f130e..943efd4 100644 --- a/src/Somnia.GuestLog/Components/Pages/StayEntries/StayEntryNew.razor +++ b/src/Somnia.GuestLog/Components/Pages/StayEntries/StayEntryNew.razor @@ -27,7 +27,7 @@ - + @code { StayEntryForm _form = null!; diff --git a/src/Somnia.GuestLog/Models/EntityMapping.cs b/src/Somnia.GuestLog/Models/EntityMapping.cs index 6b0dfee..b7183c1 100644 --- a/src/Somnia.GuestLog/Models/EntityMapping.cs +++ b/src/Somnia.GuestLog/Models/EntityMapping.cs @@ -38,8 +38,8 @@ internal static class EntityMapping return new() { Id = entity.Id, - DateIn = entity.DateIn, - DateOut = entity.DateOut, + DateIn = entity.DateIn.ToLocalTime(), + DateOut = entity.DateOut.ToLocalTime(), RoomCount = entity.RoomCount, RoomNumber = entity.RoomNumber, PaymentMethod = entity.PaymentMethod, diff --git a/src/Somnia.GuestLog/Services/StayEntryService.cs b/src/Somnia.GuestLog/Services/StayEntryService.cs index efaff58..d6c5901 100644 --- a/src/Somnia.GuestLog/Services/StayEntryService.cs +++ b/src/Somnia.GuestLog/Services/StayEntryService.cs @@ -153,12 +153,15 @@ public class StayEntryService( query = query.WhereIf(!string.IsNullOrEmpty(filter.PaymentMethod), e => e.PaymentMethod == filter.PaymentMethod); + query = query.OrderByDescending(e => e.DateIn); + if (limit > 0) { query = query.Take(limit); } - var dbList = await query.ToListAsync(); + var dbList = await query + .ToListAsync(); return dbList.Select(x => GetDtoFromDb(x, queryConfig)); } @@ -183,6 +186,7 @@ public class StayEntryService( var rs = await dbContext.StayEntries .Where(s => s.GuestDocuments.Any(g => g.DocumentType == docType && g.DocumentNum == docNum)) .AddQueryConfig(queryConfig) + .OrderByDescending(e => e.DateIn) .ToListAsync(); return rs.Select(e => GetDtoFromDb(e, queryConfig)); diff --git a/src/Somnia.GuestLog/Validators/StayEntryDTOValidator.cs b/src/Somnia.GuestLog/Validators/StayEntryDTOValidator.cs index 4d1f10a..58dcacf 100644 --- a/src/Somnia.GuestLog/Validators/StayEntryDTOValidator.cs +++ b/src/Somnia.GuestLog/Validators/StayEntryDTOValidator.cs @@ -14,7 +14,7 @@ public class StayEntryDTOValidator : ValueValidator RuleFor(e => e.DateOut) .NotEmpty() - .GreaterThan(DateTime.Today); + .GreaterThan(e => e.DateIn); RuleFor(e => e.RoomCount) .NotEmpty()