merchant onboarding process completed

This commit is contained in:
2025-08-06 16:11:02 +05:30
parent f90d1f0c57
commit 1a27e282e3
22 changed files with 768 additions and 19 deletions

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.Configuration;
using Singer_Hexdive.Models;
using System.IO;
namespace Singer_Hexdive
@ -9,6 +10,12 @@ namespace Singer_Hexdive
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { }
public DbSet<IdentificationType> IdentificationTypes { get; set; }
public DbSet<MerchantBankDetails> MerchantBankDetails { get; set; }
public DbSet<MerchantBusinessDetail> MerchantBusinessDetail { get; set; }
public DbSet<MerchantPersonalDetail> MerchantPersonalDetail { get; set; }
public DbSet<MerchantShareHolders> MerchantShareHolders { get; set; }
public DbSet<MerchantDirectors> MerchantDirectors { get; set; }
}
public class ApplicationDbContextFactory : IDesignTimeDbContextFactory<ApplicationDbContext>

View File

@ -1,5 +1,7 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Singer_Hexdive.Models.IOs;
using Singer_Hexdive.Services.FunctionHandlers;
namespace Singer_Hexdive.Controllers
{
@ -7,5 +9,18 @@ namespace Singer_Hexdive.Controllers
[Route("api")]
public class ApiController : ControllerBase
{
private readonly MerchantManager _merchantManager;
public ApiController(MerchantManager merchantManager)
{
_merchantManager = merchantManager;
}
[HttpPost("merchant")]
public async Task<IActionResult> MerchantExecute([FromBody] ApiRequest request)
{
var response = await _merchantManager.Execute(request);
return StatusCode(response.StatusCode, response);
}
}
}

View File

@ -0,0 +1,9 @@
namespace Singer_Hexdive.Enums
{
public enum ApprovedStatus
{
pending = 1,
approved = 2,
rejected = 3
}
}

View File

@ -0,0 +1,8 @@
namespace Singer_Hexdive.Enums
{
public enum BankAccountTypes
{
Saving = 1,
Current = 2,
}
}

View File

@ -0,0 +1,7 @@
namespace Singer_Hexdive.Exceptions
{
public class NotfoundException : Exception
{
public NotfoundException(string message) : base(message) { }
}
}

View File

@ -0,0 +1,32 @@
using Singer_Hexdive.Models;
namespace Singer_Hexdive.Interfaces.RepositoryInterfaces
{
public interface IMerchantRepository
{
//-------------------------------------------Merchant_Onboarding_Start----------------------------------//
Task<object> GetM_PersonalDetailsAsync(int merchantId);
Task<object> PostM_PersonalDetailsAsync(MerchantPersonalDetail merchantPersonalDetail);
Task<object> GetM_BusinessDetailsAsync(int merchantId);
Task<object> PostM_BusinessDetailsAsync(MerchantBusinessDetail merchantBusinessDetail);
Task<object> PostM_ShareHolderDetailsAsync(MerchantShareHolders merchantShareHolders);
Task<object> PostM_DiretorDetailsAsync(MerchantDirectors merchantDirectors);
Task<object> GetM_BankDetailsAsync(int merchantId);
Task<object> PostM_BankDetailsAsync(MerchantBankDetails merchantBankDetails);
//Task<object> PostM_ReviewDetails(object payload);
//Task<object> PostM_CompleteOnboarding(object payload);
//-------------------------------------------Merchant_Onboarding_End----------------------------------//
//-------------------------------------------Merchant_Management_Start----------------------------------//
//Task<object> GetMerchantDetails(string merchantId);
//Task<object> UpdateMerchantDetails(string merchantId, object payload);
//Task<object> DeleteMerchant(string merchantId);
//-------------------------------------------Merchant_Management_End----------------------------------//
//-------------------------------------------Merchant_SupportFunctions_Start----------------------------//
Task<int> CheckApprovedStatus(int merchantId, string tableName);
//-------------------------------------------Merchant_SupportFunctions_End------------------------------//
}
}

View File

