using Azure; using Marco.Pms.DataAccess.Data; using Marco.Pms.Model.Dtos.Roles; using Marco.Pms.Model.Entitlements; using Marco.Pms.Model.Mapper; using Marco.Pms.Model.Utilities; using Marco.Pms.Model.ViewModels; using MarcoBMS.Services.Helpers; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using System.Data; using static System.Runtime.InteropServices.JavaScript.JSType; namespace MarcoBMS.Services.Controllers { [Route("api/[controller]")] [ApiController] [Authorize] public class RolesController : ControllerBase { private readonly ApplicationDbContext _context; private readonly RolesHelper _rolesHelper; private readonly UserManager _userManager; public RolesController(UserManager userManager, ApplicationDbContext context, RolesHelper rolesHelper) { _context = context; _userManager = userManager; _rolesHelper = rolesHelper; } private int GetTenantId() { var tenant = User.FindFirst("TenantId")?.Value; return (tenant != null ? Convert.ToInt32(tenant) : 1); } [HttpGet("jobrole")] public async Task GetAllJobRoles() { int TenantId = GetTenantId(); var roles = await _context.JobRoles.Where(c => c.TenantId == TenantId).Select(x => new JobRoleVM() { Id = x.Id, Name = x.Name, Description = x.Description }).ToListAsync(); return Ok(ApiResponse.SuccessResponse(roles, "Success.", 200)); } [HttpPost("jobrole")] public async Task AddJobRole([FromBody] CreateJobRoleDto createJobRoleDto) { int TenantId = GetTenantId(); if (await _context.JobRoles.AnyAsync(c => c.Name.ToLower() == createJobRoleDto.Name.ToLower() && c.TenantId == TenantId)) { return BadRequest(ApiResponse.ErrorResponse("Role with same name already Exists.", "Role with same name already Exists.", 400)); } else { JobRole jr = createJobRoleDto.ToJobRoleFromCreateJobRoleDot(TenantId); _context.JobRoles.Add(jr); await _context.SaveChangesAsync(); return Ok(ApiResponse.SuccessResponse(jr, "Success.", 200)); } } [HttpPut("jobrole/{id}")] public async Task UpdateJobRole(string id, [FromBody] UpdateJobRoleDto updateRoleDto) { if (!ModelState.IsValid) { var errors = ModelState.Values .SelectMany(v => v.Errors) .Select(e => e.ErrorMessage) .ToList(); return BadRequest(ApiResponse.ErrorResponse("Invalid data", errors, 400)); } if (id != updateRoleDto.Id.ToString()) return BadRequest(ApiResponse.ErrorResponse("Role ID mismatch", "Role ID mismatch",400)); try { int TenantId = GetTenantId(); JobRole jr = updateRoleDto.ToJobRoleFromUpdateJobRoleDot(TenantId); _context.JobRoles.Update(jr); await _context.SaveChangesAsync(); return Ok(ApiResponse.SuccessResponse(jr, "Success.", 200)); } catch (Exception ex) { return BadRequest(ApiResponse.ErrorResponse(ex.Message, ex, 400)); } } [HttpGet] public async Task GetAllRoles() { int TenantId = GetTenantId(); var roles = await _context.ApplicationRoles.Where(c => c.TenantId == TenantId).ToListAsync(); var roleFeaturePermissions = await _context.RolePermissionMappings .Join( _context.FeaturePermissions, rfp => rfp.FeaturePermissionId, fp => fp.Id, (rfp, fp) => new { rfp.ApplicationRoleId, FeaturePermission = fp }) .Join( _context.ApplicationRoles, result => result.ApplicationRoleId, role => role.Id, (result, role) => new { Role = role, result.FeaturePermission }) .Where(x => x.Role.TenantId == TenantId) // Filter by TenantId .Select(x => new { RoleId = x.Role.Id, RoleName = x.Role.Role, FeaturePermission = x.FeaturePermission }) .ToListAsync(); List applicationRoles = new List(); foreach (var item in roles) { var rolesVM = new ApplicationRolesVM() { Id = item.Id, Role = item.Role, Description = item.Description, FeaturePermission = [] }; ICollection permissions = roleFeaturePermissions.Where(c => c.RoleId == item.Id) .Select(c => c.FeaturePermission).ToList(); foreach (var permission in permissions) { rolesVM.FeaturePermission.Add( new FeaturePermissionVM() { Id = permission.Id, Description = permission.Description, FeatureId = permission.FeatureId, IsEnabled = permission.IsEnabled, Name = permission.Name }); } applicationRoles.Add(rolesVM); } return Ok(ApiResponse.SuccessResponse(applicationRoles, "Roles list fetched successfully.", 200)); } [HttpPost] public async Task AddRole([FromBody] CreateApplicationRoleDto createRoleDto) { if (!ModelState.IsValid) { var errors = ModelState.Values .SelectMany(v => v.Errors) .Select(e => e.ErrorMessage) .ToList(); return BadRequest(ApiResponse.ErrorResponse("Invalid data", errors, 400)); } int TenantId = GetTenantId(); if (createRoleDto.FeaturesPermission == null || (createRoleDto.FeaturesPermission != null && createRoleDto.FeaturesPermission.Count == 0)) { return BadRequest(ApiResponse.ErrorResponse("Feature Permission is required.", "Feature Permission is required.", 400)); } bool roleExists = _context.ApplicationRoles .Any(r => r.TenantId == TenantId && r.Role.ToLower() == createRoleDto.Role.ToLower());// assuming role name is unique per tenant if (roleExists) { return BadRequest(ApiResponse.ErrorResponse("Role already exists.", "Role already exists.", 400)); } ApplicationRole role = createRoleDto.ToApplicationRoleFromCreateDto(TenantId); _context.ApplicationRoles.Add(role); foreach (var permission in createRoleDto.FeaturesPermission) { 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) _context.RolePermissionMappings.Add(item); else _context.RolePermissionMappings.Remove(item); } await _context.SaveChangesAsync(); return Ok(ApiResponse.SuccessResponse(role.ToRoleVMFromApplicationRole(), "Roles created successfully.", 200)); } [HttpPut("{id}")] public async Task UpdateRole(string id, [FromBody] UpdateApplicationRoleDto updateRoleDto) { if (!ModelState.IsValid) { var errors = ModelState.Values .SelectMany(v => v.Errors) .Select(e => e.ErrorMessage) .ToList(); return BadRequest(ApiResponse.ErrorResponse("Invalid data", errors, 400)); } if (id != updateRoleDto.Id.ToString()) return BadRequest("Role ID mismatch"); try { int TenantId = GetTenantId(); ApplicationRole role = updateRoleDto.ToApplicationRoleFromUpdateDto(TenantId); if (role.TenantId != TenantId) return Unauthorized(ApiResponse.ErrorResponse("You don't have any authority to update role", "You don't have any authority to update role", 401)); var projectModel = _context.ApplicationRoles.Update(role); if (projectModel == null) { return NotFound(ApiResponse.ErrorResponse("Project not found", "Project not found",404)); } bool modified = false; foreach (var permission in updateRoleDto.FeaturesPermission) { 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 == false && assigned == true) { _context.RolePermissionMappings.Remove(item); modified = true; } else if (permission.IsEnabled && !assigned) { _context.RolePermissionMappings.Add(item); modified = true; } } if (modified) await _context.SaveChangesAsync(); ApplicationRolesVM response = role.ToRoleVMFromApplicationRole(); List permissions = await _rolesHelper.GetFeaturePermissionByRoleID(response.Id); response.FeaturePermission = permissions.Select(c => c.ToFeaturePermissionVMFromFeaturePermission()).ToList(); return Ok(ApiResponse.SuccessResponse(response, "Roles perimssions updated.", 200)); } catch (Exception ex) { return BadRequest(ApiResponse.ErrorResponse(ex.Message,ex, 400)); } } [HttpGet("{id}")] public async Task GetRoleById(Guid id) { int TenantId = GetTenantId(); var role = await _context.ApplicationRoles.FindAsync(id); if (role == null) return NotFound(ApiResponse.ErrorResponse("Role not found", "Role not found", 404)); if (role.TenantId != TenantId) return Unauthorized(ApiResponse.ErrorResponse("You don't have any authority", "You don't have any authority", 401)); var featurePermissions = await _context.RolePermissionMappings .Where(rfp => rfp.ApplicationRoleId == id) .Join( _context.FeaturePermissions, rfp => rfp.FeaturePermissionId, fp => fp.Id, (rfp, fp) => new FeaturePermissionVM() { Id = fp.Id, Name = fp.Name, Description = fp.Description, IsEnabled = fp.IsEnabled, FeatureId = fp.FeatureId }) .ToListAsync(); ApplicationRolesVM vm = new ApplicationRolesVM() { Id = role.Id, Role = role.Role, FeaturePermission = featurePermissions }; return Ok(ApiResponse.SuccessResponse(vm, "Roles Perimssions fetched successfully.", 200)); } } }