Add remember PDFs

This commit is contained in:
philipp lang 2021-10-29 21:44:23 +02:00
parent 35f4110d0b
commit 60ddedbe8a
13 changed files with 488 additions and 13 deletions

View File

@ -28,8 +28,11 @@ class ActionFactory
$repo = app($repo);
return [
'href' => route('sendpayment.pdf', ['type' => get_class($repo)]),
'label' => $repo->allLabel(),
'link' => [
'href' => route('sendpayment.pdf', ['type' => get_class($repo)]),
'label' => $repo->allLabel(),
],
'text' => $repo->getDescription(),
];
});
}

View File

@ -2,17 +2,17 @@
namespace App\Payment;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use App\Member\Member;
use App\Payment\Status;
use App\Payment\Subscription;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Payment extends Model
{
use HasFactory;
public $fillable = ['member_id', 'subscription_id', 'nr', 'status_id'];
public $fillable = ['member_id', 'subscription_id', 'nr', 'status_id', 'last_remembered_at'];
public function member() {
return $this->belongsTo(Member::class);
@ -41,6 +41,6 @@ class Payment extends Model
public function scopeWhereNeedsRemember($q) {
return $q->whereHas('status', function($q) {
return $q->where('is_remember', true);
});
})->where(fn ($query) => $query->whereNull('last_remembered_at')->orWhere('last_remembered_at', '<=', now()->subMonths(6)));
}
}

View File

@ -18,7 +18,7 @@ class SendpaymentController extends Controller
session()->put('title', 'Rechnungen versenden');
return Inertia::render('sendpayment/Form', [
'links' => app(ActionFactory::class)->allLinks(),
'types' => app(ActionFactory::class)->allLinks(),
]);
}

View File

@ -102,4 +102,22 @@ class BillType extends Repository implements PdfRepository
return 'Rechnungen versenden';
}
/**
* Get Descriptions for sendpayment page
*
* @return array<int, string>
*/
public function getDescription(): array
{
return [
'Diese Funktion erstellt ein PDF mit allen noch nicht versendenden Rechnungen bei den Mitgliedern die Post als Versandweg haben.',
'Die Rechnungen werden automatisch auf "Rechnung gestellt" aktualisiert.',
];
}
public function afterSingle(Payment $payment): void
{
$payment->update(['status_id' => 2]);
}
}

View File

@ -3,6 +3,7 @@
namespace App\Pdf;
use App\Member\Member;
use App\Payment\Payment;
use Carbon\Carbon;
use Illuminate\Support\Collection;
@ -43,4 +44,8 @@ interface PdfRepository
public function getEmail(Collection $page): string;
public function getDescription(): array;
public function afterSingle(Payment $payment): void;
}

View File

@ -12,6 +12,7 @@ class PdfRepositoryFactory
private array $types = [
BillType::class,
RememberType::class,
];
public function getTypes(): Collection
@ -60,7 +61,7 @@ class PdfRepositoryFactory
public function afterSingle(PdfRepository $repo): void
{
foreach ($repo->allPayments() as $payment) {
$payment->update(['status_id' => 2]);
$repo->afterSingle($payment);
}
}

123
app/Pdf/RememberType.php Normal file
View File

