Add Contribution Request

This commit is contained in:
philipp lang 2025-06-18 17:01:28 +02:00
parent 392a34b5c7
commit d74fcab024
12 changed files with 223 additions and 191 deletions

View File

@ -2,11 +2,11 @@
namespace App\Contribution\Actions;
use App\Contribution\Contracts\HasContributionData;
use App\Contribution\ContributionFactory;
use App\Contribution\Documents\ContributionDocument;
use App\Contribution\Requests\GenerateRequest;
use App\Rules\JsonBase64Rule;
use Illuminate\Support\Facades\Validator;
use Lorisleiva\Actions\ActionRequest;
use Lorisleiva\Actions\Concerns\AsAction;
use Zoomyboy\Tex\BaseCompiler;
use Zoomyboy\Tex\Tex;
@ -15,23 +15,18 @@ class GenerateAction
{
use AsAction;
/**
* @param class-string<ContributionDocument> $document
* @param array<string, mixed> $payload
*/
public function handle(string $document, array $payload): BaseCompiler
public function handle(HasContributionData $request): BaseCompiler
{
return Tex::compile($document::fromRequest($payload));
return Tex::compile($request->type()::fromPayload($request));
}
public function asController(ActionRequest $request): BaseCompiler
public function asController(GenerateRequest $request): BaseCompiler
{
$payload = $this->payload($request);
$type = data_get($payload, 'type');
$type = $request->type();
ValidateAction::validateType($type);
Validator::make($payload, app(ContributionFactory::class)->rules($type))->validate();
Validator::make($request->payload(), app(ContributionFactory::class)->rules($type))->validate();
return $this->handle($type, $payload);
return $this->handle($request);
}
/**
@ -43,12 +38,4 @@ class GenerateAction
'payload' => [new JsonBase64Rule()],
];
}
/**
* @return array<string, string>
*/
private function payload(ActionRequest $request): array
{
return json_decode(rawurldecode(base64_decode($request->input('payload', ''))), true);
}
}

View File

@ -2,8 +2,8 @@
namespace App\Contribution\Actions;
use App\Contribution\Documents\ContributionDocument;
use Lorisleiva\Actions\ActionRequest;
use App\Contribution\Contracts\HasContributionData;
use App\Contribution\Requests\GenerateApiRequest;
use Lorisleiva\Actions\Concerns\AsAction;
use Zoomyboy\Tex\BaseCompiler;
use Zoomyboy\Tex\Tex;
@ -13,19 +13,19 @@ class GenerateApiAction
use AsAction;
/**
* @param class-string<ContributionDocument> $document
* @param array<string, mixed> $payload
* @todo merge this with GenerateAction
*/
public function handle(string $document, array $payload): BaseCompiler
public function handle(HasContributionData $request): BaseCompiler
{
return Tex::compile($document::fromApiRequest($payload));
return Tex::compile($request->type()::fromPayload($request));
}
public function asController(ActionRequest $request): BaseCompiler
public function asController(GenerateApiRequest $request): BaseCompiler
{
ValidateAction::validateType($request->input('type'));
$type = $request->type();
ValidateAction::validateType($type);
return $this->handle($request->input('type'), $request->input());
return $this->handle($request);
}
/**

View File

@ -0,0 +1,28 @@
<?php
namespace App\Contribution\Contracts;
use App\Contribution\Data\MemberData;
use Carbon\Carbon;
use App\Contribution\Documents\ContributionDocument;
use App\Country;
use Illuminate\Support\Collection;
interface HasContributionData {
public function dateFrom(): Carbon;
public function dateUntil(): Carbon;
public function zipLocation(): string;
public function eventName(): string;
/**
* @return class-string<ContributionDocument>
*/
public function type(): string;
/**
* @return Collection<int, MemberData>
*/
public function members(): Collection;
public function country(): ?Country;
}

View File

