diff --git a/LiteCharms.Features.MidrandBooks/Enums.cs b/LiteCharms.Features.MidrandBooks/Enums.cs deleted file mode 100644 index b3325c2..0000000 --- a/LiteCharms.Features.MidrandBooks/Enums.cs +++ /dev/null @@ -1,62 +0,0 @@ -namespace LiteCharms.Features.MidrandBooks; - -public enum PublisherTypes : int -{ - Individual = 0, - Company = 1, - Organization = 2, - SelfPublished = 3, - UniversityPress = 4, - GovernmentAgency = 5, - NonProfit = 6, - Independent = 7 -} - -public enum BookTypes : int -{ - Fiction = 0, - NonFiction = 1, - Academic = 2, - SelfHelp = 3, - Biography = 4, - Poetry = 5, - Children = 6, - YoungAdult = 7, - ScienceFiction = 8, - Fantasy = 9 -} - -public enum BookContentTypes : int -{ - Text = 0, - Image = 1, - Video = 2, - Audio = 3, - Interactive = 4, - Markdown = 5, - Html = 6, - Json = 7, - Yaml = 8 -} - -public enum BookPageTypes : int -{ - Cover = 0, - Preface = 1, - Introduction = 2, - Content = 3, - Closing = 4, - Referencer = 5, - Credits = 6, - BackCover = 7 -} - -public enum ProductTypes : int -{ - Book = 1, - Journal = 2, - Magazine = 3, - EBook = 4, - Audiobook = 5, - Accessory = 6 -} diff --git a/LiteCharms.Features.MidrandBooks/Extensions/Mappers.cs b/LiteCharms.Features.MidrandBooks/Extensions/Mappers.cs index 1a81b74..0380370 100644 --- a/LiteCharms.Features.MidrandBooks/Extensions/Mappers.cs +++ b/LiteCharms.Features.MidrandBooks/Extensions/Mappers.cs @@ -4,12 +4,61 @@ using LiteCharms.Features.MidrandBooks.Categories.Models; using LiteCharms.Features.MidrandBooks.Customers.Models; using LiteCharms.Features.MidrandBooks.Orders.Models; using LiteCharms.Features.MidrandBooks.Pages.Models; +using LiteCharms.Features.MidrandBooks.Payments.Models; using LiteCharms.Features.MidrandBooks.Products.Models; namespace LiteCharms.Features.MidrandBooks.Extensions; public static class Mappers { + public static PaymentLedger ToModel(this Payments.Entities.PaymentLedger entity) => new() + { + Id = entity.Id, + CreatedAt = entity.CreatedAt, + CustomerId = entity.CustomerId, + OrderId = entity.OrderId, + PaymentGatewayId = entity.PaymentGatewayId, + PaymentGatewayReference = entity.PaymentGatewayReference, + PaymentId = entity.PaymentId, + Status = entity.Status, + }; + + public static PaymentGateway ToModel(this Payments.Entities.PaymentGateway entity) => new() + { + Id = entity.Id, + CreatedAt = entity.CreatedAt, + UpdatedAt = entity.UpdatedAt, + Enabled = entity.Enabled, + IsSandbox = entity.IsSandbox, + MerchantId = entity.MerchantId, + MerchantKey = entity.MerchantKey, + Name = entity.Name, + Passphrase = entity.Passphrase, + Website = entity.Website, + }; + + public static Payment ToModel(this Payments.Entities.Payment entity) => new() + { + Id = entity.Id, + Amount = entity.Amount, + CreatedAt = entity.CreatedAt, + OrderId = entity.OrderId, + Reference = entity.Reference, + Status = entity.Status, + UpdatedAt = entity.UpdatedAt, + }; + + public static ProductInventory ToModel(this Products.Entities.ProductInventory entity) => new() + { + Id = entity.Id, + CreatedAt = entity.CreatedAt, + ProductId = entity.ProductId, + ProductPriceId = entity.ProductPriceId, + Status = entity.Status, + TotalAllocated = entity.TotalAllocated, + TotalReserved = entity.TotalReserved, + }; + public static Category ToModel(this Categories.Entities.Category entity) => new() { Id = entity.Id, diff --git a/LiteCharms.Features.MidrandBooks/Payments/Entities/Payment.cs b/LiteCharms.Features.MidrandBooks/Payments/Entities/Payment.cs new file mode 100644 index 0000000..69e5fcb --- /dev/null +++ b/LiteCharms.Features.MidrandBooks/Payments/Entities/Payment.cs @@ -0,0 +1,9 @@ +using LiteCharms.Features.MidrandBooks.Orders.Entities; + +namespace LiteCharms.Features.MidrandBooks.Payments.Entities; + +[EntityTypeConfiguration] +public class Payment : Models.Payment +{ + public virtual Order? Order { get; set; } +} diff --git a/LiteCharms.Features.MidrandBooks/Payments/Entities/PaymentConfiguration.cs b/LiteCharms.Features.MidrandBooks/Payments/Entities/PaymentConfiguration.cs new file mode 100644 index 0000000..d1f32ef --- /dev/null +++ b/LiteCharms.Features.MidrandBooks/Payments/Entities/PaymentConfiguration.cs @@ -0,0 +1,22 @@ +namespace LiteCharms.Features.MidrandBooks.Payments.Entities; + +public sealed class PaymentConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("Payments"); + + builder.HasKey(f => f.Id); + builder.Property(f => f.CreatedAt).IsRequired().ValueGeneratedOnAdd().HasDefaultValueSql("now()"); + builder.Property(f => f.UpdatedAt); + builder.Property(f => f.Status).IsRequired(); + builder.Property(f => f.Reference).IsRequired(); + builder.Property(f => f.OrderId).IsRequired(); + builder.Property(f => f.Amount).IsRequired().HasPrecision(18, 2); + + builder.HasOne(f => f.Order) + .WithMany() + .HasForeignKey(f => f.OrderId) + .OnDelete(DeleteBehavior.Restrict); + } +} diff --git a/LiteCharms.Features.MidrandBooks/Payments/Entities/PaymentGateway.cs b/LiteCharms.Features.MidrandBooks/Payments/Entities/PaymentGateway.cs new file mode 100644 index 0000000..cf47bf9 --- /dev/null +++ b/LiteCharms.Features.MidrandBooks/Payments/Entities/PaymentGateway.cs @@ -0,0 +1,4 @@ +namespace LiteCharms.Features.MidrandBooks.Payments.Entities; + +[EntityTypeConfiguration] +public class PaymentGateway : Models.PaymentGateway; diff --git a/LiteCharms.Features.MidrandBooks/Payments/Entities/PaymentGatewayConfiguration.cs b/LiteCharms.Features.MidrandBooks/Payments/Entities/PaymentGatewayConfiguration.cs new file mode 100644 index 0000000..adfb8a5 --- /dev/null +++ b/LiteCharms.Features.MidrandBooks/Payments/Entities/PaymentGatewayConfiguration.cs @@ -0,0 +1,20 @@ +namespace LiteCharms.Features.MidrandBooks.Payments.Entities; + +public sealed class PaymentGatewayConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("Gateways"); + + builder.HasKey(f => f.Id); + builder.Property(f => f.CreatedAt).IsRequired().ValueGeneratedOnAdd().HasDefaultValueSql("now()"); + builder.Property(f => f.UpdatedAt); + builder.Property(f => f.Website).IsRequired(false); + builder.Property(f => f.IsSandbox); + builder.Property(f => f.MerchantKey).IsRequired(); + builder.Property(f => f.MerchantId).IsRequired(); + builder.Property(f => f.Enabled); + builder.Property(f => f.Name).IsRequired(); + builder.Property(f => f.Passphrase).IsRequired(); + } +} diff --git a/LiteCharms.Features.MidrandBooks/Payments/Entities/PaymentLedger.cs b/LiteCharms.Features.MidrandBooks/Payments/Entities/PaymentLedger.cs new file mode 100644 index 0000000..3bba78b --- /dev/null +++ b/LiteCharms.Features.MidrandBooks/Payments/Entities/PaymentLedger.cs @@ -0,0 +1,16 @@ +using LiteCharms.Features.MidrandBooks.Customers.Entities; +using LiteCharms.Features.MidrandBooks.Orders.Entities; + +namespace LiteCharms.Features.MidrandBooks.Payments.Entities; + +[EntityTypeConfiguration] +public class PaymentLedger : Models.PaymentLedger +{ + public virtual Payment? Payment { get; set; } + + public virtual Order? Order { get; set; } + + public virtual Customer? Customer { get; set; } + + public virtual PaymentGateway? Gateway { get; set; } +} diff --git a/LiteCharms.Features.MidrandBooks/Payments/Entities/PaymentLedgerConfiguration.cs b/LiteCharms.Features.MidrandBooks/Payments/Entities/PaymentLedgerConfiguration.cs new file mode 100644 index 0000000..0e51655 --- /dev/null +++ b/LiteCharms.Features.MidrandBooks/Payments/Entities/PaymentLedgerConfiguration.cs @@ -0,0 +1,41 @@ +namespace LiteCharms.Features.MidrandBooks.Payments.Entities; + +public sealed class PaymentLedgerConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("Ledger"); + + builder.HasKey(f => f.Id); + builder.Property(f => f.CreatedAt).IsRequired().ValueGeneratedOnAdd().HasDefaultValueSql("now()"); + builder.Property(f => f.Status).IsRequired(); + builder.Property(f => f.PaymentGatewayReference).IsRequired(false); + builder.Property(f => f.PaymentGatewayId).IsRequired(false); + builder.Property(f => f.OrderId).IsRequired(); + builder.Property(f => f.CustomerId).IsRequired(); + builder.Property(f => f.PaymentId).IsRequired(); + + builder.HasOne(f => f.Payment) + .WithMany() + .IsRequired() + .HasForeignKey(f => f.PaymentId) + .OnDelete(DeleteBehavior.Cascade); + + builder.HasOne(f => f.Order) + .WithMany() + .IsRequired() + .HasForeignKey(f => f.OrderId) + .OnDelete(DeleteBehavior.Cascade); + + builder.HasOne(f => f.Customer) + .WithMany() + .IsRequired() + .HasForeignKey(f => f.CustomerId); + + builder.HasOne(f => f.Gateway) + .WithMany() + .IsRequired(false) + .HasForeignKey(f => f.PaymentGatewayId) + .OnDelete(DeleteBehavior.Cascade); + } +} diff --git a/LiteCharms.Features.MidrandBooks/Payments/Models/Payment.cs b/LiteCharms.Features.MidrandBooks/Payments/Models/Payment.cs new file mode 100644 index 0000000..61c22eb --- /dev/null +++ b/LiteCharms.Features.MidrandBooks/Payments/Models/Payment.cs @@ -0,0 +1,18 @@ +namespace LiteCharms.Features.MidrandBooks.Payments.Models; + +public class Payment +{ + public long Id { get; set; } + + public DateTime CreatedAt { get; set; } + + public DateTime? UpdatedAt { get; set; } + + public decimal Amount { get; set; } + + public long OrderId { get; set; } + + public string? Reference { get; set; } + + public PaymentStatuses Status { get; set; } +} diff --git a/LiteCharms.Features.MidrandBooks/Payments/Models/PaymentGateway.cs b/LiteCharms.Features.MidrandBooks/Payments/Models/PaymentGateway.cs new file mode 100644 index 0000000..bdb8a69 --- /dev/null +++ b/LiteCharms.Features.MidrandBooks/Payments/Models/PaymentGateway.cs @@ -0,0 +1,24 @@ +namespace LiteCharms.Features.MidrandBooks.Payments.Models; + +public class PaymentGateway +{ + public long Id { get; set; } + + public DateTime CreatedAt { get; set; } + + public DateTime? UpdatedAt { get; set; } + + public string? Name { get; set; } + + public string? Website { get; set; } + + public string? MerchantId { get; set; } + + public string? MerchantKey { get; set; } + + public string? Passphrase { get; set; } + + public bool IsSandbox { get; set; } + + public bool Enabled { get; set; } +} diff --git a/LiteCharms.Features.MidrandBooks/Payments/Models/PaymentLedger.cs b/LiteCharms.Features.MidrandBooks/Payments/Models/PaymentLedger.cs new file mode 100644 index 0000000..33f3d25 --- /dev/null +++ b/LiteCharms.Features.MidrandBooks/Payments/Models/PaymentLedger.cs @@ -0,0 +1,20 @@ +namespace LiteCharms.Features.MidrandBooks.Payments.Models; + +public class PaymentLedger +{ + public long Id { get; set; } + + public DateTime CreatedAt { get; set; } + + public LedgerStatuses Status { get; set; } + + public long OrderId { get; set; } + + public long PaymentId { get; set; } + + public long CustomerId { get; set; } + + public string? PaymentGatewayReference { get; set; } + + public long? PaymentGatewayId { get; set; } +} diff --git a/LiteCharms.Features.MidrandBooks/Postgres/MidrandBooksDbContext.cs b/LiteCharms.Features.MidrandBooks/Postgres/MidrandBooksDbContext.cs index 782bb1f..3d0b380 100644 --- a/LiteCharms.Features.MidrandBooks/Postgres/MidrandBooksDbContext.cs +++ b/LiteCharms.Features.MidrandBooks/Postgres/MidrandBooksDbContext.cs @@ -40,4 +40,12 @@ public sealed class MidrandBooksDbContext(DbContextOptions Categories => Set(); public DbSet ProductCategories => Set(); + + public DbSet Inventories => Set(); + + public DbSet Payments => Set(); + + public DbSet Gateways => Set(); + + public DbSet Ledger => Set(); } diff --git a/LiteCharms.Features.MidrandBooks/Postgres/Migrations/20260531094401_AddedPaymentObjects.Designer.cs b/LiteCharms.Features.MidrandBooks/Postgres/Migrations/20260531094401_AddedPaymentObjects.Designer.cs new file mode 100644 index 0000000..9bdf38e --- /dev/null +++ b/LiteCharms.Features.MidrandBooks/Postgres/Migrations/20260531094401_AddedPaymentObjects.Designer.cs @@ -0,0 +1,1235 @@ +// +using System; +using LiteCharms.Features.MidrandBooks.Postgres; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace LiteCharms.Features.MidrandBooks.Postgres.Migrations +{ + [DbContext(typeof(MidrandBooksDbContext))] + [Migration("20260531094401_AddedPaymentObjects")] + partial class AddedPaymentObjects + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.8") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.AuthorBooks.Entities.AuthorBook", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AuthorId") + .HasColumnType("bigint"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Enabled") + .HasColumnType("boolean"); + + b.Property("ProductId") + .HasColumnType("bigint"); + + b.Property("Ranking") + .HasColumnType("integer"); + + b.Property("Rating") + .HasColumnType("integer"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("AuthorId"); + + b.HasIndex("ProductId"); + + b.ToTable("Books"); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Authors.Entities.Author", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Biography") + .HasMaxLength(2048) + .HasColumnType("character varying(2048)"); + + b.Property("Company") + .HasColumnType("text"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("character varying(512)"); + + b.Property("Enabled") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(true); + + b.Property("ImageUrl") + .IsRequired() + .HasMaxLength(2048) + .HasColumnType("character varying(2048)"); + + b.Property("LastName") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.Property("PublisherType") + .HasColumnType("integer"); + + b.Property("ThumbnailImageUrl") + .HasMaxLength(2048) + .HasColumnType("character varying(2048)"); + + b.Property("UpdatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("VatNumber") + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.Property("Website") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.HasKey("Id"); + + b.ToTable("Authors", (string)null); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Categories.Entities.Category", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Enabled") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(true); + + b.Property("IsMain") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.Property("Name") + .IsRequired() + .HasMaxLength(15) + .HasColumnType("character varying(15)"); + + b.HasKey("Id"); + + b.ToTable("Categories", (string)null); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Customers.Entities.Address", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BuildingType") + .HasColumnType("integer"); + + b.Property("City") + .IsRequired() + .HasColumnType("text"); + + b.Property("Country") + .IsRequired() + .HasColumnType("text"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("CustomerId") + .HasColumnType("bigint"); + + b.Property("Enabled") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(true); + + b.Property("IsPrimary") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("PostalCode") + .IsRequired() + .HasColumnType("text"); + + b.Property("State") + .IsRequired() + .HasColumnType("text"); + + b.Property("Street") + .IsRequired() + .HasColumnType("text"); + + b.Property("Type") + .HasColumnType("integer"); + + b.Property("UpdatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.HasKey("Id"); + + b.HasIndex("CustomerId"); + + b.ToTable("Addresses", (string)null); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Customers.Entities.Contact", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("CustomerId") + .HasColumnType("bigint"); + + b.Property("Email") + .IsRequired() + .HasColumnType("text"); + + b.Property("Enabled") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(true); + + b.Property("IsPrimary") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.Property("LastName") + .IsRequired() + .HasColumnType("text"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("Phone") + .IsRequired() + .HasColumnType("text"); + + b.Property("Type") + .HasColumnType("integer"); + + b.Property("UpdatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.HasKey("Id"); + + b.HasIndex("CustomerId"); + + b.ToTable("Contacts", (string)null); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Customers.Entities.Customer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Company") + .HasColumnType("text"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("Email") + .IsRequired() + .HasColumnType("text"); + + b.Property("Enabled") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(true); + + b.Property("Phone") + .IsRequired() + .HasColumnType("text"); + + b.Property("UpdatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("VatNumber") + .HasColumnType("text"); + + b.Property("Website") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Customers", (string)null); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Orders.Entities.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("CustomerId") + .HasColumnType("bigint"); + + b.Property("InvoiceUrl") + .HasColumnType("text"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("Total") + .HasPrecision(18, 2) + .HasColumnType("numeric(18,2)"); + + b.Property("UpdatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.HasKey("Id"); + + b.ToTable("Orders", (string)null); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Orders.Entities.OrderItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AuthorBookId") + .HasColumnType("bigint"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("OrderId") + .HasColumnType("bigint"); + + b.Property("ProductPriceId") + .HasColumnType("bigint"); + + b.Property("Quantity") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AuthorBookId"); + + b.HasIndex("OrderId"); + + b.HasIndex("ProductPriceId"); + + b.ToTable("OrderItems", (string)null); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Orders.Entities.Shipping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AddressId") + .HasColumnType("bigint"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("OrderId") + .HasColumnType("bigint"); + + b.Property("ShippingProviderId") + .HasColumnType("bigint"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("TrackingNumber") + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.Property("UpdatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.HasKey("Id"); + + b.HasIndex("AddressId"); + + b.HasIndex("OrderId") + .IsUnique(); + + b.HasIndex("ShippingProviderId"); + + b.ToTable("Shippings", (string)null); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Orders.Entities.ShippingProvider", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Enabled") + .HasColumnType("boolean"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("Price") + .HasColumnType("numeric"); + + b.Property("TrackingUrl") + .HasColumnType("text"); + + b.Property("Type") + .HasColumnType("integer"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("ShippingProviders"); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Pages.Entities.BookPage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AuthorBookId") + .HasColumnType("bigint"); + + b.Property("Content") + .IsRequired() + .HasColumnType("bytea"); + + b.Property("ContentType") + .HasColumnType("integer"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("Enabled") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(true); + + b.PrimitiveCollection("Notes") + .HasColumnType("text[]"); + + b.Property("Number") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValue(0); + + b.Property("Type") + .HasColumnType("integer"); + + b.Property("UpdatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.HasKey("Id"); + + b.HasIndex("AuthorBookId"); + + b.ToTable("BookPages", (string)null); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Payments.Entities.Payment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Amount") + .HasPrecision(18, 2) + .HasColumnType("numeric(18,2)"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("OrderId") + .HasColumnType("bigint"); + + b.Property("Reference") + .IsRequired() + .HasColumnType("text"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("Payments", (string)null); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Payments.Entities.PaymentGateway", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("Enabled") + .HasColumnType("boolean"); + + b.Property("IsSandbox") + .HasColumnType("boolean"); + + b.Property("MerchantId") + .IsRequired() + .HasColumnType("text"); + + b.Property("MerchantKey") + .IsRequired() + .HasColumnType("text"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("Passphrase") + .IsRequired() + .HasColumnType("text"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Website") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Gateways", (string)null); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Payments.Entities.PaymentLedger", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("CustomerId") + .HasColumnType("bigint"); + + b.Property("OrderId") + .HasColumnType("bigint"); + + b.Property("PaymentGatewayId") + .HasColumnType("bigint"); + + b.Property("PaymentGatewayReference") + .HasColumnType("text"); + + b.Property("PaymentId") + .HasColumnType("bigint"); + + b.Property("Status") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("CustomerId"); + + b.HasIndex("OrderId"); + + b.HasIndex("PaymentGatewayId"); + + b.HasIndex("PaymentId"); + + b.ToTable("Ledger", (string)null); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Payments.Entities.Refund", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Amount") + .HasPrecision(18, 2) + .HasColumnType("numeric(18,2)"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("OrderId") + .HasColumnType("bigint"); + + b.Property("Reason") + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("Type") + .HasColumnType("integer"); + + b.Property("UpdatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("Refunds", (string)null); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Products.Entities.Product", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("Description") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("Enabled") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.Property("ImageUrl") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.Property("Summary") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("character varying(512)"); + + b.PrimitiveCollection("ThumbnailUrls") + .HasColumnType("text[]"); + + b.Property("Type") + .HasColumnType("integer"); + + b.Property("UpdatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.HasKey("Id"); + + b.ToTable("Products", (string)null); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Products.Entities.ProductCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CategoryId") + .HasColumnType("bigint"); + + b.Property("ProductId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("CategoryId"); + + b.HasIndex("ProductId"); + + b.ToTable("ProductCategories", (string)null); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Products.Entities.ProductInventory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("ProductId") + .HasColumnType("bigint"); + + b.Property("ProductPriceId") + .HasColumnType("bigint"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("TotalAllocated") + .HasColumnType("integer"); + + b.Property("TotalReserved") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ProductId"); + + b.HasIndex("ProductPriceId"); + + b.ToTable("Inventories", (string)null); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Products.Entities.ProductPrice", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Amount") + .HasPrecision(18, 2) + .HasColumnType("numeric(18,2)"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("Discount") + .HasPrecision(18, 2) + .HasColumnType("numeric(18,2)"); + + b.Property("Enabled") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.Property("ProductId") + .HasColumnType("bigint"); + + b.Property("UpdatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.HasKey("Id"); + + b.HasIndex("ProductId"); + + b.ToTable("Prices", (string)null); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.AuthorBooks.Entities.AuthorBook", b => + { + b.HasOne("LiteCharms.Features.MidrandBooks.Authors.Entities.Author", "Author") + .WithMany("Books") + .HasForeignKey("AuthorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("LiteCharms.Features.MidrandBooks.Products.Entities.Product", "Product") + .WithMany() + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Author"); + + b.Navigation("Product"); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Authors.Entities.Author", b => + { + b.OwnsMany("LiteCharms.Features.Models.SocialMedia", "SocialMedia", b1 => + { + b1.Property("AuthorId"); + + b1.Property("__synthesizedOrdinal") + .ValueGeneratedOnAdd(); + + b1.Property("ImageUrl"); + + b1.Property("Name"); + + b1.Property("Type"); + + b1.Property("Url"); + + b1.HasKey("AuthorId", "__synthesizedOrdinal"); + + b1.ToTable("Authors"); + + b1 + .ToJson("SocialMedia") + .HasColumnType("jsonb"); + + b1.WithOwner() + .HasForeignKey("AuthorId"); + }); + + b.Navigation("SocialMedia"); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Customers.Entities.Address", b => + { + b.HasOne("LiteCharms.Features.MidrandBooks.Customers.Entities.Customer", "Customer") + .WithMany("Addresses") + .HasForeignKey("CustomerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Customer"); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Customers.Entities.Contact", b => + { + b.HasOne("LiteCharms.Features.MidrandBooks.Customers.Entities.Customer", "Customer") + .WithMany("Contacts") + .HasForeignKey("CustomerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Customer"); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Customers.Entities.Customer", b => + { + b.OwnsMany("LiteCharms.Features.Models.SocialMedia", "SocialMedia", b1 => + { + b1.Property("CustomerId"); + + b1.Property("__synthesizedOrdinal") + .ValueGeneratedOnAdd(); + + b1.Property("ImageUrl"); + + b1.Property("Name"); + + b1.Property("Type"); + + b1.Property("Url"); + + b1.HasKey("CustomerId", "__synthesizedOrdinal"); + + b1.ToTable("Customers"); + + b1 + .ToJson("SocialMedia") + .HasColumnType("jsonb"); + + b1.WithOwner() + .HasForeignKey("CustomerId"); + }); + + b.Navigation("SocialMedia"); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Orders.Entities.OrderItem", b => + { + b.HasOne("LiteCharms.Features.MidrandBooks.AuthorBooks.Entities.AuthorBook", "AuthorBook") + .WithMany() + .HasForeignKey("AuthorBookId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("LiteCharms.Features.MidrandBooks.Orders.Entities.Order", "Order") + .WithMany("OrderItems") + .HasForeignKey("OrderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("LiteCharms.Features.MidrandBooks.Products.Entities.ProductPrice", "ProductPrice") + .WithMany() + .HasForeignKey("ProductPriceId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("AuthorBook"); + + b.Navigation("Order"); + + b.Navigation("ProductPrice"); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Orders.Entities.Shipping", b => + { + b.HasOne("LiteCharms.Features.MidrandBooks.Customers.Entities.Address", "Address") + .WithMany() + .HasForeignKey("AddressId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("LiteCharms.Features.MidrandBooks.Orders.Entities.Order", "Order") + .WithOne("Shipping") + .HasForeignKey("LiteCharms.Features.MidrandBooks.Orders.Entities.Shipping", "OrderId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("LiteCharms.Features.MidrandBooks.Orders.Entities.ShippingProvider", "ShippingProvider") + .WithMany("Shippings") + .HasForeignKey("ShippingProviderId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Address"); + + b.Navigation("Order"); + + b.Navigation("ShippingProvider"); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Pages.Entities.BookPage", b => + { + b.HasOne("LiteCharms.Features.MidrandBooks.AuthorBooks.Entities.AuthorBook", "Book") + .WithMany("Pages") + .HasForeignKey("AuthorBookId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.OwnsMany("LiteCharms.Features.Models.PageReference", "References", b1 => + { + b1.Property("BookPageId"); + + b1.Property("__synthesizedOrdinal") + .ValueGeneratedOnAdd(); + + b1.Property("Description"); + + b1.Property("Tag"); + + b1.Property("Url"); + + b1.HasKey("BookPageId", "__synthesizedOrdinal"); + + b1.ToTable("BookPages"); + + b1 + .ToJson("References") + .HasColumnType("jsonb"); + + b1.WithOwner() + .HasForeignKey("BookPageId"); + }); + + b.Navigation("Book"); + + b.Navigation("References"); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Payments.Entities.Payment", b => + { + b.HasOne("LiteCharms.Features.MidrandBooks.Orders.Entities.Order", "Order") + .WithMany() + .HasForeignKey("OrderId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Order"); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Payments.Entities.PaymentLedger", b => + { + b.HasOne("LiteCharms.Features.MidrandBooks.Customers.Entities.Customer", "Customer") + .WithMany() + .HasForeignKey("CustomerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("LiteCharms.Features.MidrandBooks.Orders.Entities.Order", "Order") + .WithMany() + .HasForeignKey("OrderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("LiteCharms.Features.MidrandBooks.Payments.Entities.PaymentGateway", "Gateway") + .WithMany() + .HasForeignKey("PaymentGatewayId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("LiteCharms.Features.MidrandBooks.Payments.Entities.Payment", "Payment") + .WithMany() + .HasForeignKey("PaymentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Customer"); + + b.Navigation("Gateway"); + + b.Navigation("Order"); + + b.Navigation("Payment"); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Payments.Entities.Refund", b => + { + b.HasOne("LiteCharms.Features.MidrandBooks.Orders.Entities.Order", "Order") + .WithMany("Refunds") + .HasForeignKey("OrderId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Order"); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Products.Entities.Product", b => + { + b.OwnsOne("LiteCharms.Features.Models.ProductMetadata", "Metadata", b1 => + { + b1.Property("ProductId"); + + b1.Property("CopyrightInfo"); + + b1.Property("ManufactureDate"); + + b1.Property("Manufacturer"); + + b1.Property("SerialNumber"); + + b1.HasKey("ProductId"); + + b1.ToTable("Products"); + + b1 + .ToJson("Metadata") + .HasColumnType("jsonb"); + + b1.WithOwner() + .HasForeignKey("ProductId"); + }); + + b.Navigation("Metadata"); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Products.Entities.ProductCategory", b => + { + b.HasOne("LiteCharms.Features.MidrandBooks.Categories.Entities.Category", "Category") + .WithMany() + .HasForeignKey("CategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("LiteCharms.Features.MidrandBooks.Products.Entities.Product", "Product") + .WithMany("Categories") + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Category"); + + b.Navigation("Product"); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Products.Entities.ProductInventory", b => + { + b.HasOne("LiteCharms.Features.MidrandBooks.Products.Entities.Product", "Product") + .WithMany() + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("LiteCharms.Features.MidrandBooks.Products.Entities.ProductPrice", "Price") + .WithMany() + .HasForeignKey("ProductPriceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Price"); + + b.Navigation("Product"); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Products.Entities.ProductPrice", b => + { + b.HasOne("LiteCharms.Features.MidrandBooks.Products.Entities.Product", "Product") + .WithMany("Prices") + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Product"); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.AuthorBooks.Entities.AuthorBook", b => + { + b.Navigation("Pages"); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Authors.Entities.Author", b => + { + b.Navigation("Books"); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Customers.Entities.Customer", b => + { + b.Navigation("Addresses"); + + b.Navigation("Contacts"); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Orders.Entities.Order", b => + { + b.Navigation("OrderItems"); + + b.Navigation("Refunds"); + + b.Navigation("Shipping"); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Orders.Entities.ShippingProvider", b => + { + b.Navigation("Shippings"); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Products.Entities.Product", b => + { + b.Navigation("Categories"); + + b.Navigation("Prices"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/LiteCharms.Features.MidrandBooks/Postgres/Migrations/20260531094401_AddedPaymentObjects.cs b/LiteCharms.Features.MidrandBooks/Postgres/Migrations/20260531094401_AddedPaymentObjects.cs new file mode 100644 index 0000000..b485cd1 --- /dev/null +++ b/LiteCharms.Features.MidrandBooks/Postgres/Migrations/20260531094401_AddedPaymentObjects.cs @@ -0,0 +1,185 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace LiteCharms.Features.MidrandBooks.Postgres.Migrations +{ + /// + public partial class AddedPaymentObjects : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Gateways", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + CreatedAt = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + UpdatedAt = table.Column(type: "timestamp with time zone", nullable: true), + Name = table.Column(type: "text", nullable: false), + Website = table.Column(type: "text", nullable: true), + MerchantId = table.Column(type: "text", nullable: false), + MerchantKey = table.Column(type: "text", nullable: false), + Passphrase = table.Column(type: "text", nullable: false), + IsSandbox = table.Column(type: "boolean", nullable: false), + Enabled = table.Column(type: "boolean", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Gateways", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Inventories", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + CreatedAt = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + Status = table.Column(type: "integer", nullable: false), + ProductId = table.Column(type: "bigint", nullable: false), + ProductPriceId = table.Column(type: "bigint", nullable: false), + TotalAllocated = table.Column(type: "integer", nullable: false), + TotalReserved = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Inventories", x => x.Id); + table.ForeignKey( + name: "FK_Inventories_Prices_ProductPriceId", + column: x => x.ProductPriceId, + principalTable: "Prices", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Inventories_Products_ProductId", + column: x => x.ProductId, + principalTable: "Products", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Payments", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + CreatedAt = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + UpdatedAt = table.Column(type: "timestamp with time zone", nullable: true), + Amount = table.Column(type: "numeric(18,2)", precision: 18, scale: 2, nullable: false), + OrderId = table.Column(type: "bigint", nullable: false), + Reference = table.Column(type: "text", nullable: false), + Status = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Payments", x => x.Id); + table.ForeignKey( + name: "FK_Payments_Orders_OrderId", + column: x => x.OrderId, + principalTable: "Orders", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "Ledger", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + CreatedAt = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + Status = table.Column(type: "integer", nullable: false), + OrderId = table.Column(type: "bigint", nullable: false), + PaymentId = table.Column(type: "bigint", nullable: false), + CustomerId = table.Column(type: "bigint", nullable: false), + PaymentGatewayReference = table.Column(type: "text", nullable: true), + PaymentGatewayId = table.Column(type: "bigint", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Ledger", x => x.Id); + table.ForeignKey( + name: "FK_Ledger_Customers_CustomerId", + column: x => x.CustomerId, + principalTable: "Customers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Ledger_Gateways_PaymentGatewayId", + column: x => x.PaymentGatewayId, + principalTable: "Gateways", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Ledger_Orders_OrderId", + column: x => x.OrderId, + principalTable: "Orders", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Ledger_Payments_PaymentId", + column: x => x.PaymentId, + principalTable: "Payments", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_Inventories_ProductId", + table: "Inventories", + column: "ProductId"); + + migrationBuilder.CreateIndex( + name: "IX_Inventories_ProductPriceId", + table: "Inventories", + column: "ProductPriceId"); + + migrationBuilder.CreateIndex( + name: "IX_Ledger_CustomerId", + table: "Ledger", + column: "CustomerId"); + + migrationBuilder.CreateIndex( + name: "IX_Ledger_OrderId", + table: "Ledger", + column: "OrderId"); + + migrationBuilder.CreateIndex( + name: "IX_Ledger_PaymentGatewayId", + table: "Ledger", + column: "PaymentGatewayId"); + + migrationBuilder.CreateIndex( + name: "IX_Ledger_PaymentId", + table: "Ledger", + column: "PaymentId"); + + migrationBuilder.CreateIndex( + name: "IX_Payments_OrderId", + table: "Payments", + column: "OrderId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Inventories"); + + migrationBuilder.DropTable( + name: "Ledger"); + + migrationBuilder.DropTable( + name: "Gateways"); + + migrationBuilder.DropTable( + name: "Payments"); + } + } +} diff --git a/LiteCharms.Features.MidrandBooks/Postgres/Migrations/MidrandBooksDbContextModelSnapshot.cs b/LiteCharms.Features.MidrandBooks/Postgres/Migrations/MidrandBooksDbContextModelSnapshot.cs index 8af6b80..635ea90 100644 --- a/LiteCharms.Features.MidrandBooks/Postgres/Migrations/MidrandBooksDbContextModelSnapshot.cs +++ b/LiteCharms.Features.MidrandBooks/Postgres/Migrations/MidrandBooksDbContextModelSnapshot.cs @@ -536,6 +536,133 @@ namespace LiteCharms.Features.MidrandBooks.Postgres.Migrations b.ToTable("BookPages", (string)null); }); + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Payments.Entities.Payment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Amount") + .HasPrecision(18, 2) + .HasColumnType("numeric(18,2)"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("OrderId") + .HasColumnType("bigint"); + + b.Property("Reference") + .IsRequired() + .HasColumnType("text"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("Payments", (string)null); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Payments.Entities.PaymentGateway", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("Enabled") + .HasColumnType("boolean"); + + b.Property("IsSandbox") + .HasColumnType("boolean"); + + b.Property("MerchantId") + .IsRequired() + .HasColumnType("text"); + + b.Property("MerchantKey") + .IsRequired() + .HasColumnType("text"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("Passphrase") + .IsRequired() + .HasColumnType("text"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Website") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Gateways", (string)null); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Payments.Entities.PaymentLedger", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("CustomerId") + .HasColumnType("bigint"); + + b.Property("OrderId") + .HasColumnType("bigint"); + + b.Property("PaymentGatewayId") + .HasColumnType("bigint"); + + b.Property("PaymentGatewayReference") + .HasColumnType("text"); + + b.Property("PaymentId") + .HasColumnType("bigint"); + + b.Property("Status") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("CustomerId"); + + b.HasIndex("OrderId"); + + b.HasIndex("PaymentGatewayId"); + + b.HasIndex("PaymentId"); + + b.ToTable("Ledger", (string)null); + }); + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Payments.Entities.Refund", b => { b.Property("Id") @@ -653,6 +780,43 @@ namespace LiteCharms.Features.MidrandBooks.Postgres.Migrations b.ToTable("ProductCategories", (string)null); }); + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Products.Entities.ProductInventory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("ProductId") + .HasColumnType("bigint"); + + b.Property("ProductPriceId") + .HasColumnType("bigint"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("TotalAllocated") + .HasColumnType("integer"); + + b.Property("TotalReserved") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ProductId"); + + b.HasIndex("ProductPriceId"); + + b.ToTable("Inventories", (string)null); + }); + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Products.Entities.ProductPrice", b => { b.Property("Id") @@ -891,6 +1055,51 @@ namespace LiteCharms.Features.MidrandBooks.Postgres.Migrations b.Navigation("References"); }); + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Payments.Entities.Payment", b => + { + b.HasOne("LiteCharms.Features.MidrandBooks.Orders.Entities.Order", "Order") + .WithMany() + .HasForeignKey("OrderId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Order"); + }); + + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Payments.Entities.PaymentLedger", b => + { + b.HasOne("LiteCharms.Features.MidrandBooks.Customers.Entities.Customer", "Customer") + .WithMany() + .HasForeignKey("CustomerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("LiteCharms.Features.MidrandBooks.Orders.Entities.Order", "Order") + .WithMany() + .HasForeignKey("OrderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("LiteCharms.Features.MidrandBooks.Payments.Entities.PaymentGateway", "Gateway") + .WithMany() + .HasForeignKey("PaymentGatewayId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("LiteCharms.Features.MidrandBooks.Payments.Entities.Payment", "Payment") + .WithMany() + .HasForeignKey("PaymentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Customer"); + + b.Navigation("Gateway"); + + b.Navigation("Order"); + + b.Navigation("Payment"); + }); + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Payments.Entities.Refund", b => { b.HasOne("LiteCharms.Features.MidrandBooks.Orders.Entities.Order", "Order") @@ -950,6 +1159,25 @@ namespace LiteCharms.Features.MidrandBooks.Postgres.Migrations b.Navigation("Product"); }); + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Products.Entities.ProductInventory", b => + { + b.HasOne("LiteCharms.Features.MidrandBooks.Products.Entities.Product", "Product") + .WithMany() + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("LiteCharms.Features.MidrandBooks.Products.Entities.ProductPrice", "Price") + .WithMany() + .HasForeignKey("ProductPriceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Price"); + + b.Navigation("Product"); + }); + modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Products.Entities.ProductPrice", b => { b.HasOne("LiteCharms.Features.MidrandBooks.Products.Entities.Product", "Product") diff --git a/LiteCharms.Features.MidrandBooks/Products/Entities/ProductInventory.cs b/LiteCharms.Features.MidrandBooks/Products/Entities/ProductInventory.cs new file mode 100644 index 0000000..7b43c55 --- /dev/null +++ b/LiteCharms.Features.MidrandBooks/Products/Entities/ProductInventory.cs @@ -0,0 +1,9 @@ +namespace LiteCharms.Features.MidrandBooks.Products.Entities; + +[EntityTypeConfiguration] +public class ProductInventory : Models.ProductInventory +{ + public virtual Product? Product { get; set; } + + public virtual ProductPrice? Price { get; set; } +} diff --git a/LiteCharms.Features.MidrandBooks/Products/Entities/ProductInventoryConfiguration.cs b/LiteCharms.Features.MidrandBooks/Products/Entities/ProductInventoryConfiguration.cs new file mode 100644 index 0000000..4e68570 --- /dev/null +++ b/LiteCharms.Features.MidrandBooks/Products/Entities/ProductInventoryConfiguration.cs @@ -0,0 +1,27 @@ +namespace LiteCharms.Features.MidrandBooks.Products.Entities; + +public sealed class ProductInventoryConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("Inventories"); + + builder.HasKey(f => f.Id); + builder.Property(f => f.CreatedAt).IsRequired().ValueGeneratedOnAdd().HasDefaultValueSql("now()"); + builder.Property(f => f.Status).IsRequired(); + builder.Property(f => f.TotalAllocated).IsRequired(); + builder.Property(f => f.TotalReserved).IsRequired(); + builder.Property(f => f.ProductId).IsRequired(); + builder.Property(f => f.ProductPriceId).IsRequired(); + + builder.HasOne(f => f.Product) + .WithMany() + .HasForeignKey(f => f.ProductId) + .OnDelete(DeleteBehavior.Cascade); + + builder.HasOne(f => f.Price) + .WithMany() + .HasForeignKey(f => f.ProductPriceId) + .OnDelete(DeleteBehavior.Cascade); + } +} diff --git a/LiteCharms.Features.MidrandBooks/Products/Models/ProductInventory.cs b/LiteCharms.Features.MidrandBooks/Products/Models/ProductInventory.cs new file mode 100644 index 0000000..3212a0e --- /dev/null +++ b/LiteCharms.Features.MidrandBooks/Products/Models/ProductInventory.cs @@ -0,0 +1,18 @@ +namespace LiteCharms.Features.MidrandBooks.Products.Models; + +public class ProductInventory +{ + public long Id { get; set; } + + public DateTime CreatedAt { get; set; } + + public InventoryStatuses Status { get; set; } + + public long ProductId { get; set; } + + public long ProductPriceId { get; set; } + + public int TotalAllocated { get; set; } + + public int TotalReserved { get; set; } +} diff --git a/LiteCharms.Features/Enums.cs b/LiteCharms.Features/Enums.cs index 40aabdc..786d3e5 100644 --- a/LiteCharms.Features/Enums.cs +++ b/LiteCharms.Features/Enums.cs @@ -1,5 +1,35 @@ namespace LiteCharms.Features; +public enum InventoryStatuses : int +{ + Adjustment = 0, + Reserved = 1, + Released = 2, + Sold = 3, + Replenished = 4, + Correction = 5, +} + +public enum LedgerStatuses : int +{ + Changed = 0, + Sent = 1, + Received = 2, + Refunded = 3, + Cancelled = 4, + Failed = 5, + Partial = 6, +} + +public enum PaymentStatuses : int +{ + NotPaid = 0, + Paid = 1, + Cancelled = 2, + Requested = 3, + Failed = 4, +} + public enum ShippingProviderTypes : int { Dsv = 0, @@ -114,4 +144,65 @@ public enum Priorities : int Low = 0, Medium = 1, High = 2, +} + +public enum PublisherTypes : int +{ + Individual = 0, + Company = 1, + Organization = 2, + SelfPublished = 3, + UniversityPress = 4, + GovernmentAgency = 5, + NonProfit = 6, + Independent = 7 +} + +public enum BookTypes : int +{ + Fiction = 0, + NonFiction = 1, + Academic = 2, + SelfHelp = 3, + Biography = 4, + Poetry = 5, + Children = 6, + YoungAdult = 7, + ScienceFiction = 8, + Fantasy = 9 +} + +public enum BookContentTypes : int +{ + Text = 0, + Image = 1, + Video = 2, + Audio = 3, + Interactive = 4, + Markdown = 5, + Html = 6, + Json = 7, + Yaml = 8 +} + +public enum BookPageTypes : int +{ + Cover = 0, + Preface = 1, + Introduction = 2, + Content = 3, + Closing = 4, + Referencer = 5, + Credits = 6, + BackCover = 7 +} + +public enum ProductTypes : int +{ + Book = 1, + Journal = 2, + Magazine = 3, + EBook = 4, + Audiobook = 5, + Accessory = 6 } \ No newline at end of file