- Backend : projets, solution, namespaces et références TrajetKmTracker.Api/.Tests -> SchotzIadKmTracker.Api/.Tests (dossiers, .csproj, .sln, .http, namespaces C#). GUID UserSecretsId préservé. - Specs : dossier .kiro/specs/trajet-km-tracker -> schotziad-km-tracker et mise à jour des références internes (chemins, tags de propriétés). - Frontend : projet Angular trajet-km-tracker -> schotziad-km-tracker (package.json, angular.json, chemin dist, Dockerfile), titre applicatif 'SchotzIAD KM Tracker'. - Docker et scripts (backend/Dockerfile, frontend/Dockerfile, run-dev.sh) mis à jour. - Suppression du fichier résiduel package.json.bak. Backend (solution) et frontend (build production) compilent sans erreur.
104 lines
4.2 KiB
C#
104 lines
4.2 KiB
C#
using Microsoft.AspNetCore.Mvc;
|
|
using SchotzIadKmTracker.Api.Models.DTOs;
|
|
using SchotzIadKmTracker.Api.Services;
|
|
using SchotzIadKmTracker.Api.Services.Exceptions;
|
|
|
|
namespace SchotzIadKmTracker.Api.Controllers;
|
|
|
|
/// <summary>
|
|
/// Endpoints « Barème et remboursements » : montant prévisionnel (80% indicatif),
|
|
/// montants réglés (saisie/consultation) et régularisation annuelle (barème plein).
|
|
/// </summary>
|
|
[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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 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).
|
|
/// </summary>
|
|
[HttpGet("montant-previsionnel/{annee:int}/{mois:int}")]
|
|
[ProducesResponseType(typeof(MontantPrevisionnelDto), StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
public async Task<ActionResult<MontantPrevisionnelDto>> 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);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retourne les Montant_Regle saisis pour une (année, véhicule), triés par mois croissant.
|
|
/// </summary>
|
|
[HttpGet("montants-regles/{annee:int}")]
|
|
[ProducesResponseType(typeof(IReadOnlyList<MontantRegleDto>), StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<IReadOnlyList<MontantRegleDto>>> GetMontantsRegles(
|
|
int annee, [FromQuery] int vehiculeId, CancellationToken cancellationToken)
|
|
{
|
|
var montants = await _montantRegleService.GetMontantsReglesAsync(annee, vehiculeId, cancellationToken);
|
|
return Ok(montants);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 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).
|
|
/// </summary>
|
|
[HttpPut("montants-regles")]
|
|
[ProducesResponseType(typeof(MontantRegleDto), StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
|
public async Task<ActionResult<MontantRegleDto>> 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);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 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).
|
|
/// </summary>
|
|
[HttpGet("regularisation/{annee:int}")]
|
|
[ProducesResponseType(typeof(RegularisationAnnuelleDto), StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
public async Task<ActionResult<RegularisationAnnuelleDto>> 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);
|
|
}
|
|
}
|
|
}
|