@ -2,6 +2,7 @@
namespace App\Contribution\Documents;
use App\Contribution\Contracts\HasContributionData;
use App\Contribution\Data\MemberData;
use App\Contribution\Traits\HasPdfBackground;
use App\Country;
@ -39,33 +40,15 @@ class BdkjHesse extends ContributionDocument
return Carbon::parse($this->dateUntil)->format('d.m.Y');
}
/**
* {@inheritdoc}
*/
public static function fromRequest(array $request): self
public static function fromPayload(HasContributionData $request): self
{
return new self(
dateFrom: $request['dateFrom'],
dateUntil: $request['dateUntil'],
zipLocation: $request['zipLocation'],
country: Country::where('id', $request['country'])->firstOrFail(),
members: MemberData::fromModels($request['members'])->chunk(20),
eventName: $request['eventName'],
);
}
/**
* {@inheritdoc}
*/
public static function fromApiRequest(array $request): self
{
return new self(
dateFrom: $request['dateFrom'],
dateUntil: $request['dateUntil'],
zipLocation: $request['zipLocation'],
country: Country::where('id', $request['country'])->firstOrFail(),
members: MemberData::fromApi($request['member_data'])->chunk(20),
eventName: $request['eventName'],
dateFrom: $request->dateFrom(),
dateUntil: $request->dateUntil(),
zipLocation: $request->zipLocation(),
country: $request->country(),
members: $request->members()->chunk(20),
eventName: $request->eventName(),
);
}

View File

@ -2,6 +2,7 @@
namespace App\Contribution\Documents;
use App\Contribution\Contracts\HasContributionData;
use App\Contribution\Data\MemberData;
use App\Contribution\Traits\FormatsDates;
use App\Contribution\Traits\HasPdfBackground;
@ -33,33 +34,15 @@ class CityFrankfurtMainDocument extends ContributionDocument
$this->fromName = app(InvoiceSettings::class)->from_long;
}
/**
* {@inheritdoc}
*/
public static function fromRequest(array $request): self
public static function fromPayload(HasContributionData $request): self
{
return new self(
dateFrom: $request['dateFrom'],
dateUntil: $request['dateUntil'],
zipLocation: $request['zipLocation'],
country: Country::where('id', $request['country'])->firstOrFail(),
members: MemberData::fromModels($request['members'])->chunk(15),
eventName: $request['eventName'],
);
}
/**
* {@inheritdoc}
*/
public static function fromApiRequest(array $request): self
{
return new self(
dateFrom: $request['dateFrom'],
dateUntil: $request['dateUntil'],
zipLocation: $request['zipLocation'],
country: Country::where('id', $request['country'])->firstOrFail(),
members: MemberData::fromApi($request['member_data'])->chunk(15),
eventName: $request['eventName'],
dateFrom: $request->dateFrom(),
dateUntil: $request->dateUntil(),
zipLocation: $request->zipLocation(),
country: $request->country(),
members: $request->members()->chunk(15),
eventName: $request->eventName(),
);
}

View File

@ -2,7 +2,7 @@
namespace App\Contribution\Documents;
use App\Contribution\Data\MemberData;
use App\Contribution\Contracts\HasContributionData;
use App\Contribution\Traits\FormatsDates;
use App\Contribution\Traits\HasPdfBackground;
use App\Country;
@ -32,40 +32,18 @@ class CityRemscheidDocument extends ContributionDocument
$this->setEventName($eventName);
}
/**
* {@inheritdoc}
*/
public static function fromRequest(array $request): self
public static function fromPayload(HasContributionData $request): self
{
[$leaders, $children] = MemberData::fromModels($request['members'])->partition(fn ($member) => $member->isLeader);
[$leaders, $children] = $request->members()->partition(fn ($member) => $member->isLeader);
return new self(
dateFrom: $request['dateFrom'],
dateUntil: $request['dateUntil'],
zipLocation: $request['zipLocation'],
country: Country::where('id', $request['country'])->firstOrFail(),
dateFrom: $request->dateFrom(),
dateUntil: $request->dateUntil(),
zipLocation: $request->zipLocation(),
country: $request->country(),
leaders: $leaders->values()->toBase()->chunk(6),
children: $children->values()->toBase()->chunk(20),
eventName: $request['eventName'],
);
}
/**
* {@inheritdoc}
*/
public static function fromApiRequest(array $request): self
{
$members = MemberData::fromApi($request['member_data']);
[$leaders, $children] = $members->partition(fn ($member) => $member->isLeader);
return new self(
dateFrom: $request['dateFrom'],
dateUntil: $request['dateUntil'],
zipLocation: $request['zipLocation'],
country: Country::where('id', $request['country'])->firstOrFail(),
leaders: $leaders->values()->toBase()->chunk(6),
children: $children->values()->toBase()->chunk(20),
eventName: $request['eventName'],
eventName: $request->eventName(),
);
}

