From c5d84870464db84815e1067edf32cd8d90b001865a2733e3491ead7a03e541e1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20Garc=C3=ADa?=
<93217193+Daniel-Garmig@users.noreply.github.com>
Date: Sat, 12 Sep 2026 15:28:25 +0200
Subject: [PATCH] Small fixes and improvements: - GuestDocument - At least one
contact field is required. - GuestDocument - List Page - Hide not useful
columns: "version" - StayEntry - Show stayEntry ID in UI msg after creation.
- StayEntry - Create Page - Time fields don't reset anymore when dates
change. - Show local times in UI instead of UTC times. - Validators - Use
expresions for dates so they are recalculated each time.
---
.../Components/Forms/StayEntryForm.razor | 6 ++++--
.../Components/Pages/GuestDocuments/GuestDocList.razor | 5 +++--
.../Components/Pages/StayEntries/StayEntryNew.razor | 2 +-
src/Somnia.GuestLog/Models/DTOs/Result.cs | 2 ++
src/Somnia.GuestLog/Models/EntityMapping.cs | 10 +++++-----
.../Services/Entity/StayEntryEntityService.cs | 2 +-
.../Services/StayExport/StayExportService.cs | 2 +-
.../Validators/GuestDocumentDTOValidator.cs | 10 ++++++++--
.../Validators/StayEntryDTOValidator.cs | 2 +-
9 files changed, 26 insertions(+), 15 deletions(-)
diff --git a/src/Somnia.GuestLog/Components/Forms/StayEntryForm.razor b/src/Somnia.GuestLog/Components/Forms/StayEntryForm.razor
index 37c8698..10cecfa 100644
--- a/src/Somnia.GuestLog/Components/Forms/StayEntryForm.razor
+++ b/src/Somnia.GuestLog/Components/Forms/StayEntryForm.razor
@@ -21,12 +21,14 @@
-
-
-
-
+
+
diff --git a/src/Somnia.GuestLog/Components/Pages/StayEntries/StayEntryNew.razor b/src/Somnia.GuestLog/Components/Pages/StayEntries/StayEntryNew.razor
index 970c5e7..0e4b484 100644
--- a/src/Somnia.GuestLog/Components/Pages/StayEntries/StayEntryNew.razor
+++ b/src/Somnia.GuestLog/Components/Pages/StayEntries/StayEntryNew.razor
@@ -60,7 +60,7 @@
return;
}
- userMessage.ShowMessage($"StayEntry Created!", MessageKind.Success);
+ userMessage.ShowMessage("StayEntry Created: (Id: {0})", MessageKind.Success, createResult.Context ?? ["???"]);
Navigation.NavigateTo(GuestConsts.Page_StayEntry_List);
}
diff --git a/src/Somnia.GuestLog/Models/DTOs/Result.cs b/src/Somnia.GuestLog/Models/DTOs/Result.cs
index bcbc1ec..cee351f 100644
--- a/src/Somnia.GuestLog/Models/DTOs/Result.cs
+++ b/src/Somnia.GuestLog/Models/DTOs/Result.cs
@@ -16,6 +16,8 @@ public sealed record Result(
) : IResult
{
public static Result Ok() => new(IsSuccess: true, ResultCode: ResultCode.Ok, Context: null);
+ public static Result OkWithContext(params object[] context)
+ => new(IsSuccess: true, ResultCode: ResultCode.Ok, Context: context);
public static Result Fail(ResultCode resultCode) => new(IsSuccess: false, resultCode, Context: null);
public static Result FailWithContext(ResultCode resultCode, params object[] context)
diff --git a/src/Somnia.GuestLog/Models/EntityMapping.cs b/src/Somnia.GuestLog/Models/EntityMapping.cs
index f5284be..fdd9af3 100644
--- a/src/Somnia.GuestLog/Models/EntityMapping.cs
+++ b/src/Somnia.GuestLog/Models/EntityMapping.cs
@@ -30,8 +30,8 @@ internal static class EntityMapping
AddressState = entity.AddressDetails?.AddressState ?? "",
AddressCountry = entity.AddressDetails?.AddressCountry! ?? "",
ZipCode = entity.AddressDetails?.ZipCode ?? "",
- CreateTime = entity.CreateTime,
- UpdateTime = entity.UpdateTime,
+ CreateTime = entity.CreateTime.ToLocalTime(),
+ UpdateTime = entity.UpdateTime.ToLocalTime(),
};
}
@@ -45,8 +45,8 @@ internal static class EntityMapping
RoomCount = entity.RoomCount,
RoomNumber = entity.RoomNumber,
PaymentMethod = entity.PaymentMethod,
- CreateTime = entity.CreateTime,
- UpdateTime = entity.UpdateTime,
+ CreateTime = entity.CreateTime.ToLocalTime(),
+ UpdateTime = entity.UpdateTime.ToLocalTime(),
GuestDocuments = includeGuests ? [.. entity.GuestDocuments.Select(e => MapGuestDocumentEntityToDTO(e))] : null,
};
}
@@ -68,7 +68,7 @@ internal static class EntityMapping
ExportResult = entity.ExportResult,
ExportedPath = entity.ExportedPath,
ExportDetails = entity.ExportDetails,
- ExportTime = entity.ExportTime,
+ ExportTime = entity.ExportTime.ToLocalTime(),
};
}
diff --git a/src/Somnia.GuestLog/Services/Entity/StayEntryEntityService.cs b/src/Somnia.GuestLog/Services/Entity/StayEntryEntityService.cs
index 4611e55..b3c2eea 100644
--- a/src/Somnia.GuestLog/Services/Entity/StayEntryEntityService.cs
+++ b/src/Somnia.GuestLog/Services/Entity/StayEntryEntityService.cs
@@ -67,7 +67,7 @@ public class StayEntryEntityService(
await dbContext.SaveChangesAsync();
logger.LogInformation("StayEntryService - CreateEntryAsync: StayEntry Created: '{id}'", dbStay.GetFullKey());
- return Result.Ok();
+ return Result.OkWithContext(dbStay.GetFullKey());
}
catch (Exception ex)
{
diff --git a/src/Somnia.GuestLog/Services/StayExport/StayExportService.cs b/src/Somnia.GuestLog/Services/StayExport/StayExportService.cs
index 557760e..8d44693 100644
--- a/src/Somnia.GuestLog/Services/StayExport/StayExportService.cs
+++ b/src/Somnia.GuestLog/Services/StayExport/StayExportService.cs
@@ -195,7 +195,7 @@ public class StayExportService(
throw new InvalidOperationException($"StayExportFile - ExportType {exportParams.ExportType} require date start/end. Null dates found");
}
- //Get Stays in period.
+ //Get Stays in period -> Local time should be used so it match with entities local-time.
StayEntryFilterDTO filter = new()
{
DateInStart = exportParams.ExportPeriodStart,
diff --git a/src/Somnia.GuestLog/Validators/GuestDocumentDTOValidator.cs b/src/Somnia.GuestLog/Validators/GuestDocumentDTOValidator.cs
index 6ef7d45..4aa634e 100644
--- a/src/Somnia.GuestLog/Validators/GuestDocumentDTOValidator.cs
+++ b/src/Somnia.GuestLog/Validators/GuestDocumentDTOValidator.cs
@@ -25,7 +25,7 @@ public class GuestDocumentDTOValidator : ValueValidator
.Cascade(CascadeMode.Stop)
.NotEmpty()
.When(x => x.Nationality != GuestConsts.CountryCode_ESP)
- .LessThanOrEqualTo(DateTime.Today);
+ .LessThanOrEqualTo(x => DateTime.Today);
RuleFor(x => x.SupportNum)
.Cascade(CascadeMode.Stop)
@@ -49,7 +49,7 @@ public class GuestDocumentDTOValidator : ValueValidator
RuleFor(x => x.BirthDate)
.NotEmpty()
- .LessThanOrEqualTo(DateTime.Today);
+ .LessThanOrEqualTo(x => DateTime.Today);
RuleFor(x => x.Nationality)
.Cascade(CascadeMode.Stop)
@@ -66,6 +66,12 @@ public class GuestDocumentDTOValidator : ValueValidator
.Matches(RegexUtils.RegexPhoneNumber()).WithMessage("Invalid format")
.When(x => !string.IsNullOrEmpty(x.PhoneNumber));
+ // Phone is required if mail is empty.
+ RuleFor(x => x.PhoneNumber)
+ .NotNull()
+ .When(x => string.IsNullOrEmpty(x.EmailAddress))
+ .WithMessage("At least 1 contact field (phone or email) is required!");
+
RuleFor(x => x.AddressCountry)
.NotEmpty()
.Must(val => val != null && dataListService.IsValueInList(GuestConsts.DataList_CountryCodes, val));
diff --git a/src/Somnia.GuestLog/Validators/StayEntryDTOValidator.cs b/src/Somnia.GuestLog/Validators/StayEntryDTOValidator.cs
index 58dcacf..335041a 100644
--- a/src/Somnia.GuestLog/Validators/StayEntryDTOValidator.cs
+++ b/src/Somnia.GuestLog/Validators/StayEntryDTOValidator.cs
@@ -10,7 +10,7 @@ public class StayEntryDTOValidator : ValueValidator
{
RuleFor(e => e.DateIn)
.NotEmpty()
- .LessThanOrEqualTo(DateTime.Today.AddDays(1).AddSeconds(-1));
+ .LessThanOrEqualTo(x => DateTime.Today.AddDays(1).AddSeconds(-1));
RuleFor(e => e.DateOut)
.NotEmpty()