added new cc features

This commit is contained in:
2025-09-04 14:20:16 +02:00
parent 2226944053
commit 433e8ea4af
2 changed files with 221 additions and 6 deletions

View File

@@ -483,13 +483,35 @@ foreach ($owners as $owner):
</tr>
</table>
<div class="signature-line" style="margin-top: 128px">
<div class="float-left" style="width: 25%;">Ort, Datum</div>
<div class="float-right" style="width: 75%;">
<strong><?= ($owner->title) ? $owner->title . " " : "" ?><?= $owner->company ? $owner->company : $owner->firstname . ' ' . $owner->lastname ?></strong>
<br>Unterschrift mit Geburtsdatum bzw. firmenmäßige Zeichnung des/r Liegenschaftseigentümer(s)
<?php if ($owner->signature): ?>
<table style="width: 100%; margin-top: 80px; border-collapse: collapse; page-break-inside: avoid;">
<tr>
<td style="width: 33%; vertical-align: bottom; border-bottom: 1px solid #000; padding-bottom: 2px;">
<?php if ($owner->signature_date): ?>
<span style="font-size: 9px;">Graz, <?= date("d.m.Y", $owner->signature_date) ?></span>
<?php endif; ?>
</td>
<td style="width: 67%; vertical-align: bottom; border-bottom: 1px solid #000; padding-bottom: 2px; text-align: center;">
<img src="<?= $owner->signature ?>" style="max-height: 60px; max-width: 250px;" />
</td>
</tr>
<tr>
<td style="font-size: 9px; padding-top: 4px;">Ort, Datum</td>
<td style="font-size: 9px; padding-top: 4px; text-align: center;">
<strong><?= $owner->signature_name ?></strong>
<br>Unterschrift bzw. firmenmäßige Zeichnung des/r Liegenschaftseigentümer(s)
</td>
</tr>
</table>
<?php else: ?>
<div class="signature-line" style="margin-top: 128px; page-break-inside: avoid;">
<div class="float-left" style="width: 25%;">Ort, Datum</div>
<div class="float-right" style="width: 75%;">
<strong><?= ($owner->title) ? $owner->title . " " : "" ?><?= $owner->company ? $owner->company : $owner->firstname . ' ' . $owner->lastname ?></strong>
<br>Unterschrift mit Geburtsdatum bzw. firmenmäßige Zeichnung des/r Liegenschaftseigentümer(s)
</div>
</div>
</div>
<?php endif; ?>
<?php endforeach; ?>
</body>

View File