@ -0,0 +1,25 @@
using System.Text.Json;
namespace Singer_Hexdive.Interfaces.ServiceInterfaces
{
public abstract class BaseMerchantService
{
protected Dictionary<string, JsonElement> DeserializePayload(object payload)
{
if (payload is null)
throw new ArgumentNullException(nameof(payload));
var json = JsonSerializer.Serialize(payload);
return JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(json)
?? throw new InvalidOperationException("Failed to deserialize payload.");
}
public abstract Task<object> GetM_PersonalDetails(object payload);
public abstract Task<object> PostM_PersonalDetails(object payload);
public abstract Task<object> GetM_BusinessDetails(object payload);
public abstract Task<object> PostM_BusinessDetails(object payload);
public abstract Task<object> GetM_BankDetails(object payload);
public abstract Task<object> PostM_BankDetails(object payload);
}
}

View File

@ -0,0 +1,14 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace Singer_Hexdive.Models.IOs
{
[NotMapped]
public class ApiRequest
{
public string FunctionName { get; set; }
public object Payload { get; set; }
public string Reference { get; set; }
}
}

View File

@ -0,0 +1,12 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace Singer_Hexdive.Models.IOs
{
[NotMapped]
public class ApiResponse<T>
{
public int StatusCode { get; set; }
public string Message { get; set; }
public T Data { get; set; }
}
}

View File

@ -0,0 +1,12 @@
using System.ComponentModel.DataAnnotations;
namespace Singer_Hexdive.Models
{
public class IdentificationType
{
[Key]
public int Id { get; set; }
public string IdType { get; set; }
public DateTime CreateAt { get; set; }
}
}

View File

@ -0,0 +1,25 @@
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
using Singer_Hexdive.Enums;
namespace Singer_Hexdive.Models
{
public class MerchantBankDetails
{
[Key]
public int Id { get; set; }
public int FK_MId { get; set; }
[ForeignKey("FK_MId")]
public MerchantPersonalDetail MerchantPersonalDetail { get; set; }
public string CurrencyCode { get; set; }
public BankAccountTypes BankAccountTypes { get; set; }
public string M_BankName { get; set; }
public string M_BankBranchName { get; set; }
public int M_BankAccNum { get; set; }
public string M_BankAccHolderName { get; set; }
public string M_BankHolderIdNum { get; set; }
public string M_PhoneNum { get; set; }
public ApprovedStatus ApprovedStatus { get; set; } = ApprovedStatus.pending;
public DateTime CreatedAt { get; set; }
}
}

View File

@ -0,0 +1,26 @@
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
using Singer_Hexdive.Enums;
namespace Singer_Hexdive.Models
{
public class MerchantBusinessDetail
{
[Key]
public int Id { get; set; }
public int FK_MechantId { get; set; }
[ForeignKey("FK_MechantId")]
public MerchantPersonalDetail merchantPersonalDetail { get; set; }
public string BusinessName { get; set; }
public string BusinessDoingName { get; set; }
public string BusinessRegNum { get; set; }
public string BusinessIncomeTaxNum { get; set; }
public DateTime BusinessRegDate { get; set; }
public DateTime BusinessIncomeDate { get; set; }
public string BusinessAddress { get; set; }
public string BusinessCity { get; set; }
public int PostalCode { get; set; }
public ApprovedStatus ApprovedStatus { get; set; } = ApprovedStatus.pending;
public DateTime CreatedAt { get; set; }
}
}

View File

@ -0,0 +1,21 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Singer_Hexdive.Models
{
public class MerchantDirectors
{
[Key]
public int DirectorId { get; set; }
public int FK_MBusinessId { get; set; }
[ForeignKey("FK_MBusinessId")]
public MerchantBusinessDetail MerchantBusinessDetail { get; set; }
public string D_FullName { get; set; }
public string D_IdNumber { get; set; }
public DateTime Birthday { get; set; }
public string D_MobileNumber { get; set; }
public string D_Address { get; set; }
public DateTime createdAt { get; set; } = DateTime.Now;
}
}

View File

