From 551ad2369e2d02b2097c9df0a38e13bc2c3bd963 Mon Sep 17 00:00:00 2001 From: salam Date: Mon, 20 Oct 2025 18:37:56 +0200 Subject: [PATCH] pdf wip --- app/Actions/Generate/Gutachten/Deckblatt.php | 5 +- .../Generate/Gutachten/Platzhalter.php | 13 ++++ .../Generate/Gutachten/Standardtext.php | 13 ---- app/Actions/Generate/MakeGutachten.php | 41 ++++++++++-- app/Actions/Generate/Utilities/Filter.php | 40 ++++++++++++ app/Actions/Generate/Utilities/Format.php | 15 +++++ app/Actions/Generate/Utilities/Html.php | 42 ++++++++++++ app/Actions/Generate/Utilities/Notice.php | 65 +++++++++++++++++++ .../Schemas/InhaltsverzeichnisForm.php | 23 ++++--- .../Tables/InhaltsverzeichnisTable.php | 7 ++ ...ojektInhaltsverzeichnisRelationManager.php | 28 +++++++- app/Models/Inhaltsverzeichnis.php | 1 + app/Models/ProjektInhaltsverzeichnis.php | 1 + ...25_09_24_131440_create_projektes_table.php | 1 - ...170241_create_inhaltsverzeichnis_table.php | 1 + ...reate_projekt_inhaltsverzeichnis_table.php | 1 + resources/css/pdf-download.css | 18 +++-- 17 files changed, 277 insertions(+), 38 deletions(-) create mode 100644 app/Actions/Generate/Gutachten/Platzhalter.php delete mode 100644 app/Actions/Generate/Gutachten/Standardtext.php create mode 100644 app/Actions/Generate/Utilities/Filter.php create mode 100644 app/Actions/Generate/Utilities/Format.php create mode 100644 app/Actions/Generate/Utilities/Html.php create mode 100644 app/Actions/Generate/Utilities/Notice.php diff --git a/app/Actions/Generate/Gutachten/Deckblatt.php b/app/Actions/Generate/Gutachten/Deckblatt.php index 9fbdefa..8f1eb0c 100644 --- a/app/Actions/Generate/Gutachten/Deckblatt.php +++ b/app/Actions/Generate/Gutachten/Deckblatt.php @@ -7,7 +7,7 @@ use Filament\Forms\Components\RichEditor\RichContentRenderer; class Deckblatt { - public static function create() + public static function create($textblock) { // $table->boolean('logo_anzeigen')->default(0); // $table->boolean('text_anzeigen')->default(0); @@ -33,8 +33,9 @@ class Deckblatt $html .= ''; $html .= '
'; - $html .= '

Zur Festsetzung der Nutzwerte'; + $html .= '

ZUR FESTSETZUNG DER NUTZWERTE'; $html .= '
'.trim(MakeGutachten::$projekt->offizieller_name).'
'; + $html .= '
'.trim($textblock).'
'; $html .= '

'; $html .= '
'; diff --git a/app/Actions/Generate/Gutachten/Platzhalter.php b/app/Actions/Generate/Gutachten/Platzhalter.php new file mode 100644 index 0000000..cb7ada3 --- /dev/null +++ b/app/Actions/Generate/Gutachten/Platzhalter.php @@ -0,0 +1,13 @@ +first(); self::$gutachter = Gutachter::where('id', self::$projekt->gutachter_id)->first(); @@ -61,11 +63,36 @@ class MakeGutachten $mpdf->SetCreator('nutzwerte.at'); $mpdf->SetAuthor(self::$gutachter->title.' '.self::$gutachter->gender.' '.self::$gutachter->name); - /** - * DECKBLATT - */ - $html = Deckblatt::create(); - $mpdf->WriteHTML($html, HTMLParserMode::HTML_BODY); + $inhalte = ProjektInhaltsverzeichnis::where('projekte_id', $projekte_id)->orderBy('sort')->get(); + + foreach ($inhalte as $inhalt) { + /** + * DECKBLATT + */ + if ($inhalt->name == 'DECKBLATT') { + $textblock = Platzhalter::replace($inhalt->textblock); + $html = Deckblatt::create($textblock); + $mpdf->WriteHTML($html, HTMLParserMode::HTML_BODY); + } + /** + * INHALTSVERZEICHNIS + */ + if ($inhalt->name == 'INHALTSVERZEICHNIS') { + $mpdf->AddPage(); + $html = '
INHALTSVERZEICHNIS
'; + $html .= ''; + foreach ($inhalte as $data) { + $html .= ''; + $html .= Html::td(Format::numeric($data->ordnungszahl, 2)); + $html .= Html::td($data->name); + $html .= Html::td(Format::numeric($data->seite, 0)); + $html .= ''; + } + $html .= '
'; + $mpdf->SetHTMLFooter('
Seite {PAGENO}

'); + $mpdf->WriteHTML($html, HTMLParserMode::HTML_BODY); + } + } // $inhalte = Inhaltsverzeichnis::where('projekte_id', $projekte_id)->where('is_active', 1)->orderBy('pos')->get(); // if (count($inhalte) == 0) { diff --git a/app/Actions/Generate/Utilities/Filter.php b/app/Actions/Generate/Utilities/Filter.php new file mode 100644 index 0000000..f9a9d9a --- /dev/null +++ b/app/Actions/Generate/Utilities/Filter.php @@ -0,0 +1,40 @@ + $row) { + if ($row['is_active'] == 1) { + return $row; + } + } + + return []; + } +} diff --git a/app/Actions/Generate/Utilities/Format.php b/app/Actions/Generate/Utilities/Format.php new file mode 100644 index 0000000..85d608f --- /dev/null +++ b/app/Actions/Generate/Utilities/Format.php @@ -0,0 +1,15 @@ + 0) { + return number_format($value, $stellen, '.', '.'); + } else { + return ''; + } + } +} diff --git a/app/Actions/Generate/Utilities/Html.php b/app/Actions/Generate/Utilities/Html.php new file mode 100644 index 0000000..f6d4bb8 --- /dev/null +++ b/app/Actions/Generate/Utilities/Html.php @@ -0,0 +1,42 @@ +'; + $mm = 190 / \count($_row); + foreach ($_row as $value) { + $html .= ''.$value.''; + } + $html .= ''; + + return $html; + } + + public static function make_table($str) + { + $array = explode('
', $str); + $html = ''; + foreach ($array as $value) { + $tmp = explode('|', $value); + $html .= ''; + $html .= self::td($tmp[0], 'br bb'); + $html .= self::td($tmp[1], 'br bb'); + $html .= ''; + } + $html .= '
'; + + return $html; + } + + public static function td($value = '', $classname = '', $colspan = 0) + { + $cls = $classname != '' ? ' class="'.$classname.'"' : ''; + $spn = $colspan != '' ? ' colspan="'.$colspan.'"' : ''; + + return "".$value.''; + } +} diff --git a/app/Actions/Generate/Utilities/Notice.php b/app/Actions/Generate/Utilities/Notice.php new file mode 100644 index 0000000..b556121 --- /dev/null +++ b/app/Actions/Generate/Utilities/Notice.php @@ -0,0 +1,65 @@ +'; + break; + case 'r': + echo '
'; + break; + case 'b': + echo '
'; + break; + default: + echo '
'; + break; + } + if (is_array($message)) { + print_r($message); + } else { + echo $message; + } + echo '
'; + if ($exit) { + exit(); + } + } +} diff --git a/app/Filament/Resources/Inhaltsverzeichnis/Schemas/InhaltsverzeichnisForm.php b/app/Filament/Resources/Inhaltsverzeichnis/Schemas/InhaltsverzeichnisForm.php index fde022d..78a0600 100644 --- a/app/Filament/Resources/Inhaltsverzeichnis/Schemas/InhaltsverzeichnisForm.php +++ b/app/Filament/Resources/Inhaltsverzeichnis/Schemas/InhaltsverzeichnisForm.php @@ -19,6 +19,9 @@ class InhaltsverzeichnisForm ->components([ Section::make('Überschrift') ->schema([ + Checkbox::make('neue_seite') + ->label('Start neuer Seite') + ->columnSpan(2), Textarea::make('name') ->required() ->label('Kapitel / Absatz') @@ -44,7 +47,7 @@ class InhaltsverzeichnisForm ]) ->columnSpan(1), ])->columnSpanFull(), - Section::make('Tabelle & Textblöcke') + Section::make('Tabellen & Textblöcke') ->hiddenLabel() ->schema([ Select::make('tabellen_id')->label('Tabelle') @@ -54,10 +57,11 @@ class InhaltsverzeichnisForm ) ->default(0) ->options(function () { - return Tabellen::all()->pluck('name', 'id')->toArray(); - })->belowContent([ - 'Kann auch frei bleiben', - ]), + $res = Tabellen::all()->pluck('name', 'id')->toArray(); + array_unshift($res, 'Ohne Tabelle'); + + return $res; + }), Select::make('textblock_id')->label('Textblock') ->prefixIcon('phosphor-article') @@ -66,10 +70,11 @@ class InhaltsverzeichnisForm ) ->default(0) ->options(function () { - return Textblock::all()->pluck('name', 'id')->toArray(); - })->belowContent([ - 'Kann auch frei bleiben', - ]), + $res = Textblock::all()->pluck('name', 'id')->toArray(); + array_unshift($res, 'Ohne Textblock'); + + return $res; + }), ])->columnSpanFull(), ]); } diff --git a/app/Filament/Resources/Inhaltsverzeichnis/Tables/InhaltsverzeichnisTable.php b/app/Filament/Resources/Inhaltsverzeichnis/Tables/InhaltsverzeichnisTable.php index e39b03a..1651906 100644 --- a/app/Filament/Resources/Inhaltsverzeichnis/Tables/InhaltsverzeichnisTable.php +++ b/app/Filament/Resources/Inhaltsverzeichnis/Tables/InhaltsverzeichnisTable.php @@ -5,6 +5,7 @@ namespace App\Filament\Resources\Inhaltsverzeichnis\Tables; use Filament\Actions\DeleteAction; use Filament\Actions\EditAction; use Filament\Support\Enums\FontWeight; +use Filament\Tables\Columns\IconColumn; use Filament\Tables\Columns\TextColumn; use Filament\Tables\Columns\ToggleColumn; use Filament\Tables\Table; @@ -20,6 +21,12 @@ class InhaltsverzeichnisTable TextColumn::make('ordnungszahl') ->label('Index') ->getStateUsing(fn ($record): string => $record->ordnungszahl == '0' ? '' : number_format($record->ordnungszahl, 2)), + IconColumn::make('neue_seite') + ->label('Seite') + ->icon(fn (string $state): string => match ($state) { + '1' => 'phosphor-file-plus', + default => '' + }), TextColumn::make('name') ->label('Überschrift') ->wrap() diff --git a/app/Filament/Resources/Projektes/RelationManagers/ProjektInhaltsverzeichnisRelationManager.php b/app/Filament/Resources/Projektes/RelationManagers/ProjektInhaltsverzeichnisRelationManager.php index 8cadce6..7ace75b 100644 --- a/app/Filament/Resources/Projektes/RelationManagers/ProjektInhaltsverzeichnisRelationManager.php +++ b/app/Filament/Resources/Projektes/RelationManagers/ProjektInhaltsverzeichnisRelationManager.php @@ -5,6 +5,7 @@ namespace App\Filament\Resources\Projektes\RelationManagers; use App\Actions\Create\CreateProjektInhaltsverzeichnis; use App\Models\KontoTextblock; use App\Models\ProjektInhaltsverzeichnis; +use App\Models\Tabellen; use Filament\Actions\Action; use Filament\Actions\BulkActionGroup; use Filament\Actions\CreateAction; @@ -48,7 +49,11 @@ class ProjektInhaltsverzeichnisRelationManager extends RelationManager Tabs::make('Tabs') ->tabs([ Tab::make('Überschrift') + ->hidden(fn ($record) => $record->name == 'DECKBLATT' ? true : false) ->schema([ + Checkbox::make('neue_seite') + ->label('Start neuer Seite') + ->columnSpan(2), Textarea::make('name') ->required() ->label('Kapitel / Absatz') @@ -158,6 +163,21 @@ class ProjektInhaltsverzeichnisRelationManager extends RelationManager ])->columns(1), ]), ]), + Tab::make('Tabellen') + ->schema([ + Select::make('tabellen_id')->label('Tabelle') + ->prefixIcon('phosphor-table') + ->prefixIconColor( + fn ($record): string => $record->tabellen_id == 0 ? 'gray' : 'primary' + ) + ->default(0) + ->options(function () { + $res = Tabellen::all()->pluck('name', 'id')->toArray(); + array_unshift($res, 'Ohne Tabelle'); + + return $res; + }), + ]), ])->columnSpanFull(), ]); } @@ -171,6 +191,12 @@ class ProjektInhaltsverzeichnisRelationManager extends RelationManager ->width('2rem') ->label('Index') ->getStateUsing(fn ($record): string => $record->ordnungszahl == '0' ? '' : number_format($record->ordnungszahl, 2)), + IconColumn::make('neue_seite') + ->label('Seite') + ->icon(fn (string $state): string => match ($state) { + '1' => 'phosphor-file-plus', + default => '' + }), TextColumn::make('name') ->wrap() ->weight(fn ($record): FontWeight => match ($record->ueberschrift_nicht_anzeigen) { @@ -221,7 +247,7 @@ class ProjektInhaltsverzeichnisRelationManager extends RelationManager ->createAnother(false), ]) ->recordActions([ - EditAction::make()->iconButton(), + EditAction::make()->iconButton()->hidden(fn ($record) => $record->name == 'INHALTSVERZEICHNIS' ? true : false), DeleteAction::make()->iconButton(), ]) ->toolbarActions([ diff --git a/app/Models/Inhaltsverzeichnis.php b/app/Models/Inhaltsverzeichnis.php index 9b30492..6877d15 100644 --- a/app/Models/Inhaltsverzeichnis.php +++ b/app/Models/Inhaltsverzeichnis.php @@ -14,6 +14,7 @@ class Inhaltsverzeichnis extends Model 'sort', 'ordnungszahl', 'seite', + 'neue_seite', 'ohne_seitenzahl_anzeige', ]; diff --git a/app/Models/ProjektInhaltsverzeichnis.php b/app/Models/ProjektInhaltsverzeichnis.php index cde13f9..3396323 100644 --- a/app/Models/ProjektInhaltsverzeichnis.php +++ b/app/Models/ProjektInhaltsverzeichnis.php @@ -15,6 +15,7 @@ class ProjektInhaltsverzeichnis extends Model 'sort', 'ordnungszahl', 'seite', + 'neue_seite', 'ohne_seitenzahl_anzeige', 'textblock', ]; diff --git a/database/migrations/2025_09_24_131440_create_projektes_table.php b/database/migrations/2025_09_24_131440_create_projektes_table.php index f168fdb..3a1d26d 100644 --- a/database/migrations/2025_09_24_131440_create_projektes_table.php +++ b/database/migrations/2025_09_24_131440_create_projektes_table.php @@ -29,7 +29,6 @@ return new class extends Migration $table->boolean('pdf_gutachten_status')->default(0); $table->boolean('excel_nutzwerte_status')->default(0); $table->boolean('evaluation_gutachten')->default(0); - $table->boolean('evaluation_nutzwerte')->default(0); $table->timestamp('bezahlt_am')->nullable(); $table->timestamps(); $table->softDeletes(); diff --git a/database/migrations/2025_10_02_170241_create_inhaltsverzeichnis_table.php b/database/migrations/2025_10_02_170241_create_inhaltsverzeichnis_table.php index dfded42..0923d2e 100644 --- a/database/migrations/2025_10_02_170241_create_inhaltsverzeichnis_table.php +++ b/database/migrations/2025_10_02_170241_create_inhaltsverzeichnis_table.php @@ -20,6 +20,7 @@ return new class extends Migration $table->integer('sort')->default(0); $table->double('ordnungszahl')->default(0); $table->integer('seite')->default(0); + $table->integer('neue_seite')->default(0); $table->integer('ohne_seitenzahl_anzeige')->default(0); $table->timestamps(); }); diff --git a/database/migrations/2025_10_10_085849_create_projekt_inhaltsverzeichnis_table.php b/database/migrations/2025_10_10_085849_create_projekt_inhaltsverzeichnis_table.php index 0347e88..0134e2e 100644 --- a/database/migrations/2025_10_10_085849_create_projekt_inhaltsverzeichnis_table.php +++ b/database/migrations/2025_10_10_085849_create_projekt_inhaltsverzeichnis_table.php @@ -22,6 +22,7 @@ return new class extends Migration $table->integer('sort')->default(0); $table->double('ordnungszahl')->default(0); $table->integer('seite')->default(0); + $table->integer('neue_seite')->default(0); $table->integer('ohne_seitenzahl_anzeige')->default(0); $table->text('textblock')->nullable(); $table->timestamps(); diff --git a/resources/css/pdf-download.css b/resources/css/pdf-download.css index 5e46ace..51ceb2a 100644 --- a/resources/css/pdf-download.css +++ b/resources/css/pdf-download.css @@ -1,7 +1,7 @@ body, table, .base { - font-family: DejaVuSans; + font-family: Helvetica, Arial, sans-serif; font-size: 10px; line-height: 16px; margin: 0; @@ -38,7 +38,7 @@ table, #deckblatt-auftraggeber { position: absolute; - top: 240mm; + top: 220mm; width: 185mm; text-align: right; } @@ -55,20 +55,28 @@ table, /** FORMATTING */ +.header { + padding: 1.3mm 3mm; + margin: 2rem 0; + font-size: 1.5rem; + border: 0.5px solid #f3f4f6; + background-color: #eff6ff; +} + h1 { - font-size: 24px; + font-size: 22px; line-height: 26px; margin: 0; } h2 { - font-size: 20px; + font-size: 18px; line-height: 22px; margin: 0; } h3 { - font-size: 16px; + font-size: 14px; line-height: 18px; margin: 0; }