Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
a193cf9
Updated packages.
Slimcent Jul 1, 2026
ba43124
New tables in the db context.
Slimcent Jul 3, 2026
9d67d3d
Created gender table.
Slimcent Jul 3, 2026
ae47115
Created roles and claims table.
Slimcent Jul 3, 2026
4211070
Created usertype table.
Slimcent Jul 3, 2026
66a78a8
Modified existing tables.
Slimcent Jul 3, 2026
b6d19eb
Modified existing tables.
Slimcent Jul 3, 2026
ae6c3f7
created menu table.
Slimcent Jul 3, 2026
7d0cad1
Fixed mapping profile.
Slimcent Jul 3, 2026
e58c4fc
fixed staff service.
Slimcent Jul 5, 2026
84cdab1
fixed customer service..
Slimcent Jul 5, 2026
164aadc
stopped seeding data using model builder.
Slimcent Jul 5, 2026
ecc76cf
deleted Airtime model.
Slimcent Jul 5, 2026
4169053
deleted network data model.
Slimcent Jul 5, 2026
076ee4b
added bill mode model.
Slimcent Jul 5, 2026
7afbe59
added transaction mode and transaction type models.
Slimcent Jul 5, 2026
14a4d6f
made user nullable in wallet.
Slimcent Jul 6, 2026
5253b4a
removed airtime service.
Slimcent Jul 6, 2026
e6ac243
Deleted data and airtime controllers and services.
Slimcent Jul 7, 2026
c834a7e
Removed unneeded mappings in the mapping profile.
Slimcent Jul 7, 2026
93b5ae1
Removed unneeded classes from the service extension.
Slimcent Jul 7, 2026
da5702d
Fixed role service.
Slimcent Jul 13, 2026
56a7b8f
Fixed select service.
Slimcent Jul 13, 2026
029c023
Fixed transaction service to fit new model changes.
Slimcent Jul 13, 2026
75879de
Changed name in Bill model.
Slimcent Jul 13, 2026
3b5bab5
Modified controllers to fit model changes.
Slimcent Jul 13, 2026
52e58b1
Modified seeding of data.
Slimcent Jul 13, 2026
3568cc4
Merge branch 'main' of https://github.com/Slimcent/WalletBankingApp i…
Slimcent Aug 18, 2026
a1a865d
updated dependencies.
Slimcent Aug 18, 2026
b8abe54
Merge pull request #11 from Slimcent/Fix/Updated-dependencies
Slimcent Aug 18, 2026
09bd875
merged with development.
Slimcent Aug 30, 2026
8af7c3c
Merge pull request #12 from Slimcent/Enhancement/Model
Slimcent Aug 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions NuGet.Config
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
</packageSources>
</configuration>
82 changes: 82 additions & 0 deletions Wallet.Data/Seeders/Seed.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
namespace Wallet.Data.Seeders
{
public class Seed
{
public List<string> Roles { get; set; } = new();

public List<string> Genders { get; set; } = new();

public List<string> UserTypes { get; set; } = new();

public List<string> TransactionTypes { get; set; } = new();

public List<string> TransactionModes { get; set; } = new();

public List<SeedBill> Bills { get; set; } = new();

public List<SeedBillMode> BillModes { get; set; } = new();

public List<SeedMenu> Menus { get; set; } = new();

public List<SeedStampDutyCharge> StampDutyCharges { get; set; } = new();

public SeedAdminUser AdminUser { get; set; } = new();
}

public class SeedAdminUser
{
public string FirstName { get; set; } = string.Empty;

public string LastName { get; set; } = string.Empty;

public string Email { get; set; } = string.Empty;

public string UserName { get; set; } = string.Empty;

public string PhoneNumber { get; set; } = string.Empty;

public string Password { get; set; } = string.Empty;

public string Role { get; set; } = string.Empty;

public string UserType { get; set; } = string.Empty;

public string Gender { get; set; } = string.Empty;
}

public class SeedBill
{
public string Id { get; set; } = string.Empty;

public string Name { get; set; } = string.Empty;

public decimal Amount { get; set; }
}

public class SeedBillMode
{
public string Id { get; set; } = string.Empty;

public string Name { get; set; } = string.Empty;

public string BillId { get; set; } = string.Empty;
}

public class SeedStampDutyCharge
{
public string Id { get; set; } = string.Empty;

public string Name { get; set; } = string.Empty;

public decimal Amount { get; set; }
}

public class SeedMenu
{
public string Id { get; set; } = string.Empty;

public string Name { get; set; } = string.Empty;

public int OrderId { get; set; }
}
}
247 changes: 247 additions & 0 deletions Wallet.Data/Seeders/SeedApplicationData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Wallet.Data.Seeders;
using Wallet.Entities.Models.Context;
using Wallet.Entities.Models.Domain;

