Files
mareike/app/Domains/Invoice/Actions/CreateInvoiceReceipt/CreateInvoiceReceiptCommand.php

205 lines
7.4 KiB
PHP

<?php
namespace App\Domains\Invoice\Actions\CreateInvoiceReceipt;
use App\Enumerations\InvoiceType;
use App\Models\PageText;
use App\Models\Tenant;
use App\Providers\PdfMergeProvider;
use App\Resources\InvoiceResource;
use Dompdf\Dompdf;
use Illuminate\Support\Facades\Storage;
use ZipArchive;
class CreateInvoiceReceiptCommand {
private CreateInvoiceReceiptRequest $request;
private string $tempDirectory;
public function __construct(CreateInvoiceReceiptRequest $request) {
$this->request = $request;
$this->tempDirectory = Tenant::getTempDirectory();
}
public function execute() : CreateInvoiceReceiptResponse {
$response = new CreateInvoiceReceiptResponse();
$filename = $this->tempDirectory . $this->request->invoice->invoice_number . '.pdf';
if (!Storage::exists($this->tempDirectory)) {
Storage::makeDirectory(Tenant::getTempDirectory() . '/' . $this->tempDirectory);
}
$receipt = $this->request->invoice->document_filename;
if ($receipt === null) {
Storage::put(
$filename,
$this->createPdf( $this->createHtml(), 'portrait', $filename, false )
);
$response->fileName = $filename;
return $response;
}
$token = (string)rand(1000000000, 9999999999);
$pdf_data = $this->createPdf( $this->createHtml(), 'portrait', $filename, false );
$tmpFileName = $this->tempDirectory . 'tmp-' . $token . '.pdf';
Storage::put($tmpFileName, $pdf_data);
try {
$merger = new PdfMergeProvider();
$merger
->add( storage_path('app/private/' . $tmpFileName ))
->add(storage_path('app/private/' . $receipt))
->merge(storage_path('app/private/' .$filename) );
$response->fileName = $filename;
} catch ( \Exception $e ) {
$zip = new ZipArchive();
$zip->open(
storage_path('app/private/' .$filename) . '.zip',
ZipArchive::CREATE | ZipArchive::OVERWRITE
);
$zip->addFile(storage_path('app/private/' . $tmpFileName ), 'antrag.pdf');
$zip->addFile(storage_path('app/private/' . $receipt), 'beleg.pdf');
$zip->close();
$response->fileName = $filename . '.zip';
} finally {
Storage::delete($tmpFileName);
}
return $response;
}
private function createHtml() : string {
$invoiceReadable = new InvoiceResource($this->request->invoice)->toArray();
$travelPartTemplate = <<<HTML
<tr><td>Reiseweg:</td><td>%1\$s</td></tr>
<tr><td>Gesamtlänge der Strecke:</td><td>%2\$s km x %3\$s / km</td></tr>
<tr><td>Materialtransport:</td><td>%4\$s</td></tr>
<tr><td>Mitfahrende im PKW:</td><td>%5\$s</td></tr>
HTML;
$flatTravelPart = sprintf(
$travelPartTemplate,
$invoiceReadable['travelDirection'] ,
$invoiceReadable['distance'],
$invoiceReadable['distanceAllowance'],
$invoiceReadable['transportation'],
$invoiceReadable['passengers']
);
$invoiceTravelPart = '<tr><td>Kosten für ÖPNV:</td><td>' . $invoiceReadable['amount'] . '</td></tr>';;
$expensePart = '<tr><td>Auslagenerstattung:</td><td>' . $invoiceReadable['amount'] . '</td></tr>';
$content = <<<HTML
<html>
<body style="margin-left: 20mm; margin-top: 17mm">
<h3>Abrechnungstyp %1\$s</h3><br /><br />
<table style="width: 100%%;">
<tr><td>Abrechnungsnummer:</td><td>%2\$s</td></tr>
<tr><td>Name:</td><td>%3\$s</td></tr>
<tr><td>E-Mail:</td><td>%4\$s</td></tr>
<tr><td>Telefon:</td><td>%5\$s</td></tr>
<tr><td>Name der Kostenstelle:</td><td>%6\$s</td></tr>
<tr><td>Zahlungsgrund:</td><td>%7\$s</td></tr>
<tr><td>Wird der Betrag gespendet:</td><td>%8\$s</td></tr>
%9\$s
<tr style="font-weight: bold;">
<td style="border-bottom-width: 1px; border-bottom-style: double;">
Gesamtbetrag:
</td>
<td style="border-bottom-width: 1px; border-bottom-style: double;">
%10\$s
</td>
</tr>
<tr><td colspan="2"><br /><br /></td></tr>
%11\$s
<tr><td>Beleg digital eingereicht am:</td><td>%12\$s</td></tr>
<tr><td>Beleg akzeptiert am:</td><td>%13\$s</td></tr>
<tr><td>Beleg akzeptiert von:</td><td>%14\$s</td></tr>
</table>
%15\$s
</body>
</html>
HTML;
switch ($this->request->invoice->type) {
case InvoiceType::INVOICE_TYPE_TRAVELLING:
$paymentType = $this->request->invoice->distance !== null ? $flatTravelPart : $invoiceTravelPart;
break;
default:
$paymentType = $expensePart;
}
if ($this->request->invoice->donation) {
$paymentInformation = '<tr><td colspan="2">' . PageText::where('name', 'CONFIRMATION_DONATE')->first()->content . '</td></tr>';
} else {
if ($this->request->invoice->contact_bank_iban === null) {
$paymentInformation = '';
} else {
$paymentInformationTemplate = <<<HTML
<tr><td colspan="2">%1\$s</td></tr>
<tr><td>Kontoinhaber*in:</td><td>%2\$s</td></tr>
<tr><td>INAN:</td><td>%3\$s</td></tr>
<tr><td colspan="2"><br /><br /></td></tr>
HTML;
$paymentInformation = sprintf(
$paymentInformationTemplate,
PageText::where('name', 'CONFIRMATION_PAYMENT')->first()->content,
$invoiceReadable['accountOwner'],
$invoiceReadable['accountIban']
);
}
}
$changes = $this->request->invoice->changes !== null ? '<p>' . $this->request->invoice->changes . '</p>' : '';
return sprintf(
$content,
$invoiceReadable['invoiceTypeShort'],
$invoiceReadable['invoiceNumber'],
$invoiceReadable['contactName'],
$invoiceReadable['contactEmail'],
$invoiceReadable['contactPhone'],
$invoiceReadable['costUnitName'],
$invoiceReadable['invoiceType'],
$invoiceReadable['donationText'],
$paymentType,
$invoiceReadable['amount'],
$paymentInformation,
$invoiceReadable['createdAt'],
$invoiceReadable['approvedAt'],
$invoiceReadable['approvedBy'],
$changes
);
}
private function createPdf( string $htmlfile, string $orientation, string $filename, bool $download = true ) {
$dompdf = new Dompdf();
$dompdf->loadHtml( $htmlfile, 'UTF-8' );
$dompdf->setPaper( 'A4', $orientation );
$dompdf->render();
if ( ! $download ) {
return $dompdf->output();
}
$dompdf->stream( $filename );
}
}