diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml
new file mode 100644
index 0000000..c74e6db
--- /dev/null
+++ b/.github/workflows/dotnet.yml
@@ -0,0 +1,31 @@
+# This workflow will build a .NET project
+# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net
+
+name: .NET
+
+on:
+ push:
+ branches: [ "master" ]
+ pull_request:
+ branches: [ "master" ]
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v4
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v4
+ with:
+ dotnet-version: 8.0.x
+ - name: Restore dependencies
+ run: dotnet restore
+ working-directory: Reverse-Analytics
+ - name: Build
+ run: dotnet build --no-restore
+ working-directory: Reverse-Analytics
+ - name: Test
+ run: dotnet test --no-build --verbosity normal
+ working-directory: Reverse-Analytics
diff --git a/Reverse-Analytics/Migrations/ReverseAnalytics.Migrations.SqlServer/20240317223310_Initial_Create.Designer.cs b/Reverse-Analytics/Migrations/ReverseAnalytics.Migrations.SqlServer/20240317223310_Initial_Create.Designer.cs
new file mode 100644
index 0000000..c08cc96
--- /dev/null
+++ b/Reverse-Analytics/Migrations/ReverseAnalytics.Migrations.SqlServer/20240317223310_Initial_Create.Designer.cs
@@ -0,0 +1,649 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using ReverseAnalytics.Infrastructure.Persistence;
+
+#nullable disable
+
+namespace ReverseAnalytics.Infrastructure.Persistence.Migrations
+{
+ [DbContext(typeof(ApplicationDbContext))]
+ [Migration("20240317223310_Initial_Create")]
+ partial class Initial_Create
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "8.0.3")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128);
+
+ SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
+
+ modelBuilder.Entity("ReverseAnalytics.Domain.Entities.Customer", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("Address")
+ .HasMaxLength(4000)
+ .HasColumnType("nvarchar(4000)");
+
+ b.Property("Balance")
+ .HasPrecision(18, 2)
+ .HasColumnType("decimal(18,2)");
+
+ b.Property("Company")
+ .HasMaxLength(4000)
+ .HasColumnType("nvarchar(4000)");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("CreatedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CreatedById")
+ .HasColumnType("int");
+
+ b.Property("Discount")
+ .ValueGeneratedOnAdd()
+ .HasPrecision(18, 2)
+ .HasColumnType("float(18)")
+ .HasDefaultValue(0.0);
+
+ b.Property("FirstName")
+ .IsRequired()
+ .HasMaxLength(255)
+ .HasColumnType("nvarchar(255)");
+
+ b.Property("LastModifiedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("LastModifiedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("LastModifiedById")
+ .HasColumnType("int");
+
+ b.Property("LastName")
+ .HasMaxLength(255)
+ .HasColumnType("nvarchar(255)");
+
+ b.Property("PhoneNumber")
+ .IsRequired()
+ .HasMaxLength(50)
+ .HasColumnType("nvarchar(50)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Customer", (string)null);
+ });
+
+ modelBuilder.Entity("ReverseAnalytics.Domain.Entities.Product", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("CategoryId")
+ .HasColumnType("int");
+
+ b.Property("Code")
+ .IsRequired()
+ .HasMaxLength(255)
+ .HasColumnType("nvarchar(255)");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("CreatedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CreatedById")
+ .HasColumnType("int");
+
+ b.Property("Description")
+ .HasMaxLength(4000)
+ .HasColumnType("nvarchar(4000)");
+
+ b.Property("LastModifiedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("LastModifiedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("LastModifiedById")
+ .HasColumnType("int");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(255)
+ .HasColumnType("nvarchar(255)");
+
+ b.Property("SalePrice")
+ .HasPrecision(18, 2)
+ .HasColumnType("decimal(18,2)");
+
+ b.Property("SupplyPrice")
+ .HasPrecision(18, 2)
+ .HasColumnType("decimal(18,2)");
+
+ b.Property("UnitOfMeasurement")
+ .HasColumnType("int");
+
+ b.Property("Volume")
+ .HasPrecision(18, 2)
+ .HasColumnType("float(18)");
+
+ b.Property("Weight")
+ .HasPrecision(18, 2)
+ .HasColumnType("float(18)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CategoryId");
+
+ b.ToTable("Product", (string)null);
+ });
+
+ modelBuilder.Entity("ReverseAnalytics.Domain.Entities.ProductCategory", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("CreatedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CreatedById")
+ .HasColumnType("int");
+
+ b.Property("Description")
+ .IsRequired()
+ .HasMaxLength(4000)
+ .HasColumnType("nvarchar(4000)");
+
+ b.Property("LastModifiedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("LastModifiedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("LastModifiedById")
+ .HasColumnType("int");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(255)
+ .HasColumnType("nvarchar(255)");
+
+ b.Property("ParentId")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ParentId");
+
+ b.ToTable("ProductCategory", (string)null);
+ });
+
+ modelBuilder.Entity("ReverseAnalytics.Domain.Entities.Sale", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("Comments")
+ .HasMaxLength(4000)
+ .HasColumnType("nvarchar(4000)");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("CreatedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CreatedById")
+ .HasColumnType("int");
+
+ b.Property("Currency")
+ .HasColumnType("int");
+
+ b.Property("CustomerId")
+ .HasColumnType("int");
+
+ b.Property("Date")
+ .HasColumnType("datetime2");
+
+ b.Property("LastModifiedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("LastModifiedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("LastModifiedById")
+ .HasColumnType("int");
+
+ b.Property("PaymentType")
+ .HasColumnType("int");
+
+ b.Property("SaleType")
+ .HasColumnType("int");
+
+ b.Property("Status")
+ .HasColumnType("int");
+
+ b.Property("TotalDiscount")
+ .HasPrecision(18, 2)
+ .HasColumnType("decimal(18,2)");
+
+ b.Property("TotalDue")
+ .HasPrecision(18, 2)
+ .HasColumnType("decimal(18,2)");
+
+ b.Property("TotalPaid")
+ .HasPrecision(18, 2)
+ .HasColumnType("decimal(18,2)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CustomerId");
+
+ b.ToTable("Sale", (string)null);
+ });
+
+ modelBuilder.Entity("ReverseAnalytics.Domain.Entities.SaleItem", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("CreatedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CreatedById")
+ .HasColumnType("int");
+
+ b.Property("Discount")
+ .ValueGeneratedOnAdd()
+ .HasPrecision(18, 2)
+ .HasColumnType("decimal(18,2)")
+ .HasDefaultValue(0m);
+
+ b.Property("LastModifiedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("LastModifiedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("LastModifiedById")
+ .HasColumnType("int");
+
+ b.Property("ProductId")
+ .HasColumnType("int");
+
+ b.Property("Quantity")
+ .HasColumnType("int");
+
+ b.Property("SaleId")
+ .HasColumnType("int");
+
+ b.Property("UnitPrice")
+ .HasPrecision(18, 2)
+ .HasColumnType("decimal(18,2)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ProductId");
+
+ b.HasIndex("SaleId");
+
+ b.ToTable("SaleItem", (string)null);
+ });
+
+ modelBuilder.Entity("ReverseAnalytics.Domain.Entities.Supplier", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("Balance")
+ .HasPrecision(18, 2)
+ .HasColumnType("decimal(18,2)");
+
+ b.Property("Company")
+ .HasMaxLength(4000)
+ .HasColumnType("nvarchar(4000)");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("CreatedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CreatedById")
+ .HasColumnType("int");
+
+ b.Property("FirstName")
+ .IsRequired()
+ .HasMaxLength(255)
+ .HasColumnType("nvarchar(255)");
+
+ b.Property("LastModifiedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("LastModifiedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("LastModifiedById")
+ .HasColumnType("int");
+
+ b.Property("LastName")
+ .HasMaxLength(255)
+ .HasColumnType("nvarchar(255)");
+
+ b.Property("PhoneNumber")
+ .IsRequired()
+ .HasMaxLength(50)
+ .HasColumnType("nvarchar(50)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Supplier", (string)null);
+ });
+
+ modelBuilder.Entity("ReverseAnalytics.Domain.Entities.Supply", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("Comments")
+ .HasMaxLength(4000)
+ .HasColumnType("nvarchar(4000)");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("CreatedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CreatedById")
+ .HasColumnType("int");
+
+ b.Property("Currency")
+ .HasColumnType("int");
+
+ b.Property("Date")
+ .HasColumnType("datetime2");
+
+ b.Property("LastModifiedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("LastModifiedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("LastModifiedById")
+ .HasColumnType("int");
+
+ b.Property("PaymentType")
+ .HasColumnType("int");
+
+ b.Property("SupplierId")
+ .HasColumnType("int");
+
+ b.Property("TotalDue")
+ .HasPrecision(18, 2)
+ .HasColumnType("decimal(18,2)");
+
+ b.Property("TotalPaid")
+ .HasPrecision(18, 2)
+ .HasColumnType("decimal(18,2)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("SupplierId");
+
+ b.ToTable("Supply", (string)null);
+ });
+
+ modelBuilder.Entity("ReverseAnalytics.Domain.Entities.SupplyItem", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("CreatedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CreatedById")
+ .HasColumnType("int");
+
+ b.Property("LastModifiedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("LastModifiedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("LastModifiedById")
+ .HasColumnType("int");
+
+ b.Property("ProductId")
+ .HasColumnType("int");
+
+ b.Property("Quantity")
+ .HasColumnType("int");
+
+ b.Property("SupplyId")
+ .HasColumnType("int");
+
+ b.Property("UnitPrice")
+ .HasPrecision(18, 2)
+ .HasColumnType("decimal(18,2)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ProductId");
+
+ b.HasIndex("SupplyId");
+
+ b.ToTable("SupplyItem", (string)null);
+ });
+
+ modelBuilder.Entity("ReverseAnalytics.Domain.Entities.Transaction", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("Amount")
+ .HasPrecision(18, 2)
+ .HasColumnType("decimal(18,2)");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("CreatedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CreatedById")
+ .HasColumnType("int");
+
+ b.Property("Date")
+ .HasColumnType("datetime2");
+
+ b.Property("LastModifiedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("LastModifiedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("LastModifiedById")
+ .HasColumnType("int");
+
+ b.Property("Source")
+ .HasColumnType("int");
+
+ b.Property("SourceId")
+ .IsRequired()
+ .HasColumnType("int");
+
+ b.Property("Type")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.ToTable("Transaction", (string)null);
+ });
+
+ modelBuilder.Entity("ReverseAnalytics.Domain.Entities.Product", b =>
+ {
+ b.HasOne("ReverseAnalytics.Domain.Entities.ProductCategory", "Category")
+ .WithMany("Products")
+ .HasForeignKey("CategoryId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Category");
+ });
+
+ modelBuilder.Entity("ReverseAnalytics.Domain.Entities.ProductCategory", b =>
+ {
+ b.HasOne("ReverseAnalytics.Domain.Entities.ProductCategory", "Parent")
+ .WithMany("SubCategories")
+ .HasForeignKey("ParentId");
+
+ b.Navigation("Parent");
+ });
+
+ modelBuilder.Entity("ReverseAnalytics.Domain.Entities.Sale", b =>
+ {
+ b.HasOne("ReverseAnalytics.Domain.Entities.Customer", "Customer")
+ .WithMany("Sales")
+ .HasForeignKey("CustomerId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Customer");
+ });
+
+ modelBuilder.Entity("ReverseAnalytics.Domain.Entities.SaleItem", b =>
+ {
+ b.HasOne("ReverseAnalytics.Domain.Entities.Product", "Product")
+ .WithMany("SaleItems")
+ .HasForeignKey("ProductId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("ReverseAnalytics.Domain.Entities.Sale", "Sale")
+ .WithMany("SaleItems")
+ .HasForeignKey("SaleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Product");
+
+ b.Navigation("Sale");
+ });
+
+ modelBuilder.Entity("ReverseAnalytics.Domain.Entities.Supply", b =>
+ {
+ b.HasOne("ReverseAnalytics.Domain.Entities.Supplier", "Supplier")
+ .WithMany("Supplies")
+ .HasForeignKey("SupplierId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Supplier");
+ });
+
+ modelBuilder.Entity("ReverseAnalytics.Domain.Entities.SupplyItem", b =>
+ {
+ b.HasOne("ReverseAnalytics.Domain.Entities.Product", "Product")
+ .WithMany("SupplyItems")
+ .HasForeignKey("ProductId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("ReverseAnalytics.Domain.Entities.Supply", "Supply")
+ .WithMany("SupplyItems")
+ .HasForeignKey("SupplyId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Product");
+
+ b.Navigation("Supply");
+ });
+
+ modelBuilder.Entity("ReverseAnalytics.Domain.Entities.Customer", b =>
+ {
+ b.Navigation("Sales");
+ });
+
+ modelBuilder.Entity("ReverseAnalytics.Domain.Entities.Product", b =>
+ {
+ b.Navigation("SaleItems");
+
+ b.Navigation("SupplyItems");
+ });
+
+ modelBuilder.Entity("ReverseAnalytics.Domain.Entities.ProductCategory", b =>
+ {
+ b.Navigation("Products");
+
+ b.Navigation("SubCategories");
+ });
+
+ modelBuilder.Entity("ReverseAnalytics.Domain.Entities.Sale", b =>
+ {
+ b.Navigation("SaleItems");
+ });
+
+ modelBuilder.Entity("ReverseAnalytics.Domain.Entities.Supplier", b =>
+ {
+ b.Navigation("Supplies");
+ });
+
+ modelBuilder.Entity("ReverseAnalytics.Domain.Entities.Supply", b =>
+ {
+ b.Navigation("SupplyItems");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/Reverse-Analytics/Migrations/ReverseAnalytics.Migrations.SqlServer/20240317223310_Initial_Create.cs b/Reverse-Analytics/Migrations/ReverseAnalytics.Migrations.SqlServer/20240317223310_Initial_Create.cs
new file mode 100644
index 0000000..c82d46e
--- /dev/null
+++ b/Reverse-Analytics/Migrations/ReverseAnalytics.Migrations.SqlServer/20240317223310_Initial_Create.cs
@@ -0,0 +1,350 @@
+using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace ReverseAnalytics.Infrastructure.Persistence.Migrations
+{
+ ///
+ public partial class Initial_Create : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.CreateTable(
+ name: "Customer",
+ columns: table => new
+ {
+ Id = table.Column(type: "int", nullable: false)
+ .Annotation("SqlServer:Identity", "1, 1"),
+ FirstName = table.Column(type: "nvarchar(255)", maxLength: 255, nullable: false),
+ LastName = table.Column(type: "nvarchar(255)", maxLength: 255, nullable: true),
+ PhoneNumber = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false),
+ Address = table.Column(type: "nvarchar(4000)", maxLength: 4000, nullable: true),
+ Company = table.Column(type: "nvarchar(4000)", maxLength: 4000, nullable: true),
+ Balance = table.Column(type: "decimal(18,2)", precision: 18, scale: 2, nullable: false),
+ Discount = table.Column(type: "float(18)", precision: 18, scale: 2, nullable: false, defaultValue: 0.0),
+ CreatedAt = table.Column(type: "datetime2", nullable: false),
+ LastModifiedAt = table.Column(type: "datetime2", nullable: true),
+ CreatedBy = table.Column(type: "nvarchar(max)", nullable: true),
+ LastModifiedBy = table.Column(type: "nvarchar(max)", nullable: true),
+ CreatedById = table.Column(type: "int", nullable: true),
+ LastModifiedById = table.Column(type: "int", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Customer", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "ProductCategory",
+ columns: table => new
+ {
+ Id = table.Column(type: "int", nullable: false)
+ .Annotation("SqlServer:Identity", "1, 1"),
+ Name = table.Column(type: "nvarchar(255)", maxLength: 255, nullable: false),
+ Description = table.Column(type: "nvarchar(4000)", maxLength: 4000, nullable: false),
+ ParentId = table.Column(type: "int", nullable: true),
+ CreatedAt = table.Column(type: "datetime2", nullable: false),
+ LastModifiedAt = table.Column(type: "datetime2", nullable: true),
+ CreatedBy = table.Column(type: "nvarchar(max)", nullable: true),
+ LastModifiedBy = table.Column(type: "nvarchar(max)", nullable: true),
+ CreatedById = table.Column(type: "int", nullable: true),
+ LastModifiedById = table.Column(type: "int", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_ProductCategory", x => x.Id);
+ table.ForeignKey(
+ name: "FK_ProductCategory_ProductCategory_ParentId",
+ column: x => x.ParentId,
+ principalTable: "ProductCategory",
+ principalColumn: "Id");
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Supplier",
+ columns: table => new
+ {
+ Id = table.Column(type: "int", nullable: false)
+ .Annotation("SqlServer:Identity", "1, 1"),
+ FirstName = table.Column(type: "nvarchar(255)", maxLength: 255, nullable: false),
+ LastName = table.Column(type: "nvarchar(255)", maxLength: 255, nullable: true),
+ PhoneNumber = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false),
+ Company = table.Column(type: "nvarchar(4000)", maxLength: 4000, nullable: true),
+ Balance = table.Column(type: "decimal(18,2)", precision: 18, scale: 2, nullable: false),
+ CreatedAt = table.Column(type: "datetime2", nullable: false),
+ LastModifiedAt = table.Column(type: "datetime2", nullable: true),
+ CreatedBy = table.Column(type: "nvarchar(max)", nullable: true),
+ LastModifiedBy = table.Column(type: "nvarchar(max)", nullable: true),
+ CreatedById = table.Column(type: "int", nullable: true),
+ LastModifiedById = table.Column(type: "int", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Supplier", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Transaction",
+ columns: table => new
+ {
+ Id = table.Column(type: "int", nullable: false)
+ .Annotation("SqlServer:Identity", "1, 1"),
+ Date = table.Column(type: "datetime2", nullable: false),
+ SourceId = table.Column(type: "int", nullable: false),
+ Amount = table.Column(type: "decimal(18,2)", precision: 18, scale: 2, nullable: false),
+ Type = table.Column(type: "int", nullable: false),
+ Source = table.Column(type: "int", nullable: false),
+ CreatedAt = table.Column(type: "datetime2", nullable: false),
+ LastModifiedAt = table.Column(type: "datetime2", nullable: true),
+ CreatedBy = table.Column(type: "nvarchar(max)", nullable: true),
+ LastModifiedBy = table.Column(type: "nvarchar(max)", nullable: true),
+ CreatedById = table.Column(type: "int", nullable: true),
+ LastModifiedById = table.Column(type: "int", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Transaction", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Sale",
+ columns: table => new
+ {
+ Id = table.Column(type: "int", nullable: false)
+ .Annotation("SqlServer:Identity", "1, 1"),
+ Date = table.Column(type: "datetime2", nullable: false),
+ Comments = table.Column(type: "nvarchar(4000)", maxLength: 4000, nullable: true),
+ TotalDue = table.Column(type: "decimal(18,2)", precision: 18, scale: 2, nullable: false),
+ TotalPaid = table.Column(type: "decimal(18,2)", precision: 18, scale: 2, nullable: false),
+ TotalDiscount = table.Column(type: "decimal(18,2)", precision: 18, scale: 2, nullable: false),
+ SaleType = table.Column(type: "int", nullable: false),
+ Status = table.Column(type: "int", nullable: false),
+ PaymentType = table.Column(type: "int", nullable: false),
+ Currency = table.Column(type: "int", nullable: false),
+ CustomerId = table.Column(type: "int", nullable: false),
+ CreatedAt = table.Column(type: "datetime2", nullable: false),
+ LastModifiedAt = table.Column(type: "datetime2", nullable: true),
+ CreatedBy = table.Column(type: "nvarchar(max)", nullable: true),
+ LastModifiedBy = table.Column(type: "nvarchar(max)", nullable: true),
+ CreatedById = table.Column(type: "int", nullable: true),
+ LastModifiedById = table.Column(type: "int", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Sale", x => x.Id);
+ table.ForeignKey(
+ name: "FK_Sale_Customer_CustomerId",
+ column: x => x.CustomerId,
+ principalTable: "Customer",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Product",
+ columns: table => new
+ {
+ Id = table.Column(type: "int", nullable: false)
+ .Annotation("SqlServer:Identity", "1, 1"),
+ Name = table.Column(type: "nvarchar(255)", maxLength: 255, nullable: false),
+ Code = table.Column(type: "nvarchar(255)", maxLength: 255, nullable: false),
+ Description = table.Column(type: "nvarchar(4000)", maxLength: 4000, nullable: true),
+ SalePrice = table.Column(type: "decimal(18,2)", precision: 18, scale: 2, nullable: false),
+ SupplyPrice = table.Column(type: "decimal(18,2)", precision: 18, scale: 2, nullable: false),
+ Volume = table.Column(type: "float(18)", precision: 18, scale: 2, nullable: true),
+ Weight = table.Column(type: "float(18)", precision: 18, scale: 2, nullable: true),
+ UnitOfMeasurement = table.Column(type: "int", nullable: false),
+ CategoryId = table.Column(type: "int", nullable: false),
+ CreatedAt = table.Column(type: "datetime2", nullable: false),
+ LastModifiedAt = table.Column(type: "datetime2", nullable: true),
+ CreatedBy = table.Column(type: "nvarchar(max)", nullable: true),
+ LastModifiedBy = table.Column(type: "nvarchar(max)", nullable: true),
+ CreatedById = table.Column(type: "int", nullable: true),
+ LastModifiedById = table.Column(type: "int", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Product", x => x.Id);
+ table.ForeignKey(
+ name: "FK_Product_ProductCategory_CategoryId",
+ column: x => x.CategoryId,
+ principalTable: "ProductCategory",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Supply",
+ columns: table => new
+ {
+ Id = table.Column(type: "int", nullable: false)
+ .Annotation("SqlServer:Identity", "1, 1"),
+ Date = table.Column(type: "datetime2", nullable: false),
+ Comments = table.Column(type: "nvarchar(4000)", maxLength: 4000, nullable: true),
+ TotalDue = table.Column(type: "decimal(18,2)", precision: 18, scale: 2, nullable: false),
+ TotalPaid = table.Column(type: "decimal(18,2)", precision: 18, scale: 2, nullable: false),
+ PaymentType = table.Column(type: "int", nullable: false),
+ Currency = table.Column(type: "int", nullable: false),
+ SupplierId = table.Column(type: "int", nullable: false),
+ CreatedAt = table.Column(type: "datetime2", nullable: false),
+ LastModifiedAt = table.Column(type: "datetime2", nullable: true),
+ CreatedBy = table.Column(type: "nvarchar(max)", nullable: true),
+ LastModifiedBy = table.Column(type: "nvarchar(max)", nullable: true),
+ CreatedById = table.Column(type: "int", nullable: true),
+ LastModifiedById = table.Column(type: "int", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Supply", x => x.Id);
+ table.ForeignKey(
+ name: "FK_Supply_Supplier_SupplierId",
+ column: x => x.SupplierId,
+ principalTable: "Supplier",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "SaleItem",
+ columns: table => new
+ {
+ Id = table.Column(type: "int", nullable: false)
+ .Annotation("SqlServer:Identity", "1, 1"),
+ Quantity = table.Column(type: "int", nullable: false),
+ UnitPrice = table.Column(type: "decimal(18,2)", precision: 18, scale: 2, nullable: false),
+ Discount = table.Column(type: "decimal(18,2)", precision: 18, scale: 2, nullable: false, defaultValue: 0m),
+ SaleId = table.Column(type: "int", nullable: false),
+ ProductId = table.Column(type: "int", nullable: false),
+ CreatedAt = table.Column(type: "datetime2", nullable: false),
+ LastModifiedAt = table.Column(type: "datetime2", nullable: true),
+ CreatedBy = table.Column(type: "nvarchar(max)", nullable: true),
+ LastModifiedBy = table.Column(type: "nvarchar(max)", nullable: true),
+ CreatedById = table.Column(type: "int", nullable: true),
+ LastModifiedById = table.Column(type: "int", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_SaleItem", x => x.Id);
+ table.ForeignKey(
+ name: "FK_SaleItem_Product_ProductId",
+ column: x => x.ProductId,
+ principalTable: "Product",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ name: "FK_SaleItem_Sale_SaleId",
+ column: x => x.SaleId,
+ principalTable: "Sale",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "SupplyItem",
+ columns: table => new
+ {
+ Id = table.Column(type: "int", nullable: false)
+ .Annotation("SqlServer:Identity", "1, 1"),
+ Quantity = table.Column(type: "int", nullable: false),
+ UnitPrice = table.Column(type: "decimal(18,2)", precision: 18, scale: 2, nullable: false),
+ SupplyId = table.Column(type: "int", nullable: false),
+ ProductId = table.Column(type: "int", nullable: false),
+ CreatedAt = table.Column(type: "datetime2", nullable: false),
+ LastModifiedAt = table.Column(type: "datetime2", nullable: true),
+ CreatedBy = table.Column(type: "nvarchar(max)", nullable: true),
+ LastModifiedBy = table.Column(type: "nvarchar(max)", nullable: true),
+ CreatedById = table.Column(type: "int", nullable: true),
+ LastModifiedById = table.Column(type: "int", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_SupplyItem", x => x.Id);
+ table.ForeignKey(
+ name: "FK_SupplyItem_Product_ProductId",
+ column: x => x.ProductId,
+ principalTable: "Product",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ name: "FK_SupplyItem_Supply_SupplyId",
+ column: x => x.SupplyId,
+ principalTable: "Supply",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Product_CategoryId",
+ table: "Product",
+ column: "CategoryId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_ProductCategory_ParentId",
+ table: "ProductCategory",
+ column: "ParentId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Sale_CustomerId",
+ table: "Sale",
+ column: "CustomerId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_SaleItem_ProductId",
+ table: "SaleItem",
+ column: "ProductId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_SaleItem_SaleId",
+ table: "SaleItem",
+ column: "SaleId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Supply_SupplierId",
+ table: "Supply",
+ column: "SupplierId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_SupplyItem_ProductId",
+ table: "SupplyItem",
+ column: "ProductId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_SupplyItem_SupplyId",
+ table: "SupplyItem",
+ column: "SupplyId");
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropTable(
+ name: "SaleItem");
+
+ migrationBuilder.DropTable(
+ name: "SupplyItem");
+
+ migrationBuilder.DropTable(
+ name: "Transaction");
+
+ migrationBuilder.DropTable(
+ name: "Sale");
+
+ migrationBuilder.DropTable(
+ name: "Product");
+
+ migrationBuilder.DropTable(
+ name: "Supply");
+
+ migrationBuilder.DropTable(
+ name: "Customer");
+
+ migrationBuilder.DropTable(
+ name: "ProductCategory");
+
+ migrationBuilder.DropTable(
+ name: "Supplier");
+ }
+ }
+}
diff --git a/Reverse-Analytics/Migrations/ReverseAnalytics.Migrations.SqlServer/20240321224718_Nullable_Category_Description.Designer.cs b/Reverse-Analytics/Migrations/ReverseAnalytics.Migrations.SqlServer/20240321224718_Nullable_Category_Description.Designer.cs
new file mode 100644
index 0000000..7657892
--- /dev/null
+++ b/Reverse-Analytics/Migrations/ReverseAnalytics.Migrations.SqlServer/20240321224718_Nullable_Category_Description.Designer.cs
@@ -0,0 +1,648 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using ReverseAnalytics.Infrastructure.Persistence;
+
+#nullable disable
+
+namespace ReverseAnalytics.Infrastructure.Persistence.Migrations
+{
+ [DbContext(typeof(ApplicationDbContext))]
+ [Migration("20240321224718_Nullable_Category_Description")]
+ partial class Nullable_Category_Description
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "8.0.3")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128);
+
+ SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
+
+ modelBuilder.Entity("ReverseAnalytics.Domain.Entities.Customer", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("Address")
+ .HasMaxLength(4000)
+ .HasColumnType("nvarchar(4000)");
+
+ b.Property("Balance")
+ .HasPrecision(18, 2)
+ .HasColumnType("decimal(18,2)");
+
+ b.Property("Company")
+ .HasMaxLength(4000)
+ .HasColumnType("nvarchar(4000)");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("CreatedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CreatedById")
+ .HasColumnType("int");
+
+ b.Property("Discount")
+ .ValueGeneratedOnAdd()
+ .HasPrecision(18, 2)
+ .HasColumnType("float(18)")
+ .HasDefaultValue(0.0);
+
+ b.Property