@ -0,0 +1,27 @@
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
using Singer_Hexdive.Enums;
namespace Singer_Hexdive.Models
{
public class MerchantPersonalDetail
{
[Key]
public int MechantId { get; set; }
public string MerchantName { get; set; }
public int FK_IdType { get; set; }
[ForeignKey("FK_IdType")]
public IdentificationType IdentificationType { get; set; }
public string M_IdNumber { get; set; }
public string M_Email { get; set; }
public string M_Mobile_Primary { get; set; }
public string? M_Mobile_Secondary { get; set; }
public string M_Address { get; set; }
public string M_City { get; set; }
public int M_PostalCode { get; set; }
public DateTime OnboardDate { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.Now;
public bool IsActive { get; set; } = true;
public ApprovedStatus ApprovedStatus { get; set; } = ApprovedStatus.pending;
}
}

View File

@ -0,0 +1,21 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Singer_Hexdive.Models
{
public class MerchantShareHolders
{
[Key]
public int ShareHolderId { get; set; }
public int FK_MBusinessId { get; set; }
[ForeignKey("FK_MBusinessId")]
public MerchantBusinessDetail MerchantBusinessDetail { get; set; }
public string S_FullName { get; set; }
public string S_IdNumber { get; set; }
public DateTime Bithday { get; set; }
public string S_MobileNumber { get; set; }
public string S_Address { get; set; }
public decimal S_SharePercentage { get; set; }
public DateTime createdAt { get; set; } = DateTime.Now;
}
}

View File

@ -1,5 +1,15 @@
using System.Text.Json.Serialization;
using Microsoft.EntityFrameworkCore;
using Singer_Hexdive;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<ApplicationDbContext>(option =>
option.UseMySql(
builder.Configuration.GetConnectionString("DefaultConnection"),
ServerVersion.AutoDetect(builder.Configuration.GetConnectionString("DefaultConnection"))
));
// Add services to the container.
builder.Services.AddControllers();
@ -7,6 +17,12 @@ builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddControllers()
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
});
var app = builder.Build();
// Configure the HTTP request pipeline.

View File

