Warenwirtschaft: AP-33b Sammel-Dokumente — Lieferscheine/Rechnungen der Auswahl als ein PDF

Checkbox-Auswahl im Abwicklungs-Board (Alle-auswählen, Zähler in den Buttons)
+ zwei Sammel-Aktionen: „Lieferscheine drucken" und „+ Rechnungen" — je ein
zusammengeführtes PDF (PDFMerger/FPDI) im neuen Tab zum Stapeldruck. Fehlende
Dokumente werden dabei ohne Mailversand erzeugt, auf der Platte fehlende
Altdateien mit bestehender Nummer regeneriert. API-Bestellungen sind von der
Auswahl ausgenommen (deaktivierte Checkbox, Rechnung liegt im externen Shop)
und werden in gemischter Auswahl übersprungen; max. 100 je Druck.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Kevin Adametz 2026-07-16 12:00:10 +00:00
parent c21cc63428
commit 1252c30820
4 changed files with 159 additions and 3 deletions

View file

@ -110,6 +110,56 @@ class OrderFulfillmentController extends Controller
return redirect()->route('admin.inventory.orders.index', array_filter(['filter' => $request->input('back_filter')]));
}
/**
* AP-33b: Sammel-Dokumente — Lieferscheine (optional inkl. Rechnungen) der
* ausgewählten Bestellungen als EIN zusammengeführtes PDF zum Stapeldruck.
* Fehlende Dokumente werden dabei erzeugt (ohne Mailversand); API-Bestellungen
* werden übersprungen (Rechnung liegt im externen Shop).
*/
public function batchDocuments(Request $request)
{
$data = $request->validate([
'order_ids' => ['required', 'array', 'min:1', 'max:100'],
'order_ids.*' => ['integer', 'exists:shopping_orders,id'],
'type' => ['required', Rule::in(['delivery', 'combined'])],
]);
$orders = ShoppingOrder::query()->whereIn('id', $data['order_ids'])->orderBy('id')->get();
$printable = $orders->reject(fn (ShoppingOrder $order) => $order->isApiOrder())->values();
if ($printable->isEmpty()) {
session()->flash('alert-error', __('Nur API-Bestellungen ausgewählt — deren Rechnungen liegen im externen Shop.'));
return redirect()->route('admin.inventory.orders.index');
}
$merger = new PDFMerger;
$merger->init();
foreach ($printable as $order) {
if (! Invoice::isInvoice($order)) {
(new InvoiceRepository($order))->create([]);
} elseif (! Storage::disk('public')->exists(Invoice::getDownloadPathDelivery($order))) {
// Datei fehlt auf der Platte (Altdaten) — mit bestehender Nummer neu erzeugen
(new InvoiceRepository($order))->update([]);
}
if ($data['type'] === 'combined') {
$merger->addPDF(Invoice::getDownloadPath($order, true));
}
$merger->addPDF(Invoice::getDownloadPathDelivery($order, true));
}
$filename = ($data['type'] === 'combined' ? 'Rechnungen-Lieferscheine-' : 'Lieferscheine-')
.now()->format('d-m-Y_Hi').'.pdf';
$merger->setFileName($filename);
$merger->merge();
return Response::make($merger->output(), 200)
->header('Content-Type', 'application/pdf')
->header('Content-disposition', 'inline; filename="'.$filename.'"');
}
/**
* Dokument-Download für Versand-Mitarbeiter (copyreader) — die allgemeine
* storage_file-Route verlangt admin ≥ 7 bzw. den Besteller selbst.