Refactor DocumentFactory
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
This commit is contained in:
parent
3a93d1585f
commit
94b405bcf9
|
@ -4,6 +4,7 @@ namespace App\Letter\Actions;
|
||||||
|
|
||||||
use App\Letter\BillKind;
|
use App\Letter\BillKind;
|
||||||
use App\Letter\DocumentFactory;
|
use App\Letter\DocumentFactory;
|
||||||
|
use App\Letter\Queries\BillKindQuery;
|
||||||
use App\Payment\PaymentMail;
|
use App\Payment\PaymentMail;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
@ -32,8 +33,8 @@ class LetterSendAction
|
||||||
*/
|
*/
|
||||||
public function handle(): int
|
public function handle(): int
|
||||||
{
|
{
|
||||||
foreach (app(DocumentFactory::class)->types as $type) {
|
foreach (app(DocumentFactory::class)->getTypes() as $type) {
|
||||||
$letters = app(DocumentFactory::class)->letterCollection($type, BillKind::EMAIL);
|
$letters = app(DocumentFactory::class)->letterCollection($type, new BillKindQuery(BillKind::EMAIL));
|
||||||
|
|
||||||
foreach ($letters as $letter) {
|
foreach ($letters as $letter) {
|
||||||
$letterPath = Storage::path(Tex::compile($letter)->storeIn('/tmp', 'local'));
|
$letterPath = Storage::path(Tex::compile($letter)->storeIn('/tmp', 'local'));
|
||||||
|
|
|
@ -22,24 +22,11 @@ class BillDocument extends Letter
|
||||||
return 'tex.bill';
|
return 'tex.bill';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function sendAllLabel(): string
|
public static function sendAllLabel(): string
|
||||||
{
|
{
|
||||||
return 'Rechnungen versenden';
|
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
|
public function afterSingle(Payment $payment): void
|
||||||
{
|
{
|
||||||
$payment->update(['status_id' => 2]);
|
$payment->update(['status_id' => 2]);
|
||||||
|
@ -59,4 +46,17 @@ class BillDocument extends Letter
|
||||||
{
|
{
|
||||||
return $query->whereNeedsBill();
|
return $query->whereNeedsBill();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Descriptions for sendpayment page.
|
||||||
|
*
|
||||||
|
* @return array<int, string>
|
||||||
|
*/
|
||||||
|
public static 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.',
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,72 +2,39 @@
|
||||||
|
|
||||||
namespace App\Letter;
|
namespace App\Letter;
|
||||||
|
|
||||||
use App\Letter\Queries\BillKindQuery;
|
use App\Letter\Queries\LetterMemberQuery;
|
||||||
use App\Letter\Queries\SingleMemberQuery;
|
|
||||||
use App\Member\Member;
|
|
||||||
use Illuminate\Database\Eloquent\Collection as EloquentCollection;
|
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\Str;
|
|
||||||
|
|
||||||
class DocumentFactory
|
class DocumentFactory
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var array<int, class-string<Letter>>
|
* @var array<int, class-string<Letter>>
|
||||||
*/
|
*/
|
||||||
public array $types = [
|
private array $types = [
|
||||||
BillDocument::class,
|
BillDocument::class,
|
||||||
RememberDocument::class,
|
RememberDocument::class,
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Collection<int, Letter>
|
* @return Collection<int, class-string<Letter>>
|
||||||
*/
|
*/
|
||||||
public function getTypes(): Collection
|
public function getTypes(): Collection
|
||||||
{
|
{
|
||||||
/** @var array<int, Member> */
|
return collect($this->types);
|
||||||
$emptyMembers = [];
|
|
||||||
|
|
||||||
return collect(array_map(fn ($classString) => new $classString(collect($emptyMembers)), $this->types));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param class-string<Letter> $type
|
* @param class-string<Letter> $type
|
||||||
*/
|
*/
|
||||||
public function fromSingleRequest(string $type, Member $member): ?Letter
|
public function singleLetter(string $type, LetterMemberQuery $query): ?Letter
|
||||||
{
|
{
|
||||||
$members = $this->singleMemberPages($member, $type);
|
$pages = $query->getPages($type);
|
||||||
|
|
||||||
if ($members->isEmpty()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return tap(
|
|
||||||
$this->resolve($type, $members),
|
|
||||||
fn ($repo) => $repo->setFilename(Str::slug("{$repo->getSubject()} für {$members->first()->singleName}"))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param class-string<Letter> $type
|
|
||||||
*/
|
|
||||||
public function forAll(string $type, BillKind $billKind): ?Letter
|
|
||||||
{
|
|
||||||
$pages = $this->allMemberPages($type, $billKind);
|
|
||||||
|
|
||||||
if ($pages->isEmpty()) {
|
if ($pages->isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return tap($this->resolve($type, $pages), fn ($repo) => $repo->setFilename('alle-rechnungen'));
|
return $this->resolve($type, $pages);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param class-string<Letter> $type
|
|
||||||
*/
|
|
||||||
public function afterAll(string $type, BillKind $billKind): void
|
|
||||||
{
|
|
||||||
$letter = $this->forAll($type, $billKind);
|
|
||||||
$this->afterSingle($letter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -75,11 +42,11 @@ class DocumentFactory
|
||||||
*
|
*
|
||||||
* @return Collection<int, Letter>
|
* @return Collection<int, Letter>
|
||||||
*/
|
*/
|
||||||
public function letterCollection(string $type, BillKind $billKind): Collection
|
public function letterCollection(string $type, LetterMemberQuery $query): Collection
|
||||||
{
|
{
|
||||||
$pages = $this->allMemberPages($type, $billKind);
|
return $query
|
||||||
|
->getPages($type)
|
||||||
return $pages->map(fn ($page) => $this->resolve($type, collect([$page])));
|
->map(fn ($page) => $this->resolve($type, collect([$page])));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function afterSingle(Letter $letter): void
|
public function afterSingle(Letter $letter): void
|
||||||
|
@ -89,26 +56,6 @@ class DocumentFactory
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param class-string<Letter> $type
|
|
||||||
*
|
|
||||||
* @return Collection<int, Page>
|
|
||||||
*/
|
|
||||||
private function singleMemberPages(Member $member, string $type): Collection
|
|
||||||
{
|
|
||||||
return (new SingleMemberQuery($member))->getPages($type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param class-string<Letter> $type
|
|
||||||
*
|
|
||||||
* @return Collection<int, Page>
|
|
||||||
*/
|
|
||||||
private function allMemberPages(string $type, BillKind $billKind): Collection
|
|
||||||
{
|
|
||||||
return (new BillKindQuery($billKind))->getPages($type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param class-string<Letter> $type
|
* @param class-string<Letter> $type
|
||||||
* @param Collection<int, Page> $pages
|
* @param Collection<int, Page> $pages
|
||||||
|
@ -117,18 +64,4 @@ class DocumentFactory
|
||||||
{
|
{
|
||||||
return new $type($pages);
|
return new $type($pages);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param EloquentCollection<Member> $members
|
|
||||||
*
|
|
||||||
* @return Collection<int, Page>
|
|
||||||
*/
|
|
||||||
private function toPages(EloquentCollection $members): Collection
|
|
||||||
{
|
|
||||||
return $members->groupBy(
|
|
||||||
fn ($member) => Str::slug(
|
|
||||||
"{$member->lastname}{$member->address}{$member->zip}{$member->location}",
|
|
||||||
),
|
|
||||||
)->map(fn ($page) => new Page($page));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ abstract class Letter extends Document
|
||||||
|
|
||||||
abstract public function linkLabel(): string;
|
abstract public function linkLabel(): string;
|
||||||
|
|
||||||
abstract public function sendAllLabel(): string;
|
abstract public static function sendAllLabel(): string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param HasMany<Payment> $query
|
* @param HasMany<Payment> $query
|
||||||
|
@ -33,7 +33,7 @@ abstract class Letter extends Document
|
||||||
/**
|
/**
|
||||||
* @return array<int, string>
|
* @return array<int, string>
|
||||||
*/
|
*/
|
||||||
abstract public function getDescription(): array;
|
abstract public static function getDescription(): array;
|
||||||
|
|
||||||
abstract public function afterSingle(Payment $payment): void;
|
abstract public function afterSingle(Payment $payment): void;
|
||||||
|
|
||||||
|
|
|
@ -71,24 +71,6 @@ class RememberDocument extends Letter
|
||||||
return $page->first()->location;
|
return $page->first()->location;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function sendAllLabel(): 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
|
public function afterSingle(Payment $payment): void
|
||||||
{
|
{
|
||||||
$payment->update(['last_remembered_at' => now()]);
|
$payment->update(['last_remembered_at' => now()]);
|
||||||
|
@ -108,4 +90,22 @@ class RememberDocument extends Letter
|
||||||
{
|
{
|
||||||
return $query->whereNeedsRemember();
|
return $query->whereNeedsRemember();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Descriptions for sendpayment page.
|
||||||
|
*
|
||||||
|
* @return array<int, string>
|
||||||
|
*/
|
||||||
|
public static 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 static function sendAllLabel(): string
|
||||||
|
{
|
||||||
|
return 'Erinnerungen versenden';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,20 +3,19 @@
|
||||||
namespace App\Payment;
|
namespace App\Payment;
|
||||||
|
|
||||||
use App\Letter\DocumentFactory;
|
use App\Letter\DocumentFactory;
|
||||||
use App\Letter\Letter;
|
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
class ActionFactory
|
class ActionFactory
|
||||||
{
|
{
|
||||||
public function allLinks(): Collection
|
public function allLinks(): Collection
|
||||||
{
|
{
|
||||||
return app(DocumentFactory::class)->getTypes()->map(function (Letter $repo) {
|
return app(DocumentFactory::class)->getTypes()->map(function ($repo) {
|
||||||
return [
|
return [
|
||||||
'link' => [
|
'link' => [
|
||||||
'href' => route('sendpayment.pdf', ['type' => get_class($repo)]),
|
'href' => route('sendpayment.pdf', ['type' => $repo]),
|
||||||
'label' => $repo->sendAllLabel(),
|
'label' => $repo::sendAllLabel(),
|
||||||
],
|
],
|
||||||
'text' => $repo->getDescription(),
|
'text' => $repo::getDescription(),
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ namespace App\Payment;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Letter\BillKind;
|
use App\Letter\BillKind;
|
||||||
use App\Letter\DocumentFactory;
|
use App\Letter\DocumentFactory;
|
||||||
|
use App\Letter\Queries\BillKindQuery;
|
||||||
use Illuminate\Contracts\Support\Responsable;
|
use Illuminate\Contracts\Support\Responsable;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
|
@ -29,14 +30,14 @@ class SendpaymentController extends Controller
|
||||||
*/
|
*/
|
||||||
public function send(Request $request)
|
public function send(Request $request)
|
||||||
{
|
{
|
||||||
$repo = app(DocumentFactory::class)->forAll($request->type, BillKind::POST);
|
$letter = app(DocumentFactory::class)->singleLetter($request->type, new BillKindQuery(BillKind::POST));
|
||||||
|
|
||||||
if (is_null($repo)) {
|
if (is_null($letter)) {
|
||||||
return response()->noContent();
|
return response()->noContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
$pdfFile = Tex::compile($repo);
|
$pdfFile = Tex::compile($letter);
|
||||||
app(DocumentFactory::class)->afterAll($request->type, BillKind::POST);
|
app(DocumentFactory::class)->afterSingle($letter);
|
||||||
|
|
||||||
return $pdfFile;
|
return $pdfFile;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ namespace App\Pdf;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Letter\DocumentFactory;
|
use App\Letter\DocumentFactory;
|
||||||
|
use App\Letter\Queries\SingleMemberQuery;
|
||||||
use App\Member\Member;
|
use App\Member\Member;
|
||||||
use Illuminate\Contracts\Support\Responsable;
|
use Illuminate\Contracts\Support\Responsable;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
@ -17,10 +18,10 @@ class MemberPdfController extends Controller
|
||||||
*/
|
*/
|
||||||
public function __invoke(Request $request, Member $member)
|
public function __invoke(Request $request, Member $member)
|
||||||
{
|
{
|
||||||
$document = app(DocumentFactory::class)->fromSingleRequest($request->type, $member);
|
$letter = app(DocumentFactory::class)->singleLetter($request->type, new SingleMemberQuery($member));
|
||||||
|
|
||||||
return null === $document
|
return null === $letter
|
||||||
? response()->noContent()
|
? response()->noContent()
|
||||||
: Tex::compile($document);
|
: Tex::compile($letter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@ namespace Tests\Feature\Letter;
|
||||||
use App\Letter\BillDocument;
|
use App\Letter\BillDocument;
|
||||||
use App\Letter\DocumentFactory;
|
use App\Letter\DocumentFactory;
|
||||||
use App\Letter\LetterSettings;
|
use App\Letter\LetterSettings;
|
||||||
|
use App\Letter\Queries\LetterMemberQuery;
|
||||||
|
use App\Letter\Queries\SingleMemberQuery;
|
||||||
use App\Letter\RememberDocument;
|
use App\Letter\RememberDocument;
|
||||||
use App\Member\Member;
|
use App\Member\Member;
|
||||||
use App\Payment\Payment;
|
use App\Payment\Payment;
|
||||||
|
@ -23,7 +25,7 @@ class DocumentFactoryTest extends TestCase
|
||||||
public function testItDoesntReturnARepositoryWhenMemberDoesntHavePayments(): void
|
public function testItDoesntReturnARepositoryWhenMemberDoesntHavePayments(): void
|
||||||
{
|
{
|
||||||
$member = Member::factory()->defaults()->create();
|
$member = Member::factory()->defaults()->create();
|
||||||
$letter = app(DocumentFactory::class)->fromSingleRequest(BillDocument::class, $member);
|
$letter = app(DocumentFactory::class)->singleLetter(BillDocument::class, $this->query($member));
|
||||||
$this->assertNull($letter);
|
$this->assertNull($letter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +43,7 @@ class DocumentFactoryTest extends TestCase
|
||||||
->has(Payment::factory()->notPaid()->nr('1995')->subscription('::subName::', 1500))
|
->has(Payment::factory()->notPaid()->nr('1995')->subscription('::subName::', 1500))
|
||||||
->create();
|
->create();
|
||||||
|
|
||||||
$letter = app(DocumentFactory::class)->fromSingleRequest(BillDocument::class, $member);
|
$letter = app(DocumentFactory::class)->singleLetter(BillDocument::class, $this->query($member));
|
||||||
|
|
||||||
$letter->assertHasAllContent([
|
$letter->assertHasAllContent([
|
||||||
'Rechnung',
|
'Rechnung',
|
||||||
|
@ -60,7 +62,7 @@ class DocumentFactoryTest extends TestCase
|
||||||
->has(Payment::factory()->notPaid()->nr('1995')->subscription('::subName::', 1500))
|
->has(Payment::factory()->notPaid()->nr('1995')->subscription('::subName::', 1500))
|
||||||
->create();
|
->create();
|
||||||
|
|
||||||
$letter = app(DocumentFactory::class)->fromSingleRequest(BillDocument::class, $member);
|
$letter = app(DocumentFactory::class)->singleLetter(BillDocument::class, $this->query($member));
|
||||||
|
|
||||||
$this->assertEquals('rechnung-fur-lastname.pdf', $letter->compiledFilename());
|
$this->assertEquals('rechnung-fur-lastname.pdf', $letter->compiledFilename());
|
||||||
}
|
}
|
||||||
|
@ -73,7 +75,7 @@ class DocumentFactoryTest extends TestCase
|
||||||
->has(Payment::factory()->notPaid())
|
->has(Payment::factory()->notPaid())
|
||||||
->create();
|
->create();
|
||||||
|
|
||||||
$letter = app(DocumentFactory::class)->fromSingleRequest(RememberDocument::class, $member);
|
$letter = app(DocumentFactory::class)->singleLetter(RememberDocument::class, $this->query($member));
|
||||||
|
|
||||||
$this->assertEquals('zahlungserinnerung-fur-lastname.pdf', $letter->compiledFilename());
|
$this->assertEquals('zahlungserinnerung-fur-lastname.pdf', $letter->compiledFilename());
|
||||||
}
|
}
|
||||||
|
@ -91,7 +93,7 @@ class DocumentFactoryTest extends TestCase
|
||||||
->has(Payment::factory()->notPaid()->nr('nr2'))
|
->has(Payment::factory()->notPaid()->nr('nr2'))
|
||||||
->create();
|
->create();
|
||||||
|
|
||||||
$letter = app(DocumentFactory::class)->fromSingleRequest(BillDocument::class, $firstMember);
|
$letter = app(DocumentFactory::class)->singleLetter(BillDocument::class, $this->query($firstMember));
|
||||||
|
|
||||||
$letter->assertHasAllContent(['Max1', 'Max2', 'nr1', 'nr2']);
|
$letter->assertHasAllContent(['Max1', 'Max2', 'nr1', 'nr2']);
|
||||||
}
|
}
|
||||||
|
@ -119,7 +121,7 @@ class DocumentFactoryTest extends TestCase
|
||||||
->has(Payment::factory()->notPaid()->nr('nr2'))
|
->has(Payment::factory()->notPaid()->nr('nr2'))
|
||||||
->create();
|
->create();
|
||||||
|
|
||||||
$letter = app(DocumentFactory::class)->fromSingleRequest($type, $member);
|
$letter = app(DocumentFactory::class)->singleLetter($type, $this->query($member));
|
||||||
|
|
||||||
$letter->assertHasAllContent([
|
$letter->assertHasAllContent([
|
||||||
'langer Stammesname',
|
'langer Stammesname',
|
||||||
|
@ -152,4 +154,9 @@ class DocumentFactoryTest extends TestCase
|
||||||
$this->assertEquals('application/pdf', $response->headers->get('content-type'));
|
$this->assertEquals('application/pdf', $response->headers->get('content-type'));
|
||||||
$this->assertEquals('inline; filename="rechnung-fur-lastname.pdf"', $response->headers->get('content-disposition'));
|
$this->assertEquals('inline; filename="rechnung-fur-lastname.pdf"', $response->headers->get('content-disposition'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function query(Member $member): LetterMemberQuery
|
||||||
|
{
|
||||||
|
return new SingleMemberQuery($member);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue