merchant onboarding process completed
This commit is contained in:
@ -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>
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
9
Singer_Hexdive/Enums/ApprovedStatus.cs
Normal file
9
Singer_Hexdive/Enums/ApprovedStatus.cs
Normal file
@ -0,0 +1,9 @@
|
||||
namespace Singer_Hexdive.Enums
|
||||
{
|
||||
public enum ApprovedStatus
|
||||
{
|
||||
pending = 1,
|
||||
approved = 2,
|
||||
rejected = 3
|
||||
}
|
||||
}
|
8
Singer_Hexdive/Enums/BankAccountTypes.cs
Normal file
8
Singer_Hexdive/Enums/BankAccountTypes.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace Singer_Hexdive.Enums
|
||||
{
|
||||
public enum BankAccountTypes
|
||||
{
|
||||
Saving = 1,
|
||||
Current = 2,
|
||||
}
|
||||
}
|
7
Singer_Hexdive/Exceptions/NotfoundException.cs
Normal file
7
Singer_Hexdive/Exceptions/NotfoundException.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace Singer_Hexdive.Exceptions
|
||||
{
|
||||
public class NotfoundException : Exception
|
||||
{
|
||||
public NotfoundException(string message) : base(message) { }
|
||||
}
|
||||
}
|
@ -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------------------------------//
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
||||
}
|
||||
}
|
14
Singer_Hexdive/Models/IOs/ApiRequest.cs
Normal file
14
Singer_Hexdive/Models/IOs/ApiRequest.cs
Normal 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; }
|
||||
}
|
||||
}
|
12
Singer_Hexdive/Models/IOs/ApiResponse.cs
Normal file
12
Singer_Hexdive/Models/IOs/ApiResponse.cs
Normal 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; }
|
||||
}
|
||||
}
|
12
Singer_Hexdive/Models/IdentificationType.cs
Normal file
12
Singer_Hexdive/Models/IdentificationType.cs
Normal 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; }
|
||||
}
|
||||
}
|
25
Singer_Hexdive/Models/MerchantBankDetails.cs
Normal file
25
Singer_Hexdive/Models/MerchantBankDetails.cs
Normal 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; }
|
||||
}
|
||||
}
|
26
Singer_Hexdive/Models/MerchantBusinessDetail.cs
Normal file
26
Singer_Hexdive/Models/MerchantBusinessDetail.cs
Normal 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; }
|
||||
}
|
||||
}
|
21
Singer_Hexdive/Models/MerchantDirectors.cs
Normal file
21
Singer_Hexdive/Models/MerchantDirectors.cs
Normal 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;
|
||||
|
||||
}
|
||||
}
|
27
Singer_Hexdive/Models/MerchantPersonalDetail.cs
Normal file
27
Singer_Hexdive/Models/MerchantPersonalDetail.cs
Normal 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;
|
||||
}
|
||||
}
|
21
Singer_Hexdive/Models/MerchantShareHolders.cs
Normal file
21
Singer_Hexdive/Models/MerchantShareHolders.cs
Normal 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;
|
||||
}
|
||||
}
|
@ -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.
|
||||
|
146
Singer_Hexdive/Repositories/MerchantRepository.cs
Normal file
146
Singer_Hexdive/Repositories/MerchantRepository.cs
Normal 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------------------------------//
|
||||
}
|
||||
}
|
71
Singer_Hexdive/Services/FunctionHandlers/MerchantManager.cs
Normal file
71
Singer_Hexdive/Services/FunctionHandlers/MerchantManager.cs
Normal 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
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
165
Singer_Hexdive/Services/MerchantService.cs
Normal file
165
Singer_Hexdive/Services/MerchantService.cs
Normal 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----------------------------------//
|
||||
}
|
||||
}
|
@ -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>
|
||||
|
92
Singer_Hexdive/Validations/FieldValidators.cs
Normal file
92
Singer_Hexdive/Validations/FieldValidators.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +1,12 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"DefaultConnection": "server=localhost;port=3306;database=singer;user=root;password="
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
||||
|
Reference in New Issue
Block a user