Files
ROLAC/API/ROLAC.API/Controllers/ExpenseSnapshotsController.cs
T

69 lines
2.5 KiB
C#

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using ROLAC.API.Authorization;
using ROLAC.API.DTOs.Expense;
using ROLAC.API.Services;
namespace ROLAC.API.Controllers;
// Snapshots are reusable vendor-payment templates — a finance tool. Every action requires
// Expenses:Write (super_admin bypasses), matching who can create vendor payments.
[ApiController]
[Route("api/expense-snapshots")]
[Authorize]
public class ExpenseSnapshotsController : ControllerBase
{
private readonly IExpenseSnapshotService _svc;
private readonly IPermissionService _perms;
public ExpenseSnapshotsController(IExpenseSnapshotService svc, IPermissionService perms)
{
_svc = svc;
_perms = perms;
}
private List<string> Roles() => User.FindAll("role").Select(claim => claim.Value).ToList();
private bool IsSuperAdmin() => User.IsInRole(PermissionAuthorizationHandler.SuperAdminRole);
private async Task<bool> CanManageAsync() =>
IsSuperAdmin() || await _perms.HasPermissionAsync(Roles(), Modules.Expenses, PermissionActions.Write);
[HttpGet]
public async Task<IActionResult> GetAll()
{
if (!await CanManageAsync()) return Forbid();
return Ok(await _svc.GetAllAsync());
}
[HttpGet("{id:int}")]
public async Task<IActionResult> GetById(int id)
{
if (!await CanManageAsync()) return Forbid();
var dto = await _svc.GetByIdAsync(id);
return dto is null ? NotFound() : Ok(dto);
}
[HttpPost]
public async Task<IActionResult> Create([FromBody] CreateExpenseSnapshotRequest r)
{
if (!await CanManageAsync()) return Forbid();
try { return Ok(new { id = await _svc.CreateAsync(r) }); }
catch (InvalidOperationException ex) { return Conflict(new { message = ex.Message }); }
}
[HttpPut("{id:int}")]
public async Task<IActionResult> Update(int id, [FromBody] UpdateExpenseSnapshotRequest r)
{
if (!await CanManageAsync()) return Forbid();
try { await _svc.UpdateAsync(id, r); return NoContent(); }
catch (KeyNotFoundException) { return NotFound(); }
catch (InvalidOperationException ex) { return Conflict(new { message = ex.Message }); }
}
[HttpDelete("{id:int}")]
public async Task<IActionResult> Delete(int id)
{
if (!await CanManageAsync()) return Forbid();
try { await _svc.DeleteAsync(id); return NoContent(); }
catch (KeyNotFoundException) { return NotFound(); }
}
}