117 lines
4.9 KiB
C#
117 lines
4.9 KiB
C#
using System.Security.Claims;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
[ApiController]
|
|
[Route("api/v1/cover-sheets")]
|
|
[Produces("application/json")]
|
|
[Authorize]
|
|
public class CoverSheetController : ControllerBase
|
|
{
|
|
private readonly ICoverSheetService _coverSheets;
|
|
|
|
public CoverSheetController(ICoverSheetService coverSheets)
|
|
{
|
|
_coverSheets = coverSheets;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generates one or more cover sheets with unique barcode codes.
|
|
/// Each cover sheet encodes batch type, track, optional patient, and
|
|
/// optional entry clerk assignment.
|
|
/// </summary>
|
|
[HttpPost("generate")]
|
|
[Authorize(Roles = "INTAKE_CLERK,ADMINISTRATOR")]
|
|
[ProducesResponseType(typeof(ApiResponse<List<CoverSheetResponse>>), StatusCodes.Status201Created)]
|
|
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status400BadRequest)]
|
|
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
|
public async Task<IActionResult> Generate([FromBody] GenerateCoverSheetsRequest request)
|
|
{
|
|
var actorUserId = Guid.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier)!);
|
|
var sheets = await _coverSheets.GenerateAsync(request, actorUserId);
|
|
var response = sheets.Select(MapToResponse).ToList();
|
|
return StatusCode(201, ApiResponse<List<CoverSheetResponse>>.Created(response));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Looks up a cover sheet by its barcode code. Used during barcode-assisted
|
|
/// upload to auto-populate batch type, track, patient, and clerk assignment.
|
|
/// </summary>
|
|
[HttpGet("lookup/{code}")]
|
|
[ProducesResponseType(typeof(ApiResponse<CoverSheetResponse>), StatusCodes.Status200OK)]
|
|
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
|
public async Task<IActionResult> Lookup(string code)
|
|
{
|
|
var sheet = await _coverSheets.LookupByCodeAsync(code);
|
|
if (sheet is null)
|
|
return NotFound(ApiResponse<object>.Fail(404, "Cover sheet not found.", "COVER_SHEET_NOT_FOUND"));
|
|
|
|
return Ok(ApiResponse<CoverSheetResponse>.Ok(MapToResponse(sheet)));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Lists cover sheets with optional filters.
|
|
/// </summary>
|
|
[HttpGet]
|
|
[Authorize(Roles = "INTAKE_CLERK,ADMINISTRATOR")]
|
|
[ProducesResponseType(typeof(ApiResponse<List<CoverSheetResponse>>), StatusCodes.Status200OK)]
|
|
public async Task<IActionResult> List(
|
|
[FromQuery] bool? isUsed,
|
|
[FromQuery] Guid? patientId,
|
|
[FromQuery] int page = 1,
|
|
[FromQuery] int pageSize = 20)
|
|
{
|
|
var sheets = await _coverSheets.ListAsync(isUsed, patientId, page, pageSize);
|
|
var response = sheets.Select(MapToResponse).ToList();
|
|
return Ok(ApiResponse<List<CoverSheetResponse>>.Ok(response));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generates a printable PDF containing cover sheets with QR codes.
|
|
/// Each page has the cover sheet code as a QR code, plus human-readable
|
|
/// batch type, patient info, and generation date.
|
|
/// </summary>
|
|
[HttpPost("{id:guid}/pdf")]
|
|
[Authorize(Roles = "INTAKE_CLERK,ADMINISTRATOR")]
|
|
[ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)]
|
|
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
|
public async Task<IActionResult> GeneratePdf(Guid id)
|
|
{
|
|
var sheet = await _coverSheets.LookupByIdAsync(id);
|
|
if (sheet is null)
|
|
return NotFound(ApiResponse<object>.Fail(404, "Cover sheet not found.", "COVER_SHEET_NOT_FOUND"));
|
|
|
|
var pdfBytes = CoverSheetPdfGenerator.Generate(sheet);
|
|
return File(pdfBytes, "application/pdf", $"coversheet-{sheet.Code}.pdf");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generates a batch PDF containing multiple cover sheets (one per page).
|
|
/// Accepts a list of cover sheet IDs.
|
|
/// </summary>
|
|
[HttpPost("batch-pdf")]
|
|
[Authorize(Roles = "INTAKE_CLERK,ADMINISTRATOR")]
|
|
[ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)]
|
|
public async Task<IActionResult> GenerateBatchPdf([FromBody] BatchPdfRequest request)
|
|
{
|
|
var sheets = await _coverSheets.GetByIdsAsync(request.CoverSheetIds);
|
|
var pdfBytes = CoverSheetPdfGenerator.GenerateBatch(sheets);
|
|
return File(pdfBytes, "application/pdf", $"coversheets-batch-{DateTime.UtcNow:yyyyMMdd}.pdf");
|
|
}
|
|
|
|
private static CoverSheetResponse MapToResponse(CoverSheet sheet) => new(
|
|
Id: sheet.Id,
|
|
Code: sheet.Code,
|
|
BatchType: sheet.BatchType.ToDbString(),
|
|
Track: sheet.Track.ToDbString(),
|
|
PatientId: sheet.PatientId,
|
|
PatientName: sheet.Patient?.FullName,
|
|
PatientMrn: sheet.Patient?.Mrn,
|
|
AssignToUserId: sheet.AssignToUserId,
|
|
AssignToUserName: sheet.AssignToUser?.FullName,
|
|
IsUsed: sheet.IsUsed,
|
|
BatchId: sheet.BatchId,
|
|
CreatedAt: sheet.CreatedAt,
|
|
UsedAt: sheet.UsedAt
|
|
);
|
|
} |