feat(admin): GET /admin/belege/{belegnummer}/positions-modified

Neuer Admin-Endpunkt, der zu EINER ERP-Belegnummer das positions_modified-Flag
liefert (Stück-Gutschrift auf einer Belegzeile ODER aktive Geld-Gutschrift) —
gleiche Definition wie in completed-deliveries, aber pro Beleg und ohne
Abschluss-Voraussetzung. 404 bei unbekannter Belegnummer; bei mehreren
Lieferungen gleicher Belegnummer true, sobald eine verändert ist (bool_or).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Dennis Nemec
2026-07-09 21:32:04 +02:00
parent 6378b1101b
commit 865fcfcd23
8 changed files with 146 additions and 2 deletions

View File

@ -33,6 +33,10 @@ pub fn router() -> Router<AppState> {
"/admin/completed-deliveries",
get(completed_deliveries),
)
.route(
"/admin/belege/{belegnummer}/positions-modified",
get(positions_modified),
)
.route("/admin/mark-mail-sent", post(mark_mail_sent))
.route("/admin/reviews", get(list_reviews))
.route("/admin/reviews/{delivery_id}/resolve", post(resolve_review))
@ -303,6 +307,52 @@ pub async fn completed_deliveries(
}))
}
#[derive(Debug, Serialize, ToSchema)]
pub struct PositionsModifiedResponse {
/// ERP-Belegnummer, nach der gefragt wurde.
pub belegnummer: String,
/// `true`, wenn an der Lieferung Positionen verändert wurden — eine Zeile
/// wurde entfernt oder in der Menge reduziert (Stück-Gutschrift) **oder** es
/// liegt eine aktive Geld-Gutschrift vor.
pub positions_modified: bool,
}
/// Liefert zu **einer** ERP-Belegnummer, ob an der Lieferung Positionen
/// verändert wurden (Menge reduziert/Zeile entfernt oder Geld-Gutschrift) —
/// unabhängig vom Zustand der Lieferung. `404`, wenn die Belegnummer unbekannt
/// ist. Gibt es mehrere Lieferungen mit derselben Belegnummer, ist das Flag
/// `true`, sobald **eine** davon verändert ist.
#[utoipa::path(
get,
path = "/admin/belege/{belegnummer}/positions-modified",
tag = "admin",
params(
("belegnummer" = String, Path, description = "ERP-Belegnummer, z. B. V-30690291")
),
responses(
(status = 200, description = "Änderungs-Flag der Belegpositionen", body = PositionsModifiedResponse),
(status = 401, description = "Admin-API-Key fehlt/ungültig"),
(status = 404, description = "Belegnummer unbekannt")
),
security(("admin_api_key" = []))
)]
pub async fn positions_modified(
State(state): State<AppState>,
Path(belegnummer): Path<String>,
) -> Result<Json<PositionsModifiedResponse>, ApiError> {
tracing::info!(%belegnummer, "admin.positions_modified");
let flag = state
.get_positions_modified
.execute(&belegnummer)
.await?
.ok_or(ApiError(ApplicationError::NotFound))?;
tracing::info!(%belegnummer, positions_modified = flag, "admin.positions_modified.done");
Ok(Json(PositionsModifiedResponse {
belegnummer,
positions_modified: flag,
}))
}
#[derive(Debug, Deserialize, ToSchema)]
pub struct MarkMailSentRequest {
/// Belegnummern, deren Liefermail erfolgreich versendet wurde und die als