96 lines
3.8 KiB
C#
96 lines
3.8 KiB
C#
using System.Security.Claims;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using ROLAC.API.DTOs.Disbursement;
|
|
using ROLAC.API.Services;
|
|
|
|
namespace ROLAC.API.Controllers;
|
|
|
|
[ApiController]
|
|
[Route("api/disbursements")]
|
|
[Authorize(Roles = "finance,super_admin")]
|
|
public class DisbursementsController : ControllerBase
|
|
{
|
|
private readonly IDisbursementService _svc;
|
|
public DisbursementsController(IDisbursementService svc) => _svc = svc;
|
|
|
|
[HttpGet("approved-unpaid")]
|
|
public async Task<IActionResult> GetApprovedUnpaid()
|
|
=> Ok(await _svc.GetApprovedUnpaidGroupedAsync());
|
|
|
|
[HttpPost("issue")]
|
|
public async Task<IActionResult> Issue([FromBody] IssueChecksRequest r)
|
|
{
|
|
try { return Ok(await _svc.IssueChecksAsync(r)); }
|
|
catch (KeyNotFoundException) { return NotFound(); }
|
|
catch (InvalidOperationException ex) { return Conflict(new { message = ex.Message }); }
|
|
}
|
|
|
|
[HttpGet("checks")]
|
|
public async Task<IActionResult> GetRegister(
|
|
[FromQuery] int page = 1, [FromQuery] int pageSize = 20, [FromQuery] string? status = null,
|
|
[FromQuery] string? search = null, [FromQuery] DateOnly? from = null, [FromQuery] DateOnly? to = null)
|
|
=> Ok(await _svc.GetRegisterAsync(page, pageSize, status, search, from, to));
|
|
|
|
[HttpGet("checks/{id:int}")]
|
|
public async Task<IActionResult> GetById(int id)
|
|
{
|
|
var dto = await _svc.GetByIdAsync(id);
|
|
return dto is null ? NotFound() : Ok(dto);
|
|
}
|
|
|
|
[HttpPost("checks/{id:int}/void")]
|
|
public async Task<IActionResult> Void(int id, [FromBody] VoidCheckRequest r)
|
|
{
|
|
try { await _svc.VoidAsync(id, r.Reason); return NoContent(); }
|
|
catch (KeyNotFoundException) { return NotFound(); }
|
|
catch (InvalidOperationException ex) { return Conflict(new { message = ex.Message }); }
|
|
}
|
|
|
|
[HttpGet("checks/{id:int}/pdf")]
|
|
public async Task<IActionResult> GetPdf(int id)
|
|
{
|
|
var result = await _svc.RenderPdfAsync(id);
|
|
if (result is null) return NotFound();
|
|
return File(result.Value.stream, result.Value.contentType, result.Value.fileName);
|
|
}
|
|
|
|
[HttpGet("checks/{id:int}/receipt-pdf")]
|
|
public async Task<IActionResult> GetReceiptPdf(int id)
|
|
{
|
|
var result = await _svc.RenderReceiptPdfAsync(id);
|
|
if (result is null) return NotFound();
|
|
return File(result.Value.stream, result.Value.contentType, result.Value.fileName);
|
|
}
|
|
|
|
[HttpPost("checks/{id:int}/acknowledge")]
|
|
[RequestSizeLimit(5_242_880)]
|
|
public async Task<IActionResult> Acknowledge(int id, [FromForm] IFormFile signature, [FromForm] string signedName)
|
|
{
|
|
if (signature is null || signature.Length == 0) return BadRequest(new { message = "No signature." });
|
|
if (string.IsNullOrWhiteSpace(signedName)) return BadRequest(new { message = "Signed name is required." });
|
|
var allowed = new[] { "image/png", "image/jpeg", "image/webp" };
|
|
if (!allowed.Contains(signature.ContentType)) return BadRequest(new { message = "Unsupported image type." });
|
|
try
|
|
{
|
|
await using var stream = signature.OpenReadStream();
|
|
await _svc.AcknowledgeReceiptAsync(id, stream, signature.FileName, signedName.Trim());
|
|
return NoContent();
|
|
}
|
|
catch (KeyNotFoundException) { return NotFound(); }
|
|
catch (InvalidOperationException ex) { return Conflict(new { message = ex.Message }); }
|
|
}
|
|
|
|
[HttpGet("checks/{id:int}/signature")]
|
|
public async Task<IActionResult> GetSignature(int id)
|
|
{
|
|
try
|
|
{
|
|
var result = await _svc.OpenSignatureAsync(id);
|
|
if (result is null) return NotFound();
|
|
return File(result.Value.stream, result.Value.contentType);
|
|
}
|
|
catch (KeyNotFoundException) { return NotFound(); }
|
|
}
|
|
}
|