Add Stadt Zuschuss Template

This commit is contained in:
philipp lang 2022-05-17 01:37:07 +02:00
parent f4f84b2369
commit d3bc8af711
10 changed files with 303 additions and 3 deletions

View File

@ -0,0 +1,31 @@
<?php
namespace App\Contribution;
use App\Http\Controllers\Controller;
use App\Member\Member;
use App\Member\MemberResource;
use App\Pdf\PdfGenerator;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;
class ContributionController extends Controller
{
public function form(): Response
{
session()->put('menu', 'contribution');
session()->put('title', 'Zuschüsse');
return Inertia::render('contribution/VIndex', [
'members' => MemberResource::collection(Member::get()),
]);
}
public function generate(Request $request): PdfGenerator
{
$data = app($request->query('type'));
return app(PdfGenerator::class)->setRepository($data)->render();
}
}

View File

@ -0,0 +1,90 @@
<?php
namespace App\Contribution;
use App\Member\Member;
use App\Pdf\EnvType;
use App\Pdf\PdfRepository;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Spatie\LaravelData\Data;
class SolingenData extends Data implements PdfRepository
{
public function __construct(
public string $eventName,
public string $dateFrom,
public string $dateUntil,
public ?string $filename = '',
public $type = 'FK',
) {
}
public static function fromRequest(Request $request): self
{
return new self(
eventName: $request->eventName,
dateFrom: $request->dateFrom,
dateUntil: $request->dateUntil,
);
}
public function checkboxes(): string
{
$output = '';
$firstRow = collect(['B' => 'Jugendbildungsmaßnahme', 'G' => 'Gruppenleiter/innenschulung', 'FK' => 'Ferienkolonie', 'F' => 'Freizeitnaßnahme'])->map(function ($item, $key) {
return ($this->type === $key ? '\\checkedcheckbox' : '\\checkbox').'{'.$item.'}';
})->implode(' & ').' \\\\';
$secondRow = collect(['I' => 'Int. Jugendbegegnung', 'P' => 'politische Jugendbildung', 'PR' => 'Projekte'])->map(function ($item, $key) {
return ($this->type === $key ? '\\checkedcheckbox' : '\\checkbox').'{'.$item.'}';
})->implode(' & ').' & \\emptycheckbox \\\\';
return $firstRow."\n".$secondRow;
}
public function members(): Collection
{
return Member::orderByRaw('lastname, firstname')->get();
}
public function niceEventFrom(): string
{
return Carbon::parse($this->dateFrom)->format('d.m.Y');
}
public function niceEventTo(): string
{
return Carbon::parse($this->dateUntil)->format('d.m.Y');
}
public function getFilename(): string
{
return 'zuschuesse-solingen-'.Str::slug($this->eventName);
}
public function getView(): string
{
return 'tex.zuschuss-stadt';
}
public function getTemplate(): string
{
return 'efz';
}
public function setFilename(string $filename): static
{
$this->filename = $filename;
return $this;
}
public function getScript(): EnvType
{
return EnvType::PDFLATEX;
}
}

View File

