193 lines
7.6 KiB
Java
193 lines
7.6 KiB
Java
package dev.lions.unionflow.server.resource;
|
|
|
|
import dev.lions.unionflow.server.service.BudgetService;
|
|
import dev.lions.unionflow.server.common.ErrorResponse;
|
|
import dev.lions.unionflow.server.api.dto.finance_workflow.request.CreateBudgetRequest;
|
|
import dev.lions.unionflow.server.api.dto.finance_workflow.response.BudgetResponse;
|
|
import jakarta.annotation.security.RolesAllowed;
|
|
import jakarta.inject.Inject;
|
|
import jakarta.validation.Valid;
|
|
import jakarta.ws.rs.*;
|
|
import jakarta.ws.rs.core.MediaType;
|
|
import jakarta.ws.rs.core.Response;
|
|
import org.eclipse.microprofile.openapi.annotations.Operation;
|
|
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
|
|
import org.jboss.logging.Logger;
|
|
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.UUID;
|
|
|
|
/**
|
|
* Resource REST pour la gestion des budgets
|
|
*
|
|
* @author UnionFlow Team
|
|
* @version 1.0
|
|
* @since 2026-03-13
|
|
*/
|
|
@Path("/api/finance/budgets")
|
|
@Produces(MediaType.APPLICATION_JSON)
|
|
@Consumes(MediaType.APPLICATION_JSON)
|
|
@Tag(name = "Finance - Budgets", description = "Gestion des budgets organisationnels")
|
|
public class BudgetResource {
|
|
|
|
private static final Logger LOG = Logger.getLogger(BudgetResource.class);
|
|
|
|
@Inject
|
|
BudgetService budgetService;
|
|
|
|
@GET
|
|
@RolesAllowed({"ADMIN_ORGANISATION", "SUPER_ADMIN"})
|
|
@Operation(summary = "Récupère les budgets",
|
|
description = "Liste tous les budgets d'une organisation avec filtres optionnels")
|
|
public Response getBudgets(
|
|
@QueryParam("organizationId") UUID organizationId,
|
|
@QueryParam("status") String status,
|
|
@QueryParam("year") Integer year) {
|
|
LOG.infof("GET /api/finance/budgets?organizationId=%s&status=%s&year=%s",
|
|
organizationId, status, year);
|
|
|
|
try {
|
|
List<BudgetResponse> budgets = budgetService.getBudgets(organizationId, status, year);
|
|
return Response.ok(budgets).build();
|
|
} catch (BadRequestException e) {
|
|
return Response.status(Response.Status.BAD_REQUEST)
|
|
.entity(ErrorResponse.of(e.getMessage()))
|
|
.build();
|
|
} catch (Exception e) {
|
|
LOG.error("Erreur lors de la récupération des budgets", e);
|
|
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
|
.entity(ErrorResponse.of(e.getMessage()))
|
|
.build();
|
|
}
|
|
}
|
|
|
|
@GET
|
|
@Path("/{budgetId}")
|
|
@RolesAllowed({"ADMIN_ORGANISATION", "SUPER_ADMIN"})
|
|
@Operation(summary = "Récupère un budget par ID",
|
|
description = "Retourne les détails complets d'un budget")
|
|
public Response getBudgetById(@PathParam("budgetId") UUID budgetId) {
|
|
LOG.infof("GET /api/finance/budgets/%s", budgetId);
|
|
|
|
try {
|
|
BudgetResponse budget = budgetService.getBudgetById(budgetId);
|
|
return Response.ok(budget).build();
|
|
} catch (NotFoundException e) {
|
|
return Response.status(Response.Status.NOT_FOUND)
|
|
.entity(ErrorResponse.of(e.getMessage()))
|
|
.build();
|
|
} catch (Exception e) {
|
|
LOG.error("Erreur lors de la récupération du budget", e);
|
|
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
|
.entity(ErrorResponse.of(e.getMessage()))
|
|
.build();
|
|
}
|
|
}
|
|
|
|
@POST
|
|
@RolesAllowed({"ADMIN_ORGANISATION", "SUPER_ADMIN"})
|
|
@Operation(summary = "Crée un nouveau budget",
|
|
description = "Crée un budget avec ses lignes budgétaires")
|
|
public Response createBudget(@Valid CreateBudgetRequest request) {
|
|
LOG.infof("POST /api/finance/budgets - Creating budget: %s", request.getName());
|
|
|
|
try {
|
|
BudgetResponse budget = budgetService.createBudget(request);
|
|
return Response.status(Response.Status.CREATED)
|
|
.entity(budget)
|
|
.build();
|
|
} catch (NotFoundException e) {
|
|
return Response.status(Response.Status.NOT_FOUND)
|
|
.entity(ErrorResponse.of(e.getMessage()))
|
|
.build();
|
|
} catch (BadRequestException e) {
|
|
return Response.status(Response.Status.BAD_REQUEST)
|
|
.entity(ErrorResponse.of(e.getMessage()))
|
|
.build();
|
|
} catch (Exception e) {
|
|
LOG.error("Erreur lors de la création du budget", e);
|
|
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
|
.entity(ErrorResponse.of(e.getMessage()))
|
|
.build();
|
|
}
|
|
}
|
|
|
|
@GET
|
|
@Path("/{budgetId}/tracking")
|
|
@RolesAllowed({"ADMIN_ORGANISATION", "SUPER_ADMIN"})
|
|
@Operation(summary = "Récupère le suivi budgétaire",
|
|
description = "Retourne les statistiques de suivi et réalisation du budget")
|
|
public Response getBudgetTracking(@PathParam("budgetId") UUID budgetId) {
|
|
LOG.infof("GET /api/finance/budgets/%s/tracking", budgetId);
|
|
|
|
try {
|
|
Map<String, Object> tracking = budgetService.getBudgetTracking(budgetId);
|
|
return Response.ok(tracking).build();
|
|
} catch (NotFoundException e) {
|
|
return Response.status(Response.Status.NOT_FOUND)
|
|
.entity(ErrorResponse.of(e.getMessage()))
|
|
.build();
|
|
} catch (Exception e) {
|
|
LOG.error("Erreur lors de la récupération du suivi budgétaire", e);
|
|
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
|
.entity(ErrorResponse.of(e.getMessage()))
|
|
.build();
|
|
}
|
|
}
|
|
|
|
@PUT
|
|
@Path("/{budgetId}")
|
|
@RolesAllowed({"ADMIN_ORGANISATION", "SUPER_ADMIN"})
|
|
@Operation(summary = "Met à jour un budget",
|
|
description = "Modifie un budget existant (nom, description, lignes, statut)")
|
|
public Response updateBudget(
|
|
@PathParam("budgetId") UUID budgetId,
|
|
Map<String, Object> updates) {
|
|
LOG.infof("PUT /api/finance/budgets/%s", budgetId);
|
|
|
|
try {
|
|
BudgetResponse budget = budgetService.updateBudget(budgetId, updates);
|
|
return Response.ok(budget).build();
|
|
} catch (NotFoundException e) {
|
|
return Response.status(Response.Status.NOT_FOUND)
|
|
.entity(ErrorResponse.of(e.getMessage()))
|
|
.build();
|
|
} catch (BadRequestException e) {
|
|
return Response.status(Response.Status.BAD_REQUEST)
|
|
.entity(ErrorResponse.of(e.getMessage()))
|
|
.build();
|
|
} catch (Exception e) {
|
|
LOG.error("Erreur lors de la mise à jour du budget", e);
|
|
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
|
.entity(ErrorResponse.of(e.getMessage()))
|
|
.build();
|
|
}
|
|
}
|
|
|
|
@DELETE
|
|
@Path("/{budgetId}")
|
|
@RolesAllowed({"ADMIN_ORGANISATION", "SUPER_ADMIN"})
|
|
@Operation(summary = "Supprime un budget",
|
|
description = "Supprime logiquement un budget (soft delete)")
|
|
public Response deleteBudget(@PathParam("budgetId") UUID budgetId) {
|
|
LOG.infof("DELETE /api/finance/budgets/%s", budgetId);
|
|
|
|
try {
|
|
budgetService.deleteBudget(budgetId);
|
|
return Response.noContent().build();
|
|
} catch (NotFoundException e) {
|
|
return Response.status(Response.Status.NOT_FOUND)
|
|
.entity(ErrorResponse.of(e.getMessage()))
|
|
.build();
|
|
} catch (Exception e) {
|
|
LOG.error("Erreur lors de la suppression du budget", e);
|
|
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
|
.entity(ErrorResponse.of(e.getMessage()))
|
|
.build();
|
|
}
|
|
}
|
|
|
|
}
|
|
|