DownloadInvoiceUseCase.php
Pfad: src/Application/Rechnung/DownloadInvoiceUseCase.php
Ext: php
Größe: 3057 Bytes
Geändert: 2026-07-16T14:56:39+02:00
Frühere Version vom 2026-07-16T14:56:39+02:00 · zur aktuellen Fassung
<?php
declare(strict_types=1);
namespace Demo\Application\Rechnung;
use Demo\Domain\Rechnung\InvoiceFileStoragePort;
use Demo\Domain\Rechnung\InvoiceLoggerPort;
use Demo\Domain\Rechnung\InvoiceRecord;
use Demo\Domain\Rechnung\SourceInvoice;
use Demo\Domain\Rechnung\WetellSourcePort;
use Demo\Domain\Rechnung\InvoiceErrorCode;
use Demo\Domain\Rechnung\ClockPort;
/**
* Use Case: Download des PDFs und Übergabe in die lokale Ablage.
*/
final class DownloadInvoiceUseCase
{
/**
* @param WetellSourcePort $portal Quelle.
* @param InvoiceFileStoragePort $storage Ablageadapter.
* @param InvoiceLoggerPort $logger Log.
* @param ClockPort $clock Zeitquelle.
*/
public function __construct(
private WetellSourcePort $portal,
private InvoiceFileStoragePort $storage,
private InvoiceLoggerPort $logger,
private ClockPort $clock
) {
}
/**
* @param string $runId Lauf-ID.
* @param SourceInvoice $source Rechnungsmetadaten.
* @param InvoiceRecord $record Aktueller Datensatz.
* @return InvoiceRecord Aktualisierte Datensatzversion.
*/
public function execute(string $runId, SourceInvoice $source, InvoiceRecord $record): InvoiceRecord
{
$this->logger->logStep($runId, 'download', 'START', ['sourceId' => $source->sourceId]);
try {
$tmpPdf = $this->portal->downloadInvoicePdf($source->downloadUrl);
} catch (\Throwable $error) {
throw new InvoiceProcessException(
InvoiceErrorCode::DOWNLOAD,
'download',
'Rechnungsdownload fehlgeschlagen: ' . $error->getMessage(),
0,
$error
);
}
$content = is_file($tmpPdf) ? file_get_contents($tmpPdf) : false;
if (!is_string($content) || $content === '') {
throw new InvoiceProcessException(
InvoiceErrorCode::DOWNLOAD,
'download',
'Leerer PDF-Inhalt empfangen'
);
}
if (!$this->isPdf($content)) {
@unlink($tmpPdf);
throw new InvoiceProcessException(
InvoiceErrorCode::DOWNLOAD,
'download',
'Download ist kein gueltiges PDF (Content-Type/Dateiinhalt pruefen)'
);
}
$target = $this->storage->buildTargetPath($source->invoiceDateHint, $source->vendorName, $source->sourceId);
$this->storage->persistDownloadedPdf($content, $target);
@unlink($tmpPdf);
$sha256 = $this->storage->sha256($target);
$record = $record->withDownload($target, $sha256, $this->clock->now());
$this->logger->logStep($runId, 'download', 'DONE', ['path' => $target]);
return $record;
}
private function isPdf(string $content): bool
{
if (strncmp($content, '%PDF-', 5) !== 0) {
return false;
}
return str_contains(substr($content, -4096), '%%EOF');
}
}