fix: fehlende Dateien aus vorherigem Commit nachreichen
CSRF-Schutz, DHL-Versandmarken, Entra-ID-SSO, ApiCore-Sync und die Harvest-isPublished-Migration waren gestaged aber nicht im letzten Commit enthalten — Gitea-Actions-Build brach mit "Module not found" fuer genau diese Dateien ab. Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
1 parent
4d3100e9ba
commit
b6db9254a9
10 files changed
+1205
No files matched your search
@@ -0,0 +1,104 @@
|
||||
"use server";
|
||||
|
||||
import { revalidatePath } from "next/cache";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { logAdminAction } from "@/lib/audit-log";
|
||||
import { getCompanyInfo } from "@/lib/company-info";
|
||||
import { createDhlShipmentLabel, DhlApiError, DhlNotConfiguredError, type DhlCreateShipmentResult } from "@/lib/dhl";
|
||||
import { requireAdmin, fail, str } from "./_shared";
|
||||
|
||||
/**
|
||||
* Erstellt per DHL Parcel DE Shipping API eine Versandmarke fuer eine
|
||||
* bezahlte Bestellung und speichert die zurueckgegebene Sendungsnummer im
|
||||
* Shipment-Datensatz (carrier="DHL"). Idempotent: ist bereits eine
|
||||
* Sendungsnummer erfasst, wird KEINE zweite Marke erzeugt (das wuerde bei
|
||||
* DHL echte Kosten verursachen) — die Aktion bricht in dem Fall mit einer
|
||||
* klaren Meldung ab, statt stillschweigend zu ueberschreiben.
|
||||
*/
|
||||
export async function createDhlLabelAction(formData: FormData): Promise<void> {
|
||||
const admin = await requireAdmin();
|
||||
const orderId = str(formData, "orderId");
|
||||
const detailPath = `/admin/bestellungen/${orderId}`;
|
||||
|
||||
const order = await prisma.order.findUnique({
|
||||
where: { id: orderId },
|
||||
include: {
|
||||
items: { select: { weightGrams: true, quantity: true } },
|
||||
payment: { select: { status: true } },
|
||||
shipment: { select: { trackingNumber: true } },
|
||||
},
|
||||
});
|
||||
if (!order) {
|
||||
fail("/admin/bestellungen", "Bestellung nicht gefunden.");
|
||||
}
|
||||
|
||||
if (order.fulfillmentMethod !== "VERSAND") {
|
||||
fail(detailPath, "Diese Bestellung ist zur Abholung markiert, kein Versand per DHL nötig.");
|
||||
}
|
||||
if (order.payment?.status !== "SUCCEEDED") {
|
||||
fail(detailPath, "Die Bestellung ist noch nicht bezahlt — es kann keine Versandmarke erstellt werden.");
|
||||
}
|
||||
if (order.shipment?.trackingNumber) {
|
||||
fail(detailPath, "Für diese Bestellung wurde bereits eine DHL-Sendungsnummer erfasst.");
|
||||
}
|
||||
|
||||
const totalWeightGrams = order.items.reduce((sum, item) => sum + item.weightGrams * item.quantity, 0);
|
||||
const company = await getCompanyInfo();
|
||||
|
||||
let result: DhlCreateShipmentResult;
|
||||
try {
|
||||
result = await createDhlShipmentLabel({
|
||||
reference: order.orderNumber,
|
||||
weightGrams: totalWeightGrams,
|
||||
shipper: {
|
||||
companyName: company.name,
|
||||
firstName: "",
|
||||
lastName: "",
|
||||
street: company.address.street,
|
||||
zip: company.address.zip,
|
||||
city: company.address.city,
|
||||
// Firmensitz ist Deutschland (siehe lib/site-config.ts) — bewusst
|
||||
// fest verdrahtet statt aus dem lokalisierten Anzeigetext
|
||||
// ("Deutschland") geparst.
|
||||
country: "DE",
|
||||
phone: company.phone,
|
||||
email: company.email,
|
||||
},
|
||||
receiver: {
|
||||
firstName: order.firstName,
|
||||
lastName: order.lastName,
|
||||
street: order.street,
|
||||
zip: order.zip,
|
||||
city: order.city,
|
||||
country: order.country,
|
||||
phone: order.phone,
|
||||
email: order.email,
|
||||
},
|
||||
});
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof DhlNotConfiguredError) {
|
||||
fail(detailPath, error.message);
|
||||
}
|
||||
if (error instanceof DhlApiError) {
|
||||
fail(detailPath, error.message);
|
||||
}
|
||||
const message = error instanceof Error ? error.message : "Unbekannter Fehler";
|
||||
fail(detailPath, `DHL-Versandmarke konnte nicht erstellt werden: ${message}`);
|
||||
}
|
||||
|
||||
await prisma.shipment.upsert({
|
||||
where: { orderId },
|
||||
create: { orderId, carrier: "DHL", trackingNumber: result.trackingNumber },
|
||||
update: { carrier: "DHL", trackingNumber: result.trackingNumber },
|
||||
});
|
||||
|
||||
await logAdminAction(admin, {
|
||||
action: "order.dhl_label_created",
|
||||
entityType: "Order",
|
||||
entityId: orderId,
|
||||
detail: `${order.orderNumber}: DHL-Sendungsnummer ${result.trackingNumber}`,
|
||||
});
|
||||
|
||||
revalidatePath("/admin/bestellungen");
|
||||
revalidatePath(detailPath);
|
||||
}
|
||||
Reference in new issue
Block a user