Compare commits
46
Commits
0e21ec283d
..
1.51.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0ab14d8b63 | ||
|
|
466458e230 | ||
|
|
141d32f591 | ||
|
|
d9e7f225ae | ||
|
|
6ae63e2ad1 | ||
|
|
f5efdde37c | ||
|
|
1592d5dc8f | ||
|
|
50a8a59d92 | ||
|
|
b70d9559b0 | ||
|
|
81d5e8f07c | ||
|
|
20a53942b5 | ||
|
|
9edb2aa4aa | ||
|
|
6ed023f2cf | ||
|
|
2c9f5a846c | ||
|
|
41f7c05be3 | ||
|
|
1a03355e84 | ||
|
|
7743c3178e | ||
|
|
ab3d8e6e9a | ||
|
|
db4c348288 | ||
|
|
6683234642 | ||
|
|
6ddbb9479a | ||
|
|
6c7349a0f8 | ||
|
|
e97fd6cd3f | ||
|
|
184c7c252a | ||
|
|
bfe8c458d6 | ||
|
|
e6e0475db1 | ||
|
|
5090c60797 | ||
|
|
9432252e15 | ||
|
|
47111a1a3a | ||
|
|
6eb3d50375 | ||
|
|
4deb732804 | ||
|
|
20d9387d0b | ||
|
|
9f6d0ccaa0 | ||
|
|
1acbc4d213 | ||
|
|
8c99668fac | ||
|
|
ad44f46204 | ||
|
|
49d999c1e3 | ||
|
|
9ed4777a18 | ||
|
|
0cf44f68cc | ||
|
|
41ed5a4288 | ||
|
|
bbcba5e06c | ||
|
|
502cc326dd | ||
|
|
4675d4c5fc | ||
|
|
f80bb2fff9 | ||
|
|
6767906b0d | ||
|
|
a344af4498 |
@@ -1,133 +0,0 @@
|
||||
using LiteCharms.Features.MidrandBooks.Categories;
|
||||
using LiteCharms.Features.MidrandBooks.Products;
|
||||
|
||||
namespace LiteCharms.Features.MidrandBooks.Seed;
|
||||
|
||||
public class CategorySeederService(CategoryService categoryService, ProductService productService, IFeatureManager features,
|
||||
ILogger<CategorySeederService> logger) : BackgroundService
|
||||
{
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
if (!await features.IsEnabledAsync("CategorySeederService")) return;
|
||||
|
||||
logger.LogInformation("Category and Product-Tag Mapping Seeding started (15-char limit applied)");
|
||||
|
||||
// Initialize Bogus to ensure repeatable distribution matrix pathing
|
||||
var faker = new Faker();
|
||||
Randomizer.Seed = new Random(101);
|
||||
|
||||
// 1. Curate Broad Book Categories (IsMain = true, Max 20, Max 15 chars)
|
||||
var broadMainCategories = new[]
|
||||
{
|
||||
"Fiction", "Non-Fiction", "Youth & Kids", "Academic",
|
||||
"Biographies", "Business", "Sci-Fi & Fantasy",
|
||||
"Thrillers", "Self-Help", "History",
|
||||
"Spirituality", "Arts & Photo", "Technology",
|
||||
"Cookbooks", "Travel & Maps", "Poetry & Drama", "Graphic Novels"
|
||||
};
|
||||
|
||||
// 2. Curate Niche Subcategories/Tags (IsMain = false, Max 15 chars)
|
||||
var specializedSubCategories = new[]
|
||||
{
|
||||
"Cyberpunk", "Space Opera", "Historical Fix", "Cozy Mystery", "True Crime",
|
||||
"Agile Project", "Software Eng", "AI & ML", "Cloud Comput",
|
||||
"SA History", "African Lit", "Apartheid Era", "Mandela Legacy",
|
||||
"Finance", "Investments", "Startup", "Leadership",
|
||||
"CBT Therapy", "Mindfulness", "Yoga & Health",
|
||||
"Baking Basics", "African Food", "Vegan Recipes",
|
||||
"Ancient World", "WWII History", "Geopolitics",
|
||||
"Writing Guides", "Criticism", "Classic Poetry",
|
||||
"Early Learning", "Teen Romance", "Survival",
|
||||
"Urban Fantasy", "Dark Fantasy", "Psych Thriller", "Hard Sci-Fi",
|
||||
"Data Science", "DevOps", "Cybersecurity",
|
||||
"Economics", "Real Estate", "Governance",
|
||||
"Essays", "Memoirs", "Art History",
|
||||
"Architecture", "Photography", "Travel Writing",
|
||||
"Gaming Culture", "Philosophy", "Ethics",
|
||||
"DIY Home", "SA Gardening", "Parenting"
|
||||
};
|
||||
|
||||
// 3. Seed Main Categories into the System
|
||||
logger.LogInformation("Seeding broad main categories...");
|
||||
foreach (var mainCat in broadMainCategories)
|
||||
{
|
||||
if (stoppingToken.IsCancellationRequested) return;
|
||||
|
||||
// Defensive truncation fallback just in case strings get modified later
|
||||
string safeName = mainCat.Length > 15 ? mainCat.Substring(0, 15) : mainCat;
|
||||
|
||||
var result = await categoryService.CreateCategoryAsync(safeName, isMain: true, stoppingToken);
|
||||
if (result.IsFailed && !result.Errors[0].Message.Contains("already exists", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
logger.LogWarning("Notice while adding main category '{Name}': {Msg}", safeName, result.Errors[0].Message);
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Seed Subcategories into the System
|
||||
logger.LogInformation("Seeding boundless specialized niche tags...");
|
||||
foreach (var subCat in specializedSubCategories)
|
||||
{
|
||||
if (stoppingToken.IsCancellationRequested) return;
|
||||
|
||||
string safeName = subCat.Length > 15 ? subCat.Substring(0, 15) : subCat;
|
||||
|
||||
var result = await categoryService.CreateCategoryAsync(safeName, isMain: false, stoppingToken);
|
||||
if (result.IsFailed && !result.Errors[0].Message.Contains("already exists", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
logger.LogWarning("Notice while adding subcategory '{Name}': {Msg}", safeName, result.Errors[0].Message);
|
||||
}
|
||||
}
|
||||
|
||||
// 5. Query back all enabled categories to extract active IDs for junction mapping
|
||||
var fetchMainResult = await categoryService.GetCategoriesAsync(isMain: true, stoppingToken);
|
||||
var fetchSubResult = await categoryService.GetCategoriesAsync(isMain: false, stoppingToken);
|
||||
|
||||
if (fetchMainResult.IsFailed || fetchSubResult.IsFailed)
|
||||
{
|
||||
logger.LogError("Aborting junction seeding: Could not retrieve categories from data store.");
|
||||
return;
|
||||
}
|
||||
|
||||
var mainCategoryIds = fetchMainResult.Value.Select(c => c.Id).ToArray();
|
||||
var subCategoryIds = fetchSubResult.Value.Select(c => c.Id).ToArray();
|
||||
|
||||
// 6. Map Categories to your Product Collection (Product IDs 0 - 21)
|
||||
logger.LogInformation("Beginning Product-Category mapping assignments for Product IDs 0 through 21...");
|
||||
|
||||
for (long productId = 0; productId <= 21; productId++)
|
||||
{
|
||||
if (stoppingToken.IsCancellationRequested) break;
|
||||
|
||||
// Every book belongs to 1 or 2 main categories
|
||||
int mainCategoriesToAssign = faker.Random.Number(1, 2);
|
||||
var chosenMainIds = faker.PickRandom(mainCategoryIds, mainCategoriesToAssign).Distinct();
|
||||
|
||||
foreach (var mainId in chosenMainIds)
|
||||
{
|
||||
var linkResult = await productService.AddProductCategoryAsync(productId, mainId, stoppingToken);
|
||||
if (linkResult.IsFailed)
|
||||
{
|
||||
if (!linkResult.Errors[0].Message.Contains("exist", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
logger.LogDebug("Junction note for Product {PId} and Main Category {CId}: {Msg}", productId, mainId, linkResult.Errors[0].Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Every book gets 1 to 4 granular subgenre tags
|
||||
int subCategoriesToAssign = faker.Random.Number(1, 4);
|
||||
var chosenSubIds = faker.PickRandom(subCategoryIds, subCategoriesToAssign).Distinct();
|
||||
|
||||
foreach (var subId in chosenSubIds)
|
||||
{
|
||||
var linkResult = await productService.AddProductCategoryAsync(productId, subId, stoppingToken);
|
||||
if (linkResult.IsFailed && !linkResult.Errors[0].Message.Contains("exist", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
logger.LogDebug("Junction note for Product {PId} and Sub Category {CId}: {Msg}", productId, subId, linkResult.Errors[0].Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logger.LogInformation("Category and Product-Tag Mapping Seeding completed successfully.");
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,6 @@ builder.Services
|
||||
.AddLogging()
|
||||
.AddShopServices()
|
||||
.AddHostedService<ProductsSeederService>()
|
||||
.AddHostedService<CategorySeederService>()
|
||||
.AddHostedService<CustomerSeederService>()
|
||||
.AddMidrandShopDatabase(builder.Configuration);
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"FeatureManagement": {
|
||||
"CategorySeederService": true,
|
||||
"CustomerSeederService": false,
|
||||
"ProductsSeederService": false
|
||||
},
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
using LiteCharms.Features.MidrandBooks.Categories;
|
||||
using LiteCharms.Features.MidrandBooks.Tests.Common;
|
||||
|
||||
namespace LiteCharms.Features.MidrandBooks.Tests;
|
||||
|
||||
public class CategoryServiceFeatureTests(Fixture fixture) : IClassFixture<Fixture>
|
||||
{
|
||||
private readonly CategoryService categoryService = fixture.Services.GetRequiredService<CategoryService>();
|
||||
|
||||
[IntegrationFact]
|
||||
public async Task UpdateCategoryStatusAsync_ShouldReturn_ResultWithSuccess()
|
||||
{
|
||||
var result = await categoryService.UpdateCategoryStatusAsync(3, false, false, fixture.CancellationToken);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
}
|
||||
|
||||
[IntegrationFact]
|
||||
public async Task GetCategoryAsync_ShouldReturn_ResultWithCategory()
|
||||
{
|
||||
var result = await categoryService.GetCategoryAsync(3, fixture.CancellationToken);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.NotNull(result.Value);
|
||||
}
|
||||
|
||||
[IntegrationFact]
|
||||
public async Task GetCategoriesAsync_ShouldReturn_All_ResultWithCategoryList()
|
||||
{
|
||||
var result = await categoryService.GetCategoriesAsync(isMain: null,fixture.CancellationToken);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.NotEmpty(result.Value);
|
||||
}
|
||||
|
||||
[IntegrationFact]
|
||||
public async Task GetCategoriesAsync_ShouldReturn_MainCategory_ResultWithCategoryList()
|
||||
{
|
||||
var result = await categoryService.GetCategoriesAsync(true, fixture.CancellationToken);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.NotEmpty(result.Value);
|
||||
}
|
||||
|
||||
[IntegrationFact]
|
||||
public async Task GetCategoriesAsync_ShouldReturn_SubMainCategory_ResultWithCategoryList()
|
||||
{
|
||||
var result = await categoryService.GetCategoriesAsync(false, fixture.CancellationToken);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.NotEmpty(result.Value);
|
||||
}
|
||||
|
||||
[IntegrationFact]
|
||||
public async Task CreateCategoriesAsync_ShouldReturn_ResultWithSuccess()
|
||||
{
|
||||
var result = await categoryService.CreateCategoriesAsync(fixture.CancellationToken, "Test", "Test 1", "Test 2");
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
}
|
||||
|
||||
[IntegrationFact]
|
||||
public async Task CreateCategoryAsync_ShouldReturn_ResultWithCategoryId()
|
||||
{
|
||||
var result = await categoryService.CreateCategoryAsync("Test", true, fixture.CancellationToken);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.True(result.Value > 0);
|
||||
}
|
||||
}
|
||||
@@ -10,40 +10,7 @@ public class ProductServiceFeatureTests(Fixture fixture, ITestOutputHelper outpu
|
||||
private readonly ProductService productService = fixture.Services.GetRequiredService<ProductService>();
|
||||
|
||||
[IntegrationFact]
|
||||
public async Task AddProductCategoryAsync_ShouldReturn_ResultWithId()
|
||||
{
|
||||
var result = await productService.AddProductCategoryAsync(1, 2, fixture.CancellationToken);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
}
|
||||
|
||||
[IntegrationFact]
|
||||
public async Task GetProductCategoriesAsync_ShouldReturn_ResultWithCategoryList()
|
||||
{
|
||||
var result = await productService.GetProductCategoriesAsync(1, fixture.CancellationToken);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.NotEmpty(result.Value);
|
||||
}
|
||||
|
||||
[IntegrationFact]
|
||||
public async Task DeleteProductCategoryAsync_ShouldReturn_ResultWithSuccess()
|
||||
{
|
||||
var result = await productService.DeleteProductCategoryAsync(1, 1, fixture.CancellationToken);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
}
|
||||
|
||||
[IntegrationFact]
|
||||
public async Task DeleteAllProductCategoriesAsync_ShouldReturn_ResultWithSuccess()
|
||||
{
|
||||
var result = await productService.DeleteAllProductCategoriesAsync(1, fixture.CancellationToken);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
}
|
||||
|
||||
[IntegrationFact]
|
||||
public async Task GetProductPriceAsync_ShouldReturn_ResultOneProductPrice()
|
||||
public async Task GetProductPriceAsync_ShouldReturn_RetultOneProductPrice()
|
||||
{
|
||||
var result = await productService.GetProductPriceAsync(2, fixture.CancellationToken);
|
||||
|
||||
@@ -54,7 +21,7 @@ public class ProductServiceFeatureTests(Fixture fixture, ITestOutputHelper outpu
|
||||
}
|
||||
|
||||
[IntegrationFact]
|
||||
public async Task GetProductPricesAsync_ShouldReturn_ResultProductPriceList()
|
||||
public async Task GetProductPricesAsync_ShouldReturn_RetultProductPriceList()
|
||||
{
|
||||
var result = await productService.GetProductPricesAsync(2, fixture.CancellationToken);
|
||||
|
||||
@@ -65,7 +32,7 @@ public class ProductServiceFeatureTests(Fixture fixture, ITestOutputHelper outpu
|
||||
}
|
||||
|
||||
[IntegrationFact]
|
||||
public async Task SearchProductsAsync_ShouldReturn_ResultMatchingProducts()
|
||||
public async Task SearchProductsAsync_ShouldReturn_RetultMatchingProducts()
|
||||
{
|
||||
var filter = new ProductFilter
|
||||
{
|
||||
@@ -85,7 +52,7 @@ public class ProductServiceFeatureTests(Fixture fixture, ITestOutputHelper outpu
|
||||
}
|
||||
|
||||
[IntegrationFact]
|
||||
public async Task GetProductAsync_ShouldReturn_ResultOneProduct()
|
||||
public async Task GetProductAsync_ShouldReturn_RetultOneProduct()
|
||||
{
|
||||
var result = await productService.GetProductAsync(2, fixture.CancellationToken);
|
||||
|
||||
@@ -96,7 +63,7 @@ public class ProductServiceFeatureTests(Fixture fixture, ITestOutputHelper outpu
|
||||
}
|
||||
|
||||
[IntegrationFact]
|
||||
public async Task GetProductsAsync_ShouldReturn_ResultProducts()
|
||||
public async Task GetProductsAsync_ShouldReturn_RetultProducts()
|
||||
{
|
||||
var range = new DateRange
|
||||
{
|
||||
@@ -114,7 +81,7 @@ public class ProductServiceFeatureTests(Fixture fixture, ITestOutputHelper outpu
|
||||
}
|
||||
|
||||
[IntegrationFact]
|
||||
public async Task UpdateProductStatusAsync_ShouldResurn_ResultTrue()
|
||||
public async Task UpdateProductStatusAsync_ShouldReturn_ResultTrue()
|
||||
{
|
||||
var result = await productService.UpdateProductStatusAsync(2, true, fixture.CancellationToken);
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ public sealed class BooksService(IDbContextFactory<MidrandBooksDbContext> contex
|
||||
.AsNoTracking()
|
||||
.Include(b => b.Author)
|
||||
.Include(b => b.Product)
|
||||
.ThenInclude(b => b!.Prices)
|
||||
.ThenInclude(b => b.Prices)
|
||||
.OrderByDescending(b => b.CreatedAt)
|
||||
.Where(b => b.AuthorId == authorId)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
@@ -8,29 +8,6 @@ namespace LiteCharms.Features.MidrandBooks.Authors;
|
||||
|
||||
public sealed class AuthorService(IDbContextFactory<MidrandBooksDbContext> contextFactory) : IService
|
||||
{
|
||||
public async ValueTask<Result<Author>> GetAuthorByProductIdAsync(long productId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await using var context = await contextFactory.CreateDbContextAsync(cancellationToken);
|
||||
|
||||
var author = await context.Books
|
||||
.AsNoTracking()
|
||||
.Include(i => i.Author)
|
||||
.Where(b => b.ProductId == productId)
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
|
||||
if (author is null)
|
||||
return Result.Fail<Author>(new Error($"No author association discovered for Product ID {productId}"));
|
||||
|
||||
return Result.Ok(author.Author!.ToModel());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Result.Fail<Author>(new Error(ex.Message).CausedBy(ex));
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask<Result> UpdateAuthorStatusAsync(long authorId, bool isEnabled, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -1,132 +0,0 @@
|
||||
using LiteCharms.Features.MidrandBooks.Abstractions;
|
||||
using LiteCharms.Features.MidrandBooks.Categories.Models;
|
||||
using LiteCharms.Features.MidrandBooks.Extensions;
|
||||
using LiteCharms.Features.MidrandBooks.Postgres;
|
||||
|
||||
namespace LiteCharms.Features.MidrandBooks.Categories;
|
||||
|
||||
public sealed class CategoryService(IDbContextFactory<MidrandBooksDbContext> contextFactory) : IService
|
||||
{
|
||||
public async ValueTask<Result> UpdateCategoryStatusAsync(long categoryId, bool enabled, bool isMain, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await using var context = await contextFactory.CreateDbContextAsync(cancellationToken);
|
||||
|
||||
var rowsUpdated = await context.Categories
|
||||
.Where(c => c.Id == categoryId && c.Enabled)
|
||||
.ExecuteUpdateAsync(setters => setters
|
||||
.SetProperty(c => c.Enabled, enabled)
|
||||
.SetProperty(c => c.IsMain, isMain), cancellationToken);
|
||||
|
||||
return rowsUpdated > 0
|
||||
? Result.Ok()
|
||||
: Result.Fail(new Error($"Failed to update category"));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Result.Fail(new Error(ex.Message).CausedBy(ex));
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask<Result<Category>> GetCategoryAsync(long categoryId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await using var context = await contextFactory.CreateDbContextAsync(cancellationToken);
|
||||
|
||||
var category = await context.Categories.AsNoTracking().FirstOrDefaultAsync(c => c.Id == categoryId, cancellationToken);
|
||||
|
||||
return category is not null
|
||||
? Result.Ok(category.ToModel())
|
||||
: Result.Fail<Category>("Failed to create new category");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Result.Fail<Category>(new Error(ex.Message).CausedBy(ex));
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask<Result<Category[]>> GetCategoriesAsync(bool? isMain = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await using var context = await contextFactory.CreateDbContextAsync(cancellationToken);
|
||||
|
||||
var query = context.Categories.AsNoTracking()
|
||||
.OrderByDescending(o => o.IsMain)
|
||||
.ThenByDescending(o => o.Id)
|
||||
.ThenBy(o => o.Name)
|
||||
.AsQueryable();
|
||||
|
||||
query = isMain is null
|
||||
? query.Where(c => c.Enabled).AsQueryable()
|
||||
: query.Where(c => c.Enabled && c.IsMain == isMain.Value);
|
||||
|
||||
var categories = await query.ToListAsync(cancellationToken);
|
||||
|
||||
return categories?.Count > 0
|
||||
? Result.Ok(categories.Select(c => c.ToModel()).ToArray())
|
||||
: Result.Fail<Category[]>("No categories found");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Result.Fail<Category[]>(new Error(ex.Message).CausedBy(ex));
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask<Result> CreateCategoriesAsync(CancellationToken cancellationToken = default, params string[] categories)
|
||||
{
|
||||
try
|
||||
{
|
||||
await using var context = await contextFactory.CreateDbContextAsync(cancellationToken);
|
||||
|
||||
foreach (var category in categories)
|
||||
{
|
||||
if (await context.Categories.AnyAsync(c => EF.Functions.ILike(c.Name!, category!), cancellationToken))
|
||||
continue;
|
||||
|
||||
context.Categories.Add(new Entities.Category
|
||||
{
|
||||
Name = category.Humanize(LetterCasing.Title),
|
||||
IsMain = false,
|
||||
Enabled = true,
|
||||
});
|
||||
}
|
||||
|
||||
return await context.SaveChangesAsync(cancellationToken) > 0
|
||||
? Result.Ok()
|
||||
: Result.Fail("Failed to add any category in the list");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Result.Fail(new Error(ex.Message).CausedBy(ex));
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask<Result<long>> CreateCategoryAsync(string category, bool isMain, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await using var context = await contextFactory.CreateDbContextAsync(cancellationToken);
|
||||
|
||||
if (await context.Categories.AnyAsync(c => EF.Functions.ILike(c.Name!, category!), cancellationToken))
|
||||
return Result.Fail($"Category '{category}' already exists");
|
||||
|
||||
var newCategory = context.Categories.Add(new Entities.Category
|
||||
{
|
||||
Name = StringHumanizeExtensions.Humanize(category, LetterCasing.Title),
|
||||
IsMain = isMain,
|
||||
Enabled = true,
|
||||
});
|
||||
|
||||
return await context.SaveChangesAsync(cancellationToken) > 0
|
||||
? Result.Ok(newCategory.Entity.Id)
|
||||
: Result.Fail("Failed to create new category");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Result.Fail(new Error(ex.Message).CausedBy(ex));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
namespace LiteCharms.Features.MidrandBooks.Categories.Entities;
|
||||
|
||||
[EntityTypeConfiguration<CategoryConfiguration, Category>]
|
||||
public sealed class Category : Models.Category;
|
||||
@@ -1,14 +0,0 @@
|
||||
namespace LiteCharms.Features.MidrandBooks.Categories.Entities;
|
||||
|
||||
public sealed class CategoryConfiguration : IEntityTypeConfiguration<Category>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<Category> builder)
|
||||
{
|
||||
builder.ToTable("Categories");
|
||||
|
||||
builder.HasKey(c => c.Id);
|
||||
builder.Property(c => c.Name).IsRequired().HasMaxLength(15);
|
||||
builder.Property(c => c.IsMain).HasDefaultValue(false);
|
||||
builder.Property(c => c.Enabled).HasDefaultValue(true);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
namespace LiteCharms.Features.MidrandBooks.Categories.Models;
|
||||
|
||||
public class Category
|
||||
{
|
||||
public long Id { get; set; }
|
||||
|
||||
public string? Name { get; set; }
|
||||
|
||||
public bool IsMain { get; set; }
|
||||
|
||||
public bool Enabled { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
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
|
||||
}
|
||||
@@ -1,72 +1,14 @@
|
||||
using LiteCharms.Features.MidrandBooks.AuthorBooks.Models;
|
||||
using LiteCharms.Features.MidrandBooks.Authors.Models;
|
||||
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,
|
||||
Name = entity.Name,
|
||||
IsMain = entity.IsMain,
|
||||
Enabled = entity.Enabled,
|
||||
};
|
||||
|
||||
public static ShippingProvider ToModel(this Orders.Entities.ShippingProvider entity) => new()
|
||||
{
|
||||
Id = entity.Id,
|
||||
@@ -123,7 +65,7 @@ public static class Mappers
|
||||
SocialMedia = entiry.SocialMedia,
|
||||
UpdatedAt = entiry.UpdatedAt,
|
||||
VatNumber = entiry.VatNumber,
|
||||
Website = entiry.Website
|
||||
Website = entiry.Website
|
||||
};
|
||||
|
||||
public static Address ToModel(this Customers.Entities.Address entity) => new()
|
||||
@@ -141,7 +83,7 @@ public static class Mappers
|
||||
Street = entity.Street,
|
||||
City = entity.City,
|
||||
State = entity.State,
|
||||
Country = entity.Country
|
||||
Country = entity.Country
|
||||
};
|
||||
|
||||
public static Contact ToModel(this Customers.Entities.Contact entity) => new()
|
||||
@@ -170,7 +112,7 @@ public static class Mappers
|
||||
Enabled = entity.Enabled,
|
||||
Notes = entity.Notes,
|
||||
References = entity.References,
|
||||
Type = entity.Type
|
||||
Type = entity.Type
|
||||
};
|
||||
|
||||
public static AuthorBook ToModel(this AuthorBooks.Entities.AuthorBook entity) => new()
|
||||
@@ -196,21 +138,25 @@ public static class Mappers
|
||||
Enabled = entity.Enabled
|
||||
};
|
||||
|
||||
public static Product ToModel(this Products.Entities.Product entity) => new Product
|
||||
public static Product ToModel(this Products.Entities.Product entity)
|
||||
{
|
||||
Id = entity.Id,
|
||||
CreatedAt = entity.CreatedAt,
|
||||
UpdatedAt = entity.UpdatedAt,
|
||||
Name = entity.Name,
|
||||
Summary = entity.Summary,
|
||||
Description = entity.Description,
|
||||
Type = entity.Type,
|
||||
ImageUrl = entity.ImageUrl,
|
||||
ThumbnailUrls = entity.ThumbnailUrls,
|
||||
Metadata = entity.Metadata,
|
||||
Enabled = entity.Enabled,
|
||||
Price = entity.Prices?.FirstOrDefault(p => p.Enabled)?.ToModel() ?? null,
|
||||
};
|
||||
return new Product
|
||||
{
|
||||
Id = entity.Id,
|
||||
CreatedAt = entity.CreatedAt,
|
||||
UpdatedAt = entity.UpdatedAt,
|
||||
Name = entity.Name,
|
||||
Summary = entity.Summary,
|
||||
Description = entity.Description,
|
||||
Type = entity.Type,
|
||||
ImageUrl = entity.ImageUrl,
|
||||
ThumbnailUrls = entity.ThumbnailUrls,
|
||||
Metadata = entity.Metadata,
|
||||
Categories = entity.Categories,
|
||||
Enabled = entity.Enabled,
|
||||
Price = entity.Prices?.FirstOrDefault(p => p.Enabled)?.ToModel() ?? null,
|
||||
};
|
||||
}
|
||||
|
||||
public static Author ToModel(this Authors.Entities.Author entity) => new()
|
||||
{
|
||||
|
||||
@@ -31,8 +31,7 @@
|
||||
|
||||
<!-- Quartz Scheduler-->
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Humanizer" Version="3.0.10" />
|
||||
<PackageReference Include="Meziantou.Analyzer" Version="3.0.98">
|
||||
<PackageReference Include="Meziantou.Analyzer" Version="3.0.96">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
@@ -105,7 +104,7 @@
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.2" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.1" />
|
||||
|
||||
<!-- Global Usings -->
|
||||
<Using Include="Npgsql" />
|
||||
@@ -116,8 +115,8 @@
|
||||
|
||||
<!-- Email -->
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MailKit" Version="4.17.0" />
|
||||
<PackageReference Include="MimeKit" Version="4.17.0" />
|
||||
<PackageReference Include="MailKit" Version="4.16.0" />
|
||||
<PackageReference Include="MimeKit" Version="4.16.0" />
|
||||
|
||||
<!-- Global Usings-->
|
||||
<Using Include="MimeKit" />
|
||||
@@ -148,7 +147,6 @@
|
||||
|
||||
<!-- Shared Usings -->
|
||||
<ItemGroup>
|
||||
<Using Include="Humanizer" />
|
||||
<Using Include="System.Globalization" />
|
||||
<Using Include="System.Reflection" />
|
||||
<Using Include="Microsoft.AspNetCore.Builder" />
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
using LiteCharms.Features.MidrandBooks.Orders.Entities;
|
||||
|
||||
namespace LiteCharms.Features.MidrandBooks.Payments.Entities;
|
||||
|
||||
[EntityTypeConfiguration<PaymentConfiguration, Payment>]
|
||||
public class Payment : Models.Payment
|
||||
{
|
||||
public virtual Order? Order { get; set; }
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
namespace LiteCharms.Features.MidrandBooks.Payments.Entities;
|
||||
|
||||
public sealed class PaymentConfiguration : IEntityTypeConfiguration<Payment>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<Payment> 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);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
namespace LiteCharms.Features.MidrandBooks.Payments.Entities;
|
||||
|
||||
[EntityTypeConfiguration<PaymentGatewayConfiguration, PaymentGateway>]
|
||||
public class PaymentGateway : Models.PaymentGateway;
|
||||
@@ -1,20 +0,0 @@
|
||||
namespace LiteCharms.Features.MidrandBooks.Payments.Entities;
|
||||
|
||||
public sealed class PaymentGatewayConfiguration : IEntityTypeConfiguration<PaymentGateway>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<PaymentGateway> 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();
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
using LiteCharms.Features.MidrandBooks.Customers.Entities;
|
||||
using LiteCharms.Features.MidrandBooks.Orders.Entities;
|
||||
|
||||
namespace LiteCharms.Features.MidrandBooks.Payments.Entities;
|
||||
|
||||
[EntityTypeConfiguration<PaymentLedgerConfiguration, PaymentLedger>]
|
||||
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; }
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
namespace LiteCharms.Features.MidrandBooks.Payments.Entities;
|
||||
|
||||
public sealed class PaymentLedgerConfiguration : IEntityTypeConfiguration<PaymentLedger>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<PaymentLedger> 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);
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
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; }
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
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; }
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
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; }
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
using LiteCharms.Features.MidrandBooks.AuthorBooks.Entities;
|
||||
using LiteCharms.Features.MidrandBooks.Authors.Entities;
|
||||
using LiteCharms.Features.MidrandBooks.Categories.Entities;
|
||||
using LiteCharms.Features.MidrandBooks.Customers.Entities;
|
||||
using LiteCharms.Features.MidrandBooks.Orders.Entities;
|
||||
using LiteCharms.Features.MidrandBooks.Pages.Entities;
|
||||
@@ -36,16 +35,4 @@ public sealed class MidrandBooksDbContext(DbContextOptions<MidrandBooksDbContext
|
||||
public DbSet<Shipping> Shippings => Set<Shipping>();
|
||||
|
||||
public DbSet<ShippingProvider> ShippingProviders => Set<ShippingProvider>();
|
||||
|
||||
public DbSet<Category> Categories => Set<Category>();
|
||||
|
||||
public DbSet<ProductCategory> ProductCategories => Set<ProductCategory>();
|
||||
|
||||
public DbSet<ProductInventory> Inventories => Set<ProductInventory>();
|
||||
|
||||
public DbSet<Payment> Payments => Set<Payment>();
|
||||
|
||||
public DbSet<PaymentGateway> Gateways => Set<PaymentGateway>();
|
||||
|
||||
public DbSet<PaymentLedger> Ledger => Set<PaymentLedger>();
|
||||
}
|
||||
|
||||
Generated
-966
@@ -1,966 +0,0 @@
|
||||
// <auto-generated />
|
||||
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("20260530104851_AddedCategories")]
|
||||
partial class AddedCategories
|
||||
{
|
||||
/// <inheritdoc />
|
||||
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<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<long>("AuthorId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<long>("ProductId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<int>("Ranking")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("Rating")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<DateTime?>("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<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<string>("Biography")
|
||||
.HasMaxLength(2048)
|
||||
.HasColumnType("character varying(2048)");
|
||||
|
||||
b.Property<string>("Company")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasDefaultValueSql("now()");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasMaxLength(512)
|
||||
.HasColumnType("character varying(512)");
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("boolean")
|
||||
.HasDefaultValue(true);
|
||||
|
||||
b.Property<string>("ImageUrl")
|
||||
.IsRequired()
|
||||
.HasMaxLength(2048)
|
||||
.HasColumnType("character varying(2048)");
|
||||
|
||||
b.Property<string>("LastName")
|
||||
.IsRequired()
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("character varying(255)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("character varying(255)");
|
||||
|
||||
b.Property<int>("PublisherType")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("ThumbnailImageUrl")
|
||||
.HasMaxLength(2048)
|
||||
.HasColumnType("character varying(2048)");
|
||||
|
||||
b.Property<DateTime?>("UpdatedAt")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasDefaultValueSql("now()");
|
||||
|
||||
b.Property<string>("VatNumber")
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("character varying(255)");
|
||||
|
||||
b.Property<string>("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<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("boolean")
|
||||
.HasDefaultValue(true);
|
||||
|
||||
b.Property<bool>("IsMain")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("boolean")
|
||||
.HasDefaultValue(false);
|
||||
|
||||
b.Property<string>("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<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<int>("BuildingType")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("City")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Country")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasDefaultValueSql("now()");
|
||||
|
||||
b.Property<long>("CustomerId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("boolean")
|
||||
.HasDefaultValue(true);
|
||||
|
||||
b.Property<bool>("IsPrimary")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("boolean")
|
||||
.HasDefaultValue(false);
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("PostalCode")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("State")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Street")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<DateTime?>("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<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasDefaultValueSql("now()");
|
||||
|
||||
b.Property<long>("CustomerId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("boolean")
|
||||
.HasDefaultValue(true);
|
||||
|
||||
b.Property<bool>("IsPrimary")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("boolean")
|
||||
.HasDefaultValue(false);
|
||||
|
||||
b.Property<string>("LastName")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Phone")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<DateTime?>("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<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<string>("Company")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasDefaultValueSql("now()");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("boolean")
|
||||
.HasDefaultValue(true);
|
||||
|
||||
b.Property<string>("Phone")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<DateTime?>("UpdatedAt")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasDefaultValueSql("now()");
|
||||
|
||||
b.Property<string>("VatNumber")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Website")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Customers", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Orders.Entities.Order", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasDefaultValueSql("now()");
|
||||
|
||||
b.Property<long>("CustomerId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<string>("InvoiceUrl")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Notes")
|
||||
.HasMaxLength(1000)
|
||||
.HasColumnType("character varying(1000)");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<decimal>("Total")
|
||||
.HasPrecision(18, 2)
|
||||
.HasColumnType("numeric(18,2)");
|
||||
|
||||
b.Property<DateTime?>("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<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<long>("AuthorBookId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasDefaultValueSql("now()");
|
||||
|
||||
b.Property<long>("OrderId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<long>("ProductPriceId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<int>("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<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<long>("AddressId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasDefaultValueSql("now()");
|
||||
|
||||
b.Property<long>("OrderId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<long>("ShippingProviderId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("TrackingNumber")
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("character varying(255)");
|
||||
|
||||
b.Property<DateTime?>("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<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<decimal?>("Price")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.Property<string>("TrackingUrl")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<DateTime?>("UpdatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("ShippingProviders");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Pages.Entities.BookPage", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<long>("AuthorBookId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<byte[]>("Content")
|
||||
.IsRequired()
|
||||
.HasColumnType("bytea");
|
||||
|
||||
b.Property<int>("ContentType")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasDefaultValueSql("now()");
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("boolean")
|
||||
.HasDefaultValue(true);
|
||||
|
||||
b.PrimitiveCollection<string[]>("Notes")
|
||||
.HasColumnType("text[]");
|
||||
|
||||
b.Property<int>("Number")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer")
|
||||
.HasDefaultValue(0);
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<DateTime?>("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.Refund", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<decimal>("Amount")
|
||||
.HasPrecision(18, 2)
|
||||
.HasColumnType("numeric(18,2)");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasDefaultValueSql("now()");
|
||||
|
||||
b.Property<long>("OrderId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<string>("Reason")
|
||||
.HasMaxLength(1000)
|
||||
.HasColumnType("character varying(1000)");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<DateTime?>("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<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||
|
||||
b.PrimitiveCollection<string[]>("Categories")
|
||||
.HasColumnType("text[]");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasDefaultValueSql("now()");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasMaxLength(1024)
|
||||
.HasColumnType("character varying(1024)");
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("boolean")
|
||||
.HasDefaultValue(false);
|
||||
|
||||
b.Property<string>("ImageUrl")
|
||||
.HasMaxLength(1024)
|
||||
.HasColumnType("character varying(1024)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("character varying(255)");
|
||||
|
||||
b.Property<string>("Summary")
|
||||
.IsRequired()
|
||||
.HasMaxLength(512)
|
||||
.HasColumnType("character varying(512)");
|
||||
|
||||
b.PrimitiveCollection<string[]>("ThumbnailUrls")
|
||||
.HasColumnType("text[]");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<DateTime?>("UpdatedAt")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasDefaultValueSql("now()");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Products", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Products.Entities.ProductPrice", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<decimal>("Amount")
|
||||
.HasPrecision(18, 2)
|
||||
.HasColumnType("numeric(18,2)");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasDefaultValueSql("now()");
|
||||
|
||||
b.Property<decimal>("Discount")
|
||||
.HasPrecision(18, 2)
|
||||
.HasColumnType("numeric(18,2)");
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("boolean")
|
||||
.HasDefaultValue(false);
|
||||
|
||||
b.Property<long>("ProductId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<DateTime?>("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<long>("AuthorId");
|
||||
|
||||
b1.Property<int>("__synthesizedOrdinal")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b1.Property<string>("ImageUrl");
|
||||
|
||||
b1.Property<string>("Name");
|
||||
|
||||
b1.Property<int>("Type");
|
||||
|
||||
b1.Property<string>("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<long>("CustomerId");
|
||||
|
||||
b1.Property<int>("__synthesizedOrdinal")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b1.Property<string>("ImageUrl");
|
||||
|
||||
b1.Property<string>("Name");
|
||||
|
||||
b1.Property<int>("Type");
|
||||
|
||||
b1.Property<string>("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<long>("BookPageId");
|
||||
|
||||
b1.Property<int>("__synthesizedOrdinal")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b1.Property<string>("Description");
|
||||
|
||||
b1.Property<string>("Tag");
|
||||
|
||||
b1.Property<string>("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.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<long>("ProductId");
|
||||
|
||||
b1.Property<string>("CopyrightInfo");
|
||||
|
||||
b1.Property<string>("ManufactureDate");
|
||||
|
||||
b1.Property<string>("Manufacturer");
|
||||
|
||||
b1.Property<string>("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.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("Prices");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
-37
@@ -1,37 +0,0 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace LiteCharms.Features.MidrandBooks.Postgres.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddedCategories : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Categories",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<long>(type: "bigint", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
Name = table.Column<string>(type: "character varying(15)", maxLength: 15, nullable: false),
|
||||
IsMain = table.Column<bool>(type: "boolean", nullable: false, defaultValue: false),
|
||||
Enabled = table.Column<bool>(type: "boolean", nullable: false, defaultValue: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Categories", x => x.Id);
|
||||
});
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "Categories");
|
||||
}
|
||||
}
|
||||
}
|
||||
-1007
File diff suppressed because it is too large
Load Diff
-68
@@ -1,68 +0,0 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace LiteCharms.Features.MidrandBooks.Postgres.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddedProductCategories : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Categories",
|
||||
table: "Products");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ProductCategories",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<long>(type: "bigint", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
ProductId = table.Column<long>(type: "bigint", nullable: false),
|
||||
CategoryId = table.Column<long>(type: "bigint", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ProductCategories", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ProductCategories_Categories_CategoryId",
|
||||
column: x => x.CategoryId,
|
||||
principalTable: "Categories",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_ProductCategories_Products_ProductId",
|
||||
column: x => x.ProductId,
|
||||
principalTable: "Products",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ProductCategories_CategoryId",
|
||||
table: "ProductCategories",
|
||||
column: "CategoryId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ProductCategories_ProductId",
|
||||
table: "ProductCategories",
|
||||
column: "ProductId");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "ProductCategories");
|
||||
|
||||
migrationBuilder.AddColumn<string[]>(
|
||||
name: "Categories",
|
||||
table: "Products",
|
||||
type: "text[]",
|
||||
nullable: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
Generated
-1235
File diff suppressed because it is too large
Load Diff
-185
@@ -1,185 +0,0 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace LiteCharms.Features.MidrandBooks.Postgres.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddedPaymentObjects : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Gateways",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<long>(type: "bigint", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
||||
UpdatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||
Name = table.Column<string>(type: "text", nullable: false),
|
||||
Website = table.Column<string>(type: "text", nullable: true),
|
||||
MerchantId = table.Column<string>(type: "text", nullable: false),
|
||||
MerchantKey = table.Column<string>(type: "text", nullable: false),
|
||||
Passphrase = table.Column<string>(type: "text", nullable: false),
|
||||
IsSandbox = table.Column<bool>(type: "boolean", nullable: false),
|
||||
Enabled = table.Column<bool>(type: "boolean", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Gateways", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Inventories",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<long>(type: "bigint", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
||||
Status = table.Column<int>(type: "integer", nullable: false),
|
||||
ProductId = table.Column<long>(type: "bigint", nullable: false),
|
||||
ProductPriceId = table.Column<long>(type: "bigint", nullable: false),
|
||||
TotalAllocated = table.Column<int>(type: "integer", nullable: false),
|
||||
TotalReserved = table.Column<int>(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<long>(type: "bigint", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
||||
UpdatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||
Amount = table.Column<decimal>(type: "numeric(18,2)", precision: 18, scale: 2, nullable: false),
|
||||
OrderId = table.Column<long>(type: "bigint", nullable: false),
|
||||
Reference = table.Column<string>(type: "text", nullable: false),
|
||||
Status = table.Column<int>(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<long>(type: "bigint", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
||||
Status = table.Column<int>(type: "integer", nullable: false),
|
||||
OrderId = table.Column<long>(type: "bigint", nullable: false),
|
||||
PaymentId = table.Column<long>(type: "bigint", nullable: false),
|
||||
CustomerId = table.Column<long>(type: "bigint", nullable: false),
|
||||
PaymentGatewayReference = table.Column<string>(type: "text", nullable: true),
|
||||
PaymentGatewayId = table.Column<long>(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");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "Inventories");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Ledger");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Gateways");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Payments");
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-300
@@ -130,34 +130,6 @@ namespace LiteCharms.Features.MidrandBooks.Postgres.Migrations
|
||||
b.ToTable("Authors", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Categories.Entities.Category", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("boolean")
|
||||
.HasDefaultValue(true);
|
||||
|
||||
b.Property<bool>("IsMain")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("boolean")
|
||||
.HasDefaultValue(false);
|
||||
|
||||
b.Property<string>("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<long>("Id")
|
||||
@@ -536,133 +508,6 @@ namespace LiteCharms.Features.MidrandBooks.Postgres.Migrations
|
||||
b.ToTable("BookPages", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Payments.Entities.Payment", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<decimal>("Amount")
|
||||
.HasPrecision(18, 2)
|
||||
.HasColumnType("numeric(18,2)");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasDefaultValueSql("now()");
|
||||
|
||||
b.Property<long>("OrderId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<string>("Reference")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<DateTime?>("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<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasDefaultValueSql("now()");
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsSandbox")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("MerchantId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("MerchantKey")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Passphrase")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<DateTime?>("UpdatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Website")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Gateways", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Payments.Entities.PaymentLedger", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasDefaultValueSql("now()");
|
||||
|
||||
b.Property<long>("CustomerId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<long>("OrderId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<long?>("PaymentGatewayId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<string>("PaymentGatewayReference")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<long>("PaymentId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<int>("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<long>("Id")
|
||||
@@ -713,6 +558,9 @@ namespace LiteCharms.Features.MidrandBooks.Postgres.Migrations
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||
|
||||
b.PrimitiveCollection<string[]>("Categories")
|
||||
.HasColumnType("text[]");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("timestamp with time zone")
|
||||
@@ -757,66 +605,6 @@ namespace LiteCharms.Features.MidrandBooks.Postgres.Migrations
|
||||
b.ToTable("Products", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Products.Entities.ProductCategory", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<long>("CategoryId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<long>("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<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasDefaultValueSql("now()");
|
||||
|
||||
b.Property<long>("ProductId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<long>("ProductPriceId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("TotalAllocated")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("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<long>("Id")
|
||||
@@ -1055,51 +843,6 @@ 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")
|
||||
@@ -1140,44 +883,6 @@ namespace LiteCharms.Features.MidrandBooks.Postgres.Migrations
|
||||
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")
|
||||
@@ -1222,8 +927,6 @@ namespace LiteCharms.Features.MidrandBooks.Postgres.Migrations
|
||||
|
||||
modelBuilder.Entity("LiteCharms.Features.MidrandBooks.Products.Entities.Product", b =>
|
||||
{
|
||||
b.Navigation("Categories");
|
||||
|
||||
b.Navigation("Prices");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
|
||||
@@ -3,7 +3,5 @@
|
||||
[EntityTypeConfiguration<ProductConfiguration, Product>]
|
||||
public class Product : Models.Product
|
||||
{
|
||||
public virtual ICollection<ProductCategory> Categories { get; set; } = [];
|
||||
|
||||
public virtual ICollection<ProductPrice> Prices { get; set; } = [];
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
using LiteCharms.Features.MidrandBooks.Categories.Entities;
|
||||
|
||||
namespace LiteCharms.Features.MidrandBooks.Products.Entities;
|
||||
|
||||
[EntityTypeConfiguration<ProductCategoryConfiguration, ProductCategory>]
|
||||
public class ProductCategory : Models.ProductCategory
|
||||
{
|
||||
public virtual Product? Product { get; set; }
|
||||
|
||||
public virtual Category? Category { get; set; }
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
namespace LiteCharms.Features.MidrandBooks.Products.Entities;
|
||||
|
||||
public sealed class ProductCategoryConfiguration : IEntityTypeConfiguration<ProductCategory>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<ProductCategory> builder)
|
||||
{
|
||||
builder.ToTable("ProductCategories");
|
||||
|
||||
builder.HasKey(p => p.Id);
|
||||
builder.Property(p => p.ProductId).IsRequired();
|
||||
builder.Property(p => p.CategoryId).IsRequired();
|
||||
|
||||
builder.HasOne(p => p.Product)
|
||||
.WithMany(p => p.Categories)
|
||||
.HasForeignKey(p => p.ProductId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.HasOne(c => c.Category)
|
||||
.WithMany()
|
||||
.HasForeignKey(c => c.CategoryId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ public sealed class ProductConfiguration : IEntityTypeConfiguration<Product>
|
||||
builder.Property(f => f.Description).HasMaxLength(1024);
|
||||
builder.Property(f => f.ImageUrl).HasMaxLength(1024);
|
||||
builder.Property(f => f.Enabled).HasDefaultValue(false);
|
||||
builder.Property(f => f.Categories).IsRequired(false);
|
||||
builder.Property(f => f.ThumbnailUrls).IsRequired(false);
|
||||
|
||||
builder.OwnsOne(f => f.Metadata, b => { b.ToJson(); });
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
namespace LiteCharms.Features.MidrandBooks.Products.Entities;
|
||||
|
||||
[EntityTypeConfiguration<ProductInventoryConfiguration, ProductInventory>]
|
||||
public class ProductInventory : Models.ProductInventory
|
||||
{
|
||||
public virtual Product? Product { get; set; }
|
||||
|
||||
public virtual ProductPrice? Price { get; set; }
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
namespace LiteCharms.Features.MidrandBooks.Products.Entities;
|
||||
|
||||
public sealed class ProductInventoryConfiguration : IEntityTypeConfiguration<ProductInventory>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<ProductInventory> 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);
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,8 @@ public class Product
|
||||
|
||||
public string[]? ThumbnailUrls { get; set; }
|
||||
|
||||
public string[]? Categories { get; set; }
|
||||
|
||||
public ProductMetadata? Metadata { get; set; }
|
||||
|
||||
public ProductPrice? Price { get; set; }
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
namespace LiteCharms.Features.MidrandBooks.Products.Models;
|
||||
|
||||
public class ProductCategory
|
||||
{
|
||||
public long Id { get; set; }
|
||||
|
||||
public long ProductId { get; set; }
|
||||
|
||||
public long CategoryId { get; set; }
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
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; }
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using LiteCharms.Features.MidrandBooks.Abstractions;
|
||||
using LiteCharms.Features.MidrandBooks.Categories.Models;
|
||||
using LiteCharms.Features.MidrandBooks.Extensions;
|
||||
using LiteCharms.Features.MidrandBooks.Postgres;
|
||||
using LiteCharms.Features.MidrandBooks.Products.Models;
|
||||
@@ -9,100 +8,6 @@ namespace LiteCharms.Features.MidrandBooks.Products;
|
||||
|
||||
public sealed class ProductService(IDbContextFactory<MidrandBooksDbContext> contextFactory) : IService
|
||||
{
|
||||
public async ValueTask<Result> AddProductCategoryAsync(long productId, long categoryId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await using var context = await contextFactory.CreateDbContextAsync(cancellationToken);
|
||||
|
||||
if (!await context.Products.AnyAsync(p => p.Id == productId && p.Enabled, cancellationToken))
|
||||
return Result.Fail("Product does not exist");
|
||||
|
||||
if (!await context.Categories.AnyAsync(c => c.Id == categoryId && c.Enabled, cancellationToken))
|
||||
return Result.Fail("Category does not exist");
|
||||
|
||||
if (await context.ProductCategories.AnyAsync(c => c.ProductId == productId && c.CategoryId == categoryId, cancellationToken))
|
||||
return Result.Fail("Category already assigned to product");
|
||||
|
||||
context.ProductCategories.Add(new Entities.ProductCategory
|
||||
{
|
||||
ProductId = productId,
|
||||
CategoryId = categoryId,
|
||||
});
|
||||
|
||||
return await context.SaveChangesAsync(cancellationToken) > 0
|
||||
? Result.Ok()
|
||||
: Result.Fail("Could not add category to product");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Result.Fail(new Error(ex.Message).CausedBy(ex));
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask<Result<Category[]>> GetProductCategoriesAsync(long productId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await using var context = await contextFactory.CreateDbContextAsync(cancellationToken);
|
||||
|
||||
var categories = await context.ProductCategories.AsNoTracking()
|
||||
.Where(p => p.ProductId == productId)
|
||||
.OrderByDescending(o => o.Id)
|
||||
.Select(p => p.Category)
|
||||
.ToArrayAsync(cancellationToken);
|
||||
|
||||
return categories?.Length > 0
|
||||
? Result.Ok(categories.Select(c => c!.ToModel()).ToArray())
|
||||
: Result.Fail<Category[]>("Failed to get product categories");
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Result.Fail(new Error(ex.Message).CausedBy(ex));
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask<Result> DeleteProductCategoryAsync(long productId, long categoryId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await using var context = await contextFactory.CreateDbContextAsync(cancellationToken);
|
||||
|
||||
var rowsDeleted = await context.ProductCategories
|
||||
.Where(p => p.ProductId == productId && p.CategoryId == categoryId)
|
||||
.ExecuteDeleteAsync(cancellationToken);
|
||||
|
||||
return rowsDeleted > 0
|
||||
? Result.Ok()
|
||||
: Result.Fail("No product categories were deleted");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Result.Fail(new Error(ex.Message).CausedBy(ex));
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask<Result> DeleteAllProductCategoriesAsync(long productId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await using var context = await contextFactory.CreateDbContextAsync(cancellationToken);
|
||||
|
||||
var rowsDeleted = await context.ProductCategories
|
||||
.Where(p => p.ProductId == productId)
|
||||
.ExecuteDeleteAsync(cancellationToken);
|
||||
|
||||
return rowsDeleted > 0
|
||||
? Result.Ok()
|
||||
: Result.Fail("No product categories were deleted");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Result.Fail(new Error(ex.Message).CausedBy(ex));
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask<Result> UpdateProductPriceStatusAsync(long productPriceId, bool isEnabled, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
@@ -163,6 +68,9 @@ public sealed class ProductService(IDbContextFactory<MidrandBooksDbContext> cont
|
||||
if (!string.IsNullOrWhiteSpace(filter.Title))
|
||||
query = query.Where(p => EF.Functions.ILike(p.Name!, $"%{filter.Title}%"));
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(filter.Category))
|
||||
query = query.Where(p => p.Categories.Contains(filter.Category));
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(filter.Manufacturer))
|
||||
query = query.Where(p => EF.Functions.ILike(p.Metadata!.Manufacturer!, $"%{filter.Manufacturer}%"));
|
||||
|
||||
@@ -244,6 +152,7 @@ public sealed class ProductService(IDbContextFactory<MidrandBooksDbContext> cont
|
||||
ImageUrl = request.ImageUrl,
|
||||
ThumbnailUrls = request.ThumbnailUrls,
|
||||
Metadata = request.Metadata,
|
||||
Categories = request.Categories,
|
||||
Enabled = true
|
||||
});
|
||||
|
||||
@@ -304,8 +213,7 @@ public sealed class ProductService(IDbContextFactory<MidrandBooksDbContext> cont
|
||||
{
|
||||
await using var context = await contextFactory.CreateDbContextAsync(cancellationToken);
|
||||
|
||||
var product = await context.Products
|
||||
.AsNoTracking().FirstOrDefaultAsync(p => p.Id == productId, cancellationToken);
|
||||
var product = await context.Products.AsNoTracking().FirstOrDefaultAsync(p => p.Id == productId, cancellationToken);
|
||||
|
||||
return product is null
|
||||
? Result.Fail<Product>(new Error($"Product with ID {productId} not found."))
|
||||
|
||||
@@ -1,35 +1,5 @@
|
||||
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,
|
||||
@@ -144,65 +114,4 @@ 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
|
||||
}
|
||||
@@ -6,6 +6,8 @@ public sealed class ProductFilter
|
||||
|
||||
public string? Title { get; set; }
|
||||
|
||||
public string? Category { get; set; }
|
||||
|
||||
public string? Manufacturer { get; set; }
|
||||
|
||||
public string? SerialNumber { get; set; }
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
namespace LiteCharms.Features.Models;
|
||||
|
||||
public class SearchState
|
||||
{
|
||||
public string Query { get; private set; } = string.Empty;
|
||||
|
||||
public event Action? OnSearchSubmitted;
|
||||
|
||||
public void UpdateQuery(string newQuery) => Query = newQuery;
|
||||
|
||||
public void SubmitSearch() => OnSearchSubmitted?.Invoke();
|
||||
}
|
||||
Reference in New Issue
Block a user