@ -0,0 +1,123 @@
<?php
namespace App\Pdf;
use App\Member\Member;
use App\Payment\Payment;
use Illuminate\Support\Collection;
class RememberType extends Repository implements PdfRepository
{
public string $filename;
public Collection $pages;
public function __construct(Collection $pages)
{
$this->pages = $pages;
}
public function getPayments(Member $member): Collection
{
return $member->payments()->whereNeedsRemember()->get();
}
public function linkLabel(): string
{
return 'Erinnerung erstellen';
}
public function getSubject(): string
{
return 'Zahlungserinnerung';
}
public function setFilename(string $filename): self
{
$this->filename = $filename;
return $this;
}
public function getFilename(): string
{
return $this->filename;
}
public function getView(): string
{
return 'tex.remember';
}
public function getTemplate(): string
{
return 'default';
}
public function getPositions(Collection $page): array
{
$memberIds = $page->pluck('id')->toArray();
$payments = Payment::whereIn('member_id', $memberIds)
->orderByRaw('nr, member_id')->whereNeedsRemember()->get();
return $payments->mapWithKeys(function (Payment $payment) {
$key = "Beitrag {$payment->nr} für {$payment->member->firstname} {$payment->member->lastname} ({$payment->subscription->name})";
return [$key => $this->number($payment->subscription->amount)];
})->toArray();
}
public function getFamilyName(Collection $page): string
{
return $page->first()->lastname;
}
public function getAddress(Collection $page): string
{
return $page->first()->address;
}
public function getZip(Collection $page): string
{
return $page->first()->zip;
}
public function getEmail(Collection $page): string
{
return $page->first()->email_parents ?: $page->first()->email;
}
public function getLocation(Collection $page): string
{
return $page->first()->location;
}
public function getUsage(Collection $page): string
{
return "Mitgliedsbeitrag für {$this->getFamilyName($page)}";
}
public function allLabel(): string
{
return 'Erinnerungen versenden';
}
/**
* Get Descriptions for sendpayment page
*
* @return array<int, string>
*/
public function getDescription(): array
{
return [
'Diese Funktion erstellt Erinnerungs-PDFs mit allen versendeten aber noch nich bezahlten Rechnungen bei den Mitgliedern die Post als Versandweg haben.',
'Das zuletzt erinnerte Datum wird auf heute gesetzt.',
];
}
public function afterSingle(Payment $payment): void
{
$payment->update(['last_remembered_at' => now()]);
}
}

View File

@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePaymentsLastRememberedAtColumn extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('payments', function (Blueprint $table) {
$table->datetime('last_remembered_at')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('payments', function (Blueprint $table) {
$table->dropColumn('last_remembered_at');
});
}
}

2
remember.aux Normal file
View File

@ -0,0 +1,2 @@
\relax
\providecommand*\new@tpo@label[2]{}

249
remember.log Normal file
View File

