using Microsoft.AspNetCore.Mvc; using SchotzIadKmTracker.Api.Models.DTOs; using SchotzIadKmTracker.Api.Services; using SchotzIadKmTracker.Api.Services.Exceptions; namespace SchotzIadKmTracker.Api.Controllers; /// /// Endpoints « Barème et remboursements » : montant prévisionnel (80% indicatif), /// montants réglés (saisie/consultation) et régularisation annuelle (barème plein). /// [ApiController] [Route("api")] public class RemboursementController : ControllerBase { private readonly IMontantRegleService _montantRegleService; private readonly IRemboursementService _remboursementService; public RemboursementController( IMontantRegleService montantRegleService, IRemboursementService remboursementService) { _montantRegleService = montantRegleService; _remboursementService = remboursementService; } /// /// Retourne le Montant_Previsionnel indicatif (80% du barème plein sur le total annuel partiel) /// pour un (année, mois, véhicule). Purement informatif — hors régularisation (Exigences 13.5/13.6). /// [HttpGet("montant-previsionnel/{annee:int}/{mois:int}")] [ProducesResponseType(typeof(MontantPrevisionnelDto), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task> GetMontantPrevisionnel( int annee, int mois, [FromQuery] int vehiculeId, CancellationToken cancellationToken) { try { var dto = await _montantRegleService.GetMontantPrevisionnelAsync( annee, mois, vehiculeId, cancellationToken); return Ok(dto); } catch (VehiculeNotFoundException ex) { return Problem(detail: ex.Message, statusCode: StatusCodes.Status404NotFound); } } /// /// Retourne les Montant_Regle saisis pour une (année, véhicule), triés par mois croissant. /// [HttpGet("montants-regles/{annee:int}")] [ProducesResponseType(typeof(IReadOnlyList), StatusCodes.Status200OK)] public async Task>> GetMontantsRegles( int annee, [FromQuery] int vehiculeId, CancellationToken cancellationToken) { var montants = await _montantRegleService.GetMontantsReglesAsync(annee, vehiculeId, cancellationToken); return Ok(montants); } /// /// Enregistre ou met à jour (upsert) un Montant_Regle par (année, mois, véhicule). /// Rejette un montant négatif avec un code HTTP 400 (Exigence 14.4). /// [HttpPut("montants-regles")] [ProducesResponseType(typeof(MontantRegleDto), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] public async Task> UpsertMontantRegle( [FromBody] MontantRegleDto dto, CancellationToken cancellationToken) { try { var result = await _montantRegleService.UpsertMontantRegleAsync(dto, cancellationToken); return Ok(result); } catch (MontantRegleNegatifException ex) { return Problem(detail: ex.Message, statusCode: StatusCodes.Status400BadRequest); } } /// /// Retourne la synthèse annuelle de régularisation (barème plein) pour une (année, véhicule) : /// tranche annuelle, 12 lignes mensuelles et totaux (km annuel, réglé, Montant_Reel, Regularisation). /// [HttpGet("regularisation/{annee:int}")] [ProducesResponseType(typeof(RegularisationAnnuelleDto), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task> GetRegularisation( int annee, [FromQuery] int vehiculeId, CancellationToken cancellationToken) { try { var dto = await _remboursementService.GetRegularisationAnnuelleAsync( annee, vehiculeId, cancellationToken); return Ok(dto); } catch (VehiculeNotFoundException ex) { return Problem(detail: ex.Message, statusCode: StatusCodes.Status404NotFound); } } }