240 lines
10 KiB
C#

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,
};
}
}
}