@ -0,0 +1,249 @@
This is pdfTeX, Version 3.14159265-2.6-1.40.21 (TeX Live 2020) (preloaded format=pdflatex 2020.9.29) 29 OCT 2021 21:37
entering extended mode
restricted \write18 enabled.
%&-line parsing enabled.
**resources/views/tex/remember.tex
(./resources/views/tex/remember.tex
LaTeX2e <2020-02-02> patch level 5
L3 programming layer <2020-09-24>
(/home/pille/.local/lib/texlive/texmf-dist/tex/latex/koma-script/scrlttr2.cls
Document Class: scrlttr2 2020/09/21 v3.32 KOMA-Script document class (letter)
(/home/pille/.local/lib/texlive/texmf-dist/tex/latex/koma-script/scrkbase.sty
Package: scrkbase 2020/09/21 v3.32 KOMA-Script package (KOMA-Script-dependent b
asics and keyval usage)
(/home/pille/.local/lib/texlive/texmf-dist/tex/latex/koma-script/scrbase.sty
Package: scrbase 2020/09/21 v3.32 KOMA-Script package (KOMA-Script-independent
basics and keyval usage)
(/home/pille/.local/lib/texlive/texmf-dist/tex/latex/koma-script/scrlfile.sty
Package: scrlfile 2020/09/21 v3.32 KOMA-Script package (file load hooks)
(/home/pille/.local/lib/texlive/texmf-dist/tex/latex/koma-script/scrlfile-patch
oldlatex.sty
Package: scrlfile-patcholdlatex 2020/09/21 v3.32 KOMA-Script package (patching
old LaTeX kernels)
(/home/pille/.local/lib/texlive/texmf-dist/tex/latex/koma-script/scrlogo.sty
Package: scrlogo 2020/09/21 v3.32 KOMA-Script package (logo)
))
(/home/pille/.local/lib/texlive/texmf-dist/tex/latex/l3packages/xparse/xparse.s
ty (/home/pille/.local/lib/texlive/texmf-dist/tex/latex/l3kernel/expl3.sty
Package: expl3 2020-09-24 L3 programming layer (loader)
(/home/pille/.local/lib/texlive/texmf-dist/tex/latex/l3backend/l3backend-pdftex
.def
File: l3backend-pdftex.def 2020-09-24 L3 backend support: PDF output (pdfTeX)
\l__kernel_color_stack_int=\count168
\l__pdf_internal_box=\box45
))
Package: xparse 2020-05-15 L3 Experimental document command parser
(/home/pille/.local/lib/texlive/texmf-dist/tex/latex/l3packages/xparse/xparse-g
eneric.tex
\l__xparse_current_arg_int=\count169
\g__xparse_grabber_int=\count170
\l__xparse_m_args_int=\count171
\l__xparse_v_nesting_int=\count172
)))
(/home/pille/.local/lib/texlive/texmf-dist/tex/latex/graphics/keyval.sty
Package: keyval 2014/10/28 v1.15 key=value parser (DPC)
\KV@toks@=\toks15
)))
Package scrlttr2 Info: You've used standard option `12pt'.
(scrlttr2) This is correct!
(scrlttr2) Internally I'm using `fontsize=12pt'.
(scrlttr2) If you'd like to set the option with \KOMAoptions,
(scrlttr2) you'd have to use `fontsize=12pt' there
(scrlttr2) instead of `12pt', too.
Class scrlttr2 Info: File `scrsize12pt.clo' used to setup font sizes on input l
ine 1898.
(/home/pille/.local/lib/texlive/texmf-dist/tex/latex/koma-script/scrsize12pt.cl
o
File: scrsize12pt.clo 2020/09/21 v3.32 KOMA-Script font size class option (12pt
)
)
(/home/pille/.local/lib/texlive/texmf-dist/tex/latex/koma-script/typearea.sty
Package: typearea 2020/09/21 v3.32 KOMA-Script package (type area)
\ta@bcor=\skip47
\ta@div=\count173
\ta@hblk=\skip48
\ta@vblk=\skip49
\ta@temp=\skip50
\footheight=\skip51
Package typearea Info: These are the values describing the layout:
(typearea) DIV = 12
(typearea) BCOR = 0.0pt
(typearea) \paperwidth = 597.50793pt
(typearea) \textwidth = 448.13095pt
(typearea) DIV departure = -6%
(typearea) \evensidemargin = 2.4185pt
(typearea) \oddsidemargin = 2.4185pt
(typearea) \paperheight = 845.04694pt
(typearea) \textheight = 635.5pt
(typearea) \topmargin = -41.72441pt
(typearea) \headheight = 18.125pt
(typearea) \headsep = 21.75pt
(typearea) \topskip = 12.0pt
(typearea) \footskip = 50.75pt
(typearea) \baselineskip = 14.5pt
(typearea) on input line 1740.
)
\c@letter=\count174
)
Class scrlttr2 Info: Letter-Class-Option `DIN' loaded on input line 2.
(/home/pille/.local/lib/texlive/texmf-dist/tex/latex/koma-script/DIN.lco
File: DIN.lco 2020/09/21 v3.32 KOMA-Script letter-class-option
)
LaTeX Warning: Unused global option(s):
[silvaletter].
(./remember.aux)
\openout1 = `remember.aux'.
LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 5.
LaTeX Font Info: ... okay on input line 5.
LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 5.
LaTeX Font Info: ... okay on input line 5.
LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 5.
LaTeX Font Info: ... okay on input line 5.
LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 5.
LaTeX Font Info: ... okay on input line 5.
LaTeX Font Info: Checking defaults for TS1/cmr/m/n on input line 5.
LaTeX Font Info: ... okay on input line 5.
LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 5.
LaTeX Font Info: ... okay on input line 5.
LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 5.
LaTeX Font Info: ... okay on input line 5.
Package scrbase Info: activating english \yourrefname on input line 5.
Package scrbase Info: activating english \yourmailname on input line 5.
Package scrbase Info: activating english \myrefname on input line 5.
Package scrbase Info: activating english \customername on input line 5.
Package scrbase Info: activating english \invoicename on input line 5.
Package scrbase Info: activating english \subjectname on input line 5.
Package scrbase Info: activating english \ccname on input line 5.
Package scrbase Info: activating english \enclname on input line 5.
Package scrbase Info: activating english \headtoname on input line 5.
Package scrbase Info: activating english \headfromname on input line 5.
Package scrbase Info: activating english \datename on input line 5.
Package scrbase Info: activating english \pagename on input line 5.
Package scrbase Info: activating english \phonename on input line 5.
Package scrbase Info: activating english \mobilephonename on input line 5.
Package scrbase Info: activating english \faxname on input line 5.
Package scrbase Info: activating english \emailname on input line 5.
Package scrbase Info: activating english \wwwname on input line 5.
Package scrbase Info: activating english \bankname on input line 5.
Class scrlttr2 Info: no date found for language `american'
(scrlttr2) --> skipped on input line 5.
Class scrlttr2 Info: no date found for language `australian'
(scrlttr2) --> skipped on input line 5.
Class scrlttr2 Info: no date found for language `british'
(scrlttr2) --> skipped on input line 5.
Class scrlttr2 Info: no date found for language `canadian'
(scrlttr2) --> skipped on input line 5.
Class scrlttr2 Info: no date found for language `newzealand'
(scrlttr2) --> skipped on input line 5.
Class scrlttr2 Info: no date found for language `UKenglish'
(scrlttr2) --> skipped on input line 5.
Class scrlttr2 Info: no date found for language `ukenglish'
(scrlttr2) --> skipped on input line 5.
Class scrlttr2 Info: no date found for language `USenglish'
(scrlttr2) --> skipped on input line 5.
Class scrlttr2 Info: no date found for language `usenglish'
(scrlttr2) --> skipped on input line 5.
Class scrlttr2 Info: no date found for language `german'
(scrlttr2) --> skipped on input line 5.
Class scrlttr2 Info: no date found for language `ngerman'
(scrlttr2) --> skipped on input line 5.
Class scrlttr2 Info: no date found for language `austrian'
(scrlttr2) --> skipped on input line 5.
Class scrlttr2 Info: no date found for language `naustrian'
(scrlttr2) --> skipped on input line 5.
Class scrlttr2 Info: no date found for language `swissgerman'
(scrlttr2) --> skipped on input line 5.
Class scrlttr2 Info: no date found for language `nswissgerman'
(scrlttr2) --> skipped on input line 5.
Class scrlttr2 Info: no date found for language `acadian'
(scrlttr2) --> skipped on input line 5.
Class scrlttr2 Info: no date found for language `canadien'
(scrlttr2) --> skipped on input line 5.
Class scrlttr2 Info: no date found for language `francais'
(scrlttr2) --> skipped on input line 5.
Class scrlttr2 Info: no date found for language `french'
(scrlttr2) --> skipped on input line 5.
Class scrlttr2 Info: no date found for language `italian'
(scrlttr2) --> skipped on input line 5.
Class scrlttr2 Info: no date found for language `spanish'
(scrlttr2) --> skipped on input line 5.
Class scrlttr2 Info: no date found for language `croatian'
(scrlttr2) --> skipped on input line 5.
Class scrlttr2 Info: no date found for language `dutch'
(scrlttr2) --> skipped on input line 5.
Class scrlttr2 Info: no date found for language `finnish'
(scrlttr2) --> skipped on input line 5.
Class scrlttr2 Info: no date found for language `norsk'
(scrlttr2) --> skipped on input line 5.
Class scrlttr2 Info: no date found for language `swedish'
(scrlttr2) --> skipped on input line 5.
Class scrlttr2 Info: no date found for language `polish'
(scrlttr2) --> skipped on input line 5.
Class scrlttr2 Info: no date found for language `czech'
(scrlttr2) --> skipped on input line 5.
Class scrlttr2 Info: no date found for language `slovak'
(scrlttr2) --> skipped on input line 5.
Class scrlttr2 Info: trying to activate captions and date
(scrlttr2) of language `english' on input line 5.
Class scrlttr2 Info: used language is `english'.
(scrlttr2) Supported languages are: `english', `UKenglish',
(scrlttr2) `ukenglish', `british', `american', `USenglish',
(scrlttr2) `usenglish', `australian`,`canadian', `newzealand',
(scrlttr2) `german', `ngerman', `austrian', `naustrian',
(scrlttr2) `swissgerman', `nswissgermsn',
(scrlttr2) `acadian', `canadien', `francais', `french',
(scrlttr2) `dutch', `italian', `spanish', `polish',
(scrlttr2) `croatian', `finnish', `norsk', `swedish',
(scrlttr2) `czech', `slovak' on input line 5.
LaTeX Font Info: External font `cmex10' loaded for size
(Font) <12> on input line 6.
LaTeX Font Info: External font `cmex10' loaded for size
(Font) <8> on input line 6.
LaTeX Font Info: External font `cmex10' loaded for size
(Font) <6> on input line 6.
[1
{/home/pille/.local/lib/texlive/texmf-var/fonts/map/pdftex/updmap/pdftex.map}]
Foldmarks: yes
Head of first page
Foot of first page
Address (backaddress, addressee)
Location field: empty
Title: no
Subject: before opening
! Missing $ inserted.
<inserted text>
$
l.10 ...ilie <<< $data->getFamilyName($page) >>>,}
? X
Here is how much of TeX's memory you used:
2210 strings out of 480875
44496 string characters out of 5904128
350442 words of memory out of 5000000
17872 multiletter control sequences out of 15000+600000
538738 words of font info for 41 fonts, out of 8000000 for 9000
1141 hyphenation exceptions out of 8191
68i,9n,64p,350b,289s stack positions out of 5000i,500n,10000p,200000b,80000s
</home/pille/.local/lib/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmmi1
2.pfb></home/pille/.local/lib/texlive/texmf-dist/fonts/type1/public/amsfonts/cm
/cmr12.pfb></home/pille/.local/lib/texlive/texmf-dist/fonts/type1/public/amsfon
ts/cm/cmsy10.pfb>
Output written on remember.pdf (1 page, 27611 bytes).
PDF statistics:
20 PDF objects out of 1000 (max. 8388607)
13 compressed objects within 1 object stream
0 named destinations out of 1000 (max. 500000)
1 words of extra memory for PDF output out of 10000 (max. 10000000)

BIN
remember.pdf Normal file

Binary file not shown.

View File

@ -1,8 +1,9 @@
<template>
<div class="p-6">
<p class="text-white">Diese Funktion erstellt ein PDF mit allen noch nicht versendenden Rechnungen bei den Mitgliedern die Post als Versandweg haben.</p>
<p class="text-white">Die Rechnungen werden automatisch auf "Rechnung gestellt" aktualisiert.</p>
<a :href="link.href" target="_BLANK" v-for="link in links" class="btn btn-primary mt-3 inline-block" v-text="link.label"></a>
<div class="grid grid-cols-2">
<div class="p-6" v-for="type in types">
<p class="text-white" v-for="paragraph in type.text" v-text="paragraph"></p>
<a :href="type.link.href" target="_BLANK" class="btn btn-primary mt-3 inline-block" v-text="type.link.label"></a>
</div>
</div>
</template>
@ -15,7 +16,7 @@ export default {
},
props: {
links: {}
types: {}
},
methods: {

View File

@ -0,0 +1,41 @@
\documentclass[silvaletter,12pt]{scrlttr2}
\setkomavar{subject}{<<< $data->getSubject() >>>}
\begin{document}
@foreach($data->pages as $page)
\begin{letter}{Familie <<< $data->getFamilyName($page) >>>\\<<< $data->getAddress($page) >>>\\<<< $data->getZip($page) >>> <<< $data->getLocation($page) >>>}
\sffamily
\gdef\TotalHT{0}
\opening{Liebe Familie <<< $data->getFamilyName($page) >>>,}
Ihr Mitgliedbeitrag ist noch ausstehend. Dieser setzt sich wie folgt zusammen:
\begin{center}
\begin{tabular}{@{}p{0.5\textwidth}|r}
@foreach($data->getPositions($page) as $desc => $price)
\product{<<< $desc >>>}{<<< $price >>>}
@endforeach
\hline
\textbf{Gesamt} & \textbf{\numprint[€]{\TotalHT}} \\
\end{tabular}
\end{center}
Somit bitten wir Sie, den ausstehenden Betrag von \totalttc bis zum \textbf{<<< $data->getUntil()->format('d.m.Y') >>>} auf folgendes Konto zu überweisen:
\begin{tabular}{ll}
Kontoinhaber: & DPSG Stamm Silva \\
IBAN: & DE40 3425 0000 0000 2145 51 \\
Bic: & SOLSDE33XXX \\
Verwendungszweck: & <<<$data->getUsage($page)>>>
\end{tabular}
Bitte nehmen Sie zur Kenntnis, dass der für jedes Mitglied obligatorische Versicherungsschutz über die DPSG nur dann für Ihr Kind / Ihre Kinder gilt, wenn der Mitgliedsbeitrag bezahlt wurde. Wenn dies nicht geschieht, müssen wir Ihr Kind / Ihre Kinder von allen Pfadfinderaktionen ausschließen. Dazu gehören sowohl die Gruppenstunden sowie Tagesaktionen als auch mehrtägige Lager.
Bei Fragen zur Rechnung können Sie mich auch persönlich erreichen.
\closing{Viele Grüße \\ Der Stammesvorstand}
\end{letter}
@endforeach
\end{document}