View File

@ -2,6 +2,7 @@
namespace App\Contribution\Documents;
use App\Contribution\Contracts\HasContributionData;
use App\Contribution\Data\MemberData;
use App\Invoice\InvoiceSettings;
use Carbon\Carbon;
@ -30,28 +31,14 @@ class CitySolingenDocument extends ContributionDocument
/**
* {@inheritdoc}
*/
public static function fromRequest(array $request): static
public static function fromPayload(HasContributionData $request): static
{
return new static(
dateFrom: $request['dateFrom'],
dateUntil: $request['dateUntil'],
zipLocation: $request['zipLocation'],
members: MemberData::fromModels($request['members']),
eventName: $request['eventName'],
);
}
/**
* {@inheritdoc}
*/
public static function fromApiRequest(array $request): static
{
return new static(
dateFrom: $request['dateFrom'],
dateUntil: $request['dateUntil'],
zipLocation: $request['zipLocation'],
members: MemberData::fromApi($request['member_data']),
eventName: $request['eventName'],
dateFrom: $request->dateFrom(),
dateUntil: $request->dateUntil(),
zipLocation: $request->zipLocation(),
members: $request->members(),
eventName: $request->eventName(),
);
}
@ -75,8 +62,6 @@ class CitySolingenDocument extends ContributionDocument
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(' & ') . ' \\\\';

View File

@ -2,6 +2,7 @@
namespace App\Contribution\Documents;
use App\Contribution\Contracts\HasContributionData;
use Zoomyboy\Tex\Document;
use Zoomyboy\Tex\Template;
@ -11,15 +12,7 @@ abstract class ContributionDocument extends Document
abstract public static function getName(): string;
/**
* @param ContributionRequestArray $request
*/
abstract public static function fromRequest(array $request): self;
/**
* @param ContributionApiRequestArray $request
*/
abstract public static function fromApiRequest(array $request): self;
abstract public static function fromPayload(HasContributionData $request): self;
/**
* @return array<string, mixed>

View File

@ -2,6 +2,7 @@
namespace App\Contribution\Documents;
use App\Contribution\Contracts\HasContributionData;
use App\Contribution\Data\MemberData;
use App\Contribution\Traits\FormatsDates;
use App\Contribution\Traits\HasPdfBackground;
@ -29,33 +30,15 @@ class RdpNrwDocument extends ContributionDocument
$this->setEventName($eventName);
}
/**
* {@inheritdoc}
*/
public static function fromRequest(array $request): self
public static function fromPayload(HasContributionData $request): self
{
return new self(
dateFrom: $request['dateFrom'],
dateUntil: $request['dateUntil'],
zipLocation: $request['zipLocation'],
country: Country::where('id', $request['country'])->firstOrFail(),
members: MemberData::fromModels($request['members'])->chunk(17),
eventName: $request['eventName'],
);
}
/**
* {@inheritdoc}
*/
public static function fromApiRequest(array $request): self
{
return new self(
dateFrom: $request['dateFrom'],
dateUntil: $request['dateUntil'],
zipLocation: $request['zipLocation'],
country: Country::where('id', $request['country'])->firstOrFail(),
members: MemberData::fromApi($request['member_data'])->chunk(17),
eventName: $request['eventName'],
dateFrom: $request->dateFrom(),
dateUntil: $request->dateUntil(),
zipLocation: $request->zipLocation(),
country: $request->country(),
members: $request->members()->chunk(17),
eventName: $request->eventName(),
);
}

View File

