150 lines
6.1 KiB
C#

using AutoMapper;
using Marco.Pms.DataAccess.Data;
using Marco.Pms.Model.Master;
using Marco.Pms.Model.Utilities;
using Marco.Pms.Model.ViewModels.Master;
using Marco.Pms.Services.Helpers;
using MarcoBMS.Services.Helpers;
using MarcoBMS.Services.Service;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace MarcoBMS.Services.Controllers
{
[Route("api/[controller]")]
[ApiController]
// [Authorize]
public class FeatureController : ControllerBase
{
private readonly ApplicationDbContext _context;
private readonly GeneralHelper _generalHelper;
//private readonly UserHelper _userHelper;
private readonly IMapper _mapper;
private readonly ILoggingService _logger;
private readonly Guid tenantId;
public FeatureController(ApplicationDbContext context, GeneralHelper generalHelper, UserHelper userHelper, IMapper mapper, ILoggingService logger)
{
_context = context;
_generalHelper = generalHelper;
//_userHelper = userHelper;
_mapper = mapper;
_logger = logger;
tenantId = userHelper.GetTenantId();
}
private ICollection<FeaturePermissionVM> GetFeaturePermissionVM(Feature model)
{
if (model.FeaturePermissions == null)
{
return [];
}
ICollection<FeaturePermissionVM> features = model.FeaturePermissions.Select(p => _mapper.Map<FeaturePermissionVM>(p)).OrderBy(f => f.Name).ToList();
return features;
}
[HttpGet("features")]
public async Task<IActionResult> GetAllFeatures()
{
List<Guid> featureIds = await _generalHelper.GetFeatureIdsByTenentId(tenantId);
var roles = await _context.Features
.Include(f => f.FeaturePermissions)
.Include(f => f.Module)
.Where(f => featureIds.Contains(f.Id))
.ToListAsync();
var rolesVM = roles.Select(c => new FeatureVM()
{
Id = c.Id,
Name = c.Name,
Description = c.Description,
FeaturePermissions = GetFeaturePermissionVM(c),
ModuleId = c.ModuleId,
ModuleName = c.Module != null ? c.Module.Name : string.Empty,
IsActive = c.IsActive
}).OrderBy(f => f.Name).ToList();
return Ok(ApiResponse<object>.SuccessResponse(rolesVM, "Success.", 200));
}
/// <summary>
/// Converts FeaturePermissions from Feature entity into FeaturePermissionVM collection.
/// </summary>
/// <param name="model">Feature entity from DB</param>
/// <returns>Collection of FeaturePermissionVM, ordered by Name</returns>
private ICollection<FeaturePermissionVM> GetFeaturePermissionVMs(Feature model)
{
if (model.FeaturePermissions == null || !model.FeaturePermissions.Any())
{
_logger.LogInfo("No feature permissions found for Feature: {FeatureId}", model.Id);
return new List<FeaturePermissionVM>();
}
// Project and order feature permissions
var features = model.FeaturePermissions
.Select(p => _mapper.Map<FeaturePermissionVM>(p))
.OrderBy(f => f.Name)
.ToList();
_logger.LogDebug("Mapped {Count} feature permissions for Feature: {FeatureId}", features.Count, model.Id);
return features;
}
/// <summary>
/// API endpoint to fetch all features and their permissions for the given tenant.
/// </summary>
[HttpGet]
public async Task<IActionResult> GetAllFeaturesAsync()
{
try
{
_logger.LogInfo("Fetching all features for tenant: {TenantId}", tenantId);
// Step 1: Get tenant-specific FeatureIds
List<Guid> featureIds = await _generalHelper.GetFeatureIdsByTenentIdAsync(tenantId);
if (featureIds == null || !featureIds.Any())
{
_logger.LogWarning("No features found for tenant: {TenantId}", tenantId);
return Ok(ApiResponse<object>.SuccessResponse(new List<FeatureVM>(), "No features found.", 200));
}
_logger.LogDebug("Retrieved {Count} feature IDs for tenant: {TenantId}", featureIds.Count, tenantId);
// Step 2: Query Features with related FeaturePermissions & Module
var features = await _context.Features
.AsNoTracking() // Optimization: Read-only query
.Include(f => f.FeaturePermissions)
.Include(f => f.Module)
.Where(f => featureIds.Contains(f.Id))
.ToListAsync();
_logger.LogDebug("Fetched {Count} features from DB for tenant: {TenantId}", features.Count, tenantId);
// Step 3: Map features to ViewModels
var featureVMs = features
.Select(c => new FeatureVM
{
Id = c.Id,
Name = c.Name,
Description = c.Description,
FeaturePermissions = GetFeaturePermissionVMs(c),
ModuleId = c.ModuleId,
ModuleName = c.Module?.Name ?? string.Empty,
IsActive = c.IsActive
})
.OrderBy(f => f.Name)
.ToList();
_logger.LogInfo("Returning {Count} features for tenant: {TenantId}", featureVMs.Count, tenantId);
return Ok(ApiResponse<object>.SuccessResponse(featureVMs, "Success.", 200));
}
catch (Exception ex)
{
_logger.LogError(ex, "Error while fetching features for tenant: {TenantId}", tenantId);
return StatusCode(500, ApiResponse<object>.ErrorResponse("An unexpected error occurred.", 500));
}
}
}
}