@@ -1464,4 +1464,197 @@ class ConstructionConsentController extends mfBaseController {
$this->layout()->setTemplate("VueViews/Vue");
}
private function createFileFromFile(string $sourcePath, string $filename, string $subfolder, string $name = null): ?File {
if (!file_exists($sourcePath)) {
$this->log->error(__METHOD__ . ": Source file does not exist at path: " . $sourcePath);
return null;
}
$savePath = rtrim(MFUPLOAD_FILE_SAVE_PATH, '/') . '/' . trim($subfolder, '/');
if (!is_dir($savePath)) {
if (!mkdir($savePath, 0777, true)) {
$this->log->error(__METHOD__ . ": Could not create save directory: " . $savePath);
return null;
}
}
$store_filename = uniqid() . '-' . basename($filename);
$destinationPath = $savePath . '/' . $store_filename;
if (!copy($sourcePath, $destinationPath)) {
$this->log->error(__METHOD__ . ": Could not copy file from '$sourcePath' to '$destinationPath'");
return null;
}
$fileData = [
"name" => $name ?? $filename,
"description" => "Generated signed consent form",
"filename" => $filename,
"orig_filename" => $filename,
"store_filename" => $store_filename,
"subfolder" => $subfolder,
];
$file = FileModel::create($fileData);
if (!$file->save()) {
$this->log->error(__METHOD__ . ": Error saving File Object");
unlink($destinationPath); // Clean up copied file
return null;
}
$file->mimetype = $file->getMimetype();
$file->save();
return $file;
}
protected function generateSignedPdfsAction() {
$this->layout()->setTemplate(null); // No view needed
$signedOwners = ConstructionConsentOwner::search([
'add-where' => "AND signature IS NOT NULL AND signature != '' AND signature_name IS NOT NULL AND signature_name != '' AND signature_date IS NOT NULL"
]);
if (empty($signedOwners)) {
$this->layout()->setFlash("Keine unterschriebenen Erklärungen zum Generieren gefunden.", "info");
$this->redirect("ConstructionConsent");
}
$successCount = 0;
$errorCount = 0;
foreach ($signedOwners as $owner) {
$desiredFilename = "Zustimmungserklaerung-unterschrieben-{$owner->id}.pdf";
// Check if a signed PDF already exists to avoid re-generation
$existingFile = ConstructionConsentOwnerFile::getFirst([
"constructionconsentowner_id" => $owner->id,
"filename" => $desiredFilename
]);
if ($existingFile) {
continue;
}
$pdfPath = $owner->consent->createConsentFormPdf([$owner]);
if (!$pdfPath || !file_exists($pdfPath)) {
$this->log->error("PDF generation failed for owner ID: {$owner->id}");
$errorCount++;
continue;
}
$file = $this->createFileFromFile(
$pdfPath,
$desiredFilename,
TT_CONSTRUCTIONCONSENT_FILE_UPLOAD_SUBFOLDER,
$desiredFilename
);
unlink($pdfPath);
if (!$file) {
$this->log->error("File record creation failed for owner ID: {$owner->id}");
$errorCount++;
continue;
}
$ccof = ConstructionConsentOwnerFile::create([
'constructionconsentowner_id' => $owner->id,
'file_id' => $file->id,
'filename' => $desiredFilename,
]);
if (!$ccof->save()) {
$this->log->error("ConstructionConsentOwnerFile record creation failed for owner ID: {$owner->id}. Deleting created file record.");
$file->file->delete();
$file->delete();
$errorCount++;
} else {
$successCount++;
}
}
$message = "PDF-Generierung abgeschlossen. $successCount Dokument(e) erfolgreich erstellt.";
if ($errorCount > 0) {
$message .= " $errorCount Fehler sind aufgetreten.";
$this->layout()->setFlash($message, "warning");
} else {
$this->layout()->setFlash($message, "success");
}
$this->redirect("ConstructionConsent");
}
protected function downloadProjectPdfsAction() {
$projectId = $this->request->project_id;
if (!is_numeric($projectId) || $projectId < 1) {
$this->layout()->setFlash("Projekt nicht gefunden", "error");
$this->redirect("ConstructionConsent");
}
$project = new ConstructionConsentProject($projectId);
if (!$project->id) {
$this->layout()->setFlash("Projekt nicht gefunden", "error");
$this->redirect("ConstructionConsent");
}
$consents = ConstructionConsent::search(['project_id' => $projectId]);
if (empty($consents)) {
$this->layout()->setFlash("Keine Zustimmungserklärungen für dieses Projekt gefunden.", "info");
$this->redirect("ConstructionConsent");
}
$pdf_files = [];
foreach ($consents as $consent) {
$owners = $consent->owners;
if (empty($owners)) {
continue;
}
foreach ($owners as $owner) {
$ownerFiles = $owner->files;
if (empty($ownerFiles)) {
continue;
}
foreach ($ownerFiles as $ownerFile) {
$file = $ownerFile->file;
if ($file && strtolower(pathinfo($file->store_filename, PATHINFO_EXTENSION)) === 'pdf') {
if ($file->fileExists()) {
$filePath = rtrim(MFUPLOAD_FILE_SAVE_PATH, '/') . '/' . trim($file->subfolder, '/') . '/' . $file->store_filename;
$pdf_files[] = $filePath;
}
}
}
}
}
$pdf_files = array_unique($pdf_files);
if (empty($pdf_files)) {
$this->layout()->setFlash("Keine hochgeladenen PDFs für dieses Projekt gefunden.", "error");
$this->redirect("ConstructionConsent");
}
$tempDir = rtrim(BASEDIR, '/') . "/var/temp/";
$finalPdfPath = $tempDir . "Zustimmungserklaerungen-Projekt-{$projectId}-" . date('Ymd_His') . ".pdf";
$escaped_files = array_map('escapeshellarg', $pdf_files);
$pdf_unite_cmd = PDFUNITE_BIN_PATH . " " . implode(' ', $escaped_files) . " " . escapeshellarg($finalPdfPath);
shell_exec($pdf_unite_cmd);
if (!file_exists($finalPdfPath) || filesize($finalPdfPath) === 0) {
$this->log->error("pdfunite command failed or produced an empty file. Command: " . $pdf_unite_cmd);
$this->layout()->setFlash("PDF-Zusammenführung fehlgeschlagen", "error");
$this->redirect("ConstructionConsent");
}
$downloadName = "Zustimmungserklärungen-{$project->name}-" . date('Y-m-d') . ".pdf";
$this->sendPdfResponse($finalPdfPath, $downloadName);
unlink($finalPdfPath);
exit;
}
}