@ -0,0 +1,146 @@
using Microsoft.EntityFrameworkCore;
using Singer_Hexdive.Exceptions;
using Singer_Hexdive.Interfaces.RepositoryInterfaces;
using Singer_Hexdive.Models;
namespace Singer_Hexdive.Repositories
{
public class MerchantRepository : IMerchantRepository
{
private readonly ApplicationDbContext _context;
public MerchantRepository(ApplicationDbContext applicationDbContext)
{
_context = applicationDbContext;
}
//-------------------------------------------Merchant_Onboarding_Start----------------------------------//
public async Task<object> GetM_PersonalDetailsAsync(int merchantId)
{
var merchantPersonalDetail = await _context.MerchantPersonalDetail
.Where(m => m.MechantId == merchantId)
.FirstOrDefaultAsync();
if (merchantPersonalDetail == null)
{
throw new NotfoundException($"Merchant presonal deatils with ID {merchantId} not found.");
}
return merchantPersonalDetail;
}
public async Task<object> PostM_PersonalDetailsAsync(MerchantPersonalDetail merchantPersonalDetail)
{
await _context.MerchantPersonalDetail.AddAsync(merchantPersonalDetail);
await _context.SaveChangesAsync();
return merchantPersonalDetail;
}
public async Task<object> GetM_BusinessDetailsAsync(int merchantId)
{
var merchantBusinessDetail = await _context.MerchantBusinessDetail
.Where(m => m.FK_MechantId == merchantId)
.FirstOrDefaultAsync();
if (merchantBusinessDetail == null)
{
throw new NotfoundException($"Merchant business deatils with ID {merchantId} not found.");
}
var merchantShareHolders = await _context.MerchantShareHolders
.Where(m => m.FK_MBusinessId == merchantBusinessDetail.Id)
.ToListAsync();
var merchantDirectors = await _context.MerchantDirectors
.Where(m => m.FK_MBusinessId == merchantBusinessDetail.Id)
.ToListAsync();
var details = new
{
BusinessDetails = merchantBusinessDetail,
ShareHolders = merchantShareHolders,
Directors = merchantDirectors
};
return details;
}
public async Task<object> PostM_BusinessDetailsAsync(MerchantBusinessDetail merchantBusinessDetail)
{
await _context.MerchantBusinessDetail.AddAsync(merchantBusinessDetail);
await _context.SaveChangesAsync();
return merchantBusinessDetail;
}
public async Task<object> PostM_ShareHolderDetailsAsync(MerchantShareHolders merchantShareHolders)
{
await _context.MerchantShareHolders.AddAsync(merchantShareHolders);
await _context.SaveChangesAsync();
return merchantShareHolders;
}
public async Task<object> PostM_DiretorDetailsAsync(MerchantDirectors merchantDirectors)
{
await _context.MerchantDirectors.AddAsync(merchantDirectors);
await _context.SaveChangesAsync();
return merchantDirectors;
}
public async Task<object> GetM_BankDetailsAsync(int merchantId)
{
var merchantBankDetail = await _context.MerchantBankDetails
.Where(m => m.FK_MId == merchantId)
.FirstOrDefaultAsync();
if (merchantBankDetail == null)
{
throw new NotfoundException($"Merchant Bank deatils with ID {merchantId} not found.");
}
return merchantBankDetail;
}
public async Task<object> PostM_BankDetailsAsync(MerchantBankDetails merchantBankDetails)
{
await _context.MerchantBankDetails.AddAsync(merchantBankDetails);
await _context.SaveChangesAsync();
return merchantBankDetails;
}
//-------------------------------------------Merchant_Onboarding_End------------------------------------//
//-------------------------------------------Merchant_Management_Start----------------------------------//
//-------------------------------------------Merchant_Management_End------------------------------------//
//-------------------------------------------Merchant_SupportFunctions_Start----------------------------//
public async Task<int> CheckApprovedStatus(int merchantId, string tableName)
{
object? approveSatatus = null;
switch (tableName)
{
case "MerchantPersonalDetail":
approveSatatus = await _context.MerchantPersonalDetail
.Where(m => m.MechantId == merchantId)
.Select(m => new { m.ApprovedStatus })
.FirstOrDefaultAsync();
break;
case "MerchantBusinessDetail":
approveSatatus = await _context.MerchantBusinessDetail
.Where(m => m.FK_MechantId == merchantId)
.Select(m => new { m.ApprovedStatus })
.FirstOrDefaultAsync();
break;
case "MerchantBankDetail":
approveSatatus = await _context.MerchantBankDetails
.Where(m => m.FK_MId == merchantId)
.Select(m => new { m.ApprovedStatus })
.FirstOrDefaultAsync();
break;
default:
throw new ArgumentException("Invalid table name provided.");
}
return (int)approveSatatus;
}
//-------------------------------------------Merchant_SupportFunctions_End------------------------------//
}
}

View File

@ -0,0 +1,71 @@
using Singer_Hexdive.Exceptions;
using Singer_Hexdive.Interfaces.ServiceInterfaces;
using Singer_Hexdive.Models.IOs;
namespace Singer_Hexdive.Services.FunctionHandlers
{
public class MerchantManager
{
private readonly Dictionary<string, Func<object, Task<object>>> _functionHandler;
public MerchantManager(BaseMerchantService merchantService)
{
_functionHandler = new()
{
{"PostM_PersonalDetails", merchantService.PostM_PersonalDetails }
};
}
public async Task<ApiResponse<object>> Execute(ApiRequest request)
{
if (!_functionHandler.TryGetValue(request.FunctionName, out var handler))
{
return new ApiResponse<object>
{
StatusCode = 404,
Message = $"Function '{request.FunctionName}' not found.",
Data = null
};
}
try
{
var results = await handler(request.Payload);
return new ApiResponse<object>
{
StatusCode = 200,
Message = "success",
Data = results
};
}
catch (NotfoundException ex)
{
return new ApiResponse<object>
{
StatusCode = 404,
Message = ex.Message,
Data = null
};
}
catch (InvalidOperationException ex)
{
return new ApiResponse<object>
{
StatusCode = 400,
Message = ex.Message,
Data = null
};
}
catch (ArgumentException ex)
{
return new ApiResponse<object>
{
StatusCode = 500,
Message = ex.Message,
Data = null
};
}
}
}
}

View File

