initial commit

This commit is contained in:
2026-07-21 14:35:37 +07:00
commit 0027997ff9
798 changed files with 59083 additions and 0 deletions
+201
View File
@@ -0,0 +1,201 @@
using Indotalent.ConfigBackEnd.Extensions;
using Indotalent.ConfigBackEnd.Interfaces;
using Indotalent.Data.Abstracts;
using Indotalent.Data.Entities;
using Indotalent.Data.Interfaces;
using Indotalent.Infrastructure.AutoNumberGenerator;
using Indotalent.Shared.Consts;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
namespace Indotalent.Infrastructure.Database;
public class AppDbContext : IdentityDbContext<ApplicationUser>
{
private readonly IServiceScopeFactory _scopeFactory;
private readonly ICurrentUserService _currentUserService;
public AppDbContext(
DbContextOptions<AppDbContext> options,
IServiceScopeFactory scopeFactory,
ICurrentUserService currentUserService) : base(options)
{
_scopeFactory = scopeFactory;
_currentUserService = currentUserService;
}
public DbSet<AutoNumberSequence> AutoNumberSequence { get; set; } = default!;
public DbSet<Currency> Currency { get; set; } = default!;
public DbSet<Company> Company { get; set; } = default!;
public DbSet<Tax> Tax { get; set; } = default!;
public DbSet<PaymentMethod> PaymentMethod { get; set; } = default!;
public DbSet<Booking> Booking { get; set; } = default!;
public DbSet<BookingGroup> BookingGroup { get; set; } = default!;
public DbSet<BookingResource> BookingResource { get; set; } = default!;
public DbSet<Bill> Bill { get; set; } = default!;
public DbSet<PaymentDisburse> PaymentDisburse { get; set; } = default!;
public DbSet<Invoice> Invoice { get; set; } = default!;
public DbSet<PaymentReceive> PaymentReceive { get; set; } = default!;
public DbSet<ProductGroup> ProductGroup { get; set; } = default!;
public DbSet<PurchaseOrder> PurchaseOrder { get; set; } = default!;
public DbSet<PurchaseOrderItem> PurchaseOrderItem { get; set; } = default!;
public DbSet<Customer> Customer { get; set; } = default!;
public DbSet<CustomerCategory> CustomerCategory { get; set; } = default!;
public DbSet<CustomerContact> CustomerContact { get; set; } = default!;
public DbSet<CustomerGroup> CustomerGroup { get; set; } = default!;
public DbSet<Product> Product { get; set; } = default!;
public DbSet<SalesOrder> SalesOrder { get; set; } = default!;
public DbSet<SalesOrderItem> SalesOrderItem { get; set; } = default!;
public DbSet<Todo> Todo { get; set; } = default!;
public DbSet<TodoItem> TodoItem { get; set; } = default!;
public DbSet<UnitMeasure> UnitMeasure { get; set; } = default!;
public DbSet<Vendor> Vendor { get; set; } = default!;
public DbSet<VendorCategory> VendorCategory { get; set; } = default!;
public DbSet<VendorContact> VendorContact { get; set; } = default!;
public DbSet<VendorGroup> VendorGroup { get; set; } = default!;
public DbSet<Warehouse> Warehouse { get; set; } = default!;
public DbSet<InventoryTransaction> InventoryTransaction { get; set; } = default!;
public DbSet<Employee> Employee { get; set; } = default!;
public DbSet<EmployeeCategory> EmployeeCategory { get; set; } = default!;
public DbSet<EmployeeGroup> EmployeeGroup { get; set; } = default!;
public override int SaveChanges()
{
ApplySoftDelete();
ApplyAudit(_currentUserService.UserId ?? string.Empty);
return base.SaveChanges();
}
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
{
ChangeTracker.DetectChanges();
ApplySoftDelete();
ApplyAudit(_currentUserService.UserId ?? string.Empty);
await ApplyAutoNumber(cancellationToken);
return await base.SaveChangesAsync(cancellationToken);
}
private void ApplySoftDelete()
{
var entries = ChangeTracker.Entries<IHasIsDeleted>()
.Where(e => e.State == EntityState.Deleted);
foreach (var entry in entries)
{
entry.State = EntityState.Modified;
entry.Entity.IsDeleted = true;
}
}
private void ApplyAudit(string userId)
{
var entries = ChangeTracker.Entries<IHasAudit>()
.Where(e => e.State == EntityState.Added || e.State == EntityState.Modified)
.ToList();
foreach (var entry in entries)
{
var now = DateTimeOffset.UtcNow;
var auditEntity = entry.Entity;
if (entry.State == EntityState.Added)
{
auditEntity.CreatedAt = now;
auditEntity.CreatedBy = userId;
}
else
{
entry.Property(nameof(IHasAudit.CreatedAt)).IsModified = false;
entry.Property(nameof(IHasAudit.CreatedBy)).IsModified = false;
}
auditEntity.UpdatedAt = now;
auditEntity.UpdatedBy = userId;
}
}
private async Task ApplyAutoNumber(CancellationToken ct)
{
var entries = ChangeTracker
.Entries<IHasAutoNumber>()
.Where(e => e.State == EntityState.Added && string.IsNullOrEmpty(e.Entity.AutoNumber))
.ToList();
if (!entries.Any()) return;
using var scope = _scopeFactory.CreateScope();
var generator = scope.ServiceProvider.GetRequiredService<AutoNumberGeneratorService>();
foreach (var entry in entries)
{
var entityName = entry.Entity.GetType().Name;
var shortName = entityName.ToShortNameConsonant(3);
entry.Entity.AutoNumber = await generator.GenerateNextNumberAsync(
entityName: entityName,
prefixTemplate: $"{shortName}/{{Year}}/",
paddingLength: 4,
cancellationToken: ct
);
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
if (Database.ProviderName?.Contains("MySql") == true)
{
foreach (var entity in modelBuilder.Model.GetEntityTypes())
{
if (entity.GetTableName()!.StartsWith("AspNet"))
{
foreach (var property in entity.GetProperties().Where(p => p.ClrType == typeof(string)))
{
property.SetMaxLength(191);
}
}
}
}
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
var type = entityType.ClrType;
if (typeof(BaseEntity).IsAssignableFrom(type))
{
modelBuilder.Entity(type)
.Property("Id")
.HasMaxLength(GlobalConsts.StringLengthId)
.IsFixedLength();
}
if (typeof(IHasAudit).IsAssignableFrom(type))
{
modelBuilder.Entity(type)
.Property(nameof(IHasAudit.CreatedBy))
.HasMaxLength(GlobalConsts.StringLengthShort);
modelBuilder.Entity(type)
.Property(nameof(IHasAudit.UpdatedBy))
.HasMaxLength(GlobalConsts.StringLengthShort);
}
if (typeof(IHasIsDeleted).IsAssignableFrom(type))
{
modelBuilder.Entity(type).HasQueryFilter(GetNotDeletedOnlyFilter(type));
}
}
modelBuilder.ApplyConfigurationsFromAssembly(typeof(AppDbContext).Assembly);
}
private static System.Linq.Expressions.LambdaExpression GetNotDeletedOnlyFilter(Type type)
{
var parameter = System.Linq.Expressions.Expression.Parameter(type, "e");
var property = System.Linq.Expressions.Expression.Property(parameter, nameof(IHasIsDeleted.IsDeleted));
var falseConstant = System.Linq.Expressions.Expression.Constant(false);
var comparison = System.Linq.Expressions.Expression.Equal(property, falseConstant);
return System.Linq.Expressions.Expression.Lambda(comparison, parameter);
}
}
@@ -0,0 +1,24 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Utils;
namespace Indotalent.Infrastructure.Database;
public static class AppDbContextExtensions
{
public static void CalculateInvenTrans(this AppDbContext context, InventoryTransaction transaction)
{
InventoryTransactionHelper.CalculateInvenTrans(context, transaction);
}
public static double GetStock(this AppDbContext context, string? warehouseId, string? productId, string? currentId = null)
{
return InventoryTransactionHelper.GetStock(context, warehouseId, productId, currentId);
}
public static void RecalculatePurchaseOrder(this AppDbContext context, string purchaseOrderId)
{
PurchaseOrderHelper.Recalculate(context, purchaseOrderId);
}
public static void RecalculateSalesOrder(this AppDbContext context, string salesOrderId)
{
SalesOrderHelper.Recalculate(context, salesOrderId);
}
}
+53
View File
@@ -0,0 +1,53 @@
using Microsoft.EntityFrameworkCore;
namespace Indotalent.Infrastructure.Database;
public static class DI
{
public static IServiceCollection AddDatabaseService(this IServiceCollection services, IConfiguration configuration)
{
var dbSettings = configuration.GetSection("DatabaseSettings").Get<DatabaseSettingsModel>();
if (dbSettings?.MsSQL?.IsUsed == true)
{
services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(
dbSettings.MsSQL.ConnectionString,
sqlOptions =>
{
sqlOptions.CommandTimeout(dbSettings.MsSQL.TimeoutInSeconds);
}
)
);
}
else if (dbSettings?.PostgreSQL?.IsUsed == true)
{
services.AddDbContext<AppDbContext>(options =>
options.UseNpgsql(
dbSettings.PostgreSQL.ConnectionString,
npgsqlOptions =>
{
npgsqlOptions.CommandTimeout(dbSettings.PostgreSQL.TimeoutInSeconds);
}
)
);
}
else if (dbSettings?.MySQL?.IsUsed == true)
{
services.AddDbContext<AppDbContext>(options =>
options.UseMySQL(
dbSettings.MySQL.ConnectionString,
mySqlOptions =>
{
mySqlOptions.CommandTimeout(dbSettings.MySQL.TimeoutInSeconds);
mySqlOptions.MigrationsAssembly(typeof(AppDbContext).Assembly.FullName);
}
)
);
}
services.AddScoped<DatabaseService>();
return services;
}
}
@@ -0,0 +1,8 @@
namespace Indotalent.Infrastructure.Database;
public class DatabaseProviderModel
{
public bool IsUsed { get; set; }
public string ConnectionString { get; set; } = string.Empty;
public int TimeoutInSeconds { get; set; }
}
+138
View File
@@ -0,0 +1,138 @@
using Indotalent.Data.Entities;
using Indotalent.Infrastructure.Authentication.Identity;
using Indotalent.Infrastructure.Authorization.Identity;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
namespace Indotalent.Infrastructure.Database;
public static class DatabaseSeeder
{
public static async Task SeedAsync(IServiceProvider serviceProvider)
{
var roleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
var userManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();
var configuration = serviceProvider.GetRequiredService<IConfiguration>();
var context = serviceProvider.GetRequiredService<AppDbContext>();
await SeedIdentityAsync(roleManager, userManager, configuration);
await SeedCurrenciesAsync(context);
await SeedCompanyAsync(context);
await SeedTaxAsync(context);
await SeedSystemWarehouseAsync(context);
await DatabaseSeederDemo.SeedAsync(serviceProvider);
}
private static async Task SeedIdentityAsync(RoleManager<IdentityRole> roleManager, UserManager<ApplicationUser> userManager, IConfiguration configuration)
{
var adminSettings = configuration.GetSection("IdentitySettings:DefaultAdmin").Get<DefaultAdminSettings>();
if (adminSettings == null) return;
foreach (var roleName in ApplicationRoles.AllRoles)
{
if (!await roleManager.RoleExistsAsync(roleName))
{
await roleManager.CreateAsync(new IdentityRole(roleName));
}
}
var existingUser = await userManager.FindByEmailAsync(adminSettings.Email);
if (existingUser == null)
{
var defaultAdmin = DefaultUserConfig.GetAdminUser(adminSettings);
var createAdmin = await userManager.CreateAsync(defaultAdmin, adminSettings.Password);
if (createAdmin.Succeeded)
{
await userManager.AddToRolesAsync(defaultAdmin, ApplicationRoles.AllRoles);
}
}
}
private static async Task SeedCurrenciesAsync(AppDbContext context)
{
if (await context.Set<Currency>().AnyAsync()) return;
var currencies = new List<Currency>
{
new() { Name = "US Dollar", Code = "USD", Symbol = "$", Description = "United States official currency", CountryOwner = "United States" },
new() { Name = "Euro", Code = "EUR", Symbol = "€", Description = "Eurozone member states currency", CountryOwner = "European Union" },
new() { Name = "British Pound", Code = "GBP", Symbol = "£", Description = "Official currency of the UK", CountryOwner = "United Kingdom" },
new() { Name = "Indonesian Rupiah", Code = "IDR", Symbol = "Rp", Description = "Official currency of Indonesia", CountryOwner = "Indonesia" }
};
await context.Set<Currency>().AddRangeAsync(currencies);
await context.SaveChangesAsync();
}
private static async Task SeedCompanyAsync(AppDbContext context)
{
if (await context.Set<Company>().AnyAsync()) return;
var usdCurrency = await context.Set<Currency>().FirstOrDefaultAsync(x => x.Code == "USD");
if (usdCurrency == null) return;
var companies = new List<Company>
{
new()
{
Name = "Acme Global Solutions Inc.",
Description = "A leading provider of enterprise-grade cloud software solutions.",
IsDefault = true,
CurrencyId = usdCurrency.Id,
TaxIdentification = "EIN 12-3456789",
BusinessLicense = "LC-987654321",
StreetAddress = "One World Trade Center, Suite 85",
City = "New York",
StateProvince = "NY",
ZipCode = "10007",
Phone = "+1 212 555 0198",
Email = "hr@acmeglobal.com",
SocialMediaLinkedIn = "linkedin.com/company/acme-global",
CompanyLogo = "/images/logos/acme-logo.png",
OtherInformation1 = "Corporate Headquarters",
OtherInformation2 = "Technology & SaaS",
OtherInformation3 = "Fortune 500 Candidate"
}
};
await context.Set<Company>().AddRangeAsync(companies);
await context.SaveChangesAsync();
}
private static async Task SeedTaxAsync(AppDbContext context)
{
if (await context.Set<Tax>().AnyAsync()) return;
var taxes = new List<Tax>
{
new Tax { Code = "NOTAX", Name = "NOTAX", PercentageValue = 0 },
new Tax { Code = "T10", Name = "T10", PercentageValue = 10 },
new Tax { Code = "T15", Name = "T15", PercentageValue = 15 },
new Tax { Code = "T20", Name = "T20", PercentageValue = 20 },
};
await context.Set<Tax>().AddRangeAsync(taxes);
await context.SaveChangesAsync();
}
private static async Task SeedSystemWarehouseAsync(AppDbContext context)
{
if (await context.Set<Warehouse>().AnyAsync(x => x.SystemWarehouse == true)) return;
var warehouses = new List<Warehouse>
{
new Warehouse { Name = "Customer", SystemWarehouse = true },
new Warehouse { Name = "Vendor", SystemWarehouse = true },
new Warehouse { Name = "Transfer", SystemWarehouse = true },
new Warehouse { Name = "Adjustment", SystemWarehouse = true },
new Warehouse { Name = "StockCount", SystemWarehouse = true },
new Warehouse { Name = "Scrapping", SystemWarehouse = true }
};
await context.Set<Warehouse>().AddRangeAsync(warehouses);
await context.SaveChangesAsync();
}
}
@@ -0,0 +1,61 @@
using Indotalent.Data.Entities;
using Indotalent.Infrastructure.Database.Demo;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace Indotalent.Infrastructure.Database;
public static class DatabaseSeederDemo
{
public static async Task SeedAsync(IServiceProvider serviceProvider)
{
var roleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
var userManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();
var configuration = serviceProvider.GetRequiredService<IConfiguration>();
var context = serviceProvider.GetRequiredService<AppDbContext>();
// 1. Master Data (Must be first)
await UserSeeder.GenerateDataAsync(userManager, context, configuration);
await UnitMeasureSeeder.GenerateDataAsync(context);
await WarehouseSeeder.GenerateDataAsync(context);
await PaymentMethodSeeder.GenerateDataAsync(context);
await EmployeeGroupSeeder.GenerateDataAsync(context);
await EmployeeCategorySeeder.GenerateDataAsync(context);
await EmployeeSeeder.GenerateDataAsync(context);
// 2. Customer & Vendor Related
await CustomerCategorySeeder.GenerateDataAsync(context);
await CustomerGroupSeeder.GenerateDataAsync(context);
await CustomerSeeder.GenerateDataAsync(context);
await CustomerContactSeeder.GenerateDataAsync(context);
await VendorCategorySeeder.GenerateDataAsync(context);
await VendorGroupSeeder.GenerateDataAsync(context);
await VendorSeeder.GenerateDataAsync(context);
await VendorContactSeeder.GenerateDataAsync(context);
// 3. Product Related
await ProductGroupSeeder.GenerateDataAsync(context);
await ProductSeeder.GenerateDataAsync(context);
// 4. Sales Related
await SalesOrderSeeder.GenerateDataAsync(context);
// 5. Purchase Related
await PurchaseOrderSeeder.GenerateDataAsync(context);
// 6. Inventory Operations
// 7. Finance & Project Related
await InvoiceSeeder.GenerateDataAsync(context);
await PaymentReceiveSeeder.GenerateDataAsync(context);
await BillSeeder.GenerateDataAsync(context);
await PaymentDisburseSeeder.GenerateDataAsync(context);
await BookingGroupSeeder.GenerateDataAsync(context);
await BookingResourceSeeder.GenerateDataAsync(context);
await BookingSeeder.GenerateDataAsync(context);
}
}
@@ -0,0 +1,18 @@
using Microsoft.Extensions.Options;
namespace Indotalent.Infrastructure.Database;
public class DatabaseService(IOptions<DatabaseSettingsModel> options)
{
private readonly DatabaseSettingsModel _settings = options.Value;
public DatabaseSettingsModel GetConfiguration() => _settings;
public DatabaseProviderModel GetActiveProvider()
{
if (_settings.MsSQL.IsUsed) return _settings.MsSQL;
if (_settings.MySQL.IsUsed) return _settings.MySQL;
if (_settings.PostgreSQL.IsUsed) return _settings.PostgreSQL;
return new DatabaseProviderModel();
}
}
@@ -0,0 +1,8 @@
namespace Indotalent.Infrastructure.Database;
public class DatabaseSettingsModel
{
public DatabaseProviderModel MsSQL { get; set; } = new();
public DatabaseProviderModel MySQL { get; set; } = new();
public DatabaseProviderModel PostgreSQL { get; set; } = new();
}
+104
View File
@@ -0,0 +1,104 @@
using Indotalent.ConfigBackEnd.Extensions;
using Indotalent.Data.Entities;
using Indotalent.Data.Enums;
using Microsoft.EntityFrameworkCore;
namespace Indotalent.Infrastructure.Database.Demo;
public static class BillSeeder
{
public static async Task GenerateDataAsync(AppDbContext context)
{
if (await context.Bill.AnyAsync()) return;
var random = new Random();
var entityName = nameof(Bill);
var dateFinish = DateTime.Now;
var dateStart = new DateTime(dateFinish.AddMonths(-12).Year, dateFinish.AddMonths(-12).Month, 1);
var confirmedPurchaseOrders = await context.PurchaseOrder
.Where(po => po.OrderStatus == PurchaseOrderStatus.Confirmed)
.Select(po => po.Id)
.ToListAsync();
if (!confirmedPurchaseOrders.Any()) return;
for (DateTime date = dateStart; date < dateFinish; date = date.AddMonths(1))
{
DateTime[] billDates = GetRandomDays(date.Year, date.Month, 5);
foreach (var billDate in billDates)
{
if (confirmedPurchaseOrders.Count == 0) break;
var status = GetRandomStatus(random);
var purchaseOrderId = GetRandomAndRemove(confirmedPurchaseOrders, random);
var autoNo = await context.GenerateAutoNumberAsync(
entityName: entityName,
prefixTemplate: $"{entityName.ToShortNameConsonant(3)}/{{Year}}/"
);
var bill = new Bill
{
AutoNumber = autoNo,
BillDate = billDate,
BillStatus = status,
Description = $"Bill for {billDate:MMMM yyyy}",
PurchaseOrderId = purchaseOrderId
};
await context.Bill.AddAsync(bill);
}
}
await context.SaveChangesAsync();
}
private static BillStatus GetRandomStatus(Random random)
{
var statuses = new[]
{
BillStatus.Draft,
BillStatus.Cancelled,
BillStatus.Confirmed
};
var weights = new[] { 1, 1, 4 };
int totalWeight = weights.Sum();
int randomNumber = random.Next(0, totalWeight);
for (int i = 0; i < statuses.Length; i++)
{
if (randomNumber < weights[i]) return statuses[i];
randomNumber -= weights[i];
}
return BillStatus.Confirmed;
}
private static string GetRandomAndRemove(List<string> list, Random random)
{
int index = random.Next(list.Count);
string value = list[index];
list.RemoveAt(index);
return value;
}
private static DateTime[] GetRandomDays(int year, int month, int count)
{
var random = new Random();
int daysInMonthCount = DateTime.DaysInMonth(year, month);
var daysInMonth = Enumerable.Range(1, daysInMonthCount).ToList();
var selectedDays = new List<int>();
for (int i = 0; i < count && daysInMonth.Count > 0; i++)
{
int day = daysInMonth[random.Next(daysInMonth.Count)];
selectedDays.Add(day);
daysInMonth.Remove(day);
}
return selectedDays.Select(day => new DateTime(year, month, day)).ToArray();
}
}
@@ -0,0 +1,33 @@
using Indotalent.Data.Entities;
using Microsoft.EntityFrameworkCore;
namespace Indotalent.Infrastructure.Database.Demo;
public static class BookingGroupSeeder
{
public static async Task GenerateDataAsync(AppDbContext context)
{
if (await context.BookingGroup.AnyAsync()) return;
var bookingGroups = new List<BookingGroup>
{
new BookingGroup { Name = "Massage & Spa Suites" },
new BookingGroup { Name = "Private Fitness Training" },
new BookingGroup { Name = "Group Exercise Classes" },
new BookingGroup { Name = "Yoga & Pilates Studios" },
new BookingGroup { Name = "Hydrotherapy & Pool Lanes" },
new BookingGroup { Name = "Sauna & Steam Facilities" },
new BookingGroup { Name = "Holistic Health Consultations" },
new BookingGroup { Name = "Beauty & Aesthetic Stations" },
new BookingGroup { Name = "Meditation & Recovery Lounges" },
new BookingGroup { Name = "Physical Therapy Zones" }
};
foreach (var bookingGroup in bookingGroups)
{
await context.BookingGroup.AddAsync(bookingGroup);
}
await context.SaveChangesAsync();
}
}
@@ -0,0 +1,161 @@
using Indotalent.Data.Entities;
using Microsoft.EntityFrameworkCore;
namespace Indotalent.Infrastructure.Database.Demo;
public static class BookingResourceSeeder
{
public static async Task GenerateDataAsync(AppDbContext context)
{
if (await context.BookingResource.AnyAsync()) return;
var groups = await context.BookingGroup.ToListAsync();
var resources = new List<BookingResource>();
foreach (var group in groups)
{
if (group.Name == "Massage & Spa Suites")
{
resources.Add(new BookingResource { Name = "Therapeutic Suite 101", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Therapeutic Suite 102", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Therapeutic Suite 103", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Therapeutic Suite 104", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Therapeutic Suite 105", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Luxury VIP Suite A", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Luxury VIP Suite B", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Couples Retreat Room 1", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Couples Retreat Room 2", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Deep Tissue Suite 201", BookingGroupId = group.Id });
}
if (group.Name == "Private Fitness Training")
{
resources.Add(new BookingResource { Name = "Performance Zone 1", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Performance Zone 2", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Performance Zone 3", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Strength Lab A", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Strength Lab B", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Functional Training Area 1", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Functional Training Area 2", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Elite Trainer Station 1", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Elite Trainer Station 2", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Cardio Assessment Bay", BookingGroupId = group.Id });
}
if (group.Name == "Group Exercise Classes")
{
resources.Add(new BookingResource { Name = "Grand Aerobics Hall", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "HIIT Dungeon 1", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "HIIT Dungeon 2", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Spin Revolution Studio", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Zumba Fitness Floor", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Barre Sculpt Studio", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Kickboxing Zone", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "BodyPump Arena", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Flexibility Studio", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Core Strength Room", BookingGroupId = group.Id });
}
if (group.Name == "Yoga & Pilates Studios")
{
resources.Add(new BookingResource { Name = "Zen Meditation Garden", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Hot Yoga Studio A", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Hot Yoga Studio B", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Vinyasa Flow Room", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Pilates Reformer Station 1", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Pilates Reformer Station 2", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Pilates Reformer Station 3", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Pilates Reformer Station 4", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Pilates Reformer Station 5", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Aerial Yoga Lounge", BookingGroupId = group.Id });
}
if (group.Name == "Hydrotherapy & Pool Lanes")
{
resources.Add(new BookingResource { Name = "Olympic Lap Lane 1", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Olympic Lap Lane 2", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Olympic Lap Lane 3", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Olympic Lap Lane 4", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Warm Water Therapy Pool", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Saltwater Plunge Pool", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Hydro-Massage Jet Bay 1", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Hydro-Massage Jet Bay 2", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Watsu Therapy Tank", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Aquatic Rehab Zone", BookingGroupId = group.Id });
}
if (group.Name == "Sauna & Steam Facilities")
{
resources.Add(new BookingResource { Name = "Finnish Dry Sauna 1", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Finnish Dry Sauna 2", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Infrared Detox Cabin A", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Infrared Detox Cabin B", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Eucalyptus Steam Room 1", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Eucalyptus Steam Room 2", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Himalayan Salt Sauna", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Turkish Hammam Station", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Cryo-Recovery Room", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Aromatherapy Mist Room", BookingGroupId = group.Id });
}
if (group.Name == "Holistic Health Consultations")
{
resources.Add(new BookingResource { Name = "Nutritionist Office 1", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Nutritionist Office 2", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Lifestyle Coaching Room A", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Lifestyle Coaching Room B", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Naturopathic Clinic 1", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Mental Wellness Suite", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Biometric Testing Lab", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Ayurvedic Consultation Room", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Wellness Assessment Hub", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Health Screening Room", BookingGroupId = group.Id });
}
if (group.Name == "Beauty & Aesthetic Stations")
{
resources.Add(new BookingResource { Name = "Advanced Facial Suite 1", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Advanced Facial Suite 2", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Laser Treatment Room", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Microdermabrasion Station", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Mani-Pedi Lounge Station 1", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Mani-Pedi Lounge Station 2", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Mani-Pedi Lounge Station 3", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Mani-Pedi Lounge Station 4", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Brow & Lash Studio", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Organic Makeup Counter", BookingGroupId = group.Id });
}
if (group.Name == "Meditation & Recovery Lounges")
{
resources.Add(new BookingResource { Name = "Zero-Gravity Pod 1", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Zero-Gravity Pod 2", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Zero-Gravity Pod 3", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Zero-Gravity Pod 4", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Compression Therapy Lounge", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Sound Bath Sanctuary", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Deep Sleep Cabin A", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Deep Sleep Cabin B", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Mindfulness Corner 1", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Mindfulness Corner 2", BookingGroupId = group.Id });
}
if (group.Name == "Physical Therapy Zones")
{
resources.Add(new BookingResource { Name = "Rehabilitation Table 1", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Rehabilitation Table 2", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Rehabilitation Table 3", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Rehabilitation Table 4", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Mobility Assessment Area", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Sports Massage Bench 1", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Sports Massage Bench 2", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Posture Correction Zone", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Ultrasound Therapy Room", BookingGroupId = group.Id });
resources.Add(new BookingResource { Name = "Electrotherapy Station", BookingGroupId = group.Id });
}
}
await context.BookingResource.AddRangeAsync(resources);
await context.SaveChangesAsync();
}
}
@@ -0,0 +1,76 @@
using Indotalent.ConfigBackEnd.Extensions;
using Indotalent.Data.Entities;
using Indotalent.Data.Enums;
using Microsoft.EntityFrameworkCore;
namespace Indotalent.Infrastructure.Database.Demo;
public static class BookingSeeder
{
public static async Task GenerateDataAsync(AppDbContext context)
{
if (await context.Booking.AnyAsync()) return;
var random = new Random();
var bookingStatusValues = Enum.GetValues(typeof(BookingStatus)).Cast<BookingStatus>().ToList();
var entityName = nameof(Booking);
var dateEnd = DateTime.Now;
var dateStart = dateEnd.AddMonths(-12);
var bookingResources = await context.BookingResource
.Select(x => x.Id)
.ToListAsync();
var locations = await context.Warehouse
.Where(x => x.SystemWarehouse == false)
.Select(x => x.Name)
.ToListAsync();
if (!bookingResources.Any() || !locations.Any()) return;
for (DateTime date = dateStart; date < dateEnd; date = date.AddMonths(1))
{
DateTime[] transactionDates = GenerateRandomDays(date.Year, date.Month, 25);
foreach (DateTime transDate in transactionDates)
{
int hourStart = random.Next(8, 18);
DateTime startTime = transDate.Date.AddHours(hourStart);
var autoNo = await context.GenerateAutoNumberAsync(
entityName: entityName,
prefixTemplate: $"{entityName.ToShortNameConsonant(3)}/{{Year}}/"
);
var booking = new Booking
{
Subject = $"Appointment {autoNo}",
AutoNumber = autoNo,
StartTime = startTime,
EndTime = startTime.AddHours(random.Next(1, 3)),
BookingResourceId = GetRandomValue(bookingResources, random),
Status = bookingStatusValues[random.Next(bookingStatusValues.Count)],
Location = GetRandomValue(locations, random)
};
await context.Booking.AddAsync(booking);
}
}
await context.SaveChangesAsync();
}
private static DateTime[] GenerateRandomDays(int year, int month, int count)
{
var random = new Random();
int daysInMonthCount = DateTime.DaysInMonth(year, month);
return Enumerable.Range(1, count)
.Select(_ => new DateTime(year, month, random.Next(1, daysInMonthCount + 1)))
.ToArray();
}
private static T GetRandomValue<T>(List<T> list, Random random)
{
return list[random.Next(list.Count)];
}
}
@@ -0,0 +1,33 @@
using Indotalent.Data.Entities;
using Microsoft.EntityFrameworkCore;
namespace Indotalent.Infrastructure.Database.Demo;
public static class CustomerCategorySeeder
{
public static async Task GenerateDataAsync(AppDbContext context)
{
if (await context.CustomerCategory.AnyAsync()) return;
var customerCategories = new List<CustomerCategory>
{
new CustomerCategory { Name = "Platinum Elite" },
new CustomerCategory { Name = "Gold Premium" },
new CustomerCategory { Name = "Silver Standard" },
new CustomerCategory { Name = "VIP Executive" },
new CustomerCategory { Name = "Influencer & Ambassador" },
new CustomerCategory { Name = "Family Plan" },
new CustomerCategory { Name = "Seasonal Member" },
new CustomerCategory { Name = "Trial / Guest" },
new CustomerCategory { Name = "Rehabilitative Patient" },
new CustomerCategory { Name = "Weekend Warrior" }
};
foreach (var category in customerCategories)
{
await context.CustomerCategory.AddAsync(category);
}
await context.SaveChangesAsync();
}
}
@@ -0,0 +1,82 @@
using Indotalent.ConfigBackEnd.Extensions;
using Indotalent.Data.Entities;
using Microsoft.EntityFrameworkCore;
namespace Indotalent.Infrastructure.Database.Demo;
public static class CustomerContactSeeder
{
public static async Task GenerateDataAsync(AppDbContext context)
{
if (await context.CustomerContact.AnyAsync()) return;
var firstNames = new string[]
{
"James", "Mary", "Robert", "Patricia", "John", "Jennifer",
"Michael", "Linda", "David", "Elizabeth", "William", "Barbara",
"Richard", "Susan", "Joseph", "Jessica", "Thomas", "Sarah",
"Charles", "Karen"
};
var lastNames = new string[]
{
"Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia",
"Miller", "Davis", "Rodriguez", "Martinez", "Hernandez", "Lopez",
"Gonzalez", "Wilson", "Anderson", "Thomas", "Taylor", "Moore",
"Jackson", "Martin"
};
var jobTitles = new string[]
{
"Corporate Wellness Director", "Employee Benefits Coordinator", "Head of Athletic Programs",
"Membership Relations Manager", "Spa & Esthetics Director", "Personal Training Lead",
"Health & Safety Compliance Officer", "VIP Guest Liaison", "Community Program Manager",
"Facility Operations Lead", "Wellness Program Coordinator", "Account Executive",
"Chief Experience Officer", "HR Wellness Specialist", "Executive Assistant",
"Lifestyle Consultant", "Senior Wellness Advisor", "Events & Retreats Manager",
"Member Success Specialist", "Regional Program Director"
};
var customerIds = await context.Customer.Select(x => x.Id).ToListAsync();
var random = new Random();
var entityName = nameof(CustomerContact);
foreach (var customerId in customerIds)
{
for (int i = 0; i < 3; i++)
{
var firstName = GetRandomString(firstNames, random);
var lastName = GetRandomString(lastNames, random);
var autoNo = await context.GenerateAutoNumberAsync(
entityName: entityName,
prefixTemplate: $"{entityName.ToShortNameConsonant(3)}/{{Year}}/"
);
var contact = new CustomerContact
{
Name = $"{firstName} {lastName}",
AutoNumber = autoNo,
CustomerId = customerId,
JobTitle = GetRandomString(jobTitles, random),
EmailAddress = $"{firstName.ToLower()}.{lastName.ToLower()}@wellness-partner.us",
PhoneNumber = GenerateRandomPhoneNumber(random)
};
await context.CustomerContact.AddAsync(contact);
}
}
await context.SaveChangesAsync();
}
private static string GetRandomString(string[] array, Random random)
{
return array[random.Next(array.Length)];
}
private static string GenerateRandomPhoneNumber(Random random)
{
return $"+1-{random.Next(200, 999)}-{random.Next(100, 999)}-{random.Next(1000, 9999)}";
}
}
@@ -0,0 +1,33 @@
using Indotalent.Data.Entities;
using Microsoft.EntityFrameworkCore;
namespace Indotalent.Infrastructure.Database.Demo;
public static class CustomerGroupSeeder
{
public static async Task GenerateDataAsync(AppDbContext context)
{
if (await context.CustomerGroup.AnyAsync()) return;
var customerGroups = new List<CustomerGroup>
{
new CustomerGroup { Name = "Individual Members" },
new CustomerGroup { Name = "Corporate Wellness Partners" },
new CustomerGroup { Name = "Hotel & Hospitality Guests" },
new CustomerGroup { Name = "Professional Athletes" },
new CustomerGroup { Name = "Senior Wellness Club" },
new CustomerGroup { Name = "Student & University" },
new CustomerGroup { Name = "Military & Veterans" },
new CustomerGroup { Name = "Healthcare & Medical Referrals" },
new CustomerGroup { Name = "Local Resident Program" },
new CustomerGroup { Name = "Tourists & Travelers" }
};
foreach (var group in customerGroups)
{
await context.CustomerGroup.AddAsync(group);
}
await context.SaveChangesAsync();
}
}
@@ -0,0 +1,82 @@
using Indotalent.ConfigBackEnd.Extensions;
using Indotalent.Data.Entities;
using Microsoft.EntityFrameworkCore;
namespace Indotalent.Infrastructure.Database.Demo;
public static class CustomerSeeder
{
public static async Task GenerateDataAsync(AppDbContext context)
{
if (await context.Customer.AnyAsync()) return;
var groups = await context.CustomerGroup.Select(x => x.Id).ToArrayAsync();
var categories = await context.CustomerCategory.Select(x => x.Id).ToArrayAsync();
var cities = new string[] { "New York", "Los Angeles", "Chicago", "Houston", "Phoenix", "Philadelphia", "Miami", "Seattle", "Austin", "Denver" };
var streets = new string[] { "Broadway Ave", "Sunset Blvd", "Michigan Ave", "Fifth Ave", "Market St", "Peachtree St", "Ocean Dr", "Cedar Rd", "Oak St", "Washington Blvd" };
var states = new string[] { "NY", "CA", "IL", "TX", "AZ", "PA", "FL", "WA", "CO", "MA" };
var zipCodes = new string[] { "10001", "90210", "60601", "77001", "85001", "19101", "33101", "98101", "73301", "80201" };
var phoneNumbers = new string[] { "212-555-0101", "310-555-0102", "312-555-0103", "713-555-0104", "602-555-0105", "305-555-0106" };
var emailDomains = new string[] { "gmail.com", "outlook.com", "icloud.com", "yahoo.com", "wellness-member.us" };
var random = new Random();
var entityName = nameof(Customer);
var customers = new List<Customer>
{
new Customer { Name = "Samantha Reed" },
new Customer { Name = "Marcus Thompson" },
new Customer { Name = "Elite Athletics Group" },
new Customer { Name = "Michael Chen" },
new Customer { Name = "Central Park Yoga Club" },
new Customer { Name = "Jennifer Lopez-Davis" },
new Customer { Name = "Manhattan Corporate Wellness" },
new Customer { Name = "Robert Fitzgerald" },
new Customer { Name = "Seattle Rowing Team" },
new Customer { Name = "Emily Whitehouse" },
new Customer { Name = "Texas Oil Corporate Health" },
new Customer { Name = "David Miller" },
new Customer { Name = "Silicon Valley Tech Retreats" },
new Customer { Name = "Linda Montgomery" },
new Customer { Name = "Beverly Hills Social Club" },
new Customer { Name = "Christopher Vance" },
new Customer { Name = "Miami Beach Resort Partners" },
new Customer { Name = "Sarah Jenkins" },
new Customer { Name = "Aspen Ski Lodge Staff" },
new Customer { Name = "William Harrison" }
};
foreach (var customer in customers)
{
var autoNo = await context.GenerateAutoNumberAsync(
entityName: entityName,
prefixTemplate: $"{entityName.ToShortNameConsonant(3)}/{{Year}}/"
);
customer.AutoNumber = autoNo;
customer.CustomerGroupId = GetRandomValue(groups, random);
customer.CustomerCategoryId = GetRandomValue(categories, random);
customer.City = GetRandomString(cities, random);
customer.Street = GetRandomString(streets, random);
customer.State = GetRandomString(states, random);
customer.ZipCode = GetRandomString(zipCodes, random);
customer.PhoneNumber = GetRandomString(phoneNumbers, random);
customer.EmailAddress = $"{customer.Name?.Replace(" ", ".").ToLower()}@{GetRandomString(emailDomains, random)}";
await context.Customer.AddAsync(customer);
}
await context.SaveChangesAsync();
}
private static T GetRandomValue<T>(T[] array, Random random)
{
return array[random.Next(array.Length)];
}
private static string GetRandomString(string[] array, Random random)
{
return array[random.Next(array.Length)];
}
}
@@ -0,0 +1,25 @@
using Indotalent.Data.Entities;
using Microsoft.EntityFrameworkCore;
namespace Indotalent.Infrastructure.Database.Demo;
public static class EmployeeCategorySeeder
{
public static async Task GenerateDataAsync(AppDbContext context)
{
if (await context.EmployeeCategory.AnyAsync()) return;
var employeeCategories = new List<EmployeeCategory>
{
new EmployeeCategory { Name = "Front of House" },
new EmployeeCategory { Name = "Back of House" }
};
foreach (var category in employeeCategories)
{
await context.EmployeeCategory.AddAsync(category);
}
await context.SaveChangesAsync();
}
}
@@ -0,0 +1,33 @@
using Indotalent.Data.Entities;
using Microsoft.EntityFrameworkCore;
namespace Indotalent.Infrastructure.Database.Demo;
public static class EmployeeGroupSeeder
{
public static async Task GenerateDataAsync(AppDbContext context)
{
if (await context.EmployeeGroup.AnyAsync()) return;
var employeeGroups = new List<EmployeeGroup>
{
new EmployeeGroup { Name = "Sales & Membership Advisors" },
new EmployeeGroup { Name = "Front Desk & Guest Services" },
new EmployeeGroup { Name = "Licensed Massage Therapists" },
new EmployeeGroup { Name = "Professional Estheticians" },
new EmployeeGroup { Name = "Certified Personal Trainers" },
new EmployeeGroup { Name = "Group Exercise Instructors" },
new EmployeeGroup { Name = "Holistic Wellness Coaches" },
new EmployeeGroup { Name = "Clinical Physical Therapists" },
new EmployeeGroup { Name = "Facility & Operations Team" },
new EmployeeGroup { Name = "Executive Management Team" }
};
foreach (var group in employeeGroups)
{
await context.EmployeeGroup.AddAsync(group);
}
await context.SaveChangesAsync();
}
}
@@ -0,0 +1,90 @@
using Indotalent.ConfigBackEnd.Extensions;
using Indotalent.Data.Entities;
using Microsoft.EntityFrameworkCore;
namespace Indotalent.Infrastructure.Database.Demo;
public static class EmployeeSeeder
{
public static async Task GenerateDataAsync(AppDbContext context)
{
if (await context.Employee.AnyAsync()) return;
var fohCategory = await context.EmployeeCategory.FirstOrDefaultAsync(x => x.Name == "Front of House");
var bohCategory = await context.EmployeeCategory.FirstOrDefaultAsync(x => x.Name == "Back of House");
var groups = await context.EmployeeGroup.ToListAsync();
if (fohCategory == null || bohCategory == null || !groups.Any()) return;
var streets = new string[] { "Main St", "Broadway", "Oak Avenue", "Maple Drive", "Park Avenue", "Washington Blvd", "Lakeview Dr", "Sunset Blvd" };
var cities = new string[] { "New York", "Los Angeles", "Chicago", "Miami", "Seattle" };
var states = new string[] { "NY", "CA", "IL", "FL", "WA" };
var zipCodes = new string[] { "10001", "90210", "60601", "33101", "98101" };
var random = new Random();
var entityName = nameof(Employee);
var employeeData = new List<(string Name, string Title, string GroupName, string CategoryName, decimal Commission)>
{
("Robert Sterling", "Senior Membership Advisor", "Sales & Membership Advisors", "Front of House", 0.05m),
("Jennifer Adams", "Wellness Consultant", "Sales & Membership Advisors", "Front of House", 0.03m),
("Michael Vance", "Front Desk Lead", "Front Desk & Guest Services", "Front of House", 0.00m),
("Sarah Mitchell", "Guest Relations Specialist", "Front Desk & Guest Services", "Front of House", 0.00m),
("David Miller", "Senior Massage Therapist", "Licensed Massage Therapists", "Back of House", 0.25m),
("Jessica Taylor", "Deep Tissue Specialist", "Licensed Massage Therapists", "Back of House", 0.20m),
("Amanda Williams", "Master Esthetician", "Professional Estheticians", "Back of House", 0.15m),
("Christopher Moore", "Skin Care Specialist", "Professional Estheticians", "Back of House", 0.15m),
("Kevin Anderson", "Elite Personal Trainer", "Certified Personal Trainers", "Back of House", 0.30m),
("Samantha White", "Fitness Performance Coach", "Certified Personal Trainers", "Back of House", 0.25m),
("Ashley Johnson", "Yoga Lead Instructor", "Group Exercise Instructors", "Back of House", 0.10m),
("Matthew Davis", "Pilates Master Coach", "Group Exercise Instructors", "Back of House", 0.10m),
("Lauren Martinez", "Nutrition & Wellness Coach", "Holistic Wellness Coaches", "Back of House", 0.15m),
("Jonathan Wilson", "Holistic Health Advisor", "Holistic Wellness Coaches", "Back of House", 0.15m),
("Stephanie Rodriguez", "Clinical Physiotherapist", "Clinical Physical Therapists", "Back of House", 0.20m),
("Nicholas Thomas", "Sports Rehab Specialist", "Clinical Physical Therapists", "Back of House", 0.20m),
("Jason Hernandez", "Facility Director", "Facility & Operations Team", "Back of House", 0.00m),
("Olivia Jackson", "Operations Manager", "Facility & Operations Team", "Back of House", 0.00m),
("Alexander Smith", "General Manager", "Executive Management Team", "Front of House", 0.00m),
("Elizabeth Brown", "Club Director", "Executive Management Team", "Front of House", 0.00m)
};
foreach (var data in employeeData)
{
var group = groups.FirstOrDefault(x => x.Name == data.GroupName);
var categoryId = data.CategoryName == "Front of House" ? fohCategory.Id : bohCategory.Id;
var autoNo = await context.GenerateAutoNumberAsync(
entityName: entityName,
prefixTemplate: $"EMP-{{Year}}-"
);
var employee = new Employee
{
Name = data.Name,
AutoNumber = autoNo,
EmployeeNumber = $"ID-{random.Next(1000, 9999)}",
JobTitle = data.Title,
CommissionRate = data.Commission,
EmployeeGroupId = group?.Id,
EmployeeCategoryId = categoryId,
Street = $"{random.Next(100, 999)} {GetRandomString(streets, random)}",
City = GetRandomString(cities, random),
State = GetRandomString(states, random),
ZipCode = GetRandomString(zipCodes, random),
Country = "United States",
PhoneNumber = $"+1-{random.Next(200, 999)}-{random.Next(100, 999)}-{random.Next(1000, 9999)}",
EmailAddress = $"{data.Name.Replace(" ", ".").ToLower()}@swm-wellness.us",
Description = $"Professional {data.Title} based in the {data.CategoryName} division."
};
await context.Employee.AddAsync(employee);
}
await context.SaveChangesAsync();
}
private static string GetRandomString(string[] array, Random random)
{
return array[random.Next(array.Length)];
}
}
@@ -0,0 +1,99 @@
using Indotalent.ConfigBackEnd.Extensions;
using Indotalent.Data.Entities;
using Indotalent.Data.Enums;
using Microsoft.EntityFrameworkCore;
namespace Indotalent.Infrastructure.Database.Demo;
public static class InvoiceSeeder
{
public static async Task GenerateDataAsync(AppDbContext context)
{
if (await context.Invoice.AnyAsync()) return;
var random = new Random();
var entityName = nameof(Invoice);
var dateFinish = DateTime.Now;
var dateStart = new DateTime(dateFinish.AddMonths(-12).Year, dateFinish.AddMonths(-12).Month, 1);
var confirmedSalesOrders = await context.SalesOrder
.Where(so => so.OrderStatus == SalesOrderStatus.Confirmed)
.Select(so => so.Id)
.ToListAsync();
if (!confirmedSalesOrders.Any()) return;
for (DateTime date = dateStart; date < dateFinish; date = date.AddMonths(1))
{
DateTime[] invoiceDates = GetRandomDays(date.Year, date.Month, 5);
foreach (var invoiceDate in invoiceDates)
{
if (confirmedSalesOrders.Count == 0) break;
var status = GetRandomStatus(random);
var salesOrderId = GetRandomAndRemove(confirmedSalesOrders, random);
var autoNo = await context.GenerateAutoNumberAsync(
entityName: entityName,
prefixTemplate: $"{entityName.ToShortNameConsonant(3)}/{{Year}}/"
);
var invoice = new Invoice
{
AutoNumber = autoNo,
InvoiceDate = invoiceDate,
InvoiceStatus = status,
Description = $"Invoice for {invoiceDate:MMMM yyyy}",
SalesOrderId = salesOrderId
};
await context.Invoice.AddAsync(invoice);
}
}
await context.SaveChangesAsync();
}
private static InvoiceStatus GetRandomStatus(Random random)
{
var statuses = new[] { InvoiceStatus.Draft, InvoiceStatus.Cancelled, InvoiceStatus.Confirmed };
var weights = new[] { 1, 1, 4 };
int totalWeight = weights.Sum();
int randomNumber = random.Next(0, totalWeight);
for (int i = 0; i < statuses.Length; i++)
{
if (randomNumber < weights[i]) return statuses[i];
randomNumber -= weights[i];
}
return InvoiceStatus.Confirmed;
}
private static string GetRandomAndRemove(List<string> list, Random random)
{
int index = random.Next(list.Count);
string value = list[index];
list.RemoveAt(index);
return value;
}
private static DateTime[] GetRandomDays(int year, int month, int count)
{
var random = new Random();
int daysInMonthCount = DateTime.DaysInMonth(year, month);
var daysInMonth = Enumerable.Range(1, daysInMonthCount).ToList();
var selectedDays = new List<int>();
for (int i = 0; i < count && daysInMonth.Count > 0; i++)
{
int day = daysInMonth[random.Next(daysInMonth.Count)];
selectedDays.Add(day);
daysInMonth.Remove(day);
}
return selectedDays.Select(day => new DateTime(year, month, day)).ToArray();
}
}
@@ -0,0 +1,117 @@
using Indotalent.ConfigBackEnd.Extensions;
using Indotalent.Data.Entities;
using Indotalent.Data.Enums;
using Microsoft.EntityFrameworkCore;
namespace Indotalent.Infrastructure.Database.Demo;
public static class PaymentDisburseSeeder
{
public static async Task GenerateDataAsync(AppDbContext context)
{
if (await context.PaymentDisburse.AnyAsync()) return;
var random = new Random();
var entityName = nameof(PaymentDisburse);
var dateFinish = DateTime.Now;
var dateStart = new DateTime(dateFinish.AddMonths(-12).Year, dateFinish.AddMonths(-12).Month, 1);
var confirmedBills = await context.Bill
.Include(b => b.PurchaseOrder)
.Where(b => b.BillStatus == BillStatus.Confirmed)
.ToListAsync();
var paymentMethods = await context.PaymentMethod
.Select(pm => pm.Id)
.ToListAsync();
if (!paymentMethods.Any()) return;
for (DateTime date = dateStart; date < dateFinish; date = date.AddMonths(1))
{
DateTime[] paymentDates = GetRandomDays(date.Year, date.Month, 4);
foreach (var paymentDate in paymentDates)
{
if (confirmedBills.Count == 0) break;
var status = GetRandomStatus(random);
var bill = GetRandomAndRemove(confirmedBills, random);
var paymentMethodId = GetRandomValue(paymentMethods, random);
var autoNo = await context.GenerateAutoNumberAsync(
entityName: entityName,
prefixTemplate: $"{entityName.ToShortNameConsonant(3)}/{{Year}}/"
);
var paymentDisburse = new PaymentDisburse
{
AutoNumber = autoNo,
Description = $"Payment Disbursed on {paymentDate:MMMM yyyy}",
PaymentDate = paymentDate,
PaymentMethodId = paymentMethodId,
PaymentAmount = bill.PurchaseOrder?.AfterTaxAmount,
Status = status,
BillId = bill.Id
};
await context.PaymentDisburse.AddAsync(paymentDisburse);
}
}
await context.SaveChangesAsync();
}
private static PaymentDisburseStatus GetRandomStatus(Random random)
{
var statuses = new[]
{
PaymentDisburseStatus.Draft,
PaymentDisburseStatus.Cancelled,
PaymentDisburseStatus.Confirmed,
PaymentDisburseStatus.Archived
};
var weights = new[] { 1, 1, 4, 1 };
int totalWeight = weights.Sum();
int randomNumber = random.Next(0, totalWeight);
for (int i = 0; i < statuses.Length; i++)
{
if (randomNumber < weights[i]) return statuses[i];
randomNumber -= weights[i];
}
return PaymentDisburseStatus.Confirmed;
}
private static T GetRandomAndRemove<T>(List<T> list, Random random)
{
int index = random.Next(list.Count);
T value = list[index];
list.RemoveAt(index);
return value;
}
private static T GetRandomValue<T>(List<T> list, Random random)
{
return list[random.Next(list.Count)];
}
private static DateTime[] GetRandomDays(int year, int month, int count)
{
var random = new Random();
int daysInMonthCount = DateTime.DaysInMonth(year, month);
var daysInMonth = Enumerable.Range(1, daysInMonthCount).ToList();
var selectedDays = new List<int>();
for (int i = 0; i < count && daysInMonth.Count > 0; i++)
{
int day = daysInMonth[random.Next(daysInMonth.Count)];
selectedDays.Add(day);
daysInMonth.Remove(day);
}
return selectedDays.Select(day => new DateTime(year, month, day)).ToArray();
}
}
@@ -0,0 +1,28 @@
using Indotalent.Data.Entities;
using Microsoft.EntityFrameworkCore;
namespace Indotalent.Infrastructure.Database.Demo;
public static class PaymentMethodSeeder
{
public static async Task GenerateDataAsync(AppDbContext context)
{
if (await context.PaymentMethod.AnyAsync()) return;
var paymentMethods = new List<PaymentMethod>
{
new PaymentMethod { Name = "Credit Card" },
new PaymentMethod { Name = "Debit Card" },
new PaymentMethod { Name = "Bank Transfer" },
new PaymentMethod { Name = "PayPal" },
new PaymentMethod { Name = "Cash" }
};
foreach (var paymentMethod in paymentMethods)
{
await context.PaymentMethod.AddAsync(paymentMethod);
}
await context.SaveChangesAsync();
}
}
@@ -0,0 +1,117 @@
using Indotalent.ConfigBackEnd.Extensions;
using Indotalent.Data.Entities;
using Indotalent.Data.Enums;
using Microsoft.EntityFrameworkCore;
namespace Indotalent.Infrastructure.Database.Demo;
public static class PaymentReceiveSeeder
{
public static async Task GenerateDataAsync(AppDbContext context)
{
if (await context.PaymentReceive.AnyAsync()) return;
var random = new Random();
var entityName = nameof(PaymentReceive);
var dateFinish = DateTime.Now;
var dateStart = new DateTime(dateFinish.AddMonths(-12).Year, dateFinish.AddMonths(-12).Month, 1);
var confirmedInvoices = await context.Invoice
.Include(i => i.SalesOrder)
.Where(i => i.InvoiceStatus == InvoiceStatus.Confirmed && i.SalesOrder != null)
.ToListAsync();
var paymentMethods = await context.PaymentMethod
.Select(pm => pm.Id)
.ToListAsync();
if (!paymentMethods.Any()) return;
for (DateTime date = dateStart; date < dateFinish; date = date.AddMonths(1))
{
DateTime[] paymentDates = GetRandomDays(date.Year, date.Month, 4);
foreach (var paymentDate in paymentDates)
{
if (confirmedInvoices.Count == 0) break;
var status = GetRandomStatus(random);
var invoice = GetRandomAndRemove(confirmedInvoices, random);
var paymentMethodId = GetRandomValue(paymentMethods, random);
var autoNo = await context.GenerateAutoNumberAsync(
entityName: entityName,
prefixTemplate: $"{entityName.ToShortNameConsonant(3)}/{{Year}}/"
);
var paymentReceive = new PaymentReceive
{
AutoNumber = autoNo,
Description = $"Payment Received on {paymentDate:MMMM yyyy}",
PaymentDate = paymentDate,
PaymentMethodId = paymentMethodId,
PaymentAmount = invoice?.SalesOrder?.AfterTaxAmount,
Status = status,
InvoiceId = invoice?.Id
};
await context.PaymentReceive.AddAsync(paymentReceive);
}
}
await context.SaveChangesAsync();
}
private static PaymentReceiveStatus GetRandomStatus(Random random)
{
var statuses = new[]
{
PaymentReceiveStatus.Draft,
PaymentReceiveStatus.Cancelled,
PaymentReceiveStatus.Confirmed,
PaymentReceiveStatus.Archived
};
var weights = new[] { 1, 1, 4, 1 };
int totalWeight = weights.Sum();
int randomNumber = random.Next(0, totalWeight);
for (int i = 0; i < statuses.Length; i++)
{
if (randomNumber < weights[i]) return statuses[i];
randomNumber -= weights[i];
}
return PaymentReceiveStatus.Confirmed;
}
private static T GetRandomAndRemove<T>(List<T> list, Random random)
{
int index = random.Next(list.Count);
T value = list[index];
list.RemoveAt(index);
return value;
}
private static T GetRandomValue<T>(List<T> list, Random random)
{
return list[random.Next(list.Count)];
}
private static DateTime[] GetRandomDays(int year, int month, int count)
{
var random = new Random();
int daysInMonthCount = DateTime.DaysInMonth(year, month);
var daysInMonth = Enumerable.Range(1, daysInMonthCount).ToList();
var selectedDays = new List<int>();
for (int i = 0; i < count && daysInMonth.Count > 0; i++)
{
int day = daysInMonth[random.Next(daysInMonth.Count)];
selectedDays.Add(day);
daysInMonth.Remove(day);
}
return selectedDays.Select(day => new DateTime(year, month, day)).ToArray();
}
}
@@ -0,0 +1,43 @@
using Indotalent.Data.Entities;
using Microsoft.EntityFrameworkCore;
namespace Indotalent.Infrastructure.Database.Demo;
public static class ProductGroupSeeder
{
public static async Task GenerateDataAsync(AppDbContext context)
{
if (await context.ProductGroup.AnyAsync()) return;
var productGroups = new List<ProductGroup>
{
new ProductGroup { Name = "Skincare & Facial Products" },
new ProductGroup { Name = "Body & Massage Oils" },
new ProductGroup { Name = "Essential Oils & Diffusers" },
new ProductGroup { Name = "Nutritional Supplements" },
new ProductGroup { Name = "Healthy Snacks & Beverages" },
new ProductGroup { Name = "Home Fitness Equipment" },
new ProductGroup { Name = "Yoga & Pilates Gear" },
new ProductGroup { Name = "Wellness Apparel & Footwear" },
new ProductGroup { Name = "Luxury Linens & Bathrobes" },
new ProductGroup { Name = "Personal Care & Hygiene" },
new ProductGroup { Name = "Professional Massage Services" },
new ProductGroup { Name = "Esthetic & Skin Treatments" },
new ProductGroup { Name = "Private Fitness Training" },
new ProductGroup { Name = "Group Exercise Programs" },
new ProductGroup { Name = "Yoga & Meditation Classes" },
new ProductGroup { Name = "Holistic Wellness Consulting" },
new ProductGroup { Name = "Hydrotherapy & Water Rituals" },
new ProductGroup { Name = "Rehabilitative Therapy Services" },
new ProductGroup { Name = "Body Contouring & Slimming" },
new ProductGroup { Name = "Exclusive Retreat Packages" }
};
foreach (var productGroup in productGroups)
{
await context.ProductGroup.AddAsync(productGroup);
}
await context.SaveChangesAsync();
}
}
@@ -0,0 +1,264 @@
using Indotalent.ConfigBackEnd.Extensions;
using Indotalent.Data.Entities;
using Microsoft.EntityFrameworkCore;
namespace Indotalent.Infrastructure.Database.Demo;
public static class ProductSeeder
{
public static async Task GenerateDataAsync(AppDbContext context)
{
if (await context.Product.AnyAsync()) return;
var productGroups = await context.ProductGroup.ToListAsync();
var measureId = await context.UnitMeasure
.Where(x => x.Name == "unit")
.Select(x => x.Id)
.FirstOrDefaultAsync();
if (string.IsNullOrEmpty(measureId)) return;
var groupMapping = productGroups
.Where(pg => !string.IsNullOrEmpty(pg.Name) && !string.IsNullOrEmpty(pg.Id))
.ToDictionary(pg => pg.Name!, pg => pg.Id!);
var entityName = nameof(Product);
var products = new List<Product>();
products.Add(new Product { Name = "Organic Face Cleanser", UnitPrice = 35m, ProductGroupId = groupMapping["Skincare & Facial Products"] });
products.Add(new Product { Name = "Hydrating Rose Toner", UnitPrice = 28m, ProductGroupId = groupMapping["Skincare & Facial Products"] });
products.Add(new Product { Name = "Vitamin C Brightening Serum", UnitPrice = 65m, ProductGroupId = groupMapping["Skincare & Facial Products"] });
products.Add(new Product { Name = "Anti-Aging Night Cream", UnitPrice = 85m, ProductGroupId = groupMapping["Skincare & Facial Products"] });
products.Add(new Product { Name = "SPF 50 Daily Face Shield", UnitPrice = 42m, ProductGroupId = groupMapping["Skincare & Facial Products"] });
products.Add(new Product { Name = "Dead Sea Mud Mask", UnitPrice = 38m, ProductGroupId = groupMapping["Skincare & Facial Products"] });
products.Add(new Product { Name = "Hyaluronic Acid Booster", UnitPrice = 55m, ProductGroupId = groupMapping["Skincare & Facial Products"] });
products.Add(new Product { Name = "Retinol Eye Recovery", UnitPrice = 75m, ProductGroupId = groupMapping["Skincare & Facial Products"] });
products.Add(new Product { Name = "Gentle Bamboo Scrub", UnitPrice = 30m, ProductGroupId = groupMapping["Skincare & Facial Products"] });
products.Add(new Product { Name = "Herbal Lip Therapy", UnitPrice = 12m, ProductGroupId = groupMapping["Skincare & Facial Products"] });
products.Add(new Product { Name = "Lavender Relaxation Oil", UnitPrice = 45m, ProductGroupId = groupMapping["Body & Massage Oils"] });
products.Add(new Product { Name = "Eucalyptus Muscle Relief", UnitPrice = 48m, ProductGroupId = groupMapping["Body & Massage Oils"] });
products.Add(new Product { Name = "Pure Jojoba Carrier Oil", UnitPrice = 35m, ProductGroupId = groupMapping["Body & Massage Oils"] });
products.Add(new Product { Name = "Peppermint Cooling Blend", UnitPrice = 40m, ProductGroupId = groupMapping["Body & Massage Oils"] });
products.Add(new Product { Name = "Argan Radiance Body Oil", UnitPrice = 58m, ProductGroupId = groupMapping["Body & Massage Oils"] });
products.Add(new Product { Name = "Coconut Deep Moisture", UnitPrice = 32m, ProductGroupId = groupMapping["Body & Massage Oils"] });
products.Add(new Product { Name = "Almond Smoothing Oil", UnitPrice = 38m, ProductGroupId = groupMapping["Body & Massage Oils"] });
products.Add(new Product { Name = "Ginger Warming Blend", UnitPrice = 50m, ProductGroupId = groupMapping["Body & Massage Oils"] });
products.Add(new Product { Name = "Rosehip Vitality Oil", UnitPrice = 62m, ProductGroupId = groupMapping["Body & Massage Oils"] });
products.Add(new Product { Name = "Lemongrass Detox Oil", UnitPrice = 44m, ProductGroupId = groupMapping["Body & Massage Oils"] });
products.Add(new Product { Name = "Premium Ultrasonic Diffuser", UnitPrice = 85m, ProductGroupId = groupMapping["Essential Oils & Diffusers"] });
products.Add(new Product { Name = "Ceramic Stone Diffuser", UnitPrice = 120m, ProductGroupId = groupMapping["Essential Oils & Diffusers"] });
products.Add(new Product { Name = "Travel USB Nebulizer", UnitPrice = 55m, ProductGroupId = groupMapping["Essential Oils & Diffusers"] });
products.Add(new Product { Name = "Frankincense Essential Oil", UnitPrice = 42m, ProductGroupId = groupMapping["Essential Oils & Diffusers"] });
products.Add(new Product { Name = "Sandalwood Sacred Oil", UnitPrice = 95m, ProductGroupId = groupMapping["Essential Oils & Diffusers"] });
products.Add(new Product { Name = "Citrus Energy Blend", UnitPrice = 28m, ProductGroupId = groupMapping["Essential Oils & Diffusers"] });
products.Add(new Product { Name = "Sleep Well Blend", UnitPrice = 32m, ProductGroupId = groupMapping["Essential Oils & Diffusers"] });
products.Add(new Product { Name = "Breathe Easy Oil", UnitPrice = 30m, ProductGroupId = groupMapping["Essential Oils & Diffusers"] });
products.Add(new Product { Name = "Patchouli Earth Oil", UnitPrice = 35m, ProductGroupId = groupMapping["Essential Oils & Diffusers"] });
products.Add(new Product { Name = "Ylang Ylang Floral Oil", UnitPrice = 38m, ProductGroupId = groupMapping["Essential Oils & Diffusers"] });
products.Add(new Product { Name = "Multi-Vitamin Complex", UnitPrice = 45m, ProductGroupId = groupMapping["Nutritional Supplements"] });
products.Add(new Product { Name = "Vegan Protein Powder 2lb", UnitPrice = 55m, ProductGroupId = groupMapping["Nutritional Supplements"] });
products.Add(new Product { Name = "Omega-3 Fish Oil", UnitPrice = 32m, ProductGroupId = groupMapping["Nutritional Supplements"] });
products.Add(new Product { Name = "Probiotic Wellness 60ct", UnitPrice = 48m, ProductGroupId = groupMapping["Nutritional Supplements"] });
products.Add(new Product { Name = "Magnesium Sleep Aid", UnitPrice = 28m, ProductGroupId = groupMapping["Nutritional Supplements"] });
products.Add(new Product { Name = "Collagen Peptides", UnitPrice = 52m, ProductGroupId = groupMapping["Nutritional Supplements"] });
products.Add(new Product { Name = "Ashwagandha Stress Relief", UnitPrice = 35m, ProductGroupId = groupMapping["Nutritional Supplements"] });
products.Add(new Product { Name = "Turmeric Curcumin Plus", UnitPrice = 38m, ProductGroupId = groupMapping["Nutritional Supplements"] });
products.Add(new Product { Name = "Vitamin D3 + K2", UnitPrice = 25m, ProductGroupId = groupMapping["Nutritional Supplements"] });
products.Add(new Product { Name = "Greens Superfood Blend", UnitPrice = 60m, ProductGroupId = groupMapping["Nutritional Supplements"] });
products.Add(new Product { Name = "Organic Almond Protein Bar", UnitPrice = 4.5m, ProductGroupId = groupMapping["Healthy Snacks & Beverages"] });
products.Add(new Product { Name = "Cold Pressed Green Juice", UnitPrice = 9.0m, ProductGroupId = groupMapping["Healthy Snacks & Beverages"] });
products.Add(new Product { Name = "Sparkling Kombucha 12oz", UnitPrice = 6.5m, ProductGroupId = groupMapping["Healthy Snacks & Beverages"] });
products.Add(new Product { Name = "Roasted Chickpeas Sea Salt", UnitPrice = 5.0m, ProductGroupId = groupMapping["Healthy Snacks & Beverages"] });
products.Add(new Product { Name = "Antioxidant Trail Mix", UnitPrice = 8.0m, ProductGroupId = groupMapping["Healthy Snacks & Beverages"] });
products.Add(new Product { Name = "Alkaline Water 1L", UnitPrice = 4.0m, ProductGroupId = groupMapping["Healthy Snacks & Beverages"] });
products.Add(new Product { Name = "Coconut Water Pure", UnitPrice = 5.5m, ProductGroupId = groupMapping["Healthy Snacks & Beverages"] });
products.Add(new Product { Name = "Matcha Tea Sachet Box", UnitPrice = 22m, ProductGroupId = groupMapping["Healthy Snacks & Beverages"] });
products.Add(new Product { Name = "Dark Chocolate Goji Berry", UnitPrice = 7.5m, ProductGroupId = groupMapping["Healthy Snacks & Beverages"] });
products.Add(new Product { Name = "Turmeric Latte Mix", UnitPrice = 18m, ProductGroupId = groupMapping["Healthy Snacks & Beverages"] });
products.Add(new Product { Name = "Adjustable Dumbbell Set", UnitPrice = 350m, ProductGroupId = groupMapping["Home Fitness Equipment"] });
products.Add(new Product { Name = "Pro-Series Resistance Bands", UnitPrice = 45m, ProductGroupId = groupMapping["Home Fitness Equipment"] });
products.Add(new Product { Name = "Kettlebell 25lbs", UnitPrice = 65m, ProductGroupId = groupMapping["Home Fitness Equipment"] });
products.Add(new Product { Name = "Foldable Treadmill", UnitPrice = 1200m, ProductGroupId = groupMapping["Home Fitness Equipment"] });
products.Add(new Product { Name = "Indoor Cycling Bike", UnitPrice = 950m, ProductGroupId = groupMapping["Home Fitness Equipment"] });
products.Add(new Product { Name = "Pull-Up Bar Doorway", UnitPrice = 55m, ProductGroupId = groupMapping["Home Fitness Equipment"] });
products.Add(new Product { Name = "Ab Roller Wheel", UnitPrice = 25m, ProductGroupId = groupMapping["Home Fitness Equipment"] });
products.Add(new Product { Name = "Medicine Ball 10lbs", UnitPrice = 40m, ProductGroupId = groupMapping["Home Fitness Equipment"] });
products.Add(new Product { Name = "Adjustable Bench", UnitPrice = 180m, ProductGroupId = groupMapping["Home Fitness Equipment"] });
products.Add(new Product { Name = "Jump Rope Speed Pro", UnitPrice = 20m, ProductGroupId = groupMapping["Home Fitness Equipment"] });
products.Add(new Product { Name = "Eco-Friendly Yoga Mat", UnitPrice = 85m, ProductGroupId = groupMapping["Yoga & Pilates Gear"] });
products.Add(new Product { Name = "Cork Yoga Block Set", UnitPrice = 35m, ProductGroupId = groupMapping["Yoga & Pilates Gear"] });
products.Add(new Product { Name = "Pilates Reformer Ring", UnitPrice = 30m, ProductGroupId = groupMapping["Yoga & Pilates Gear"] });
products.Add(new Product { Name = "Cotton Yoga Strap", UnitPrice = 15m, ProductGroupId = groupMapping["Yoga & Pilates Gear"] });
products.Add(new Product { Name = "Non-Slip Yoga Towel", UnitPrice = 40m, ProductGroupId = groupMapping["Yoga & Pilates Gear"] });
products.Add(new Product { Name = "Yoga Bolster Cushion", UnitPrice = 65m, ProductGroupId = groupMapping["Yoga & Pilates Gear"] });
products.Add(new Product { Name = "Balance Ball 65cm", UnitPrice = 35m, ProductGroupId = groupMapping["Yoga & Pilates Gear"] });
products.Add(new Product { Name = "Mat Carrying Bag", UnitPrice = 45m, ProductGroupId = groupMapping["Yoga & Pilates Gear"] });
products.Add(new Product { Name = "Pilates Socks Grip", UnitPrice = 18m, ProductGroupId = groupMapping["Yoga & Pilates Gear"] });
products.Add(new Product { Name = "Meditation Bench Wood", UnitPrice = 75m, ProductGroupId = groupMapping["Yoga & Pilates Gear"] });
products.Add(new Product { Name = "Performance Leggings", UnitPrice = 95m, ProductGroupId = groupMapping["Wellness Apparel & Footwear"] });
products.Add(new Product { Name = "Moisture-Wick Tank Top", UnitPrice = 45m, ProductGroupId = groupMapping["Wellness Apparel & Footwear"] });
products.Add(new Product { Name = "Seamless Sports Bra", UnitPrice = 55m, ProductGroupId = groupMapping["Wellness Apparel & Footwear"] });
products.Add(new Product { Name = "Cross-Training Sneakers", UnitPrice = 130m, ProductGroupId = groupMapping["Wellness Apparel & Footwear"] });
products.Add(new Product { Name = "Yoga Flow Shorts", UnitPrice = 50m, ProductGroupId = groupMapping["Wellness Apparel & Footwear"] });
products.Add(new Product { Name = "Compression Recovery Socks", UnitPrice = 25m, ProductGroupId = groupMapping["Wellness Apparel & Footwear"] });
products.Add(new Product { Name = "Lightweight Hooded Jacket", UnitPrice = 110m, ProductGroupId = groupMapping["Wellness Apparel & Footwear"] });
products.Add(new Product { Name = "Thermal Base Layer", UnitPrice = 65m, ProductGroupId = groupMapping["Wellness Apparel & Footwear"] });
products.Add(new Product { Name = "Anti-Slip Studio Shoes", UnitPrice = 85m, ProductGroupId = groupMapping["Wellness Apparel & Footwear"] });
products.Add(new Product { Name = "Athletic Crew Socks 3pk", UnitPrice = 15m, ProductGroupId = groupMapping["Wellness Apparel & Footwear"] });
products.Add(new Product { Name = "Egyptian Cotton Bathrobe", UnitPrice = 150m, ProductGroupId = groupMapping["Luxury Linens & Bathrobes"] });
products.Add(new Product { Name = "Oversized Spa Towel Set", UnitPrice = 85m, ProductGroupId = groupMapping["Luxury Linens & Bathrobes"] });
products.Add(new Product { Name = "Bamboo Silk Sheet Set", UnitPrice = 220m, ProductGroupId = groupMapping["Luxury Linens & Bathrobes"] });
products.Add(new Product { Name = "Velvet Spa Slippers", UnitPrice = 35m, ProductGroupId = groupMapping["Luxury Linens & Bathrobes"] });
products.Add(new Product { Name = "Silk Eye Sleeping Mask", UnitPrice = 25m, ProductGroupId = groupMapping["Luxury Linens & Bathrobes"] });
products.Add(new Product { Name = "Microfiber Hair Wrap", UnitPrice = 20m, ProductGroupId = groupMapping["Luxury Linens & Bathrobes"] });
products.Add(new Product { Name = "Weighted Relaxation Blanket", UnitPrice = 180m, ProductGroupId = groupMapping["Luxury Linens & Bathrobes"] });
products.Add(new Product { Name = "Linen Face Towels 10pk", UnitPrice = 45m, ProductGroupId = groupMapping["Luxury Linens & Bathrobes"] });
products.Add(new Product { Name = "Satin Pillowcase Pair", UnitPrice = 40m, ProductGroupId = groupMapping["Luxury Linens & Bathrobes"] });
products.Add(new Product { Name = "Hooded Plush Wrap", UnitPrice = 95m, ProductGroupId = groupMapping["Luxury Linens & Bathrobes"] });
products.Add(new Product { Name = "Antibacterial Hand Wash", UnitPrice = 18m, ProductGroupId = groupMapping["Personal Care & Hygiene"] });
products.Add(new Product { Name = "Natural Crystal Deodorant", UnitPrice = 15m, ProductGroupId = groupMapping["Personal Care & Hygiene"] });
products.Add(new Product { Name = "Organic Body Scrub", UnitPrice = 32m, ProductGroupId = groupMapping["Personal Care & Hygiene"] });
products.Add(new Product { Name = "Sensitive Skin Shower Gel", UnitPrice = 22m, ProductGroupId = groupMapping["Personal Care & Hygiene"] });
products.Add(new Product { Name = "Eco-Bamboo Toothbrush", UnitPrice = 6m, ProductGroupId = groupMapping["Personal Care & Hygiene"] });
products.Add(new Product { Name = "Herbal Mouthwash 500ml", UnitPrice = 14m, ProductGroupId = groupMapping["Personal Care & Hygiene"] });
products.Add(new Product { Name = "Dry Brushing Body Brush", UnitPrice = 25m, ProductGroupId = groupMapping["Personal Care & Hygiene"] });
products.Add(new Product { Name = "Epsom Salt Detox Soak", UnitPrice = 28m, ProductGroupId = groupMapping["Personal Care & Hygiene"] });
products.Add(new Product { Name = "Hand Sanitizer Mist", UnitPrice = 12m, ProductGroupId = groupMapping["Personal Care & Hygiene"] });
products.Add(new Product { Name = "Natural Sea Sponge", UnitPrice = 20m, ProductGroupId = groupMapping["Personal Care & Hygiene"] });
products.Add(new Product { Name = "Deep Tissue Massage 60m", UnitPrice = 120m, Physical = false, ProductGroupId = groupMapping["Professional Massage Services"] });
products.Add(new Product { Name = "Swedish Relaxation 90m", UnitPrice = 160m, Physical = false, ProductGroupId = groupMapping["Professional Massage Services"] });
products.Add(new Product { Name = "Hot Stone Therapy 75m", UnitPrice = 185m, Physical = false, ProductGroupId = groupMapping["Professional Massage Services"] });
products.Add(new Product { Name = "Sports Recovery Massage", UnitPrice = 135m, Physical = false, ProductGroupId = groupMapping["Professional Massage Services"] });
products.Add(new Product { Name = "Prenatal Care Massage", UnitPrice = 130m, Physical = false, ProductGroupId = groupMapping["Professional Massage Services"] });
products.Add(new Product { Name = "Foot Reflexology 45m", UnitPrice = 85m, Physical = false, ProductGroupId = groupMapping["Professional Massage Services"] });
products.Add(new Product { Name = "Thai Stretching Massage", UnitPrice = 150m, Physical = false, ProductGroupId = groupMapping["Professional Massage Services"] });
products.Add(new Product { Name = "Aromatherapy Session", UnitPrice = 145m, Physical = false, ProductGroupId = groupMapping["Professional Massage Services"] });
products.Add(new Product { Name = "Couple Massage Package", UnitPrice = 280m, Physical = false, ProductGroupId = groupMapping["Professional Massage Services"] });
products.Add(new Product { Name = "Lymphatic Drainage 60m", UnitPrice = 155m, Physical = false, ProductGroupId = groupMapping["Professional Massage Services"] });
products.Add(new Product { Name = "Signature Radiance Facial", UnitPrice = 110m, Physical = false, ProductGroupId = groupMapping["Esthetic & Skin Treatments"] });
products.Add(new Product { Name = "Microdermabrasion Therapy", UnitPrice = 175m, Physical = false, ProductGroupId = groupMapping["Esthetic & Skin Treatments"] });
products.Add(new Product { Name = "Chemical Peel Advanced", UnitPrice = 225m, Physical = false, ProductGroupId = groupMapping["Esthetic & Skin Treatments"] });
products.Add(new Product { Name = "Hydra-Lift Treatment", UnitPrice = 195m, Physical = false, ProductGroupId = groupMapping["Esthetic & Skin Treatments"] });
products.Add(new Product { Name = "LED Light Skin Therapy", UnitPrice = 95m, Physical = false, ProductGroupId = groupMapping["Esthetic & Skin Treatments"] });
products.Add(new Product { Name = "Acne Clarifying Facial", UnitPrice = 125m, Physical = false, ProductGroupId = groupMapping["Esthetic & Skin Treatments"] });
products.Add(new Product { Name = "Anti-Pollution Detox", UnitPrice = 140m, Physical = false, ProductGroupId = groupMapping["Esthetic & Skin Treatments"] });
products.Add(new Product { Name = "Oxygen Infusion Facial", UnitPrice = 165m, Physical = false, ProductGroupId = groupMapping["Esthetic & Skin Treatments"] });
products.Add(new Product { Name = "Dermaplaning Session", UnitPrice = 115m, Physical = false, ProductGroupId = groupMapping["Esthetic & Skin Treatments"] });
products.Add(new Product { Name = "Collagen Boost Treatment", UnitPrice = 185m, Physical = false, ProductGroupId = groupMapping["Esthetic & Skin Treatments"] });
products.Add(new Product { Name = "Personal Trainer 1-on-1", UnitPrice = 85m, Physical = false, ProductGroupId = groupMapping["Private Fitness Training"] });
products.Add(new Product { Name = "Elite Athletic Coaching", UnitPrice = 150m, Physical = false, ProductGroupId = groupMapping["Private Fitness Training"] });
products.Add(new Product { Name = "Online Custom Workout Plan", UnitPrice = 199m, Physical = false, ProductGroupId = groupMapping["Private Fitness Training"] });
products.Add(new Product { Name = "Strength Training Session", UnitPrice = 95m, Physical = false, ProductGroupId = groupMapping["Private Fitness Training"] });
products.Add(new Product { Name = "Post-Injury Fitness Prep", UnitPrice = 110m, Physical = false, ProductGroupId = groupMapping["Private Fitness Training"] });
products.Add(new Product { Name = "Body Transformation Plan", UnitPrice = 450m, Physical = false, ProductGroupId = groupMapping["Private Fitness Training"] });
products.Add(new Product { Name = "Senior Mobility Coaching", UnitPrice = 75m, Physical = false, ProductGroupId = groupMapping["Private Fitness Training"] });
products.Add(new Product { Name = "HIIT Private Session", UnitPrice = 90m, Physical = false, ProductGroupId = groupMapping["Private Fitness Training"] });
products.Add(new Product { Name = "Cardio Enduro Training", UnitPrice = 80m, Physical = false, ProductGroupId = groupMapping["Private Fitness Training"] });
products.Add(new Product { Name = "Fitness Assessment Pro", UnitPrice = 120m, Physical = false, ProductGroupId = groupMapping["Private Fitness Training"] });
products.Add(new Product { Name = "Monthly Unlimited Classes", UnitPrice = 199m, Physical = false, ProductGroupId = groupMapping["Group Exercise Programs"] });
products.Add(new Product { Name = "Single Class Drop-In", UnitPrice = 25m, Physical = false, ProductGroupId = groupMapping["Group Exercise Programs"] });
products.Add(new Product { Name = "HIIT Group Workout", UnitPrice = 30m, Physical = false, ProductGroupId = groupMapping["Group Exercise Programs"] });
products.Add(new Product { Name = "Zumba Dance Party", UnitPrice = 20m, Physical = false, ProductGroupId = groupMapping["Group Exercise Programs"] });
products.Add(new Product { Name = "Spin Cycle Revolution", UnitPrice = 35m, Physical = false, ProductGroupId = groupMapping["Group Exercise Programs"] });
products.Add(new Product { Name = "Barre Sculpt Group", UnitPrice = 30m, Physical = false, ProductGroupId = groupMapping["Group Exercise Programs"] });
products.Add(new Product { Name = "Bootcamp Outdoor", UnitPrice = 40m, Physical = false, ProductGroupId = groupMapping["Group Exercise Programs"] });
products.Add(new Product { Name = "Boxing Fitness Class", UnitPrice = 35m, Physical = false, ProductGroupId = groupMapping["Group Exercise Programs"] });
products.Add(new Product { Name = "BodyPump Weights Class", UnitPrice = 25m, Physical = false, ProductGroupId = groupMapping["Group Exercise Programs"] });
products.Add(new Product { Name = "Kettlebell Skill Class", UnitPrice = 30m, Physical = false, ProductGroupId = groupMapping["Group Exercise Programs"] });
products.Add(new Product { Name = "Beginner Vinyasa Flow", UnitPrice = 25m, Physical = false, ProductGroupId = groupMapping["Yoga & Meditation Classes"] });
products.Add(new Product { Name = "Guided Mindfulness 30m", UnitPrice = 15m, Physical = false, ProductGroupId = groupMapping["Yoga & Meditation Classes"] });
products.Add(new Product { Name = "Hot Power Yoga", UnitPrice = 35m, Physical = false, ProductGroupId = groupMapping["Yoga & Meditation Classes"] });
products.Add(new Product { Name = "Restorative Yin Yoga", UnitPrice = 28m, Physical = false, ProductGroupId = groupMapping["Yoga & Meditation Classes"] });
products.Add(new Product { Name = "Sound Bath Meditation", UnitPrice = 45m, Physical = false, ProductGroupId = groupMapping["Yoga & Meditation Classes"] });
products.Add(new Product { Name = "Kundalini Awakening", UnitPrice = 30m, Physical = false, ProductGroupId = groupMapping["Yoga & Meditation Classes"] });
products.Add(new Product { Name = "Aerial Yoga Experience", UnitPrice = 50m, Physical = false, ProductGroupId = groupMapping["Yoga & Meditation Classes"] });
products.Add(new Product { Name = "Morning Zen Meditation", UnitPrice = 20m, Physical = false, ProductGroupId = groupMapping["Yoga & Meditation Classes"] });
products.Add(new Product { Name = "Yoga Nidra Deep Sleep", UnitPrice = 30m, Physical = false, ProductGroupId = groupMapping["Yoga & Meditation Classes"] });
products.Add(new Product { Name = "Private Yoga Coaching", UnitPrice = 120m, Physical = false, ProductGroupId = groupMapping["Yoga & Meditation Classes"] });
products.Add(new Product { Name = "Nutritional Coaching 1h", UnitPrice = 125m, Physical = false, ProductGroupId = groupMapping["Holistic Wellness Consulting"] });
products.Add(new Product { Name = "Stress Management Audit", UnitPrice = 150m, Physical = false, ProductGroupId = groupMapping["Holistic Wellness Consulting"] });
products.Add(new Product { Name = "Life Balance Consulting", UnitPrice = 110m, Physical = false, ProductGroupId = groupMapping["Holistic Wellness Consulting"] });
products.Add(new Product { Name = "Corporate Wellness Plan", UnitPrice = 2500m, Physical = false, ProductGroupId = groupMapping["Holistic Wellness Consulting"] });
products.Add(new Product { Name = "Sleep Optimization Study", UnitPrice = 180m, Physical = false, ProductGroupId = groupMapping["Holistic Wellness Consulting"] });
products.Add(new Product { Name = "Ayurvedic Lifestyle Consult", UnitPrice = 160m, Physical = false, ProductGroupId = groupMapping["Holistic Wellness Consulting"] });
products.Add(new Product { Name = "Naturopathic Review", UnitPrice = 210m, Physical = false, ProductGroupId = groupMapping["Holistic Wellness Consulting"] });
products.Add(new Product { Name = "Eco-Living Consultant", UnitPrice = 140m, Physical = false, ProductGroupId = groupMapping["Holistic Wellness Consulting"] });
products.Add(new Product { Name = "Bio-Hacking Consultation", UnitPrice = 300m, Physical = false, ProductGroupId = groupMapping["Holistic Wellness Consulting"] });
products.Add(new Product { Name = "Wellness Journey Roadmap", UnitPrice = 95m, Physical = false, ProductGroupId = groupMapping["Holistic Wellness Consulting"] });
products.Add(new Product { Name = "Thermal Circuit Access", UnitPrice = 65m, Physical = false, ProductGroupId = groupMapping["Hydrotherapy & Water Rituals"] });
products.Add(new Product { Name = "Dead Sea Salt Float", UnitPrice = 95m, Physical = false, ProductGroupId = groupMapping["Hydrotherapy & Water Rituals"] });
products.Add(new Product { Name = "Watsu Water Therapy", UnitPrice = 155m, Physical = false, ProductGroupId = groupMapping["Hydrotherapy & Water Rituals"] });
products.Add(new Product { Name = "Turkish Hammam Ritual", UnitPrice = 190m, Physical = false, ProductGroupId = groupMapping["Hydrotherapy & Water Rituals"] });
products.Add(new Product { Name = "Underwater Sound Healing", UnitPrice = 120m, Physical = false, ProductGroupId = groupMapping["Hydrotherapy & Water Rituals"] });
products.Add(new Product { Name = "Cold Plunge Recovery", UnitPrice = 45m, Physical = false, ProductGroupId = groupMapping["Hydrotherapy & Water Rituals"] });
products.Add(new Product { Name = "Mineral Mud Hydro-Bath", UnitPrice = 85m, Physical = false, ProductGroupId = groupMapping["Hydrotherapy & Water Rituals"] });
products.Add(new Product { Name = "Vichy Shower Massage", UnitPrice = 135m, Physical = false, ProductGroupId = groupMapping["Hydrotherapy & Water Rituals"] });
products.Add(new Product { Name = "Hydro-Massage Bed 30m", UnitPrice = 40m, Physical = false, ProductGroupId = groupMapping["Hydrotherapy & Water Rituals"] });
products.Add(new Product { Name = "Detox Seaweed Bath", UnitPrice = 75m, Physical = false, ProductGroupId = groupMapping["Hydrotherapy & Water Rituals"] });
products.Add(new Product { Name = "Sports Injury Rehab 1h", UnitPrice = 165m, Physical = false, ProductGroupId = groupMapping["Rehabilitative Therapy Services"] });
products.Add(new Product { Name = "Posture Correction Therapy", UnitPrice = 140m, Physical = false, ProductGroupId = groupMapping["Rehabilitative Therapy Services"] });
products.Add(new Product { Name = "Fascial Stretch Therapy", UnitPrice = 125m, Physical = false, ProductGroupId = groupMapping["Rehabilitative Therapy Services"] });
products.Add(new Product { Name = "Mobility Restoration", UnitPrice = 115m, Physical = false, ProductGroupId = groupMapping["Rehabilitative Therapy Services"] });
products.Add(new Product { Name = "Acupuncture Wellness", UnitPrice = 130m, Physical = false, ProductGroupId = groupMapping["Rehabilitative Therapy Services"] });
products.Add(new Product { Name = "Cupping Therapy Session", UnitPrice = 95m, Physical = false, ProductGroupId = groupMapping["Rehabilitative Therapy Services"] });
products.Add(new Product { Name = "Chiropractic Adjustment", UnitPrice = 150m, Physical = false, ProductGroupId = groupMapping["Rehabilitative Therapy Services"] });
products.Add(new Product { Name = "Kinesio Taping Session", UnitPrice = 45m, Physical = false, ProductGroupId = groupMapping["Rehabilitative Therapy Services"] });
products.Add(new Product { Name = "Electrical Stim Therapy", UnitPrice = 85m, Physical = false, ProductGroupId = groupMapping["Rehabilitative Therapy Services"] });
products.Add(new Product { Name = "Rehab Progress Tracking", UnitPrice = 60m, Physical = false, ProductGroupId = groupMapping["Rehabilitative Therapy Services"] });
products.Add(new Product { Name = "Cryo-Sculpt Session", UnitPrice = 250m, Physical = false, ProductGroupId = groupMapping["Body Contouring & Slimming"] });
products.Add(new Product { Name = "Radio Frequency Tighten", UnitPrice = 350m, Physical = false, ProductGroupId = groupMapping["Body Contouring & Slimming"] });
products.Add(new Product { Name = "Cellulite Reduction Wrap", UnitPrice = 180m, Physical = false, ProductGroupId = groupMapping["Body Contouring & Slimming"] });
products.Add(new Product { Name = "Laser Lipo Treatment", UnitPrice = 500m, Physical = false, ProductGroupId = groupMapping["Body Contouring & Slimming"] });
products.Add(new Product { Name = "Body Firming Ritual", UnitPrice = 210m, Physical = false, ProductGroupId = groupMapping["Body Contouring & Slimming"] });
products.Add(new Product { Name = "Lymphatic Pressotherapy", UnitPrice = 120m, Physical = false, ProductGroupId = groupMapping["Body Contouring & Slimming"] });
products.Add(new Product { Name = "Weight Loss IV Drip", UnitPrice = 225m, Physical = false, ProductGroupId = groupMapping["Body Contouring & Slimming"] });
products.Add(new Product { Name = "Metabolic Reset Plan", UnitPrice = 650m, Physical = false, ProductGroupId = groupMapping["Body Contouring & Slimming"] });
products.Add(new Product { Name = "Ultrasonic Cavitation", UnitPrice = 280m, Physical = false, ProductGroupId = groupMapping["Body Contouring & Slimming"] });
products.Add(new Product { Name = "Slimming Tea Therapy", UnitPrice = 45m, Physical = false, ProductGroupId = groupMapping["Body Contouring & Slimming"] });
products.Add(new Product { Name = "Weekend Zen Escape", UnitPrice = 1200m, Physical = false, ProductGroupId = groupMapping["Exclusive Retreat Packages"] });
products.Add(new Product { Name = "7-Day Holistic Cleanse", UnitPrice = 3500m, Physical = false, ProductGroupId = groupMapping["Exclusive Retreat Packages"] });
products.Add(new Product { Name = "Couples Romantic Hideaway", UnitPrice = 2800m, Physical = false, ProductGroupId = groupMapping["Exclusive Retreat Packages"] });
products.Add(new Product { Name = "Executive Burnout Reset", UnitPrice = 4500m, Physical = false, ProductGroupId = groupMapping["Exclusive Retreat Packages"] });
products.Add(new Product { Name = "Silent Meditation Retreat", UnitPrice = 1500m, Physical = false, ProductGroupId = groupMapping["Exclusive Retreat Packages"] });
products.Add(new Product { Name = "Fitness Performance Camp", UnitPrice = 2200m, Physical = false, ProductGroupId = groupMapping["Exclusive Retreat Packages"] });
products.Add(new Product { Name = "Digital Detox Weekend", UnitPrice = 1100m, Physical = false, ProductGroupId = groupMapping["Exclusive Retreat Packages"] });
products.Add(new Product { Name = "Weight Loss Intensive", UnitPrice = 4200m, Physical = false, ProductGroupId = groupMapping["Exclusive Retreat Packages"] });
products.Add(new Product { Name = "Yoga Mastery Immersion", UnitPrice = 1800m, Physical = false, ProductGroupId = groupMapping["Exclusive Retreat Packages"] });
products.Add(new Product { Name = "Luxury Spa Getaway 3D2N", UnitPrice = 2400m, Physical = false, ProductGroupId = groupMapping["Exclusive Retreat Packages"] });
foreach (var product in products)
{
var autoNo = await context.GenerateAutoNumberAsync(
entityName: entityName,
prefixTemplate: $"{entityName.ToShortNameConsonant(3)}/{{Year}}/"
);
product.AutoNumber = autoNo;
product.UnitMeasureId = measureId;
product.Physical ??= true;
await context.Product.AddAsync(product);
}
await context.SaveChangesAsync();
}
}
@@ -0,0 +1,112 @@
using Indotalent.ConfigBackEnd.Extensions;
using Indotalent.Data.Entities;
using Indotalent.Data.Enums;
using Microsoft.EntityFrameworkCore;
namespace Indotalent.Infrastructure.Database.Demo;
public static class PurchaseOrderSeeder
{
public static async Task GenerateDataAsync(AppDbContext context)
{
if (await context.PurchaseOrder.AnyAsync()) return;
var random = new Random();
var entityName = nameof(PurchaseOrder);
var vendors = await context.Vendor.Select(x => x.Id).ToListAsync();
var taxes = await context.Tax.Select(x => x.Id).ToListAsync();
var products = await context.Product.ToListAsync();
if (!vendors.Any() || !taxes.Any() || !products.Any()) return;
var allStatusValues = Enum.GetValues(typeof(PurchaseOrderStatus))
.Cast<PurchaseOrderStatus>()
.ToList();
var nonConfirmedStatusValues = allStatusValues
.Where(x => x != PurchaseOrderStatus.Confirmed)
.ToList();
var dateFinish = DateTime.Now;
var dateStart = new DateTime(dateFinish.AddMonths(-12).Year, dateFinish.AddMonths(-12).Month, 1);
for (DateTime date = dateStart; date < dateFinish; date = date.AddMonths(1))
{
DateTime[] transactionDates = GetRandomDays(date.Year, date.Month, 6);
foreach (DateTime transDate in transactionDates)
{
var autoNo = await context.GenerateAutoNumberAsync(
entityName: entityName,
prefixTemplate: $"{entityName.ToShortNameConsonant(3)}/{{Year}}/"
);
PurchaseOrderStatus selectedStatus;
int probability = random.Next(1, 101);
if (probability <= 90)
{
selectedStatus = PurchaseOrderStatus.Confirmed;
}
else
{
selectedStatus = nonConfirmedStatusValues[random.Next(nonConfirmedStatusValues.Count)];
}
var purchaseOrder = new PurchaseOrder
{
AutoNumber = autoNo,
OrderDate = transDate,
OrderStatus = selectedStatus,
VendorId = GetRandomValue(vendors, random),
TaxId = GetRandomValue(taxes, random),
};
await context.PurchaseOrder.AddAsync(purchaseOrder);
int numberOfProducts = random.Next(3, 6);
for (int i = 0; i < numberOfProducts; i++)
{
var product = products[random.Next(products.Count)];
var quantity = random.Next(20, 50);
var purchaseOrderItem = new PurchaseOrderItem
{
PurchaseOrderId = purchaseOrder.Id,
ProductId = product.Id,
Summary = product.AutoNumber,
UnitPrice = product.UnitPrice,
Quantity = (double)quantity,
Total = product.UnitPrice * (decimal)quantity
};
await context.PurchaseOrderItem.AddAsync(purchaseOrderItem);
}
await context.SaveChangesAsync();
context.RecalculatePurchaseOrder(purchaseOrder.Id);
await context.SaveChangesAsync();
}
}
}
private static T GetRandomValue<T>(List<T> list, Random random)
{
return list[random.Next(list.Count)];
}
private static DateTime[] GetRandomDays(int year, int month, int count)
{
var random = new Random();
int daysInMonthCount = DateTime.DaysInMonth(year, month);
var daysInMonth = Enumerable.Range(1, daysInMonthCount).ToList();
var selectedDays = new List<int>();
for (int i = 0; i < count && daysInMonth.Count > 0; i++)
{
int day = daysInMonth[random.Next(daysInMonth.Count)];
selectedDays.Add(day);
daysInMonth.Remove(day);
}
return selectedDays.Select(day => new DateTime(year, month, day)).ToArray();
}
}
@@ -0,0 +1,109 @@
using Indotalent.ConfigBackEnd.Extensions;
using Indotalent.Data.Entities;
using Indotalent.Data.Enums;
using Microsoft.EntityFrameworkCore;
namespace Indotalent.Infrastructure.Database.Demo;
public static class SalesOrderSeeder
{
public static async Task GenerateDataAsync(AppDbContext context)
{
if (await context.SalesOrder.AnyAsync()) return;
var random = new Random();
var entityName = nameof(SalesOrder);
var customers = await context.Customer.Select(x => x.Id).ToListAsync();
var employees = await context.Employee.Select(x => x.Id).ToListAsync();
var taxes = await context.Tax.Select(x => x.Id).ToListAsync();
var products = await context.Product.ToListAsync();
if (!customers.Any() || !employees.Any() || !taxes.Any() || !products.Any()) return;
var dateFinish = DateTime.Now;
var dateStart = new DateTime(dateFinish.AddMonths(-12).Year, dateFinish.AddMonths(-12).Month, 1);
for (DateTime date = dateStart; date < dateFinish; date = date.AddMonths(1))
{
DateTime[] transactionDates = GetRandomDays(date.Year, date.Month, 6);
foreach (DateTime transDate in transactionDates)
{
var autoNo = await context.GenerateAutoNumberAsync(
entityName: entityName,
prefixTemplate: $"{entityName.ToShortNameConsonant(3)}/{{Year}}/"
);
var salesOrder = new SalesOrder
{
AutoNumber = autoNo,
OrderDate = transDate,
OrderStatus = GetHighProbabilityStatus(random),
CustomerId = GetRandomValue(customers, random),
EmployeeId = GetRandomValue(employees, random),
TaxId = GetRandomValue(taxes, random),
};
await context.SalesOrder.AddAsync(salesOrder);
int numberOfProducts = random.Next(3, 6);
for (int i = 0; i < numberOfProducts; i++)
{
var qty = (double)random.Next(2, 5);
var product = products[random.Next(products.Count)];
var salesOrderItem = new SalesOrderItem
{
SalesOrderId = salesOrder.Id,
ProductId = product.Id,
Summary = product.AutoNumber,
UnitPrice = product.UnitPrice,
Quantity = qty,
Total = (product.UnitPrice ?? 0m) * (decimal)qty
};
await context.SalesOrderItem.AddAsync(salesOrderItem);
}
await context.SaveChangesAsync();
context.RecalculateSalesOrder(salesOrder.Id);
await context.SaveChangesAsync();
}
}
}
private static SalesOrderStatus GetHighProbabilityStatus(Random random)
{
int probability = random.Next(1, 101);
if (probability <= 90)
{
return SalesOrderStatus.Confirmed;
}
else
{
var otherStatuses = new[] { SalesOrderStatus.Draft, SalesOrderStatus.Cancelled, SalesOrderStatus.Archived };
return otherStatuses[random.Next(otherStatuses.Length)];
}
}
private static T GetRandomValue<T>(List<T> list, Random random)
{
return list[random.Next(list.Count)];
}
private static DateTime[] GetRandomDays(int year, int month, int count)
{
var random = new Random();
int daysInMonthCount = DateTime.DaysInMonth(year, month);
var daysInMonth = Enumerable.Range(1, daysInMonthCount).ToList();
var selectedDays = new List<int>();
for (int i = 0; i < count && daysInMonth.Count > 0; i++)
{
int day = daysInMonth[random.Next(daysInMonth.Count)];
selectedDays.Add(day);
daysInMonth.Remove(day);
}
return selectedDays.Select(day => new DateTime(year, month, day)).ToArray();
}
}
@@ -0,0 +1,29 @@
using Indotalent.Data.Entities;
using Microsoft.EntityFrameworkCore;
namespace Indotalent.Infrastructure.Database.Demo;
public static class UnitMeasureSeeder
{
public static async Task GenerateDataAsync(AppDbContext context)
{
if (await context.UnitMeasure.AnyAsync()) return;
var unitMeasures = new List<UnitMeasure>
{
new UnitMeasure { Name = "m" },
new UnitMeasure { Name = "kg" },
new UnitMeasure { Name = "hour" },
new UnitMeasure { Name = "unit" },
new UnitMeasure { Name = "pcs" },
new UnitMeasure { Name = "package" }
};
foreach (var unitMeasure in unitMeasures)
{
await context.UnitMeasure.AddAsync(unitMeasure);
}
await context.SaveChangesAsync();
}
}
@@ -0,0 +1,54 @@
using DocumentFormat.OpenXml.InkML;
using Indotalent.Data.Entities;
using Indotalent.Infrastructure.Authentication.Identity;
using Indotalent.Infrastructure.Authorization.Identity;
using Microsoft.AspNetCore.Identity;
namespace Indotalent.Infrastructure.Database.Demo;
public static class UserSeeder
{
public static async Task GenerateDataAsync(UserManager<ApplicationUser> userManager, AppDbContext context, IConfiguration configuration)
{
var adminSettings = configuration.GetSection("IdentitySettings:DefaultAdmin").Get<DefaultAdminSettings>();
if (adminSettings == null) return;
if (context.Users.Where(x => x.Email != adminSettings.Email).Any()) return;
var userNames = new List<string>
{
"Alex", "Taylor", "Jordan", "Morgan", "Riley",
"Casey", "Peyton", "Cameron", "Jamie", "Drew",
"Dakota", "Avery", "Quinn", "Harper", "Rowan",
"Emerson", "Finley", "Skyler", "Charlie", "Sage"
};
var defaultPassword = "123456";
var domain = "@example.com";
var role = ApplicationRoles.Member;
foreach (var name in userNames)
{
var email = $"{name.ToLower()}{domain}";
if (await userManager.FindByEmailAsync(email) == null)
{
var applicationUser = new ApplicationUser
{
UserName = email,
Email = email,
FullName = name,
EmailConfirmed = true
};
var result = await userManager.CreateAsync(applicationUser, defaultPassword);
if (result.Succeeded)
{
await userManager.AddToRoleAsync(applicationUser, role);
}
}
}
}
}
@@ -0,0 +1,33 @@
using Indotalent.Data.Entities;
using Microsoft.EntityFrameworkCore;
namespace Indotalent.Infrastructure.Database.Demo;
public static class VendorCategorySeeder
{
public static async Task GenerateDataAsync(AppDbContext context)
{
if (await context.VendorCategory.AnyAsync()) return;
var vendorCategories = new List<VendorCategory>
{
new VendorCategory { Name = "Preferred Partner" },
new VendorCategory { Name = "Exclusive Distributor" },
new VendorCategory { Name = "Direct Manufacturer" },
new VendorCategory { Name = "Boutique / Artisan Provider" },
new VendorCategory { Name = "Wholesale Supplier" },
new VendorCategory { Name = "Authorized Reseller" },
new VendorCategory { Name = "Local Provider" },
new VendorCategory { Name = "Regional Provider" },
new VendorCategory { Name = "National Provider" },
new VendorCategory { Name = "International / Global Provider" }
};
foreach (var category in vendorCategories)
{
await context.VendorCategory.AddAsync(category);
}
await context.SaveChangesAsync();
}
}
@@ -0,0 +1,75 @@
using Indotalent.ConfigBackEnd.Extensions;
using Indotalent.Data.Entities;
using Microsoft.EntityFrameworkCore;
namespace Indotalent.Infrastructure.Database.Demo;
public static class VendorContactSeeder
{
public static async Task GenerateDataAsync(AppDbContext context)
{
if (await context.VendorContact.AnyAsync()) return;
var firstNames = new string[]
{
"James", "Mary", "Robert", "Patricia", "John", "Jennifer",
"Michael", "Linda", "David", "Elizabeth", "William", "Barbara",
"Richard", "Susan", "Joseph", "Jessica", "Thomas", "Sarah",
"Charles", "Karen"
};
var lastNames = new string[]
{
"Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia",
"Miller", "Davis", "Rodriguez", "Martinez", "Hernandez", "Lopez",
"Gonzalez", "Wilson", "Anderson", "Thomas", "Taylor", "Moore",
"Jackson", "Martin"
};
var jobTitles = new string[]
{
"Wholesale Account Manager", "Product Specialist", "Sales Director", "Supply Chain Coordinator",
"Regional Sales Manager", "Customer Success Lead", "Distribution Manager", "Key Account Executive",
"Technical Support Specialist", "Operations Lead", "Equipment Consultant", "Inventory Manager",
"Brand Ambassador", "Logistics Coordinator", "Business Development Manager", "Procurement Officer",
"Corporate Relations Manager", "Quality Control Manager", "Field Sales Representative", "Contract Manager"
};
var vendorIds = await context.Vendor.Select(x => x.Id).ToListAsync();
var random = new Random();
var entityName = nameof(VendorContact);
foreach (var vendorId in vendorIds)
{
for (int i = 0; i < 3; i++)
{
var firstName = GetRandomString(firstNames, random);
var lastName = GetRandomString(lastNames, random);
var autoNo = await context.GenerateAutoNumberAsync(
entityName: entityName,
prefixTemplate: $"{entityName.ToShortNameConsonant(3)}/{{Year}}/"
);
var contact = new VendorContact
{
Name = $"{firstName} {lastName}",
AutoNumber = autoNo,
VendorId = vendorId,
JobTitle = GetRandomString(jobTitles, random),
EmailAddress = $"{firstName.ToLower()}.{lastName.ToLower()}@example.com",
PhoneNumber = $"+1-{random.Next(200, 999)}-{random.Next(100, 999)}-{random.Next(1000, 9999)}"
};
await context.VendorContact.AddAsync(contact);
}
}
await context.SaveChangesAsync();
}
private static string GetRandomString(string[] array, Random random)
{
return array[random.Next(array.Length)];
}
}
@@ -0,0 +1,33 @@
using Indotalent.Data.Entities;
using Microsoft.EntityFrameworkCore;
namespace Indotalent.Infrastructure.Database.Demo;
public static class VendorGroupSeeder
{
public static async Task GenerateDataAsync(AppDbContext context)
{
if (await context.VendorGroup.AnyAsync()) return;
var vendorGroups = new List<VendorGroup>
{
new VendorGroup { Name = "Skincare & Professional Cosmetics" },
new VendorGroup { Name = "Spa Equipment & Furniture" },
new VendorGroup { Name = "Fitness & Gym Machinery" },
new VendorGroup { Name = "Nutritional & Dietary Supplements" },
new VendorGroup { Name = "Essential Oils & Aromatherapy" },
new VendorGroup { Name = "Linen, Towels & Uniforms" },
new VendorGroup { Name = "Cleaning & Hygiene Chemicals" },
new VendorGroup { Name = "Facility Maintenance & Technical" },
new VendorGroup { Name = "IT & Software Services" },
new VendorGroup { Name = "Marketing & Branding Agencies" }
};
foreach (var group in vendorGroups)
{
await context.VendorGroup.AddAsync(group);
}
await context.SaveChangesAsync();
}
}
@@ -0,0 +1,82 @@
using Indotalent.ConfigBackEnd.Extensions;
using Indotalent.Data.Entities;
using Microsoft.EntityFrameworkCore;
namespace Indotalent.Infrastructure.Database.Demo;
public static class VendorSeeder
{
public static async Task GenerateDataAsync(AppDbContext context)
{
if (await context.Vendor.AnyAsync()) return;
var groups = await context.VendorGroup.Select(x => x.Id).ToArrayAsync();
var categories = await context.VendorCategory.Select(x => x.Id).ToArrayAsync();
var cities = new string[] { "New York", "Los Angeles", "Chicago", "Houston", "Phoenix", "Philadelphia", "Miami", "San Francisco", "Seattle", "Austin" };
var streets = new string[] { "Broadway", "Main Street", "Sunset Blvd", "Fifth Avenue", "Market Street", "Peachtree Street", "Washington Blvd", "Wall Street", "Cedar Road", "Oak Street" };
var states = new string[] { "NY", "CA", "IL", "TX", "AZ", "PA", "FL", "GA", "WA", "MA" };
var zipCodes = new string[] { "10001", "90210", "60601", "77001", "85001", "19101", "33101", "94102", "98101", "73301" };
var phoneNumbers = new string[] { "212-555-0199", "310-555-0188", "312-555-0177", "713-555-0166", "602-555-0155", "305-555-0144" };
var emails = new string[] { "sales@wellness-us.com", "info@fitness-pro.net", "contact@spa-direct.com", "support@organic-supplies.us", "wholesale@gym-factory.com" };
var random = new Random();
var entityName = nameof(Vendor);
var vendors = new List<Vendor>
{
new Vendor { Name = "Pacific Coast Skincare" },
new Vendor { Name = "Midwest Gym Equipment" },
new Vendor { Name = "Evergreen Holistic Labs" },
new Vendor { Name = "Atlantic Spa & Beauty" },
new Vendor { Name = "Sunshine State Nutriments" },
new Vendor { Name = "Mountain Peak Fitness" },
new Vendor { Name = "Empire State Linen" },
new Vendor { Name = "Silicon Valley Wellness Tech" },
new Vendor { Name = "Lone Star Spa Supplies" },
new Vendor { Name = "Golden Gate Aromatherapy" },
new Vendor { Name = "Liberty Fitness Machines" },
new Vendor { Name = "Canyon Creek Supplements" },
new Vendor { Name = "Gulf Coast Wellness Group" },
new Vendor { Name = "Great Lakes Spa Textiles" },
new Vendor { Name = "Blue Ridge Herbal Remedies" },
new Vendor { Name = "Windy City Gym Solutions" },
new Vendor { Name = "Desert Oasis Wellness" },
new Vendor { Name = "Big Apple Fitness Distribution" },
new Vendor { Name = "Cascade Organic Oils" },
new Vendor { Name = "National Wellness Marketing" }
};
foreach (var vendor in vendors)
{
var autoNo = await context.GenerateAutoNumberAsync(
entityName: entityName,
prefixTemplate: $"{entityName.ToShortNameConsonant(3)}/{{Year}}/"
);
vendor.AutoNumber = autoNo;
vendor.VendorGroupId = GetRandomValue(groups, random);
vendor.VendorCategoryId = GetRandomValue(categories, random);
vendor.City = GetRandomString(cities, random);
vendor.Street = GetRandomString(streets, random);
vendor.State = GetRandomString(states, random);
vendor.ZipCode = GetRandomString(zipCodes, random);
vendor.PhoneNumber = GetRandomString(phoneNumbers, random);
vendor.EmailAddress = GetRandomString(emails, random);
await context.Vendor.AddAsync(vendor);
}
await context.SaveChangesAsync();
}
private static T GetRandomValue<T>(T[] array, Random random)
{
return array[random.Next(array.Length)];
}
private static string GetRandomString(string[] array, Random random)
{
return array[random.Next(array.Length)];
}
}
@@ -0,0 +1,33 @@
using Indotalent.Data.Entities;
using Microsoft.EntityFrameworkCore;
namespace Indotalent.Infrastructure.Database.Demo;
public static class WarehouseSeeder
{
public static async Task GenerateDataAsync(AppDbContext context)
{
if (await context.Warehouse.Where(x => x.SystemWarehouse == false).AnyAsync()) return;
var warehouses = new List<Warehouse>
{
new Warehouse { Name = "Grand Wellness Corporate Center - Manhattan" },
new Warehouse { Name = "Serenity Sanctuary Spa - Beverly Hills" },
new Warehouse { Name = "Tranquil Bliss Spa & Retreat - Maui" },
new Warehouse { Name = "Oceanic Refresh Spa - Miami" },
new Warehouse { Name = "Holistic Harmony Wellness - Aspen" },
new Warehouse { Name = "Mindful Living Center - Seattle" },
new Warehouse { Name = "Zenith Soul & Spirit - Sedona" },
new Warehouse { Name = "Iron & Oxygen Fitness Club - Brooklyn" },
new Warehouse { Name = "Peak Performance Gym - Austin" },
new Warehouse { Name = "Urban Pulse Fitness Studio - Chicago" }
};
foreach (var warehouse in warehouses)
{
await context.Warehouse.AddAsync(warehouse);
}
await context.SaveChangesAsync();
}
}
@@ -0,0 +1,68 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class ApplicationUserConfiguration : IEntityTypeConfiguration<ApplicationUser>
{
public void Configure(EntityTypeBuilder<ApplicationUser> builder)
{
builder.Property(e => e.FullName).HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.SsoIdFirebase).HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.SsoIdKeycloak).HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.SsoIdAzure).HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.SsoIdAws).HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.SsoIdOther1).HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.SsoIdOther2).HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.SsoIdOther3).HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.AvatarFile).HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.RefreshToken).HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.FirstName).HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.LastName).HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.ShortBio).HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.JobTitle).HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.StreetAddress)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.City)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.StateProvince)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.ZipCode)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Country)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.SocialMediaLinkedIn)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.SocialMediaX)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.SocialMediaFacebook)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.SocialMediaInstagram)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.SocialMediaTikTok)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.OtherInformation1)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.OtherInformation2)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.OtherInformation3)
.HasMaxLength(GlobalConsts.StringLengthMedium);
}
}
@@ -0,0 +1,25 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class AutoNumberSequenceConfiguration : IEntityTypeConfiguration<AutoNumberSequence>
{
public void Configure(EntityTypeBuilder<AutoNumberSequence> builder)
{
builder.Property(e => e.EntityName)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.PrefixTemplate)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.SuffixTemplate)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.HasIndex(e => new { e.EntityName, e.Year, e.Month })
.IsUnique();
}
}
@@ -0,0 +1,30 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class BillConfiguration : IEntityTypeConfiguration<Bill>
{
public void Configure(EntityTypeBuilder<Bill> builder)
{
builder.Property(e => e.AutoNumber)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Description)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.PurchaseOrderId)
.HasMaxLength(GlobalConsts.StringLengthId);
builder.HasOne(e => e.PurchaseOrder)
.WithMany()
.HasForeignKey(e => e.PurchaseOrderId)
.OnDelete(DeleteBehavior.NoAction);
builder.HasIndex(e => e.AutoNumber).IsUnique();
builder.HasIndex(e => e.BillDate);
builder.HasIndex(e => e.PurchaseOrderId);
}
}
@@ -0,0 +1,53 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class BookingConfiguration : IEntityTypeConfiguration<Booking>
{
public void Configure(EntityTypeBuilder<Booking> builder)
{
builder.Property(e => e.Subject)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.AutoNumber)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.StartTimezone)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.EndTimezone)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Location)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Description)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.RecurrenceRule)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.RecurrenceID)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.FollowingID)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.RecurrenceException)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.BookingResourceId)
.HasMaxLength(GlobalConsts.StringLengthId);
builder.HasOne(e => e.BookingResource)
.WithMany()
.HasForeignKey(e => e.BookingResourceId)
.OnDelete(DeleteBehavior.NoAction);
builder.HasIndex(e => e.AutoNumber).IsUnique();
builder.HasIndex(e => e.BookingResourceId);
}
}
@@ -0,0 +1,20 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class BookingGroupConfiguration : IEntityTypeConfiguration<BookingGroup>
{
public void Configure(EntityTypeBuilder<BookingGroup> builder)
{
builder.Property(e => e.Name)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Description)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.HasIndex(e => e.Name);
}
}
@@ -0,0 +1,29 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class BookingResourceConfiguration : IEntityTypeConfiguration<BookingResource>
{
public void Configure(EntityTypeBuilder<BookingResource> builder)
{
builder.Property(e => e.Name)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Description)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.BookingGroupId)
.HasMaxLength(GlobalConsts.StringLengthId);
builder.HasOne(e => e.BookingGroup)
.WithMany()
.HasForeignKey(e => e.BookingGroupId)
.OnDelete(DeleteBehavior.NoAction);
builder.HasIndex(e => e.Name);
builder.HasIndex(e => e.BookingGroupId);
}
}
@@ -0,0 +1,87 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class CompanyConfiguration : IEntityTypeConfiguration<Company>
{
public void Configure(EntityTypeBuilder<Company> builder)
{
builder.Property(e => e.AutoNumber)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Name)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Description)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.CurrencyId)
.HasMaxLength(GlobalConsts.StringLengthId);
builder.HasOne(e => e.Currency)
.WithMany()
.HasForeignKey(e => e.CurrencyId)
.OnDelete(DeleteBehavior.NoAction);
builder.Property(e => e.TaxIdentification)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.BusinessLicense)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.CompanyLogo)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.StreetAddress)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.City)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.StateProvince)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.ZipCode)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Phone)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Email)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.SocialMediaLinkedIn)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.SocialMediaX)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.SocialMediaFacebook)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.SocialMediaInstagram)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.SocialMediaTikTok)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.OtherInformation1)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.OtherInformation2)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.OtherInformation3)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.HasIndex(e => e.AutoNumber).IsUnique();
builder.HasIndex(e => e.Name);
builder.HasIndex(e => e.Email);
builder.HasIndex(e => e.CurrencyId);
}
}
@@ -0,0 +1,36 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class CurrencyConfiguration : IEntityTypeConfiguration<Currency>
{
public void Configure(EntityTypeBuilder<Currency> builder)
{
builder.Property(e => e.AutoNumber)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Code)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Name)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Symbol)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.CountryOwner)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Description)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.HasIndex(e => e.AutoNumber).IsUnique();
builder.HasIndex(e => e.Code).IsUnique();
builder.HasIndex(e => e.Name);
}
}
@@ -0,0 +1,20 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class CustomerCategoryConfiguration : IEntityTypeConfiguration<CustomerCategory>
{
public void Configure(EntityTypeBuilder<CustomerCategory> builder)
{
builder.Property(e => e.Name)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Description)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.HasIndex(e => e.Name);
}
}
@@ -0,0 +1,87 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class CustomerConfiguration : IEntityTypeConfiguration<Customer>
{
public void Configure(EntityTypeBuilder<Customer> builder)
{
builder.Property(e => e.Name)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.AutoNumber)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Description)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.Street)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.City)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.State)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.ZipCode)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Country)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.PhoneNumber)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.FaxNumber)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.EmailAddress)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Website)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.WhatsApp)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.LinkedIn)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Facebook)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Instagram)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.TwitterX)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.TikTok)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.CustomerGroupId)
.HasMaxLength(GlobalConsts.StringLengthId);
builder.Property(e => e.CustomerCategoryId)
.HasMaxLength(GlobalConsts.StringLengthId);
builder.HasOne(e => e.CustomerGroup)
.WithMany()
.HasForeignKey(e => e.CustomerGroupId)
.OnDelete(DeleteBehavior.NoAction);
builder.HasOne(e => e.CustomerCategory)
.WithMany()
.HasForeignKey(e => e.CustomerCategoryId)
.OnDelete(DeleteBehavior.NoAction);
builder.HasIndex(e => e.Name);
builder.HasIndex(e => e.AutoNumber).IsUnique();
builder.HasIndex(e => e.CustomerGroupId);
builder.HasIndex(e => e.CustomerCategoryId);
}
}
@@ -0,0 +1,42 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class CustomerContactConfiguration : IEntityTypeConfiguration<CustomerContact>
{
public void Configure(EntityTypeBuilder<CustomerContact> builder)
{
builder.Property(e => e.Name)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.AutoNumber)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.JobTitle)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.PhoneNumber)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.EmailAddress)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Description)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.CustomerId)
.HasMaxLength(GlobalConsts.StringLengthId);
builder.HasOne(e => e.Customer)
.WithMany(e => e.CustomerContactList)
.HasForeignKey(e => e.CustomerId)
.OnDelete(DeleteBehavior.NoAction);
builder.HasIndex(e => e.Name);
builder.HasIndex(e => e.AutoNumber).IsUnique();
builder.HasIndex(e => e.CustomerId);
}
}
@@ -0,0 +1,20 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class CustomerGroupConfiguration : IEntityTypeConfiguration<CustomerGroup>
{
public void Configure(EntityTypeBuilder<CustomerGroup> builder)
{
builder.Property(e => e.Name)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Description)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.HasIndex(e => e.Name);
}
}
@@ -0,0 +1,20 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class EmployeeCategoryConfiguration : IEntityTypeConfiguration<EmployeeCategory>
{
public void Configure(EntityTypeBuilder<EmployeeCategory> builder)
{
builder.Property(e => e.Name)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Description)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.HasIndex(e => e.Name);
}
}
@@ -0,0 +1,94 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class EmployeeConfiguration : IEntityTypeConfiguration<Employee>
{
public void Configure(EntityTypeBuilder<Employee> builder)
{
builder.Property(e => e.Name)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.AutoNumber)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.JobTitle)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.EmployeeNumber)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Description)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.Street)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.City)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.State)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.ZipCode)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Country)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.PhoneNumber)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.FaxNumber)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.EmailAddress)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Website)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.WhatsApp)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.LinkedIn)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Facebook)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Instagram)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.TwitterX)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.TikTok)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.EmployeeGroupId)
.HasMaxLength(GlobalConsts.StringLengthId);
builder.Property(e => e.EmployeeCategoryId)
.HasMaxLength(GlobalConsts.StringLengthId);
builder.HasOne(e => e.EmployeeGroup)
.WithMany()
.HasForeignKey(e => e.EmployeeGroupId)
.OnDelete(DeleteBehavior.NoAction);
builder.HasOne(e => e.EmployeeCategory)
.WithMany()
.HasForeignKey(e => e.EmployeeCategoryId)
.OnDelete(DeleteBehavior.NoAction);
builder.HasIndex(e => e.Name);
builder.HasIndex(e => e.AutoNumber).IsUnique();
builder.HasIndex(e => e.EmployeeNumber).IsUnique();
builder.HasIndex(e => e.EmployeeGroupId);
builder.HasIndex(e => e.EmployeeCategoryId);
}
}
@@ -0,0 +1,20 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class EmployeeGroupConfiguration : IEntityTypeConfiguration<EmployeeGroup>
{
public void Configure(EntityTypeBuilder<EmployeeGroup> builder)
{
builder.Property(e => e.Name)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Description)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.HasIndex(e => e.Name);
}
}
@@ -0,0 +1,64 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class InventoryTransactionConfiguration : IEntityTypeConfiguration<InventoryTransaction>
{
public void Configure(EntityTypeBuilder<InventoryTransaction> builder)
{
builder.Property(e => e.ModuleId)
.HasMaxLength(GlobalConsts.StringLengthId);
builder.Property(e => e.ModuleName)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.ModuleCode)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.ModuleNumber)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.AutoNumber)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.WarehouseId)
.HasMaxLength(GlobalConsts.StringLengthId);
builder.Property(e => e.ProductId)
.HasMaxLength(GlobalConsts.StringLengthId);
builder.Property(e => e.WarehouseFromId)
.HasMaxLength(GlobalConsts.StringLengthId);
builder.Property(e => e.WarehouseToId)
.HasMaxLength(GlobalConsts.StringLengthId);
builder.HasOne(e => e.Warehouse)
.WithMany()
.HasForeignKey(e => e.WarehouseId)
.OnDelete(DeleteBehavior.NoAction);
builder.HasOne(e => e.Product)
.WithMany()
.HasForeignKey(e => e.ProductId)
.OnDelete(DeleteBehavior.NoAction);
builder.HasOne(e => e.WarehouseFrom)
.WithMany()
.HasForeignKey(e => e.WarehouseFromId)
.OnDelete(DeleteBehavior.NoAction);
builder.HasOne(e => e.WarehouseTo)
.WithMany()
.HasForeignKey(e => e.WarehouseToId)
.OnDelete(DeleteBehavior.NoAction);
builder.HasIndex(e => e.AutoNumber).IsUnique();
builder.HasIndex(e => e.MovementDate);
builder.HasIndex(e => e.WarehouseId);
builder.HasIndex(e => e.ProductId);
}
}
@@ -0,0 +1,30 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class InvoiceConfiguration : IEntityTypeConfiguration<Invoice>
{
public void Configure(EntityTypeBuilder<Invoice> builder)
{
builder.Property(e => e.AutoNumber)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Description)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.SalesOrderId)
.HasMaxLength(GlobalConsts.StringLengthId);
builder.HasOne(e => e.SalesOrder)
.WithMany()
.HasForeignKey(e => e.SalesOrderId)
.OnDelete(DeleteBehavior.NoAction);
builder.HasIndex(e => e.AutoNumber).IsUnique();
builder.HasIndex(e => e.InvoiceDate);
builder.HasIndex(e => e.SalesOrderId);
}
}
@@ -0,0 +1,39 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class PaymentDisburseConfiguration : IEntityTypeConfiguration<PaymentDisburse>
{
public void Configure(EntityTypeBuilder<PaymentDisburse> builder)
{
builder.Property(e => e.BillId)
.HasMaxLength(GlobalConsts.StringLengthId);
builder.Property(e => e.AutoNumber)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Description)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.PaymentMethodId)
.HasMaxLength(GlobalConsts.StringLengthId);
builder.HasOne(e => e.Bill)
.WithMany()
.HasForeignKey(e => e.BillId)
.OnDelete(DeleteBehavior.NoAction);
builder.HasOne(e => e.PaymentMethod)
.WithMany()
.HasForeignKey(e => e.PaymentMethodId)
.OnDelete(DeleteBehavior.NoAction);
builder.HasIndex(e => e.AutoNumber).IsUnique();
builder.HasIndex(e => e.BillId);
builder.HasIndex(e => e.PaymentMethodId);
builder.HasIndex(e => e.PaymentDate);
}
}
@@ -0,0 +1,20 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class PaymentMethodConfiguration : IEntityTypeConfiguration<PaymentMethod>
{
public void Configure(EntityTypeBuilder<PaymentMethod> builder)
{
builder.Property(e => e.Name)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Description)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.HasIndex(e => e.Name);
}
}
@@ -0,0 +1,39 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class PaymentReceiveConfiguration : IEntityTypeConfiguration<PaymentReceive>
{
public void Configure(EntityTypeBuilder<PaymentReceive> builder)
{
builder.Property(e => e.InvoiceId)
.HasMaxLength(GlobalConsts.StringLengthId);
builder.Property(e => e.AutoNumber)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Description)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.PaymentMethodId)
.HasMaxLength(GlobalConsts.StringLengthId);
builder.HasOne(e => e.Invoice)
.WithMany()
.HasForeignKey(e => e.InvoiceId)
.OnDelete(DeleteBehavior.NoAction);
builder.HasOne(e => e.PaymentMethod)
.WithMany()
.HasForeignKey(e => e.PaymentMethodId)
.OnDelete(DeleteBehavior.NoAction);
builder.HasIndex(e => e.AutoNumber).IsUnique();
builder.HasIndex(e => e.InvoiceId);
builder.HasIndex(e => e.PaymentMethodId);
builder.HasIndex(e => e.PaymentDate);
}
}
@@ -0,0 +1,42 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class ProductConfiguration : IEntityTypeConfiguration<Product>
{
public void Configure(EntityTypeBuilder<Product> builder)
{
builder.Property(e => e.Name)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.AutoNumber)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Description)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.UnitMeasureId)
.HasMaxLength(GlobalConsts.StringLengthId);
builder.Property(e => e.ProductGroupId)
.HasMaxLength(GlobalConsts.StringLengthId);
builder.HasOne(e => e.UnitMeasure)
.WithMany()
.HasForeignKey(e => e.UnitMeasureId)
.OnDelete(DeleteBehavior.NoAction);
builder.HasOne(e => e.ProductGroup)
.WithMany()
.HasForeignKey(e => e.ProductGroupId)
.OnDelete(DeleteBehavior.NoAction);
builder.HasIndex(e => e.Name);
builder.HasIndex(e => e.AutoNumber).IsUnique();
builder.HasIndex(e => e.UnitMeasureId);
builder.HasIndex(e => e.ProductGroupId);
}
}
@@ -0,0 +1,20 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class ProductGroupConfiguration : IEntityTypeConfiguration<ProductGroup>
{
public void Configure(EntityTypeBuilder<ProductGroup> builder)
{
builder.Property(e => e.Name)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Description)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.HasIndex(e => e.Name);
}
}
@@ -0,0 +1,44 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class PurchaseOrderConfiguration : IEntityTypeConfiguration<PurchaseOrder>
{
public void Configure(EntityTypeBuilder<PurchaseOrder> builder)
{
builder.Property(e => e.AutoNumber)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Description)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.VendorId)
.HasMaxLength(GlobalConsts.StringLengthId);
builder.Property(e => e.TaxId)
.HasMaxLength(GlobalConsts.StringLengthId);
builder.HasOne(e => e.Vendor)
.WithMany()
.HasForeignKey(e => e.VendorId)
.OnDelete(DeleteBehavior.NoAction);
builder.HasOne(e => e.Tax)
.WithMany()
.HasForeignKey(e => e.TaxId)
.OnDelete(DeleteBehavior.NoAction);
builder.HasMany(e => e.PurchaseOrderItemList)
.WithOne(e => e.PurchaseOrder)
.HasForeignKey(e => e.PurchaseOrderId)
.OnDelete(DeleteBehavior.NoAction);
builder.HasIndex(e => e.AutoNumber).IsUnique();
builder.HasIndex(e => e.OrderDate);
builder.HasIndex(e => e.VendorId);
builder.HasIndex(e => e.TaxId);
}
}
@@ -0,0 +1,34 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class PurchaseOrderItemConfiguration : IEntityTypeConfiguration<PurchaseOrderItem>
{
public void Configure(EntityTypeBuilder<PurchaseOrderItem> builder)
{
builder.Property(e => e.PurchaseOrderId)
.HasMaxLength(GlobalConsts.StringLengthId);
builder.Property(e => e.ProductId)
.HasMaxLength(GlobalConsts.StringLengthId);
builder.Property(e => e.Summary)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.HasOne(e => e.PurchaseOrder)
.WithMany(e => e.PurchaseOrderItemList)
.HasForeignKey(e => e.PurchaseOrderId)
.OnDelete(DeleteBehavior.Cascade);
builder.HasOne(e => e.Product)
.WithMany()
.HasForeignKey(e => e.ProductId)
.OnDelete(DeleteBehavior.NoAction);
builder.HasIndex(e => e.PurchaseOrderId);
builder.HasIndex(e => e.ProductId);
}
}
@@ -0,0 +1,50 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class SalesOrderConfiguration : IEntityTypeConfiguration<SalesOrder>
{
public void Configure(EntityTypeBuilder<SalesOrder> builder)
{
builder.Property(e => e.AutoNumber)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Description)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.CustomerId)
.HasMaxLength(GlobalConsts.StringLengthId);
builder.Property(e => e.TaxId)
.HasMaxLength(GlobalConsts.StringLengthId);
builder.HasOne(e => e.Customer)
.WithMany()
.HasForeignKey(e => e.CustomerId)
.OnDelete(DeleteBehavior.NoAction);
builder.HasOne(e => e.Employee)
.WithMany()
.HasForeignKey(e => e.EmployeeId)
.OnDelete(DeleteBehavior.NoAction);
builder.HasOne(e => e.Tax)
.WithMany()
.HasForeignKey(e => e.TaxId)
.OnDelete(DeleteBehavior.NoAction);
builder.HasMany(e => e.SalesOrderItemList)
.WithOne(e => e.SalesOrder)
.HasForeignKey(e => e.SalesOrderId)
.OnDelete(DeleteBehavior.NoAction);
builder.HasIndex(e => e.AutoNumber).IsUnique();
builder.HasIndex(e => e.OrderDate);
builder.HasIndex(e => e.CustomerId);
builder.HasIndex(e => e.TaxId);
builder.HasIndex(e => e.EmployeeId);
}
}
@@ -0,0 +1,34 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class SalesOrderItemConfiguration : IEntityTypeConfiguration<SalesOrderItem>
{
public void Configure(EntityTypeBuilder<SalesOrderItem> builder)
{
builder.Property(e => e.SalesOrderId)
.HasMaxLength(GlobalConsts.StringLengthId);
builder.Property(e => e.ProductId)
.HasMaxLength(GlobalConsts.StringLengthId);
builder.Property(e => e.Summary)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.HasOne(e => e.SalesOrder)
.WithMany(e => e.SalesOrderItemList)
.HasForeignKey(e => e.SalesOrderId)
.OnDelete(DeleteBehavior.Cascade);
builder.HasOne(e => e.Product)
.WithMany()
.HasForeignKey(e => e.ProductId)
.OnDelete(DeleteBehavior.NoAction);
builder.HasIndex(e => e.SalesOrderId);
builder.HasIndex(e => e.ProductId);
}
}
@@ -0,0 +1,39 @@
using Indotalent.Data.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class LogConfiguration : IEntityTypeConfiguration<SerilogLogs>
{
public void Configure(EntityTypeBuilder<SerilogLogs> builder)
{
builder.ToTable("SerilogLogs");
builder.HasKey(e => e.Id);
builder.Property(e => e.Message)
.HasMaxLength(2000);
builder.Property(e => e.Level)
.HasMaxLength(128);
builder.Property(e => e.TimeStamp)
.IsRequired();
builder.Property(e => e.Exception)
.HasColumnType("nvarchar(max)");
builder.Property(e => e.Properties)
.HasColumnType("nvarchar(max)");
builder.Property(e => e.MessageTemplate)
.HasMaxLength(2000);
builder.Property(e => e.LogEvent)
.HasColumnType("nvarchar(max)");
builder.HasIndex(e => e.TimeStamp)
.HasDatabaseName("IX_SerilogLogs_TimeStamp");
}
}
@@ -0,0 +1,36 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class TaxConfiguration : IEntityTypeConfiguration<Tax>
{
public void Configure(EntityTypeBuilder<Tax> builder)
{
builder.Property(e => e.AutoNumber)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Code)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Name)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.PercentageValue)
.HasColumnType("decimal(18,2)");
builder.Property(e => e.Category)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Description)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.HasIndex(e => e.AutoNumber).IsUnique();
builder.HasIndex(e => e.Code).IsUnique();
builder.HasIndex(e => e.Name);
}
}
@@ -0,0 +1,25 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class TodoConfiguration : IEntityTypeConfiguration<Todo>
{
public void Configure(EntityTypeBuilder<Todo> builder)
{
builder.Property(e => e.Name)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Description)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.HasMany(e => e.TodoItemList)
.WithOne(e => e.Todo)
.HasForeignKey(e => e.TodoId)
.OnDelete(DeleteBehavior.NoAction);
builder.HasIndex(e => e.Name);
}
}
@@ -0,0 +1,29 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class TodoItemConfiguration : IEntityTypeConfiguration<TodoItem>
{
public void Configure(EntityTypeBuilder<TodoItem> builder)
{
builder.Property(e => e.Name)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Description)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.TodoId)
.HasMaxLength(GlobalConsts.StringLengthId);
builder.HasOne(e => e.Todo)
.WithMany(e => e.TodoItemList)
.HasForeignKey(e => e.TodoId)
.OnDelete(DeleteBehavior.Cascade);
builder.HasIndex(e => e.Name);
builder.HasIndex(e => e.TodoId);
}
}
@@ -0,0 +1,20 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class UnitMeasureConfiguration : IEntityTypeConfiguration<UnitMeasure>
{
public void Configure(EntityTypeBuilder<UnitMeasure> builder)
{
builder.Property(e => e.Name)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Description)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.HasIndex(e => e.Name);
}
}
@@ -0,0 +1,20 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class VendorCategoryConfiguration : IEntityTypeConfiguration<VendorCategory>
{
public void Configure(EntityTypeBuilder<VendorCategory> builder)
{
builder.Property(e => e.Name)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Description)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.HasIndex(e => e.Name);
}
}
@@ -0,0 +1,92 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class VendorConfiguration : IEntityTypeConfiguration<Vendor>
{
public void Configure(EntityTypeBuilder<Vendor> builder)
{
builder.Property(e => e.Name)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.AutoNumber)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Description)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.Street)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.City)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.State)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.ZipCode)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Country)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.PhoneNumber)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.FaxNumber)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.EmailAddress)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Website)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.WhatsApp)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.LinkedIn)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Facebook)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Instagram)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.TwitterX)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.TikTok)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.VendorGroupId)
.HasMaxLength(GlobalConsts.StringLengthId);
builder.Property(e => e.VendorCategoryId)
.HasMaxLength(GlobalConsts.StringLengthId);
builder.HasOne(e => e.VendorGroup)
.WithMany()
.HasForeignKey(e => e.VendorGroupId)
.OnDelete(DeleteBehavior.NoAction);
builder.HasOne(e => e.VendorCategory)
.WithMany()
.HasForeignKey(e => e.VendorCategoryId)
.OnDelete(DeleteBehavior.NoAction);
builder.HasMany(e => e.VendorContactList)
.WithOne(e => e.Vendor)
.HasForeignKey(e => e.VendorId)
.OnDelete(DeleteBehavior.Cascade);
builder.HasIndex(e => e.Name);
builder.HasIndex(e => e.AutoNumber).IsUnique();
builder.HasIndex(e => e.VendorGroupId);
builder.HasIndex(e => e.VendorCategoryId);
}
}
@@ -0,0 +1,42 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class VendorContactConfiguration : IEntityTypeConfiguration<VendorContact>
{
public void Configure(EntityTypeBuilder<VendorContact> builder)
{
builder.Property(e => e.Name)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.AutoNumber)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.JobTitle)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.PhoneNumber)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.EmailAddress)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Description)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.Property(e => e.VendorId)
.HasMaxLength(GlobalConsts.StringLengthId);
builder.HasOne(e => e.Vendor)
.WithMany(e => e.VendorContactList)
.HasForeignKey(e => e.VendorId)
.OnDelete(DeleteBehavior.Cascade);
builder.HasIndex(e => e.Name);
builder.HasIndex(e => e.AutoNumber).IsUnique();
builder.HasIndex(e => e.VendorId);
}
}
@@ -0,0 +1,20 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class VendorGroupConfiguration : IEntityTypeConfiguration<VendorGroup>
{
public void Configure(EntityTypeBuilder<VendorGroup> builder)
{
builder.Property(e => e.Name)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Description)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.HasIndex(e => e.Name);
}
}
@@ -0,0 +1,20 @@
using Indotalent.Data.Entities;
using Indotalent.Shared.Consts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Indotalent.Infrastructure.Database.MsSQL.Configuration;
public class WarehouseConfiguration : IEntityTypeConfiguration<Warehouse>
{
public void Configure(EntityTypeBuilder<Warehouse> builder)
{
builder.Property(e => e.Name)
.HasMaxLength(GlobalConsts.StringLengthShort);
builder.Property(e => e.Description)
.HasMaxLength(GlobalConsts.StringLengthMedium);
builder.HasIndex(e => e.Name);
}
}
@@ -0,0 +1,23 @@
namespace Indotalent.Infrastructure.Database.MsSQL;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
public static class MsSQLConfiguration
{
public static IServiceCollection AddMsSQLContext<TContext>(this IServiceCollection services, string connectionString)
where TContext : DbContext
{
services.AddDbContext<TContext>(options =>
options.UseSqlServer(connectionString, m =>
m.MigrationsAssembly(typeof(TContext).Assembly.FullName)));
return services;
}
public static void InitializeDatabase<TContext>(IServiceProvider serviceProvider) where TContext : DbContext
{
using var scope = serviceProvider.CreateScope();
var context = scope.ServiceProvider.GetRequiredService<TContext>();
context.Database.EnsureCreated();
}
}
@@ -0,0 +1,17 @@
namespace Indotalent.Infrastructure.Database.MySQL;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
public static class MySQLConfiguration
{
public static IServiceCollection AddMySQLContext<TContext>(this IServiceCollection services, string connectionString)
where TContext : DbContext
{
services.AddDbContext<TContext>(options =>
options.UseMySQL(connectionString, m =>
m.MigrationsAssembly(typeof(TContext).Assembly.FullName)));
return services;
}
}
@@ -0,0 +1,17 @@
namespace Indotalent.Infrastructure.Database.PostgreSQL;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
public static class PostgreSQLConfiguration
{
public static IServiceCollection AddPostgreSQLContext<TContext>(this IServiceCollection services, string connectionString)
where TContext : DbContext
{
services.AddDbContext<TContext>(options =>
options.UseNpgsql(connectionString, m =>
m.MigrationsAssembly(typeof(TContext).Assembly.FullName)));
return services;
}
}