Compare commits

...
1 Commits
Author SHA256 Message Date
Daniel-Garmig 9ec87d56da feat StayExport - Added ExportDetails for StayExports
Store a new field ('ExportDetails') with export details. This is a JSON field in DB that can store information about the export depending on the format provider used.

Changes:
- Updated models and created required migrations.
- Show field in StayExport list.
2026-09-08 19:58:47 +02:00
16 changed files with 352 additions and 16 deletions
@@ -52,8 +52,13 @@
</TemplateColumn> </TemplateColumn>
<PropertyColumn Property="x => Localizer.GetEnumValue(x.ExportResult)" <PropertyColumn Property="x => Localizer.GetEnumValue(x.ExportResult)"
Title="@LanguageLocale.dto_StayExportFile_ExportResult" /> Title="@LanguageLocale.dto_StayExportFile_ExportResult" />
<PropertyColumn Property="x => x.ExportedPath" Title="@LanguageLocale.dto_StayExportFile_ExportedPath" Hidden />
<PropertyColumn Property="x => x.ExportTime" Title="@LanguageLocale.dto_StayExportFile_ExportTime" /> <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" <TemplateColumn CellClass="d-flex justify-between" Title="Options" StickyRight Hideable="false"
ShowColumnOptions="false"> ShowColumnOptions="false">
@@ -118,7 +123,21 @@
{ {
string jsonParams = JsonSerializer.Serialize(dto.ExportParams, options: new() { WriteIndented = true }); string jsonParams = JsonSerializer.Serialize(dto.ExportParams, options: new() { WriteIndented = true });
await DialogService.ShowMessageBoxAsync("Details", jsonParams); 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) private async Task BtnDownloadFile(StayExportFileDTO item)
@@ -6,5 +6,7 @@ public static class DbConsts
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"; public const string PK_NotApply = "N/A";
} }
@@ -25,6 +25,9 @@ public class StayExportFileEntityConfig : IEntityTypeConfiguration<StayExportFil
builder.Property(e => e.ExportedPath) builder.Property(e => e.ExportedPath)
.HasMaxLength(256); .HasMaxLength(256);
builder.Property(e => e.ExportDetails)
.HasColumnType(DbConsts.DbType_jsonb);
builder.Property(e => e.ExportTime) builder.Property(e => e.ExportTime)
.IsRequired() .IsRequired()
@@ -0,0 +1,252 @@
// <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("20260908172441_StayExportFile_AddColumn_ExportDetails")]
partial class StayExportFile_AddColumn_ExportDetails
{
/// <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<string>("ExportDetails")
.HasColumnType("jsonb");
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
}
}
}
@@ -0,0 +1,28 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Somnia.GuestLog.Infrastructure.Migrations
{
/// <inheritdoc />
public partial class StayExportFile_AddColumn_ExportDetails : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "ExportDetails",
table: "StayExportFile",
type: "jsonb",
nullable: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "ExportDetails",
table: "StayExportFile");
}
}
}
@@ -193,6 +193,9 @@ namespace Somnia.GuestLog.Infrastructure.Migrations
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id")); NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<string>("ExportDetails")
.HasColumnType("jsonb");
b.Property<int>("ExportFormat") b.Property<int>("ExportFormat")
.HasColumnType("integer"); .HasColumnType("integer");
@@ -14,6 +14,8 @@ public class StayExportFileDTO
public string? ExportedPath { get; set; } public string? ExportedPath { get; set; }
public string? ExportDetails { get; set; }
public DateTime? ExportTime { get; set; } public DateTime? ExportTime { get; set; }
} }
@@ -17,6 +17,11 @@ public class StayExportFile : BaseEntity
/// </summary> /// </summary>
public string? ExportedPath { get; set; } public string? ExportedPath { get; set; }
/// <summary>
/// A JSON column to store details about the exported file.
/// This details can contain information about errors, which stays where included, etc.
/// </summary>
public string? ExportDetails { get; set; }
/// <summary> /// <summary>
/// Date/Time when export file was generated. /// Date/Time when export file was generated.
@@ -67,6 +67,7 @@ internal static class EntityMapping
ExportParams = exportParamsDto, ExportParams = exportParamsDto,
ExportResult = entity.ExportResult, ExportResult = entity.ExportResult,
ExportedPath = entity.ExportedPath, ExportedPath = entity.ExportedPath,
ExportDetails = entity.ExportDetails,
ExportTime = entity.ExportTime, ExportTime = entity.ExportTime,
}; };
} }
+4
View File
@@ -1,3 +1,4 @@
using FluentStorage;
using FluentValidation; using FluentValidation;
using Microsoft.AspNetCore.Localization; using Microsoft.AspNetCore.Localization;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
@@ -115,4 +116,7 @@ app.MapStaticAssets();
app.MapRazorComponents<App>() app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode(); .AddInteractiveServerRenderMode();