namespace WalletApi.Data.Seeders
{
public static class SeedApplicationData
{
public static IServiceCollection BindSeedConfig(this IServiceCollection services, IConfiguration configuration)
{
Seed seed = new();

configuration.GetSection("Seed").Bind(seed);

services.AddSingleton(seed);

return services;
}

public static async Task EnsurePopulated(IApplicationBuilder app)
{
using var scope = app.ApplicationServices.CreateScope();

Seed seed = scope.ServiceProvider.GetRequiredService<Seed>();
WalletDbContext context = scope.ServiceProvider.GetRequiredService<WalletDbContext>();
UserManager<ApplicationUser> userManager = scope.ServiceProvider.GetRequiredService<UserManager<ApplicationUser>>();
RoleManager<ApplicationRole> roleManager = scope.ServiceProvider.GetRequiredService<RoleManager<ApplicationRole>>();

await context.Database.MigrateAsync();

var strategy = context.Database.CreateExecutionStrategy();

await strategy.ExecuteAsync(async () =>
{
await using IDbContextTransaction transaction = await context.Database.BeginTransactionAsync();

try
{
await SeedIfEmptyAsync(context.Genders, seed.Genders.Select(name => new Gender
{
Name = name,
Active = true,
CreatedBy = "seed",
UpdatedBy = "seed"
}),
context);

await SeedIfEmptyAsync(context.UserTypes, seed.UserTypes.Select(name => new UserType
{
Name = name,
Active = true,
CreatedBy = "seed",
UpdatedBy = "seed"
}),
context);

await SeedIfEmptyAsync(context.TransactionTypes, seed.TransactionTypes.Select(name => new TransactionType
{
Name = name,
Active = true,
CreatedBy = "seed",
UpdatedBy = "seed"
}),
context);

await SeedIfEmptyAsync(context.TransactionModes, seed.TransactionModes.Select(name => new TransactionMode
{
Name = name,
Active = true,
CreatedBy = "seed",
UpdatedBy = "seed"
}),
context);

await SeedIfEmptyAsync(context.Bills, seed.Bills.Select(bill => new Bill
{
Id = bill.Id,
Name = bill.Name,
Amount = bill.Amount,
Active = true,
CreatedBy = "seed",
UpdatedBy = "seed"
}),
context);

await SeedIfEmptyAsync(context.BillModes, seed.BillModes.Select(billMode => new BillMode
{
Id = billMode.Id,
Name = billMode.Name,
BillId = billMode.BillId,
Active = true,
CreatedBy = "seed",
UpdatedBy = "seed"
}),
context);

await SeedIfEmptyAsync(context.StampDutyCharges, seed.StampDutyCharges.Select(stampDutyCharge => new StampDutyCharge
{
Id = stampDutyCharge.Id,
Name = stampDutyCharge.Name,
Amount = stampDutyCharge.Amount,
Active = true
}),
context);

await SeedIfEmptyAsync(context.Menus, seed.Menus.Select(menu => new Menu
{
Id = menu.Id,
Name = menu.Name,
OrderId = menu.OrderId,
CreatedBy = "seed",
UpdatedBy = "seed"
}),
context);

await SeedRolesAsync(roleManager, seed);

await SeedAdminUserAsync(context, userManager, seed);

await transaction.CommitAsync();
}
catch
{
await transaction.RollbackAsync();
throw;
}
});
}

private static async Task SeedIfEmptyAsync<T>(DbSet<T> dbSet, IEnumerable<T> entities, WalletDbContext context) where T : class
{
if (await dbSet.AnyAsync())
return;

List<T> items = entities.ToList();

if (!items.Any())
return;

await dbSet.AddRangeAsync(items);

//await context.SaveChangesAsync();
}

private static async Task SeedRolesAsync(RoleManager<ApplicationRole> roleManager, Seed seed)
{
foreach (string role in seed.Roles)
{
if (await roleManager.RoleExistsAsync(role))
continue;

ApplicationRole applicationRole = new ApplicationRole
{
Name = role,
Active = true,
CreatedBy = "seed",
UpdatedBy = "seed"
};

IdentityResult result = await roleManager.CreateAsync(applicationRole);

if (!result.Succeeded)
{
throw new InvalidOperationException(
string.Join(", ", result.Errors.Select(x => x.Description)));
}
}
}

private static async Task SeedAdminUserAsync(WalletDbContext context, UserManager<ApplicationUser> userManager, Seed seed)
{
if (await userManager.Users.AnyAsync())
return;

SeedAdminUser adminSeed = seed.AdminUser;

UserType userType = await context.UserTypes.FirstOrDefaultAsync(x => x.Name == adminSeed.UserType);

if (userType == null)
throw new InvalidOperationException($"User type '{adminSeed.UserType}' was not found.");

ApplicationUser user = new ApplicationUser
{
FirstName = adminSeed.FirstName,
LastName = adminSeed.LastName,
Email = adminSeed.Email,
UserName = adminSeed.UserName,
PhoneNumber = adminSeed.PhoneNumber,
UserTypeId = userType.Id,
Active = true,
EmailConfirmed = true,
PhoneNumberConfirmed = true,
CreatedBy = "seed",
UpdatedBy = "seed"
};

IdentityResult createUser = await userManager.CreateAsync(user, adminSeed.Password);

if (!createUser.Succeeded)
{
throw new InvalidOperationException(
string.Join(", ", createUser.Errors.Select(x => x.Description)));
}

IdentityResult addToRole = await userManager.AddToRoleAsync(user, adminSeed.Role);

if (!addToRole.Succeeded)
{
throw new InvalidOperationException(
string.Join(", ", addToRole.Errors.Select(x => x.Description)));
}

await SeedAdminStaffAsync(context, user, adminSeed);
}

private static async Task SeedAdminStaffAsync(WalletDbContext context, ApplicationUser user, SeedAdminUser adminSeed)
{
if (await context.Staff.AnyAsync(x => x.UserId == user.Id))
return;

Gender gender = await context.Genders.FirstOrDefaultAsync(x => x.Name == adminSeed.Gender);

if (gender == null)
throw new InvalidOperationException($"Gender '{adminSeed.Gender}' was not found.");

context.Staff.Add(new Staff
{
Id = Guid.NewGuid().ToString(),
UserId = user.Id,
Email = user.Email ?? string.Empty,
PhoneNumber = user.PhoneNumber ?? string.Empty,
Gender = gender,
Active = true,
CreatedBy = "seed",
UpdatedBy = "seed"
});

await context.SaveChangesAsync();
}
}
}
9 changes: 8 additions & 1 deletion Wallet.Data/Wallet.Data.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,14 @@

<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.7" />
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.4.3" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="10.0.9" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.9" />
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.6.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Wallet.Entities\Wallet.Entities.csproj" />
</ItemGroup>

</Project>
29 changes: 0 additions & 29 deletions Wallet.Entities/Data/AirTimeSeed.cs

This file was deleted.

Loading
Loading