@ -2,6 +2,7 @@
namespace App\Contribution\Documents;
use App\Contribution\Contracts\HasContributionData;
use App\Contribution\Data\MemberData;
use App\Contribution\Traits\FormatsDates;
use App\Contribution\Traits\HasPdfBackground;
@ -30,33 +31,15 @@ class WuppertalDocument extends ContributionDocument
$this->setEventName($eventName);
}
/**
* {@inheritdoc}
*/
public static function fromRequest(array $request): self
public static function fromPayload(HasContributionData $request): self
{
return new self(
dateFrom: $request['dateFrom'],
dateUntil: $request['dateUntil'],
zipLocation: $request['zipLocation'],
country: Country::where('id', $request['country'])->firstOrFail(),
members: MemberData::fromModels($request['members'])->chunk(14),
eventName: $request['eventName'],
);
}
/**
* {@inheritdoc}
*/
public static function fromApiRequest(array $request): self
{
return new self(
dateFrom: $request['dateFrom'],
dateUntil: $request['dateUntil'],
zipLocation: $request['zipLocation'],
country: Country::where('id', $request['country'])->firstOrFail(),
members: MemberData::fromApi($request['member_data'])->chunk(14),
eventName: $request['eventName'],
dateFrom: $request->dateFrom(),
dateUntil: $request->dateUntil(),
zipLocation: $request->zipLocation(),
country: $request->country(),
members: $request->members()->chunk(14),
eventName: $request->eventName(),
);
}

View File

@ -0,0 +1,67 @@
<?php
namespace App\Contribution\Requests;
use App\Contribution\Contracts\HasContributionData;
use App\Contribution\Data\MemberData;
use App\Contribution\Documents\ContributionDocument;
use App\Country;
use Lorisleiva\Actions\ActionRequest;
use Carbon\Carbon;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use RuntimeException;
class GenerateApiRequest extends ActionRequest implements HasContributionData {
/**
* @return array<string, string>
*/
public function payload(): array
{
return $this->input();
}
/**
* @return string|array<array-key, mixed>
*/
public function value(string $key): string|array
{
if (!Arr::has($this->payload(), $key)) {
throw new RuntimeException('Wert für '.$key.' nicht gefunden.');
}
return data_get($this->payload(), $key);
}
/**
* @return class-string<ContributionDocument>
*/
public function type(): string
{
return $this->value('type');
}
public function dateFrom(): Carbon {
return Carbon::parse($this->value('dateFrom'));
}
public function dateUntil(): Carbon {
return Carbon::parse($this->value('dateUntil'));
}
public function zipLocation(): string {
return $this->value('zipLocation');
}
public function eventName(): string {
return $this->value('eventName');
}
public function members(): Collection {
return MemberData::fromApi($this->value('member_data'));
}
public function country(): ?Country {
return Country::where('id', $this->value('country'))->first();
}
}

View File

@ -0,0 +1,62 @@
<?php
namespace App\Contribution\Requests;
use App\Contribution\Contracts\HasContributionData;
use App\Contribution\Data\MemberData;
use App\Contribution\Documents\ContributionDocument;
use App\Country;
use Lorisleiva\Actions\ActionRequest;
use Carbon\Carbon;
use Illuminate\Support\Collection;
class GenerateRequest extends ActionRequest implements HasContributionData {
/**
* @return array<string, string>
*/
public function payload(): array
{
return json_decode(rawurldecode(base64_decode($this->input('payload', ''))), true);
}
/**
* @return string|array<array-key, mixed>
*/
public function value(string $key): string|array
{
return data_get($this->payload(), $key);
}
/**
* @return class-string<ContributionDocument>
*/
public function type(): string
{
return $this->value('type');
}
public function dateFrom(): Carbon {
return Carbon::parse($this->value('dateFrom'));
}
public function dateUntil(): Carbon {
return Carbon::parse($this->value('dateUntil'));
}
public function zipLocation(): string {
return $this->value('zipLocation');
}
public function eventName(): string {
return $this->value('eventName');
}
public function members(): Collection {
return MemberData::fromModels($this->value('members'));
}
public function country(): ?Country {
return Country::where('id', $this->value('country'))->first();
}
}