@ -0,0 +1,165 @@
using System.Text.Json;
using Singer_Hexdive.Enums;
using Singer_Hexdive.Interfaces.RepositoryInterfaces;
using Singer_Hexdive.Interfaces.ServiceInterfaces;
using Singer_Hexdive.Models;
using Singer_Hexdive.Validations;
namespace Singer_Hexdive.Services
{
public class MerchantService : BaseMerchantService
{
private readonly IMerchantRepository _merchantRepository;
public MerchantService(IMerchantRepository merchantRepository)
{
_merchantRepository = merchantRepository;
}
//-------------------------------------------Merchant_Onboarding_Start----------------------------------//
public override async Task<object> GetM_PersonalDetails(object payload)
{
var data = DeserializePayload(payload);
int merchantId = FieldValidators.EnsureNotLessZero(data["MerchantId"].GetInt32(), "MerchantId");
var result = await _merchantRepository.GetM_PersonalDetailsAsync(merchantId);
return result;
}
public override async Task<object> PostM_PersonalDetails(object payload)
{
var data = DeserializePayload(payload);
int approveStatus = await _merchantRepository.CheckApprovedStatus(data["MechantId"].GetInt32(), "MerchantPersonalDetail");
if (approveStatus == 2)
{
var merchantPersonalDetail = new MerchantPersonalDetail
{
MerchantName = FieldValidators.EnsureNotNullOrEmpty(data["MerchantName"].GetString(), "MerchantName"),
FK_IdType = FieldValidators.EnsureNotLessZero(data["FK_IdType"].GetInt32(), "FK_IdType"),
M_IdNumber = FieldValidators.EnsureNotNullOrEmpty(data["M_IdNumber"].GetString(), "M_IdNumber"),
M_Email = FieldValidators.EnsureValidEmail(data["M_Email"].GetString(), "M_Email"),
M_Mobile_Primary = FieldValidators.IsValidPhoneNumber(data["M_Mobile_Primary"].GetString(), "M_Mobile_Primary"),
M_Mobile_Secondary = FieldValidators.IsValidPhoneNumber(data["M_Mobile_Secondary"].GetString(), "M_Mobile_Secondary"),
M_Address = FieldValidators.EnsureNotNullOrEmpty(data["M_Address"].GetString(), "M_Address"),
M_City = FieldValidators.EnsureNotNullOrEmpty(data["M_City"].GetString(), "M_City"),
M_PostalCode = FieldValidators.EnsureNotLessZero(data["M_PostalCode"].GetInt32(), "M_PostalCode"),
OnboardDate = data["OnboardDate"].GetDateTime(),
};
var result = await _merchantRepository.PostM_PersonalDetailsAsync(merchantPersonalDetail);
return result;
}
else
{
throw new InvalidOperationException("Merchant is not approved for onboarding.");
}
}
public override async Task<object> GetM_BusinessDetails(object payload)
{
var data = DeserializePayload(payload);
int merchantId = FieldValidators.EnsureNotLessZero(data["MerchantId"].GetInt32(), "MerchantId");
var result = await _merchantRepository.GetM_PersonalDetailsAsync(merchantId);
return result;
}
public override async Task<object> PostM_BusinessDetails(object payload)
{
var data = DeserializePayload(payload);
int approveStatus = await _merchantRepository.CheckApprovedStatus(data["MechantId"].GetInt32(), "MerchantBusinessDetail");
if (approveStatus == 2)
{
var merchantBusinessDetail = new MerchantBusinessDetail
{
FK_MechantId = FieldValidators.EnsureNotLessZero(data["MechantId"].GetInt32(), "MechantId"),
BusinessName = FieldValidators.EnsureNotNullOrEmpty(data["BusinessName"].GetString(), "BusinessName"),
BusinessDoingName = FieldValidators.EnsureNotNullOrEmpty(data["BusinessDoingName"].GetString(), "BusinessDoingName"),
BusinessRegNum = FieldValidators.EnsureNotNullOrEmpty(data["BusinessRegNum"].GetString(), "BusinessRegNum"),
BusinessIncomeTaxNum = FieldValidators.EnsureNotNullOrEmpty(data["BusinessIncomeTaxNum"].GetString(), "BusinessIncomeTaxNum"),
BusinessRegDate = data["BusinessRegDate"].GetDateTime(),
BusinessIncomeDate = data["BusinessIncomeDate"].GetDateTime(),
BusinessAddress = FieldValidators.EnsureNotNullOrEmpty(data["BusinessAddress"].GetString(), "BusinessAddress"),
BusinessCity = FieldValidators.EnsureNotNullOrEmpty(data["BusinessCity"].GetString(), "BusinessCity"),
PostalCode = FieldValidators.EnsureNotLessZero(data["PostalCode"].GetInt32(), "PostalCode"),
};
var result = (MerchantBusinessDetail)await _merchantRepository.PostM_BusinessDetailsAsync(merchantBusinessDetail);
if (data["ShareHolders"].ValueKind == JsonValueKind.Array)
{
foreach (var shareHolder in data["ShareHolders"].EnumerateArray())
{
var shareHolderDetail = new MerchantShareHolders
{
FK_MBusinessId = result.Id,
S_FullName = FieldValidators.EnsureNotNullOrEmpty(shareHolder.GetProperty("S_FullName").GetString(), "S_FullName"),
S_IdNumber = FieldValidators.EnsureNotNullOrEmpty(shareHolder.GetProperty("S_IdNumber").GetString(), "S_IdNumber"),
S_MobileNumber = FieldValidators.IsValidPhoneNumber(shareHolder.GetProperty("S_MobileNumber").GetString(), "S_MobileNumber"),
S_Address = FieldValidators.EnsureNotNullOrEmpty(shareHolder.GetProperty("S_Address").GetString(), "S_Address"),
S_SharePercentage = shareHolder.GetProperty("S_SharePercentage").GetDecimal(),
Bithday = shareHolder.GetProperty("Bithday").GetDateTime(),
};
await _merchantRepository.PostM_ShareHolderDetailsAsync(shareHolderDetail);
}
}
if (data["Directors"].ValueKind == JsonValueKind.Array)
{
foreach (var directors in data["Directors"].EnumerateArray())
{
var DirectorsDetail = new MerchantDirectors
{
FK_MBusinessId = result.Id,
D_FullName = FieldValidators.EnsureNotNullOrEmpty(directors.GetProperty("D_FullName").GetString(), "D_FullName"),
D_IdNumber = FieldValidators.EnsureNotNullOrEmpty(directors.GetProperty("D_IdNumber").GetString(), "D_IdNumber"),
D_MobileNumber = FieldValidators.IsValidPhoneNumber(directors.GetProperty("D_MobileNumber").GetString(), "D_MobileNumber"),
D_Address = FieldValidators.EnsureNotNullOrEmpty(directors.GetProperty("D_Address").GetString(), "D_Address"),
Birthday = directors.GetProperty("D_Bithday").GetDateTime(),
};
await _merchantRepository.PostM_DiretorDetailsAsync(DirectorsDetail);
}
}
return result;
}
else
{
throw new InvalidOperationException("Merchant is not approved for onboarding.");
}
}
public override async Task<object> GetM_BankDetails(object payload)
{
var data = DeserializePayload(payload);
int merchantId = FieldValidators.EnsureNotLessZero(data["MerchantId"].GetInt32(), "MerchantId");
var result = await _merchantRepository.GetM_BankDetailsAsync(merchantId);
return result;
}
public override async Task<object> PostM_BankDetails(object payload)
{
var data = DeserializePayload(payload);
int approveStatus = await _merchantRepository.CheckApprovedStatus(data["MechantId"].GetInt32(), "MerchantBankDetail");
if (approveStatus == 2)
{
var merchantBankDetails = new MerchantBankDetails
{
FK_MId = FieldValidators.EnsureNotLessZero(data["MechantId"].GetInt32(), "MechantId"),
CurrencyCode = FieldValidators.EnsureNotNullOrEmpty(data["CurrencyCode"].GetString(), "CurrencyCode"),
BankAccountTypes = (BankAccountTypes)FieldValidators.EnsureNotLessZero(data["BankAccountTypes"].GetInt32(), "BankAccountTypes"),
M_BankName = FieldValidators.EnsureNotNullOrEmpty(data["M_BankName"].GetString(), "M_BankName"),
M_BankBranchName = FieldValidators.EnsureNotNullOrEmpty(data["M_BankBranchName"].GetString(), "M_BankBranchName"),
M_BankAccNum = FieldValidators.EnsureNotLessZero(data["M_BankAccNum"].GetInt32(), "M_BankAccNum"),
M_BankAccHolderName = FieldValidators.EnsureNotNullOrEmpty(data["M_BankAccHolderName"].GetString(), "M_BankAccHolderName"),
M_BankHolderIdNum = FieldValidators.EnsureNotNullOrEmpty(data["M_BankHolderIdNum"].GetString(), "M_BankHolderIdNum"),
M_PhoneNum = FieldValidators.IsValidPhoneNumber(data["M_PhoneNum"].GetString(), "M_PhoneNum")
};
var result = await _merchantRepository.PostM_BankDetailsAsync(merchantBankDetails);
return result;
}
else
{
throw new InvalidOperationException("Merchant is not approved for onboarding.");
}
}
//-------------------------------------------Merchant_Onboarding_End----------------------------------//
}
}