@ -83,7 +83,7 @@ class Member extends Model
])); ]));
} }
//----------------------------------- Getters ----------------------------------- // ----------------------------------- Getters -----------------------------------
public function getFullnameAttribute(): string public function getFullnameAttribute(): string
{ {
return $this->firstname.' '.$this->lastname; return $this->firstname.' '.$this->lastname;
@ -118,7 +118,7 @@ class Member extends Model
return $this->subscription->fee->nami_id; return $this->subscription->fee->nami_id;
} }
//---------------------------------- Relations ---------------------------------- // ---------------------------------- Relations ----------------------------------
public function country(): BelongsTo public function country(): BelongsTo
{ {
return $this->belongsTo(Country::class); return $this->belongsTo(Country::class);

View File

@ -7,4 +7,6 @@ use Illuminate\View\Compilers\BladeCompiler;
class TexCompiler extends BladeCompiler class TexCompiler extends BladeCompiler
{ {
protected $contentTags = ['<<<', '>>>']; protected $contentTags = ['<<<', '>>>'];
protected $rawTags = ['<<<!!', '!!>>>'];
} }

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512" xml:space="preserve"><path d="M47.054 302h-32c-8.291 0-15 6.709-15 15v180c0 8.291 6.709 15 15 15h32c24.814 0 45-20.186 45-45V347c0-24.814-20.185-45-45-45zM507.554 331.099c-1.8-2.999-4.199-5.4-6.899-7.5-11.045-9.662-29.654-8.749-40.499 3.001l-68.101 78.6-2.1 2.399c-8.399 9.3-20.4 14.401-32.999 14.401h-116.4c-8.401 0-15-6.601-15-15 0-8.401 6.599-15 15-15h91.5c16.5 0 30-13.5 30-30v-.3c-.3-16.5-13.5-29.7-30-29.7h-54.3c-8.996 0-18.636-3.303-26.4-9.901-36.599-32.1-90-34.2-129.3-6.899v184.499c29.7 8.101 60.3 12.301 91.199 12.301h133.801c32.999 0 64.2-15.601 84-42.001l72.001-96c10.503-13.789 11.295-32.699 4.497-42.9zM402.264 28.995C385.627 10.297 362.564 0 337.324 0c-28.172 0-52.593 13.321-70.622 38.522a120.814 120.814 0 0 0-3.802 5.649 119.486 119.486 0 0 0-3.801-5.649C241.07 13.321 216.649 0 188.477 0c-25.24 0-48.303 10.297-64.939 28.994-15.788 17.744-24.484 41.465-24.484 66.794 0 27.525 10.681 52.924 33.611 79.934 20.009 23.565 48.708 47.788 81.938 75.836 12.28 10.365 24.979 21.083 38.473 32.778a14.968 14.968 0 0 0 9.824 3.665 14.97 14.97 0 0 0 9.824-3.665c13.492-11.693 26.189-22.41 38.469-32.773 21.342-18.014 39.773-33.57 55.767-48.66 31.053-29.298 59.787-62.553 59.787-107.114 0-25.329-8.695-49.05-24.483-66.794z"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -12,9 +12,10 @@
<v-link href="/subscription" v-show="hasModule('bill')" menu="subscription" icon="money" <v-link href="/subscription" v-show="hasModule('bill')" menu="subscription" icon="money"
>Beiträge</v-link >Beiträge</v-link
> >
<v-link href="/contribution" menu="contribution" icon="contribution">Zuschüsse</v-link>
</div> </div>
<div class="grid gap-2"> <div class="grid gap-2">
<v-link method="POST" icon="logout" href="/logout">Abmelden</v-link> <v-link @click.prevent="$inertia.post('/logout')" icon="logout" href="/logout">Abmelden</v-link>
</div> </div>
</div> </div>

View File

@ -2,6 +2,7 @@
<i-link <i-link
class="flex text-white py-2 px-3 rounded-lg hover:bg-gray-600" class="flex text-white py-2 px-3 rounded-lg hover:bg-gray-600"
:method="method" :method="method"
v-on="$listeners"
:href="href" :href="href"
:class="{'bg-gray-700': $page.props.menu == menu}" :class="{'bg-gray-700': $page.props.menu == menu}"
> >

View File

@ -0,0 +1,47 @@
<template>
<form action="/contribution/generate" target="_BLANK" class="max-w-2xl w-full mx-auto gap-6 grid-cols-2 grid p-6">
<f-text
id="eventName"
name="eventName"
class="col-span-2"
v-model="values.eventName"
label="Veranstaltungs-Name"
required
></f-text>
<f-text id="dateFrom" name="dateFrom" type="date" v-model="values.dateFrom" label="Datum von" required></f-text>
<f-text
id="dateUntil"
name="dateUntil"
type="date"
v-model="values.dateUntil"
label="Datum bis"
required
></f-text>
<button
target="_BLANK"
type="submit"
name="type"
value="\App\Contribution\SolingenData"
class="btn btn-primary mt-3 inline-block"
>
Für Stadt erstellen
</button>
</form>
</template>
<script>
export default {
data: function () {
return {
values: {
event_name: '',
dateFrom: '',
dateUntil: '',
},
};
},
props: {
members: {},
},
};
</script>

View File

@ -0,0 +1,124 @@
\documentclass[a4paper,landscape]{article}
\usepackage[landscape,top=0cm,left=0cm,bottom=0cm,right=0cm]{geometry}
\usepackage{tikz,ulem}
\usetikzlibrary{matrix}
\usetikzlibrary{backgrounds}
\usetikzlibrary{intersections}
\usetikzlibrary{positioning}
\usetikzlibrary{calc}
\pagestyle{empty}
\setlength{\parindent}{0cm}
\tikzset{outer/.style={overlay, remember picture}}
\tikzset{formfill/.style={pos=0.01,anchor=base west,font=\LARGE}}
\tikzset{
table/.style={
matrix of nodes,
row sep=-\pgflinewidth,
column sep=-\pgflinewidth,
nodes={
rectangle,
draw=black,
font=\Large,
},
minimum height=1.5em,
text depth=0.5ex,
text height=2.5ex,
nodes in empty cells,
column 1/.style={
nodes={
align=center,
text width=5em,
}
},
column 2/.style={
nodes={
align=center,
text width=17em,
}
},
column 3/.style={
nodes={
align=center,
text width=15em,
}
},
column 4/.style={
nodes={
align=center,
text width=5em,
}
},
column 5/.style={
nodes={
align=center,
text width=9em,
}
},
column 6/.style={
nodes={
align=center,
text width=7em,
}
},
column 7/.style={
nodes={
align=center,
text width=12.5em,
}
},
row 1/.style={
nodes={
draw=white,
align=center,
}
}
}
}
\newcommand{\checkbox}[1]{\tikz[label distance=0.2cm]{\node[label={east:\large{#1}},draw,very thick,rectangle,text height=0.5cm,text width=0.5cm,inner sep=0cm] at (0,0) {};}}
\newcommand{\checkedcheckbox}[1]{\tikz[label distance=0.2cm]{\node[label={east:\large{#1}},draw,very thick,rectangle,text height=0.5cm,text width=0.5cm,inner sep=0cm] at (0,0) {}; \draw (--0.25cm,0) -- (-0.25cm,0.5cm) (-0.25cm,0) -- (0.25cm,0.5cm); }}
\newcommand{\emptycheckbox}{\tikz{\node[text height=0.5cm,text width=0.5cm,inner sep=0cm] at (0,0) {};}}
\begin{document} \sffamily
@foreach($data->members()->chunk(14) as $chunk)
\begin{tikzpicture}[outer]
\path (current page.north west) ++(1cm,-1cm) coordinate (OL) -- (current page.north east) ++(-1cm,0cm) coordinate (OR) node[midway,below=0.5cm] {\textbf{TEILNEHMER - / INNENLISTE}};
\matrix (options) at ($(OL)+(0.5cm,-1cm)$) [matrix of nodes, column sep=0cm,row sep=0.5cm,nodes in empty cells, every node/.style={inner sep=0cm,align=left,text width=6.2cm}, anchor=north west] {
<<<!!$data->checkboxes()!!>>>
};
\node[align=left,inner sep=0cm,anchor=west] at (options-2-4.west) {\tikz{\node[draw,very thick,rectangle,text height=0.5cm,text width=0.5cm,inner sep=0cm] (checkbox) at (0,0) {}; \draw[thick] (checkbox.south east) ++(0.2cm,0) -- (checkbox.south east -| options-2-4.south east);}};
\node[anchor=north west] (org) at ($(options.south west)+(0cm,-0.5cm)$) {\large{Veranstalter:}};
\draw (org.south east -| options-2-2.south west) -- (org.south east -| options-2-4.south east) node[formfill] {DPSG Stamm Silva Solingen Wald};
\node[anchor=north west] (title) at ($(org.south west)+(0cm,-0.5cm)$) {\large{Titel der Maßnahme:}};
\draw (title.south east -| options-2-2.south west) -- (title.south east -| options-2-4.south east) node[formfill] {<<<$data->eventName>>>};
\node[anchor=north west] (datefrom) at ($(title.south west)+(0cm,-0.5cm)$) {\large{Datum vom:}};
\draw (datefrom.south east -| options-2-2.south west) -- ($(datefrom.south east -| options-2-2.south east) - (1,0cm)$) node[formfill] {<<<$data->niceEventFrom()>>>};
\node[anchor=south west] (dateuntil) at (options-2-3.south west |- datefrom.south west) {\large{bis:}};
\draw[label={east:aaa}] (dateuntil.south east) -- (datefrom.south east -| options-2-3.south east) node[formfill] {<<<$data->niceEventTo()>>>};
\path[fill=yellow] (datefrom.south -| OL) ++(0,-1.0) rectangle ($(datefrom.south -| OR) + (0,-1.5)$);
\matrix (table) at ($(datefrom.south west) + (0,-2.3cm)$) [table,below right] {
\uline{Lfd. Nr.} & \uline{Name / Vorname} & \uline{Straße} & \uline{PLZ} & \uline{Wohnort} & \uline{Geburtsjahr} & \uline{Unterschrift} \\
@foreach($chunk as $i => $member)
<<<$i+1>>> & <<<$member->fullname>>> & <<<$member->address>>> & <<<$member->zip>>> & <<<$member->location>>> & <<<$member->birthday->year>>> & \\
@endforeach
};
\draw[ultra thick] (OL) rectangle (table.south east -| OR);
\end{tikzpicture}
\pagebreak[4]
@endforeach
\end{document}

View File

@ -1,5 +1,6 @@
<?php <?php
use App\Contribution\ContributionController;
use App\Course\Controllers\CourseController; use App\Course\Controllers\CourseController;
use App\Http\Controllers\HomeController; use App\Http\Controllers\HomeController;
use App\Initialize\InitializeController; use App\Initialize\InitializeController;
@ -36,4 +37,6 @@ Route::group(['middleware' => 'auth:web'], function (): void {
Route::resource('member.course', CourseController::class); Route::resource('member.course', CourseController::class);
Route::get('/member/{member}/efz', MemberEfzController::class)->name('efz'); Route::get('/member/{member}/efz', MemberEfzController::class)->name('efz');
Route::get('/member/{member}/resync', MemberResyncController::class)->name('member.resync'); Route::get('/member/{member}/resync', MemberResyncController::class)->name('member.resync');
Route::get('/contribution', [ContributionController::class, 'form'])->name('contribution.form');
Route::get('/contribution/generate', [ContributionController::class, 'generate'])->name('contribution.generate');
}); });