Perform CRUD oprations on Tenanat
This commit is contained in:
parent
fa5a8c178d
commit
f2e2862b0f
26
Marco.Pms.Model/Dtos/Tenant/CreateTenantDto.cs
Normal file
26
Marco.Pms.Model/Dtos/Tenant/CreateTenantDto.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Marco.Pms.Model.Dtos.Tenant
|
||||
{
|
||||
public class CreateTenantDto
|
||||
{
|
||||
[Required]
|
||||
[EmailAddress]
|
||||
public string Email { get; set; }
|
||||
|
||||
[Required]
|
||||
[MinLength(6)]
|
||||
[RegularExpression(@"^(?=.*[^a-zA-Z0-9])(?=.*\d)(?=.*[A-Z]).+$", ErrorMessage = "Passwords must have at least one non-alphanumeric character, at least one digit ('0'-'9'), and at least one uppercase ('A'-'Z').")]
|
||||
public string Password { get; set; }
|
||||
|
||||
|
||||
public string OrganizatioinName { get; set; }
|
||||
public string? About { get; set; }
|
||||
public string? OragnizationSize { get; set; }
|
||||
public int IndustryId { get; set; }
|
||||
public string Website { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string ContactNumber { get; set; }
|
||||
public DateTime OnBoardingDate { get; set; }
|
||||
}
|
||||
}
|
15
Marco.Pms.Model/Dtos/Tenant/UpdateTenantDto.cs
Normal file
15
Marco.Pms.Model/Dtos/Tenant/UpdateTenantDto.cs
Normal file
@ -0,0 +1,15 @@
|
||||
namespace Marco.Pms.Model.Dtos.Tenant
|
||||
{
|
||||
public class UpdateTenantDto
|
||||
{
|
||||
public string OrganizatioinName { get; set; }
|
||||
public string About { get; set; }
|
||||
public string Website { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string ContactNumber { get; set; }
|
||||
|
||||
public string? OragnizationSize { get; set; }
|
||||
public int IndustryId { get; set; }
|
||||
public DateTime OnBoardingDate { get; set; }
|
||||
}
|
||||
}
|
38
Marco.Pms.Model/Mapper/TenantMapper.cs
Normal file
38
Marco.Pms.Model/Mapper/TenantMapper.cs
Normal file
@ -0,0 +1,38 @@
|
||||
using Marco.Pms.Model.Dtos.Tenant;
|
||||
using Marco.Pms.Model.Entitlements;
|
||||
using Marco.Pms.Model.ViewModels.Tenant;
|
||||
|
||||
namespace Marco.Pms.Model.Mapper
|
||||
{
|
||||
public static class TenantMapper
|
||||
{
|
||||
public static Tenant CreateDtoToTenant(this CreateTenantDto createTenant)
|
||||
{
|
||||
return new Tenant
|
||||
{
|
||||
Name = createTenant.OrganizatioinName,
|
||||
Description = createTenant.About,
|
||||
DomainName = createTenant.Website,
|
||||
ContactName = createTenant.Name,
|
||||
OragnizationSize = createTenant.OragnizationSize,
|
||||
IndustryId = createTenant.IndustryId,
|
||||
ContactNumber = createTenant.ContactNumber,
|
||||
OnBoardingDate = createTenant.OnBoardingDate,
|
||||
};
|
||||
}
|
||||
public static TenantVM ToTenantVMFromTenant(this Tenant tenant)
|
||||
{
|
||||
return new TenantVM
|
||||
{
|
||||
OrganizationName = tenant.Name,
|
||||
About = tenant.Description,
|
||||
Website = tenant.DomainName,
|
||||
Name = tenant.ContactName,
|
||||
OragnizationSize = tenant.OragnizationSize,
|
||||
IndustryId = tenant.IndustryId,
|
||||
ContactNumber = tenant.ContactNumber,
|
||||
OnBoardingDate = tenant.OnBoardingDate,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
10
Marco.Pms.Model/Utilities/RoleConfiguration.cs
Normal file
10
Marco.Pms.Model/Utilities/RoleConfiguration.cs
Normal file
@ -0,0 +1,10 @@
|
||||
namespace Marco.Pms.Model.Utilities
|
||||
{
|
||||
public class RoleConfiguration
|
||||
{
|
||||
public string JobRoleName { get; set; }
|
||||
public string JobRoleDescription { get; set; }
|
||||
public string RoleName { get; set; }
|
||||
public string RoleDescription { get; set; }
|
||||
}
|
||||
}
|
15
Marco.Pms.Model/ViewModels/Tenant/TenantVM.cs
Normal file
15
Marco.Pms.Model/ViewModels/Tenant/TenantVM.cs
Normal file
@ -0,0 +1,15 @@
|
||||
namespace Marco.Pms.Model.ViewModels.Tenant
|
||||
{
|
||||
public class TenantVM
|
||||
{
|
||||
public string OrganizationName { get; set; }
|
||||
public string About { get; set; }
|
||||
public string Website { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string ContactNumber { get; set; }
|
||||
|
||||
public string? OragnizationSize { get; set; }
|
||||
public int? IndustryId { get; set; }
|
||||
public DateTime OnBoardingDate { get; set; }
|
||||
}
|
||||
}
|
239
Marco.Pms.Services/Controllers/TenantController.cs
Normal file
239
Marco.Pms.Services/Controllers/TenantController.cs
Normal file
@ -0,0 +1,239 @@
|
||||
using System.Text.Json;
|
||||
using Marco.Pms.DataAccess.Data;
|
||||
using Marco.Pms.Model.Dtos.Tenant;
|
||||
using Marco.Pms.Model.Employees;
|
||||
using Marco.Pms.Model.Entitlements;
|
||||
using Marco.Pms.Model.Mapper;
|
||||
using Marco.Pms.Model.Utilities;
|
||||
using Marco.Pms.Model.ViewModels.Tenant;
|
||||
using MarcoBMS.Services.Service;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Marco.Pms.Services.Controllers
|
||||
{
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class TenantController : ControllerBase
|
||||
{
|
||||
private readonly string jsonString = System.IO.File.ReadAllText("Data/RolesCofiguration.json");
|
||||
private readonly ApplicationDbContext _context;
|
||||
private readonly UserManager<IdentityUser> _userManager;
|
||||
private readonly ILoggingService _logger;
|
||||
public TenantController(ApplicationDbContext context, UserManager<IdentityUser> userManager, ILoggingService logger)
|
||||
{
|
||||
_context = context;
|
||||
_userManager = userManager;
|
||||
_logger = logger;
|
||||
}
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> CreateTenant([FromForm] CreateTenantDto createTenantDto)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
var existedUser = await _userManager.FindByEmailAsync(createTenantDto.Email);
|
||||
var existedTenanat = await _context.Tenants.FirstOrDefaultAsync(t => t.Name == createTenantDto.OrganizatioinName);
|
||||
if (existedUser == null && existedTenanat == null)
|
||||
{
|
||||
var transaction = _context.Database.BeginTransaction();
|
||||
Tenant newTenant = createTenantDto.CreateDtoToTenant();
|
||||
_context.Tenants.Add(newTenant);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
//Tenant? tenant = await _context.Tenants.FirstOrDefaultAsync(t => t.Name == newTenant.Name);
|
||||
|
||||
if (newTenant != null)
|
||||
{
|
||||
RoleConfiguration settings = JsonSerializer.Deserialize<RoleConfiguration>(jsonString);
|
||||
var TenantId = newTenant.Id;
|
||||
JobRole jobRole = new JobRole
|
||||
{
|
||||
Name = settings.JobRoleName,
|
||||
Description = settings.JobRoleDescription,
|
||||
TenantId = TenantId
|
||||
};
|
||||
|
||||
ApplicationRole role = new ApplicationRole
|
||||
{
|
||||
Role = settings.RoleName,
|
||||
Description = settings.RoleDescription,
|
||||
TenantId = TenantId
|
||||
};
|
||||
|
||||
_context.JobRoles.Add(jobRole);
|
||||
_context.ApplicationRoles.Add(role);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
|
||||
List<FeaturePermission> permissions = await _context.FeaturePermissions.AsNoTracking().ToListAsync();
|
||||
List<RolePermissionMappings> rolePermissionMappings = new List<RolePermissionMappings>();
|
||||
|
||||
foreach (var permission in permissions)
|
||||
{
|
||||
var item = new RolePermissionMappings() { ApplicationRoleId = role.Id, FeaturePermissionId = permission.Id };
|
||||
bool assigned = _context.RolePermissionMappings.Any(c => c.ApplicationRoleId == role.Id && c.FeaturePermissionId == permission.Id);
|
||||
if (permission.IsEnabled && !assigned)
|
||||
rolePermissionMappings.Add(item);
|
||||
|
||||
}
|
||||
_context.RolePermissionMappings.AddRange(rolePermissionMappings);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
var user = new ApplicationUser
|
||||
{
|
||||
UserName = createTenantDto.Email,
|
||||
Email = createTenantDto.Email,
|
||||
TenantId = TenantId,
|
||||
IsRootUser = true,
|
||||
EmailConfirmed = true
|
||||
};
|
||||
|
||||
var result = await _userManager.CreateAsync(user, createTenantDto.Password);
|
||||
if (result.Succeeded)
|
||||
{
|
||||
try
|
||||
{
|
||||
Employee newEmployee = CreateTenantDtoToEmployee(createTenantDto, TenantId, user.Id, jobRole.Id);
|
||||
_context.Employees.Add(newEmployee);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
var employeeRoleMapping = new EmployeeRoleMapping
|
||||
{
|
||||
EmployeeId = newEmployee.Id,
|
||||
RoleId = role.Id,
|
||||
TenantId = TenantId,
|
||||
IsEnabled = true
|
||||
};
|
||||
_context.EmployeeRoleMappings.Add(employeeRoleMapping);
|
||||
await _context.SaveChangesAsync();
|
||||
transaction.Commit();
|
||||
return Ok(ApiResponse<object>.SuccessResponse(result.Succeeded, "Tenant created successfully.", 200));
|
||||
}catch(Exception ex)
|
||||
{
|
||||
transaction.Rollback();
|
||||
_logger.LogError("{Error}", ex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Log the errors for debugging
|
||||
foreach (var error in result.Errors)
|
||||
{
|
||||
// Log error.Description
|
||||
_logger.LogError("{Error}", error.Description);
|
||||
}
|
||||
transaction.Rollback();
|
||||
return BadRequest("Failed to create the root user.");
|
||||
}
|
||||
}
|
||||
transaction.Rollback();
|
||||
return BadRequest("Falied to create Tenant");
|
||||
|
||||
|
||||
}
|
||||
return BadRequest("Tenant Already Exists");
|
||||
|
||||
}
|
||||
|
||||
[HttpGet("profile/{tenantId}")]
|
||||
public async Task<IActionResult> GetTenantProfile(int tenantId)
|
||||
{
|
||||
if (tenantId <= 0)
|
||||
{
|
||||
return BadRequest("Tenant Id is required and must be greater than zero.");
|
||||
}
|
||||
var tenant = await _context.Tenants.FirstOrDefaultAsync(t => t.Id == tenantId && t.IsActive ==true);
|
||||
if (tenant == null)
|
||||
{
|
||||
return NotFound("Tenant Not Found");
|
||||
}
|
||||
TenantVM tenantVM = tenant.ToTenantVMFromTenant();
|
||||
return Ok(ApiResponse<object>.SuccessResponse(tenantVM, "Tenant Profile.", 200));
|
||||
}
|
||||
|
||||
[HttpPost("edit/{tenantId}")]
|
||||
public async Task<IActionResult> SuspendTenant(int tenantId, UpdateTenantDto model)
|
||||
{
|
||||
if (tenantId <= 0)
|
||||
{
|
||||
return BadRequest("Tenant Id is required and must be greater than zero.");
|
||||
}
|
||||
var tenant = await _context.Tenants.FirstOrDefaultAsync(t => t.Id == tenantId && t.IsActive == true);
|
||||
//var user = await _context.ApplicationUsers.FirstOrDefaultAsync(u => u.TenantId == tenantId && u.IsRootUser == true);
|
||||
//var employee = await _context.Employees.FirstOrDefaultAsync(e => e.Id == tenantId && e.ApplicationUserId == user.Id);
|
||||
if (tenant == null)
|
||||
{
|
||||
return NotFound("Tenant Not Found");
|
||||
}
|
||||
tenant.Name = model.OrganizatioinName;
|
||||
tenant.DomainName = model.Website;
|
||||
tenant.ContactName = model.Name;
|
||||
tenant.Description = model.About;
|
||||
tenant.ContactNumber = model.ContactNumber;
|
||||
tenant.OnBoardingDate = model.OnBoardingDate;
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
TenantVM tenantVM = tenant.ToTenantVMFromTenant();
|
||||
return Ok(ApiResponse<object>.SuccessResponse(tenantVM, "Tenant Profile.", 200));
|
||||
}
|
||||
|
||||
[HttpDelete("suspend/{tenantId}")]
|
||||
public async Task<IActionResult> SuspendTenant(int tenantId)
|
||||
{
|
||||
if (tenantId <= 0)
|
||||
{
|
||||
return BadRequest("Tenant Id is required and must be greater than zero.");
|
||||
}
|
||||
var tenant = await _context.Tenants.FirstOrDefaultAsync(t => t.Id == tenantId);
|
||||
var user = await _context.ApplicationUsers.FirstOrDefaultAsync(u => u.TenantId == tenantId && u.IsRootUser == true);
|
||||
if (tenant != null && user != null)
|
||||
{
|
||||
var employee = await _context.Employees.FirstOrDefaultAsync(e => e.TenantId == tenantId && e.ApplicationUserId == user.Id);
|
||||
tenant.IsActive = false;
|
||||
user.IsActive = false;
|
||||
user.IsRootUser = false;
|
||||
employee.IsActive = false;
|
||||
|
||||
|
||||
var result = await _userManager.UpdateAsync(user);
|
||||
_context.Tenants.Update(tenant);
|
||||
_context.Employees.Update(employee);
|
||||
await _context.SaveChangesAsync();
|
||||
return Ok("Tenant is Suspended");
|
||||
}
|
||||
return NotFound("Tenant Not Found");
|
||||
}
|
||||
|
||||
private static Employee CreateTenantDtoToEmployee(CreateTenantDto model, int TenantId, string? ApplicationUserId, int jobRoleId)
|
||||
{
|
||||
return new Employee
|
||||
{
|
||||
ApplicationUserId = ApplicationUserId,
|
||||
FirstName = model.Name,
|
||||
LastName = "",
|
||||
Email = model.Email,
|
||||
TenantId = TenantId,
|
||||
CurrentAddress = "",
|
||||
BirthDate = DateTime.UtcNow,
|
||||
EmergencyPhoneNumber = "",
|
||||
EmergencyContactPerson = "",
|
||||
AadharNumber = "",
|
||||
Gender = "",
|
||||
MiddleName = "",
|
||||
PanNumber = "",
|
||||
PeramnentAddress = "",
|
||||
PhoneNumber = model.ContactNumber,
|
||||
Photo = null, // GetFileDetails(model.Photo).Result.FileData,
|
||||
JobRoleId = jobRoleId,
|
||||
JoiningDate = DateTime.UtcNow,
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
6
Marco.Pms.Services/Data/RolesCofiguration.json
Normal file
6
Marco.Pms.Services/Data/RolesCofiguration.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"JobRoleName": "Admin",
|
||||
"JobRoleDescription": "Admin",
|
||||
"RoleName": "SuperUser",
|
||||
"RoleDescription": "SuperUser"
|
||||
}
|
@ -44,6 +44,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="images\" />
|
||||
<Folder Include="Data\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
Loading…
x
Reference in New Issue
Block a user