From b8cbdbd1658d8ed4307cbbccd8a5b2c6504ed93c Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Wed, 20 May 2026 17:26:02 +0100 Subject: [PATCH 1/2] Add file import config entities and update dependencies Introduce FileFormatHandler, FileProfileConfiguration, and RequestType entities with EF Core model configs and migration. Update EstateManagementContext and model builder for new tables and indexes. Refresh SQL Server model snapshot. Bump and add project dependencies across solution, including EF Core, OpenTelemetry, and test libraries. --- ...ansactionProcessor.Aggregates.Tests.csproj | 12 +- .../TransactionProcessor.Aggregates.csproj | 7 +- ...actionProcessor.BusinessLogic.Tests.csproj | 18 +- .../TransactionProcessor.BusinessLogic.csproj | 20 +- ...actionProcessor.DataTransferObjects.csproj | 4 +- .../EstateManagementGenericContext.cs | 13 +- .../Contexts/Extensions.cs | 31 + .../Entities/FileFormatHandler.cs | 7 + .../Entities/FileProfileConfiguration.cs | 17 + .../Entities/RequestType.cs | 7 + ..._add_file_import_config_tables.Designer.cs | 1710 +++++++++++++++++ ...520162516_add_file_import_config_tables.cs | 87 + ...ManagementSqlServerContextModelSnapshot.cs | 125 +- .../TransactionProcessor.Database.csproj | 22 +- .../TransactionProcessor.DatabaseTests.csproj | 8 +- ...rocessor.IntegrationTesting.Helpers.csproj | 8 +- ...ansactionProcessor.IntegrationTests.csproj | 28 +- ...ionProcessor.ProjectionEngine.Tests.csproj | 13 +- ...ansactionProcessor.ProjectionEngine.csproj | 7 +- .../TransactionProcessor.Repository.csproj | 13 +- .../TransactionProcessor.Testing.csproj | 10 +- .../TransactionProcessor.Tests.csproj | 20 +- .../TransactionProcessor.csproj | 33 +- 23 files changed, 2094 insertions(+), 126 deletions(-) create mode 100644 TransactionProcessor.Database/Entities/FileFormatHandler.cs create mode 100644 TransactionProcessor.Database/Entities/FileProfileConfiguration.cs create mode 100644 TransactionProcessor.Database/Entities/RequestType.cs create mode 100644 TransactionProcessor.Database/Migrations/SqlServer/20260520162516_add_file_import_config_tables.Designer.cs create mode 100644 TransactionProcessor.Database/Migrations/SqlServer/20260520162516_add_file_import_config_tables.cs diff --git a/TransactionProcessor.Aggregates.Tests/TransactionProcessor.Aggregates.Tests.csproj b/TransactionProcessor.Aggregates.Tests/TransactionProcessor.Aggregates.Tests.csproj index b06c32fc..74f8229c 100644 --- a/TransactionProcessor.Aggregates.Tests/TransactionProcessor.Aggregates.Tests.csproj +++ b/TransactionProcessor.Aggregates.Tests/TransactionProcessor.Aggregates.Tests.csproj @@ -10,12 +10,16 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + + + + + @@ -24,8 +28,8 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + diff --git a/TransactionProcessor.Aggregates/TransactionProcessor.Aggregates.csproj b/TransactionProcessor.Aggregates/TransactionProcessor.Aggregates.csproj index 0d024ffc..7181df2a 100644 --- a/TransactionProcessor.Aggregates/TransactionProcessor.Aggregates.csproj +++ b/TransactionProcessor.Aggregates/TransactionProcessor.Aggregates.csproj @@ -7,10 +7,11 @@ - + + - - + + diff --git a/TransactionProcessor.BusinessLogic.Tests/TransactionProcessor.BusinessLogic.Tests.csproj b/TransactionProcessor.BusinessLogic.Tests/TransactionProcessor.BusinessLogic.Tests.csproj index 78848b0b..d996b53a 100644 --- a/TransactionProcessor.BusinessLogic.Tests/TransactionProcessor.BusinessLogic.Tests.csproj +++ b/TransactionProcessor.BusinessLogic.Tests/TransactionProcessor.BusinessLogic.Tests.csproj @@ -8,16 +8,20 @@ - - - + + + + + + - + + - - + + @@ -25,7 +29,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/TransactionProcessor.BusinessLogic/TransactionProcessor.BusinessLogic.csproj b/TransactionProcessor.BusinessLogic/TransactionProcessor.BusinessLogic.csproj index 1a228469..ba7c06f6 100644 --- a/TransactionProcessor.BusinessLogic/TransactionProcessor.BusinessLogic.csproj +++ b/TransactionProcessor.BusinessLogic/TransactionProcessor.BusinessLogic.csproj @@ -7,21 +7,25 @@ - + - - + + + + + - - - + + + + - - + + diff --git a/TransactionProcessor.DataTransferObjects/TransactionProcessor.DataTransferObjects.csproj b/TransactionProcessor.DataTransferObjects/TransactionProcessor.DataTransferObjects.csproj index bbd67581..9b1b6f8f 100644 --- a/TransactionProcessor.DataTransferObjects/TransactionProcessor.DataTransferObjects.csproj +++ b/TransactionProcessor.DataTransferObjects/TransactionProcessor.DataTransferObjects.csproj @@ -6,8 +6,8 @@ - - + + diff --git a/TransactionProcessor.Database/Contexts/EstateManagementGenericContext.cs b/TransactionProcessor.Database/Contexts/EstateManagementGenericContext.cs index 8db346c0..f93e12fa 100644 --- a/TransactionProcessor.Database/Contexts/EstateManagementGenericContext.cs +++ b/TransactionProcessor.Database/Contexts/EstateManagementGenericContext.cs @@ -40,6 +40,9 @@ public EstateManagementContext(DbContextOptions dbContextOptions) : base(dbConte #region Properties + public DbSet FileProfileConfigurations { get; set; } + public DbSet RequestTypes { get; set; } + public DbSet FileFormatHandlers { get; set; } public DbSet MerchantOpeningHours { get; set; } public DbSet MerchantBalanceChangedEntry { get; set; } @@ -266,10 +269,7 @@ FROM sys.databases await alterCommand.ExecuteNonQueryAsync(cancellationToken); } } - - - - + public static Boolean IsDuplicateInsertsIgnored(String tableName) => EstateManagementContext.TablesToIgnoreDuplicates.Contains(tableName.Trim(), StringComparer.InvariantCultureIgnoreCase); @@ -326,7 +326,10 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .SetupEstateOperator() .SetupMerchantSchedule() .SetupMerchantScheduleMonth() - .SetupMerchantOpeningHours(); + .SetupMerchantOpeningHours() + .SetupFileProfileConfiguration() + .SetupRequestType() + .SetupFileFormatHandler(); modelBuilder.SetupViewEntities(); diff --git a/TransactionProcessor.Database/Contexts/Extensions.cs b/TransactionProcessor.Database/Contexts/Extensions.cs index 2b687b52..f7df5f8c 100644 --- a/TransactionProcessor.Database/Contexts/Extensions.cs +++ b/TransactionProcessor.Database/Contexts/Extensions.cs @@ -515,6 +515,37 @@ public static ModelBuilder SetupFloatActivity(this ModelBuilder modelBuilder) return modelBuilder; } + public static ModelBuilder SetupFileProfileConfiguration(this ModelBuilder modelBuilder) + { + modelBuilder.Entity().HasKey(t => new { + t.FileProfileId + }); + + modelBuilder.Entity().HasIndex(t => new { + t.Name + }).IsUnique(); + + return modelBuilder; + } + + public static ModelBuilder SetupFileFormatHandler(this ModelBuilder modelBuilder) + { + modelBuilder.Entity().HasKey(t => new { + t.FileFormatHandlerId + }); + modelBuilder.Entity().HasIndex(t => new { t.Name }).IsUnique(); + + return modelBuilder; + } + + public static ModelBuilder SetupRequestType(this ModelBuilder modelBuilder) { + modelBuilder.Entity().HasKey(t => new { t.RequestTypeId }); + + modelBuilder.Entity().HasIndex(t => new { t.Name }).IsUnique(); + + return modelBuilder; + } + #endregion } diff --git a/TransactionProcessor.Database/Entities/FileFormatHandler.cs b/TransactionProcessor.Database/Entities/FileFormatHandler.cs new file mode 100644 index 00000000..475b7a38 --- /dev/null +++ b/TransactionProcessor.Database/Entities/FileFormatHandler.cs @@ -0,0 +1,7 @@ +namespace TransactionProcessor.Database.Entities; + +public class FileFormatHandler +{ + public Guid FileFormatHandlerId { get; set; } + public String Name { get; set; } +} \ No newline at end of file diff --git a/TransactionProcessor.Database/Entities/FileProfileConfiguration.cs b/TransactionProcessor.Database/Entities/FileProfileConfiguration.cs new file mode 100644 index 00000000..38bbf7f8 --- /dev/null +++ b/TransactionProcessor.Database/Entities/FileProfileConfiguration.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace TransactionProcessor.Database.Entities +{ + public class FileProfileConfiguration + { + public Guid FileProfileId { get; set; } + public String Name { get; set; } + public String ListeningDirectory { get; set; } + public Guid RequestTypeId { get; set; } + public Guid OperatorId { get; set; } + public String LineTerminator { get; set; } + public Guid FileFormatHandlerId { get; set; } + } +} diff --git a/TransactionProcessor.Database/Entities/RequestType.cs b/TransactionProcessor.Database/Entities/RequestType.cs new file mode 100644 index 00000000..afda2dac --- /dev/null +++ b/TransactionProcessor.Database/Entities/RequestType.cs @@ -0,0 +1,7 @@ +namespace TransactionProcessor.Database.Entities; + +public class RequestType +{ + public Guid RequestTypeId { get; set; } + public String Name { get; set; } +} \ No newline at end of file diff --git a/TransactionProcessor.Database/Migrations/SqlServer/20260520162516_add_file_import_config_tables.Designer.cs b/TransactionProcessor.Database/Migrations/SqlServer/20260520162516_add_file_import_config_tables.Designer.cs new file mode 100644 index 00000000..58bfaa26 --- /dev/null +++ b/TransactionProcessor.Database/Migrations/SqlServer/20260520162516_add_file_import_config_tables.Designer.cs @@ -0,0 +1,1710 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using TransactionProcessor.Database.Contexts; + +#nullable disable + +namespace TransactionProcessor.Database.Migrations.SqlServer +{ + [DbContext(typeof(EstateManagementContext))] + [Migration("20260520162516_add_file_import_config_tables")] + partial class add_file_import_config_tables + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.8") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.Calendar", b => + { + b.Property("Date") + .HasColumnType("datetime2"); + + b.Property("DayOfWeek") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("DayOfWeekNumber") + .HasColumnType("int"); + + b.Property("DayOfWeekShort") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("MonthNameLong") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("MonthNameShort") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("MonthNumber") + .HasColumnType("int"); + + b.Property("WeekNumber") + .HasColumnType("int"); + + b.Property("WeekNumberString") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Year") + .HasColumnType("int"); + + b.Property("YearWeekNumber") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Date"); + + b.ToTable("calendar"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.Contract", b => + { + b.Property("EstateId") + .HasColumnType("uniqueidentifier"); + + b.Property("OperatorId") + .HasColumnType("uniqueidentifier"); + + b.Property("ContractId") + .HasColumnType("uniqueidentifier"); + + b.Property("ContractReportingId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("ContractReportingId")); + + b.Property("Description") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("EstateId", "OperatorId", "ContractId"); + + b.ToTable("contract"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.ContractProduct", b => + { + b.Property("ContractProductReportingId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("ContractProductReportingId")); + + b.Property("ContractId") + .HasColumnType("uniqueidentifier"); + + b.Property("ContractProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("DisplayText") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ProductName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ProductType") + .HasColumnType("int"); + + b.Property("Value") + .HasColumnType("decimal(18,2)"); + + b.HasKey("ContractProductReportingId"); + + b.HasIndex("ContractProductId", "ContractId") + .IsUnique(); + + b.ToTable("contractproduct"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.ContractProductTransactionFee", b => + { + b.Property("ContractProductTransactionFeeReportingId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("ContractProductTransactionFeeReportingId")); + + b.Property("CalculationType") + .HasColumnType("int"); + + b.Property("ContractProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("ContractProductTransactionFeeId") + .HasColumnType("uniqueidentifier"); + + b.Property("Description") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FeeType") + .HasColumnType("int"); + + b.Property("IsEnabled") + .HasColumnType("bit"); + + b.Property("Value") + .HasColumnType("decimal(18,4)"); + + b.HasKey("ContractProductTransactionFeeReportingId"); + + b.HasIndex("ContractProductTransactionFeeId", "ContractProductId") + .IsUnique(); + + b.ToTable("contractproducttransactionfee"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.Estate", b => + { + b.Property("EstateReportingId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("EstateReportingId")); + + b.Property("CreatedDateTime") + .HasColumnType("datetime2"); + + b.Property("EstateId") + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Reference") + .HasColumnType("nvarchar(max)"); + + b.HasKey("EstateReportingId"); + + b.HasIndex("EstateId") + .IsUnique(); + + b.ToTable("estate"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.EstateOperator", b => + { + b.Property("EstateId") + .HasColumnType("uniqueidentifier"); + + b.Property("OperatorId") + .HasColumnType("uniqueidentifier"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.HasKey("EstateId", "OperatorId"); + + b.ToTable("estateoperator"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.EstateSecurityUser", b => + { + b.Property("SecurityUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("EstateId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedDateTime") + .HasColumnType("datetime2"); + + b.Property("EmailAddress") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("SecurityUserId", "EstateId"); + + b.ToTable("estatesecurityuser"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.File", b => + { + b.Property("FileReportingId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("FileReportingId")); + + b.Property("EstateId") + .HasColumnType("uniqueidentifier"); + + b.Property("FileId") + .HasColumnType("uniqueidentifier"); + + b.Property("FileImportLogId") + .HasColumnType("uniqueidentifier"); + + b.Property("FileLocation") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FileProfileId") + .HasColumnType("uniqueidentifier"); + + b.Property("FileReceivedDate") + .HasColumnType("date"); + + b.Property("FileReceivedDateTime") + .HasColumnType("datetime2"); + + b.Property("IsCompleted") + .HasColumnType("bit"); + + b.Property("MerchantId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("FileReportingId"); + + b.HasIndex("FileId") + .IsUnique(); + + b.ToTable("file"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.FileFormatHandler", b => + { + b.Property("FileFormatHandlerId") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("FileFormatHandlerId"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("FileFormatHandlers"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.FileImportLog", b => + { + b.Property("EstateId") + .HasColumnType("uniqueidentifier"); + + b.Property("FileImportLogReportingId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("FileImportLogReportingId")); + + b.Property("FileImportLogId") + .HasColumnType("uniqueidentifier"); + + b.Property("ImportLogDate") + .HasColumnType("date"); + + b.Property("ImportLogDateTime") + .HasColumnType("datetime2"); + + b.HasKey("EstateId", "FileImportLogReportingId"); + + b.HasIndex("EstateId", "FileImportLogId") + .IsUnique(); + + b.ToTable("fileimportlog"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.FileImportLogFile", b => + { + b.Property("FileImportLogId") + .HasColumnType("uniqueidentifier"); + + b.Property("FileId") + .HasColumnType("uniqueidentifier"); + + b.Property("FilePath") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FileProfileId") + .HasColumnType("uniqueidentifier"); + + b.Property("FileUploadedDate") + .HasColumnType("date"); + + b.Property("FileUploadedDateTime") + .HasColumnType("datetime2"); + + b.Property("MerchantId") + .HasColumnType("uniqueidentifier"); + + b.Property("OriginalFileName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("FileImportLogId", "FileId"); + + b.ToTable("fileimportlogfile"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.FileLine", b => + { + b.Property("FileId") + .HasColumnType("uniqueidentifier"); + + b.Property("LineNumber") + .HasColumnType("int"); + + b.Property("FileLineData") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Status") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TransactionId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("FileId", "LineNumber"); + + SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("FileId", "LineNumber")); + + b.ToTable("fileline"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.FileProfileConfiguration", b => + { + b.Property("FileProfileId") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("FileFormatHandlerId") + .HasColumnType("uniqueidentifier"); + + b.Property("LineTerminator") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ListeningDirectory") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.Property("OperatorId") + .HasColumnType("uniqueidentifier"); + + b.Property("RequestTypeId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("FileProfileId"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("FileProfileConfigurations"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.Float", b => + { + b.Property("FloatId") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ContractId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedDate") + .HasColumnType("date"); + + b.Property("CreatedDateTime") + .HasColumnType("datetime2"); + + b.Property("EstateId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("FloatId"); + + SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("FloatId"), false); + + b.HasIndex("CreatedDate"); + + SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("CreatedDate")); + + b.ToTable("Floats"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.FloatActivity", b => + { + b.Property("EventId") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ActivityDate") + .HasColumnType("date"); + + b.Property("ActivityDateTime") + .HasColumnType("datetime2"); + + b.Property("Amount") + .HasColumnType("decimal(18,2)"); + + b.Property("CostPrice") + .HasColumnType("decimal(18,2)"); + + b.Property("CreditOrDebit") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FloatId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("EventId"); + + SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("EventId"), false); + + b.HasIndex("ActivityDate"); + + SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("ActivityDate")); + + b.ToTable("FloatActivity"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.Merchant", b => + { + b.Property("MerchantReportingId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("MerchantReportingId")); + + b.Property("CreatedDateTime") + .HasColumnType("datetime2"); + + b.Property("EstateId") + .HasColumnType("uniqueidentifier"); + + b.Property("LastSaleDate") + .HasColumnType("date"); + + b.Property("LastSaleDateTime") + .HasColumnType("datetime2"); + + b.Property("LastStatementGenerated") + .HasColumnType("datetime2"); + + b.Property("MerchantId") + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Reference") + .HasColumnType("nvarchar(max)"); + + b.Property("SettlementSchedule") + .HasColumnType("int"); + + b.HasKey("MerchantReportingId"); + + b.HasIndex("EstateId", "MerchantId") + .IsUnique(); + + b.ToTable("merchant"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.MerchantAddress", b => + { + b.Property("MerchantId") + .HasColumnType("uniqueidentifier"); + + b.Property("AddressId") + .HasColumnType("uniqueidentifier"); + + b.Property("AddressLine1") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("AddressLine2") + .HasColumnType("nvarchar(max)"); + + b.Property("AddressLine3") + .HasColumnType("nvarchar(max)"); + + b.Property("AddressLine4") + .HasColumnType("nvarchar(max)"); + + b.Property("Country") + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedDateTime") + .HasColumnType("datetime2"); + + b.Property("PostalCode") + .HasColumnType("nvarchar(max)"); + + b.Property("Region") + .HasColumnType("nvarchar(max)"); + + b.Property("Town") + .HasColumnType("nvarchar(max)"); + + b.HasKey("MerchantId", "AddressId"); + + b.ToTable("merchantaddress"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.MerchantContact", b => + { + b.Property("MerchantId") + .HasColumnType("uniqueidentifier"); + + b.Property("ContactId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedDateTime") + .HasColumnType("datetime2"); + + b.Property("EmailAddress") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.HasKey("MerchantId", "ContactId"); + + b.ToTable("merchantcontact"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.MerchantContract", b => + { + b.Property("MerchantId") + .HasColumnType("uniqueidentifier"); + + b.Property("ContractId") + .HasColumnType("uniqueidentifier"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.HasKey("MerchantId", "ContractId"); + + b.ToTable("MerchantContracts"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.MerchantDevice", b => + { + b.Property("MerchantId") + .HasColumnType("uniqueidentifier"); + + b.Property("DeviceId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedDateTime") + .HasColumnType("datetime2"); + + b.Property("DeviceIdentifier") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsEnabled") + .HasColumnType("bit"); + + b.HasKey("MerchantId", "DeviceId"); + + b.ToTable("merchantdevice"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.MerchantOpeningHours", b => + { + b.Property("MerchantId") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("FridayClosing") + .HasColumnType("nvarchar(max)"); + + b.Property("FridayOpening") + .HasColumnType("nvarchar(max)"); + + b.Property("MondayClosing") + .HasColumnType("nvarchar(max)"); + + b.Property("MondayOpening") + .HasColumnType("nvarchar(max)"); + + b.Property("SaturdayClosing") + .HasColumnType("nvarchar(max)"); + + b.Property("SaturdayOpening") + .HasColumnType("nvarchar(max)"); + + b.Property("SundayClosing") + .HasColumnType("nvarchar(max)"); + + b.Property("SundayOpening") + .HasColumnType("nvarchar(max)"); + + b.Property("ThursdayClosing") + .HasColumnType("nvarchar(max)"); + + b.Property("ThursdayOpening") + .HasColumnType("nvarchar(max)"); + + b.Property("TuesdayClosing") + .HasColumnType("nvarchar(max)"); + + b.Property("TuesdayOpening") + .HasColumnType("nvarchar(max)"); + + b.Property("WednesdayClosing") + .HasColumnType("nvarchar(max)"); + + b.Property("WednesdayOpening") + .HasColumnType("nvarchar(max)"); + + b.HasKey("MerchantId"); + + b.ToTable("merchantopeninghours"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.MerchantOperator", b => + { + b.Property("MerchantId") + .HasColumnType("uniqueidentifier"); + + b.Property("OperatorId") + .HasColumnType("uniqueidentifier"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("MerchantNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TerminalNumber") + .HasColumnType("nvarchar(max)"); + + b.HasKey("MerchantId", "OperatorId"); + + b.ToTable("merchantoperator"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.MerchantSchedule", b => + { + b.Property("MerchantScheduleId") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("EstateId") + .HasColumnType("uniqueidentifier"); + + b.Property("MerchantId") + .HasColumnType("uniqueidentifier"); + + b.Property("Year") + .HasColumnType("int"); + + b.HasKey("MerchantScheduleId"); + + b.HasIndex("MerchantId", "Year") + .IsUnique(); + + b.ToTable("merchantschedule"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.MerchantScheduleMonth", b => + { + b.Property("MerchantScheduleId") + .HasColumnType("uniqueidentifier"); + + b.Property("Month") + .HasColumnType("int"); + + b.Property("ClosedDays") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("MerchantScheduleId", "Month"); + + b.ToTable("merchantschedulemonth"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.MerchantSecurityUser", b => + { + b.Property("MerchantId") + .HasColumnType("uniqueidentifier"); + + b.Property("SecurityUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedDateTime") + .HasColumnType("datetime2"); + + b.Property("EmailAddress") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("MerchantId", "SecurityUserId"); + + b.ToTable("merchantsecurityuser"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.MerchantSettlementFee", b => + { + b.Property("SettlementId") + .HasColumnType("uniqueidentifier"); + + b.Property("TransactionId") + .HasColumnType("uniqueidentifier"); + + b.Property("ContractProductTransactionFeeId") + .HasColumnType("uniqueidentifier"); + + b.Property("CalculatedValue") + .HasColumnType("decimal(18,2)"); + + b.Property("FeeCalculatedDateTime") + .HasColumnType("datetime2"); + + b.Property("FeeValue") + .HasColumnType("decimal(18,2)"); + + b.Property("IsSettled") + .HasColumnType("bit"); + + b.Property("MerchantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("SettlementId", "TransactionId", "ContractProductTransactionFeeId"); + + b.ToTable("merchantsettlementfee"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.Operator", b => + { + b.Property("OperatorReportingId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("OperatorReportingId")); + + b.Property("EstateId") + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OperatorId") + .HasColumnType("uniqueidentifier"); + + b.Property("RequireCustomMerchantNumber") + .HasColumnType("bit"); + + b.Property("RequireCustomTerminalNumber") + .HasColumnType("bit"); + + b.HasKey("OperatorReportingId"); + + b.HasIndex("OperatorId") + .IsUnique(); + + b.ToTable("operator"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.Reconciliation", b => + { + b.Property("TransactionReportingId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("TransactionReportingId")); + + b.Property("DeviceIdentifier") + .HasColumnType("nvarchar(max)"); + + b.Property("IsAuthorised") + .HasColumnType("bit"); + + b.Property("IsCompleted") + .HasColumnType("bit"); + + b.Property("MerchantId") + .HasColumnType("uniqueidentifier"); + + b.Property("ResponseCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ResponseMessage") + .HasColumnType("nvarchar(max)"); + + b.Property("TransactionCount") + .HasColumnType("int"); + + b.Property("TransactionDate") + .HasColumnType("date"); + + b.Property("TransactionDateTime") + .HasColumnType("datetime2"); + + b.Property("TransactionId") + .HasColumnType("uniqueidentifier"); + + b.Property("TransactionTime") + .HasColumnType("time"); + + b.Property("TransactionValue") + .HasColumnType("decimal(18,2)"); + + b.HasKey("TransactionReportingId"); + + SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("TransactionReportingId"), false); + + b.HasIndex("TransactionDate"); + + SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("TransactionDate")); + + b.HasIndex("TransactionId", "MerchantId") + .IsUnique(); + + SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("TransactionId", "MerchantId"), false); + + b.ToTable("reconciliation"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.RequestType", b => + { + b.Property("RequestTypeId") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("RequestTypeId"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("RequestTypes"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.ResponseCodes", b => + { + b.Property("ResponseCode") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("ResponseCode")); + + b.Property("Description") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("ResponseCode"); + + b.ToTable("responsecodes"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.Settlement", b => + { + b.Property("SettlementReportingId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("SettlementReportingId")); + + b.Property("EstateId") + .HasColumnType("uniqueidentifier"); + + b.Property("IsCompleted") + .HasColumnType("bit"); + + b.Property("MerchantId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProcessingStarted") + .HasColumnType("bit"); + + b.Property("ProcessingStartedDateTIme") + .HasColumnType("datetime2"); + + b.Property("SettlementDate") + .HasColumnType("date"); + + b.Property("SettlementId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("SettlementReportingId"); + + SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("SettlementReportingId"), false); + + b.HasIndex("SettlementDate"); + + SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("SettlementDate")); + + b.HasIndex("EstateId", "SettlementId") + .IsUnique(); + + SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("EstateId", "SettlementId"), false); + + b.ToTable("settlement"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.StatementHeader", b => + { + b.Property("MerchantId") + .HasColumnType("uniqueidentifier"); + + b.Property("StatementId") + .HasColumnType("uniqueidentifier"); + + b.Property("StatementCreatedDate") + .HasColumnType("date"); + + b.Property("StatementCreatedDateTime") + .HasColumnType("datetime2"); + + b.Property("StatementGeneratedDate") + .HasColumnType("date"); + + b.Property("StatementGeneratedDateTime") + .HasColumnType("datetime2"); + + b.Property("StatementReportingId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("StatementReportingId")); + + b.HasKey("MerchantId", "StatementId"); + + SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("MerchantId", "StatementId"), false); + + b.HasIndex("StatementGeneratedDate"); + + SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("StatementGeneratedDate")); + + b.ToTable("statementheader"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.StatementLine", b => + { + b.Property("StatementId") + .HasColumnType("uniqueidentifier"); + + b.Property("TransactionId") + .HasColumnType("uniqueidentifier"); + + b.Property("ActivityDateTime") + .HasColumnType("datetime2"); + + b.Property("ActivityType") + .HasColumnType("int"); + + b.Property("ActivityDate") + .HasColumnType("date"); + + b.Property("ActivityDescription") + .HasColumnType("nvarchar(max)"); + + b.Property("InAmount") + .HasColumnType("decimal(18,2)"); + + b.Property("OutAmount") + .HasColumnType("decimal(18,2)"); + + b.HasKey("StatementId", "TransactionId", "ActivityDateTime", "ActivityType"); + + b.ToTable("statementline"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.Summary.SettlementSummary", b => + { + b.Property("ContractProductReportingId") + .HasColumnType("int"); + + b.Property("FeeCount") + .HasColumnType("int"); + + b.Property("FeeValue") + .HasColumnType("decimal(18,2)"); + + b.Property("IsCompleted") + .HasColumnType("bit"); + + b.Property("IsSettled") + .HasColumnType("bit"); + + b.Property("MerchantReportingId") + .HasColumnType("int"); + + b.Property("OperatorReportingId") + .HasColumnType("int"); + + b.Property("SalesCount") + .HasColumnType("int"); + + b.Property("SalesValue") + .HasColumnType("decimal(18,2)"); + + b.Property("SettlementDate") + .HasColumnType("date"); + + b.HasIndex("SettlementDate"); + + SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("SettlementDate")); + + b.HasIndex("SettlementDate", "MerchantReportingId", "OperatorReportingId", "ContractProductReportingId", "IsCompleted", "IsSettled") + .IsUnique(); + + b.ToTable("SettlementSummary"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.Summary.TodayTransaction", b => + { + b.Property("AuthorisationCode") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ContractProductReportingId") + .HasColumnType("int"); + + b.Property("ContractReportingId") + .HasColumnType("int"); + + b.Property("DeviceIdentifier") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Hour") + .HasColumnType("int"); + + b.Property("IsAuthorised") + .HasColumnType("bit"); + + b.Property("IsCompleted") + .HasColumnType("bit"); + + b.Property("MerchantReportingId") + .HasColumnType("int"); + + b.Property("OperatorReportingId") + .HasColumnType("int"); + + b.Property("ResponseCode") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ResponseMessage") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TransactionAmount") + .HasColumnType("decimal(18,2)"); + + b.Property("TransactionDate") + .HasColumnType("date"); + + b.Property("TransactionDateTime") + .HasColumnType("datetime2"); + + b.Property("TransactionId") + .HasColumnType("uniqueidentifier"); + + b.Property("TransactionNumber") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TransactionReference") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TransactionReportingId") + .HasColumnType("int"); + + b.Property("TransactionSource") + .HasColumnType("int"); + + b.Property("TransactionTime") + .HasColumnType("time"); + + b.Property("TransactionType") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasIndex("TransactionDate"); + + SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("TransactionDate")); + + b.HasIndex("TransactionId") + .IsUnique(); + + b.ToTable("TodayTransactions"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.Summary.TransactionHistory", b => + { + b.Property("AuthorisationCode") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ContractProductReportingId") + .HasColumnType("int"); + + b.Property("ContractReportingId") + .HasColumnType("int"); + + b.Property("DeviceIdentifier") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Hour") + .HasColumnType("int"); + + b.Property("IsAuthorised") + .HasColumnType("bit"); + + b.Property("IsCompleted") + .HasColumnType("bit"); + + b.Property("MerchantReportingId") + .HasColumnType("int"); + + b.Property("OperatorReportingId") + .HasColumnType("int"); + + b.Property("ResponseCode") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ResponseMessage") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TransactionAmount") + .HasColumnType("decimal(18,2)"); + + b.Property("TransactionDate") + .HasColumnType("date"); + + b.Property("TransactionDateTime") + .HasColumnType("datetime2"); + + b.Property("TransactionId") + .HasColumnType("uniqueidentifier"); + + b.Property("TransactionNumber") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TransactionReference") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TransactionReportingId") + .HasColumnType("int"); + + b.Property("TransactionSource") + .HasColumnType("int"); + + b.Property("TransactionTime") + .HasColumnType("time"); + + b.Property("TransactionType") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasIndex("TransactionDate"); + + SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("TransactionDate")); + + b.HasIndex("TransactionId") + .IsUnique(); + + b.ToTable("TransactionHistory"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.Transaction", b => + { + b.Property("TransactionReportingId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("TransactionReportingId")); + + b.Property("AuthorisationCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ContractId") + .HasColumnType("uniqueidentifier"); + + b.Property("ContractProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("DeviceIdentifier") + .HasColumnType("nvarchar(max)"); + + b.Property("IsAuthorised") + .HasColumnType("bit"); + + b.Property("IsCompleted") + .HasColumnType("bit"); + + b.Property("MerchantId") + .HasColumnType("uniqueidentifier"); + + b.Property("OperatorId") + .HasColumnType("uniqueidentifier"); + + b.Property("ResponseCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ResponseMessage") + .HasColumnType("nvarchar(max)"); + + b.Property("TransactionAmount") + .HasColumnType("decimal(18,2)"); + + b.Property("TransactionDate") + .HasColumnType("date"); + + b.Property("TransactionDateTime") + .HasColumnType("datetime2"); + + b.Property("TransactionId") + .HasColumnType("uniqueidentifier"); + + b.Property("TransactionNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("TransactionReference") + .HasColumnType("nvarchar(max)"); + + b.Property("TransactionSource") + .HasColumnType("int"); + + b.Property("TransactionTime") + .HasColumnType("time"); + + b.Property("TransactionType") + .HasColumnType("nvarchar(max)"); + + b.HasKey("TransactionReportingId"); + + SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("TransactionReportingId"), false); + + b.HasIndex("TransactionDate"); + + SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("TransactionDate")); + + b.HasIndex("TransactionId") + .IsUnique(); + + SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("TransactionId"), false); + + b.ToTable("transaction"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.TransactionAdditionalRequestData", b => + { + b.Property("TransactionId") + .HasColumnType("uniqueidentifier"); + + b.Property("Amount") + .HasColumnType("nvarchar(max)"); + + b.Property("CustomerAccountNumber") + .HasColumnType("nvarchar(max)"); + + b.HasKey("TransactionId"); + + b.ToTable("transactionadditionalrequestdata"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.TransactionAdditionalResponseData", b => + { + b.Property("TransactionId") + .HasColumnType("uniqueidentifier"); + + b.Property("TransactionReportingId") + .HasColumnType("int"); + + b.HasKey("TransactionId"); + + b.ToTable("transactionadditionalresponsedata"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.TransactionTimings", b => + { + b.Property("TransactionId") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("OperatorCommunicationsCompletedDateTime") + .HasColumnType("datetime2"); + + b.Property("OperatorCommunicationsDurationInMilliseconds") + .HasColumnType("float"); + + b.Property("OperatorCommunicationsStartedDateTime") + .HasColumnType("datetime2"); + + b.Property("TotalTransactionInMilliseconds") + .HasColumnType("float"); + + b.Property("TransactionCompletedDateTime") + .HasColumnType("datetime2"); + + b.Property("TransactionProcessingDurationInMilliseconds") + .HasColumnType("float"); + + b.Property("TransactionStartedDateTime") + .HasColumnType("datetime2"); + + b.HasKey("TransactionId"); + + SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("TransactionId"), false); + + b.ToTable("transactiontimings"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.Entities.VoucherProjectionState", b => + { + b.Property("VoucherId") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Barcode") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("EstateId") + .HasColumnType("uniqueidentifier"); + + b.Property("ExpiryDate") + .HasColumnType("date"); + + b.Property("ExpiryDateTime") + .HasColumnType("datetime2"); + + b.Property("GenerateDate") + .HasColumnType("date"); + + b.Property("GenerateDateTime") + .HasColumnType("datetime2"); + + b.Property("IsGenerated") + .HasColumnType("bit"); + + b.Property("IsIssued") + .HasColumnType("bit"); + + b.Property("IsRedeemed") + .HasColumnType("bit"); + + b.Property("IssuedDate") + .HasColumnType("date"); + + b.Property("IssuedDateTime") + .HasColumnType("datetime2"); + + b.Property("OperatorIdentifier") + .HasColumnType("nvarchar(max)"); + + b.Property("RecipientEmail") + .HasColumnType("nvarchar(max)"); + + b.Property("RecipientMobile") + .HasColumnType("nvarchar(max)"); + + b.Property("RedeemedDate") + .HasColumnType("datetime2"); + + b.Property("RedeemedDateTime") + .HasColumnType("datetime2"); + + b.Property("Timestamp") + .IsConcurrencyToken() + .IsRequired() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("rowversion"); + + b.Property("TransactionId") + .HasColumnType("uniqueidentifier"); + + b.Property("Value") + .HasColumnType("decimal(18,2)"); + + b.Property("VoucherCode") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("VoucherId"); + + b.HasIndex("TransactionId"); + + b.HasIndex("VoucherCode"); + + b.ToTable("voucherprojectionstate"); + }); + + modelBuilder.Entity("TransactionProcessor.Database.ViewEntities.SettlementView", b => + { + b.Property("Amount") + .HasColumnType("decimal(18,2)"); + + b.Property("CalculatedValue") + .HasColumnType("decimal(18,2)"); + + b.Property("DayOfWeek") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("EstateId") + .HasColumnType("uniqueidentifier"); + + b.Property("FeeDescription") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsCompleted") + .HasColumnType("bit"); + + b.Property("IsSettled") + .HasColumnType("bit"); + + b.Property("MerchantId") + .HasColumnType("uniqueidentifier"); + + b.Property("MerchantName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Month") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("MonthNumber") + .HasColumnType("int"); + + b.Property("OperatorIdentifier") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("SettlementDate") + .HasColumnType("datetime2"); + + b.Property("SettlementId") + .HasColumnType("uniqueidentifier"); + + b.Property("TransactionId") + .HasColumnType("uniqueidentifier"); + + b.Property("WeekNumber") + .HasColumnType("int"); + + b.Property("YearNumber") + .HasColumnType("int"); + + b.ToTable((string)null); + + b.ToView("uvwSettlements", (string)null); + }); + + modelBuilder.Entity("TransactionProcessor.ProjectionEngine.Database.Database.Entities.Event", b => + { + b.Property("EventId") + .HasColumnType("uniqueidentifier"); + + b.Property("Type") + .HasColumnType("nvarchar(450)"); + + b.Property("Date") + .HasColumnType("date"); + + b.HasKey("EventId", "Type"); + + SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("EventId", "Type")); + + b.ToTable("Events"); + }); + + modelBuilder.Entity("TransactionProcessor.ProjectionEngine.Database.Database.Entities.MerchantBalanceChangedEntry", b => + { + b.Property("AggregateId") + .HasColumnType("uniqueidentifier"); + + b.Property("OriginalEventId") + .HasColumnType("uniqueidentifier"); + + b.Property("CauseOfChangeId") + .HasColumnType("uniqueidentifier"); + + b.Property("ChangeAmount") + .HasColumnType("decimal(18,2)"); + + b.Property("DateTime") + .HasColumnType("datetime2"); + + b.Property("DebitOrCredit") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("EstateId") + .HasColumnType("uniqueidentifier"); + + b.Property("MerchantId") + .HasColumnType("uniqueidentifier"); + + b.Property("Reference") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("AggregateId", "OriginalEventId"); + + b.ToTable("MerchantBalanceChangedEntry"); + }); + + modelBuilder.Entity("TransactionProcessor.ProjectionEngine.Database.Database.Entities.MerchantBalanceProjectionState", b => + { + b.Property("EstateId") + .HasColumnType("uniqueidentifier"); + + b.Property("MerchantId") + .HasColumnType("uniqueidentifier"); + + b.Property("AuthorisedSales") + .HasColumnType("decimal(18,2)"); + + b.Property("AvailableBalance") + .HasColumnType("decimal(18,2)"); + + b.Property("Balance") + .HasColumnType("decimal(18,2)"); + + b.Property("CompletedTransactionCount") + .HasColumnType("int"); + + b.Property("DeclinedSales") + .HasColumnType("decimal(18,2)"); + + b.Property("DepositCount") + .HasColumnType("int"); + + b.Property("FeeCount") + .HasColumnType("int"); + + b.Property("LastDeposit") + .HasColumnType("datetime2"); + + b.Property("LastFee") + .HasColumnType("datetime2"); + + b.Property("LastSale") + .HasColumnType("datetime2"); + + b.Property("LastWithdrawal") + .HasColumnType("datetime2"); + + b.Property("MerchantName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("SaleCount") + .HasColumnType("int"); + + b.Property("StartedTransactionCount") + .HasColumnType("int"); + + b.Property("Timestamp") + .IsConcurrencyToken() + .IsRequired() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("rowversion"); + + b.Property("TotalDeposited") + .HasColumnType("decimal(18,2)"); + + b.Property("TotalWithdrawn") + .HasColumnType("decimal(18,2)"); + + b.Property("ValueOfFees") + .HasColumnType("decimal(18,2)"); + + b.Property("WithdrawalCount") + .HasColumnType("int"); + + b.HasKey("EstateId", "MerchantId"); + + b.ToTable("MerchantBalanceProjectionState"); + }); + + modelBuilder.Entity("TransactionProcessor.ProjectionEngine.Database.Database.ViewEntities.MerchantBalanceHistoryViewEntry", b => + { + b.Property("Balance") + .HasColumnType("decimal(18,2)"); + + b.Property("ChangeAmount") + .HasColumnType("decimal(18,2)"); + + b.Property("DebitOrCredit") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("EntryDateTime") + .HasColumnType("datetime2"); + + b.Property("MerchantId") + .HasColumnType("uniqueidentifier"); + + b.Property("OriginalEventId") + .HasColumnType("uniqueidentifier"); + + b.Property("Reference") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.ToTable((string)null); + + b.ToView("uvwMerchantBalanceHistory", (string)null); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/TransactionProcessor.Database/Migrations/SqlServer/20260520162516_add_file_import_config_tables.cs b/TransactionProcessor.Database/Migrations/SqlServer/20260520162516_add_file_import_config_tables.cs new file mode 100644 index 00000000..89b2dac3 --- /dev/null +++ b/TransactionProcessor.Database/Migrations/SqlServer/20260520162516_add_file_import_config_tables.cs @@ -0,0 +1,87 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace TransactionProcessor.Database.Migrations.SqlServer +{ + /// + public partial class add_file_import_config_tables : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "FileFormatHandlers", + columns: table => new + { + FileFormatHandlerId = table.Column(type: "uniqueidentifier", nullable: false), + Name = table.Column(type: "nvarchar(450)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_FileFormatHandlers", x => x.FileFormatHandlerId); + }); + + migrationBuilder.CreateTable( + name: "FileProfileConfigurations", + columns: table => new + { + FileProfileId = table.Column(type: "uniqueidentifier", nullable: false), + Name = table.Column(type: "nvarchar(450)", nullable: false), + ListeningDirectory = table.Column(type: "nvarchar(max)", nullable: false), + RequestTypeId = table.Column(type: "uniqueidentifier", nullable: false), + OperatorId = table.Column(type: "uniqueidentifier", nullable: false), + LineTerminator = table.Column(type: "nvarchar(max)", nullable: false), + FileFormatHandlerId = table.Column(type: "uniqueidentifier", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_FileProfileConfigurations", x => x.FileProfileId); + }); + + migrationBuilder.CreateTable( + name: "RequestTypes", + columns: table => new + { + RequestTypeId = table.Column(type: "uniqueidentifier", nullable: false), + Name = table.Column(type: "nvarchar(450)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_RequestTypes", x => x.RequestTypeId); + }); + + migrationBuilder.CreateIndex( + name: "IX_FileFormatHandlers_Name", + table: "FileFormatHandlers", + column: "Name", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_FileProfileConfigurations_Name", + table: "FileProfileConfigurations", + column: "Name", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_RequestTypes_Name", + table: "RequestTypes", + column: "Name", + unique: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "FileFormatHandlers"); + + migrationBuilder.DropTable( + name: "FileProfileConfigurations"); + + migrationBuilder.DropTable( + name: "RequestTypes"); + } + } +} diff --git a/TransactionProcessor.Database/Migrations/SqlServer/EstateManagementSqlServerContextModelSnapshot.cs b/TransactionProcessor.Database/Migrations/SqlServer/EstateManagementSqlServerContextModelSnapshot.cs index 497b3654..79fbcbe7 100644 --- a/TransactionProcessor.Database/Migrations/SqlServer/EstateManagementSqlServerContextModelSnapshot.cs +++ b/TransactionProcessor.Database/Migrations/SqlServer/EstateManagementSqlServerContextModelSnapshot.cs @@ -17,7 +17,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "10.0.3") + .HasAnnotation("ProductVersion", "10.0.8") .HasAnnotation("Relational:MaxIdentifierLength", 128); SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); @@ -280,6 +280,24 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("file"); }); + modelBuilder.Entity("TransactionProcessor.Database.Entities.FileFormatHandler", b => + { + b.Property("FileFormatHandlerId") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("FileFormatHandlerId"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("FileFormatHandlers"); + }); + modelBuilder.Entity("TransactionProcessor.Database.Entities.FileImportLog", b => { b.Property("EstateId") @@ -370,6 +388,41 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("fileline"); }); + modelBuilder.Entity("TransactionProcessor.Database.Entities.FileProfileConfiguration", b => + { + b.Property("FileProfileId") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("FileFormatHandlerId") + .HasColumnType("uniqueidentifier"); + + b.Property("LineTerminator") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ListeningDirectory") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.Property("OperatorId") + .HasColumnType("uniqueidentifier"); + + b.Property("RequestTypeId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("FileProfileId"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("FileProfileConfigurations"); + }); + modelBuilder.Entity("TransactionProcessor.Database.Entities.Float", b => { b.Property("FloatId") @@ -641,6 +694,32 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("merchantopeninghours"); }); + modelBuilder.Entity("TransactionProcessor.Database.Entities.MerchantOperator", b => + { + b.Property("MerchantId") + .HasColumnType("uniqueidentifier"); + + b.Property("OperatorId") + .HasColumnType("uniqueidentifier"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("MerchantNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TerminalNumber") + .HasColumnType("nvarchar(max)"); + + b.HasKey("MerchantId", "OperatorId"); + + b.ToTable("merchantoperator"); + }); + modelBuilder.Entity("TransactionProcessor.Database.Entities.MerchantSchedule", b => { b.Property("MerchantScheduleId") @@ -681,32 +760,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("merchantschedulemonth"); }); - modelBuilder.Entity("TransactionProcessor.Database.Entities.MerchantOperator", b => - { - b.Property("MerchantId") - .HasColumnType("uniqueidentifier"); - - b.Property("OperatorId") - .HasColumnType("uniqueidentifier"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("MerchantNumber") - .HasColumnType("nvarchar(max)"); - - b.Property("Name") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("TerminalNumber") - .HasColumnType("nvarchar(max)"); - - b.HasKey("MerchantId", "OperatorId"); - - b.ToTable("merchantoperator"); - }); - modelBuilder.Entity("TransactionProcessor.Database.Entities.MerchantSecurityUser", b => { b.Property("MerchantId") @@ -850,6 +903,24 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("reconciliation"); }); + modelBuilder.Entity("TransactionProcessor.Database.Entities.RequestType", b => + { + b.Property("RequestTypeId") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("RequestTypeId"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("RequestTypes"); + }); + modelBuilder.Entity("TransactionProcessor.Database.Entities.ResponseCodes", b => { b.Property("ResponseCode") diff --git a/TransactionProcessor.Database/TransactionProcessor.Database.csproj b/TransactionProcessor.Database/TransactionProcessor.Database.csproj index 22c8404b..efe69bd2 100644 --- a/TransactionProcessor.Database/TransactionProcessor.Database.csproj +++ b/TransactionProcessor.Database/TransactionProcessor.Database.csproj @@ -8,22 +8,22 @@ - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + - + - - - + + + diff --git a/TransactionProcessor.DatabaseTests/TransactionProcessor.DatabaseTests.csproj b/TransactionProcessor.DatabaseTests/TransactionProcessor.DatabaseTests.csproj index d4bfb49c..c4111a20 100644 --- a/TransactionProcessor.DatabaseTests/TransactionProcessor.DatabaseTests.csproj +++ b/TransactionProcessor.DatabaseTests/TransactionProcessor.DatabaseTests.csproj @@ -9,14 +9,18 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + + + + + all diff --git a/TransactionProcessor.IntegrationTesting.Helpers/TransactionProcessor.IntegrationTesting.Helpers.csproj b/TransactionProcessor.IntegrationTesting.Helpers/TransactionProcessor.IntegrationTesting.Helpers.csproj index 45a61f27..a7ed24a6 100644 --- a/TransactionProcessor.IntegrationTesting.Helpers/TransactionProcessor.IntegrationTesting.Helpers.csproj +++ b/TransactionProcessor.IntegrationTesting.Helpers/TransactionProcessor.IntegrationTesting.Helpers.csproj @@ -10,11 +10,11 @@ - - + + - - + + diff --git a/TransactionProcessor.IntegrationTests/TransactionProcessor.IntegrationTests.csproj b/TransactionProcessor.IntegrationTests/TransactionProcessor.IntegrationTests.csproj index 1775968b..5b4c8cbd 100644 --- a/TransactionProcessor.IntegrationTests/TransactionProcessor.IntegrationTests.csproj +++ b/TransactionProcessor.IntegrationTests/TransactionProcessor.IntegrationTests.csproj @@ -11,27 +11,31 @@ - - - - + + + + + + + - - - - - - + + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive + - - + + diff --git a/TransactionProcessor.ProjectionEngine.Tests/TransactionProcessor.ProjectionEngine.Tests.csproj b/TransactionProcessor.ProjectionEngine.Tests/TransactionProcessor.ProjectionEngine.Tests.csproj index 625b20f7..de406563 100644 --- a/TransactionProcessor.ProjectionEngine.Tests/TransactionProcessor.ProjectionEngine.Tests.csproj +++ b/TransactionProcessor.ProjectionEngine.Tests/TransactionProcessor.ProjectionEngine.Tests.csproj @@ -9,12 +9,13 @@ - - - - - + + + + + + @@ -22,7 +23,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/TransactionProcessor.ProjectionEngine/TransactionProcessor.ProjectionEngine.csproj b/TransactionProcessor.ProjectionEngine/TransactionProcessor.ProjectionEngine.csproj index 0005c5bc..45858a8f 100644 --- a/TransactionProcessor.ProjectionEngine/TransactionProcessor.ProjectionEngine.csproj +++ b/TransactionProcessor.ProjectionEngine/TransactionProcessor.ProjectionEngine.csproj @@ -9,9 +9,10 @@ - - - + + + + diff --git a/TransactionProcessor.Repository/TransactionProcessor.Repository.csproj b/TransactionProcessor.Repository/TransactionProcessor.Repository.csproj index 684f8444..ee29f9ae 100644 --- a/TransactionProcessor.Repository/TransactionProcessor.Repository.csproj +++ b/TransactionProcessor.Repository/TransactionProcessor.Repository.csproj @@ -10,14 +10,15 @@ - - - - + + + + + - - + + diff --git a/TransactionProcessor.Testing/TransactionProcessor.Testing.csproj b/TransactionProcessor.Testing/TransactionProcessor.Testing.csproj index 84ec864b..01372deb 100644 --- a/TransactionProcessor.Testing/TransactionProcessor.Testing.csproj +++ b/TransactionProcessor.Testing/TransactionProcessor.Testing.csproj @@ -8,11 +8,15 @@ - + + + + + - - + + diff --git a/TransactionProcessor.Tests/TransactionProcessor.Tests.csproj b/TransactionProcessor.Tests/TransactionProcessor.Tests.csproj index cddf9111..5c23316b 100644 --- a/TransactionProcessor.Tests/TransactionProcessor.Tests.csproj +++ b/TransactionProcessor.Tests/TransactionProcessor.Tests.csproj @@ -8,17 +8,21 @@ - - - - - + + + + + + + + + - - + + @@ -26,7 +30,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/TransactionProcessor/TransactionProcessor.csproj b/TransactionProcessor/TransactionProcessor.csproj index 7041c389..d2c86a62 100644 --- a/TransactionProcessor/TransactionProcessor.csproj +++ b/TransactionProcessor/TransactionProcessor.csproj @@ -10,8 +10,10 @@ - - + + + + @@ -19,34 +21,35 @@ - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + + - + - - + + - - - + + + - - - + + + From 676856f03d7ff9260a50ec6172ef1053b6ecf554 Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Wed, 20 May 2026 18:40:45 +0100 Subject: [PATCH 2/2] fix test failures from PR --- .../Contexts/EstateManagementGenericContext.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/TransactionProcessor.Database/Contexts/EstateManagementGenericContext.cs b/TransactionProcessor.Database/Contexts/EstateManagementGenericContext.cs index f93e12fa..ac47dfd8 100644 --- a/TransactionProcessor.Database/Contexts/EstateManagementGenericContext.cs +++ b/TransactionProcessor.Database/Contexts/EstateManagementGenericContext.cs @@ -401,7 +401,11 @@ private static String BuildUniqueConstraintExceptionLogMessage(UniqueConstraintE if (uex.ConstraintProperties != null) { constraintProperties = String.Join(",", uex.ConstraintProperties); } - return $"Unique Constraint Exception. Message [{uex.Message}] Inner Exception [{uex.InnerException.Message}]"; + + return uex.InnerException switch { + null => $"Unique Constraint Exception. Message [{uex.Message}] Constraint Name [{constraintName}] Constraint Properties [{constraintProperties}]", + _ => $"Unique Constraint Exception. Message [{uex.Message}] Inner Exception [{uex.InnerException.Message}]" + }; }