feat(admin): GET /admin/completed-deliveries — abgeschlossene Lieferungen eines Tages
Neuer Admin-Endpunkt, der ALLE an einem Tag (Berliner Kalendertag von completed_at) abgeschlossenen Lieferungen liefert — unabhängig vom Mail-Versand-Status. Pro Lieferung: Belegnummer und ein Flag `positions_modified`, das true ist, wenn eine Belegzeile in der Menge reduziert/entfernt wurde (delivery_items.credited_quantity > 0) oder eine aktive Geld-Gutschrift vorliegt (jüngstes delivery_credit_audit-Event 'set'). Pflichtparameter `day` (DD-MM-YYYY). Geschützt per admin_api_key. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -29,6 +29,10 @@ pub fn router() -> Router<AppState> {
|
||||
"/admin/delivered-belegnummern",
|
||||
get(delivered_belegnummern),
|
||||
)
|
||||
.route(
|
||||
"/admin/completed-deliveries",
|
||||
get(completed_deliveries),
|
||||
)
|
||||
.route("/admin/mark-mail-sent", post(mark_mail_sent))
|
||||
.route("/admin/reviews", get(list_reviews))
|
||||
.route("/admin/reviews/{delivery_id}/resolve", post(resolve_review))
|
||||
@ -186,6 +190,80 @@ pub async fn delivered_belegnummern(
|
||||
}))
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct CompletedDeliveriesQuery {
|
||||
/// Ziel-Tag im Format `DD-MM-YYYY`. **Pflicht** — der Endpunkt liefert nur
|
||||
/// Abschlüsse genau dieses (Berliner) Kalendertages.
|
||||
pub day: String,
|
||||
}
|
||||
|
||||
/// Eine abgeschlossene Lieferung im Tagesabruf.
|
||||
#[derive(Debug, Serialize, ToSchema)]
|
||||
pub struct CompletedDeliveryItem {
|
||||
/// ERP-Belegnummer der Lieferung.
|
||||
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,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, ToSchema)]
|
||||
pub struct CompletedDeliveriesResponse {
|
||||
/// Tag, nach dem gefiltert wurde (ISO `YYYY-MM-DD`).
|
||||
pub day: String,
|
||||
/// Anzahl der abgeschlossenen Lieferungen an diesem Tag.
|
||||
pub count: usize,
|
||||
/// Die abgeschlossenen Lieferungen, aufsteigend nach Abschluss-Zeitpunkt.
|
||||
pub deliveries: Vec<CompletedDeliveryItem>,
|
||||
}
|
||||
|
||||
/// Liefert **alle** an einem Tag abgeschlossenen (ausgelieferten) Lieferungen —
|
||||
/// unabhängig vom Mail-Versand-Status. Der Tag (`day`, `DD-MM-YYYY`) ist Pflicht
|
||||
/// und wird als Berliner Kalendertag auf den Abschluss-Zeitpunkt
|
||||
/// (`completed_at`) angewandt. Pro Lieferung: Belegnummer und ein Flag, ob
|
||||
/// Positionen verändert wurden (Menge reduziert/Zeile entfernt oder
|
||||
/// Geld-Gutschrift).
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/admin/completed-deliveries",
|
||||
tag = "admin",
|
||||
params(
|
||||
("day" = String, Query, description = "Tag DD-MM-YYYY (Pflicht)")
|
||||
),
|
||||
responses(
|
||||
(status = 200, description = "Abgeschlossene Lieferungen des Tages", body = CompletedDeliveriesResponse),
|
||||
(status = 400, description = "Ungültiger/fehlender Tag"),
|
||||
(status = 401, description = "Admin-API-Key fehlt/ungültig")
|
||||
),
|
||||
security(("admin_api_key" = []))
|
||||
)]
|
||||
pub async fn completed_deliveries(
|
||||
State(state): State<AppState>,
|
||||
Query(query): Query<CompletedDeliveriesQuery>,
|
||||
) -> Result<Json<CompletedDeliveriesResponse>, ApiError> {
|
||||
let day = NaiveDate::parse_from_str(query.day.trim(), "%d-%m-%Y").map_err(|e| {
|
||||
ApiError(ApplicationError::Validation(format!(
|
||||
"ungültiger Tag '{}' (erwartet DD-MM-YYYY): {e}",
|
||||
query.day
|
||||
)))
|
||||
})?;
|
||||
tracing::info!(?day, "admin.completed_deliveries");
|
||||
let summaries = state.list_completed_deliveries.execute(day).await?;
|
||||
tracing::info!(?day, count = summaries.len(), "admin.completed_deliveries.done");
|
||||
Ok(Json(CompletedDeliveriesResponse {
|
||||
day: day.format("%Y-%m-%d").to_string(),
|
||||
count: summaries.len(),
|
||||
deliveries: summaries
|
||||
.into_iter()
|
||||
.map(|s| CompletedDeliveryItem {
|
||||
belegnummer: s.belegnummer,
|
||||
positions_modified: s.positions_modified,
|
||||
})
|
||||
.collect(),
|
||||
}))
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, ToSchema)]
|
||||
pub struct MarkMailSentRequest {
|
||||
/// Belegnummern, deren Liefermail erfolgreich versendet wurde und die als
|
||||
|
||||
Reference in New Issue
Block a user