View File

@ -7,17 +7,12 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="8.0.3" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
</ItemGroup>
<ItemGroup>
<Folder Include="Interfaces\ServiceInterfaces\" />
<Folder Include="Interfaces\RepositoryInterfaces\" />
<Folder Include="Models\IOs\" />
<Folder Include="Validations\" />
<Folder Include="Services\" />
<Folder Include="Repositories\" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,92 @@
namespace Singer_Hexdive.Validations
{
public class FieldValidators
{
public static string EnsureNotNullOrEmpty(string value, string fieldName)
{
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentException($"{fieldName} cannot be empty.", fieldName);
else
{
return value;
}
}
public static int EnsureNotLessZero(int value, string fieldName)
{
if (value < 0)
throw new ArgumentException($"{fieldName} cannot be less than zero.", fieldName);
else
{
return value;
}
}
public static decimal EnsureIsMin(decimal value, int minValue, string fieldName)
{
if (value > minValue)
throw new ArgumentException($"{fieldName} cannot be less than {minValue}.", fieldName);
else
{
return value;
}
}
public static decimal EnsureIsMax(decimal value, int maxValue, string fieldName)
{
if (value < maxValue)
throw new ArgumentException($"{fieldName} cannot be less than {maxValue}.", fieldName);
else
{
return value;
}
}
//public static bool IsValidEmail(string email, string fieldName)
//{
// if (string.IsNullOrWhiteSpace(email))
// throw new ArgumentException($"{fieldName} cannot be empty.", fieldName);
// try
// {
// var addr = new System.Net.Mail.MailAddress(email);
// return addr.Address == email;
// }
// catch
// {
// throw new ArgumentException($"{fieldName} is not a valid .", fieldName);
// }
//}
public static string IsValidPhoneNumber(string phoneNumber, string fieldName)
{
if (string.IsNullOrWhiteSpace(phoneNumber))
throw new ArgumentException($"{fieldName} cannot be empty.", fieldName);
if (!phoneNumber.All(char.IsDigit) || phoneNumber.Length != 10)
throw new ArgumentException($"{fieldName} must be exactly 10 digits.", fieldName);
return phoneNumber;
}
public static string EnsureValidEmail(string email, string fieldName)
{
if (string.IsNullOrWhiteSpace(email))
throw new ArgumentException($"{fieldName} cannot be empty.", fieldName);
try
{
var addr = new System.Net.Mail.MailAddress(email);
if (addr.Address != email)
throw new ArgumentException($"{fieldName} is not a valid email address.", fieldName);
}
catch
{
throw new ArgumentException($"{fieldName} is not a valid email address.", fieldName);
}
return email;
}
}
}

View File

@ -5,5 +5,8 @@
"Microsoft.AspNetCore": "Warning"
}
},
"ConnectionStrings": {
"DefaultConnection": "server=localhost;port=3306;database=singer;user=root;password="
},
"AllowedHosts": "*"
}