From 978cc483851b775a535b7d20ed72da245ce5d9a0 Mon Sep 17 00:00:00 2001 From: philipp lang Date: Wed, 17 May 2023 00:22:43 +0200 Subject: [PATCH] Add api for contribution documents --- .../Actions/GenerateApiAction.php | 38 ++++ app/Contribution/Data/MemberData.php | 74 +++++++ .../Documents/ContributionDocument.php | 7 +- app/Contribution/Documents/DvDocument.php | 40 ++-- .../Documents/RemscheidDocument.php | 23 +- .../Documents/SolingenDocument.php | 28 ++- app/Gender.php | 5 + app/Providers/AuthServiceProvider.php | 7 + app/Providers/RouteServiceProvider.php | 3 + composer.lock | 206 +++++++----------- packages/laravel-nami | 2 +- phpstan.neon | 5 + resources/views/tex/zuschuss-remscheid.tex | 4 +- resources/views/tex/zuschuss-stadt.tex | 2 +- routes/api.php | 5 + tests/Feature/Contribution/StoreTest.php | 39 +++- .../ContributionMemberApiRequestFactory.php | 22 ++ 17 files changed, 349 insertions(+), 161 deletions(-) create mode 100644 app/Contribution/Actions/GenerateApiAction.php create mode 100644 app/Contribution/Data/MemberData.php create mode 100644 routes/api.php create mode 100644 tests/RequestFactories/ContributionMemberApiRequestFactory.php diff --git a/app/Contribution/Actions/GenerateApiAction.php b/app/Contribution/Actions/GenerateApiAction.php new file mode 100644 index 00000000..fc8de068 --- /dev/null +++ b/app/Contribution/Actions/GenerateApiAction.php @@ -0,0 +1,38 @@ + $document + * @param array $payload + */ + public function handle(string $document, array $payload): BaseCompiler + { + return Tex::compile($document::fromApiRequest($payload)); + } + + public function asController(ActionRequest $request): BaseCompiler + { + ValidateAction::validateType($request->input('type')); + + return $this->handle($request->input('type'), $request->input()); + } + + /** + * @return array + */ + public function rules(): array + { + return []; + } +} diff --git a/app/Contribution/Data/MemberData.php b/app/Contribution/Data/MemberData.php new file mode 100644 index 00000000..734ef66e --- /dev/null +++ b/app/Contribution/Data/MemberData.php @@ -0,0 +1,74 @@ + $ids + * + * @return Collection + */ + public static function fromModels(array $ids): Collection + { + return Member::whereIn('id', $ids)->orderByRaw('lastname, firstname')->get()->map(fn ($member) => self::withoutMagicalCreationFrom([ + ...$member->toArray(), + 'birthday' => $member->birthday->toAtomString(), + 'isLeader' => $member->isLeader(), + 'gender' => $member->gender, + ]))->toBase(); + } + + /** + * @param array $data + * + * @return Collection + */ + public static function fromApi(array $data): Collection + { + return collect($data)->map(fn ($member) => self::withoutMagicalCreationFrom([ + ...$member, + 'birthday' => Carbon::parse($member['birthday'])->toAtomString(), + 'gender' => Gender::fromString($member['gender']), + 'isLeader' => $member['is_leader'], + ])); + } + + public function fullname(): string + { + return $this->firstname.' '.$this->lastname; + } + + public function separatedName(): string + { + return $this->lastname.', '.$this->firstname; + } + + public function fullAddress(): string + { + return $this->address.', '.$this->zip.' '.$this->location; + } + + public function age(): string + { + return (string) $this->birthday->diffInYears(now()) ?: ''; + } +} diff --git a/app/Contribution/Documents/ContributionDocument.php b/app/Contribution/Documents/ContributionDocument.php index 0d84d840..21fd7e70 100644 --- a/app/Contribution/Documents/ContributionDocument.php +++ b/app/Contribution/Documents/ContributionDocument.php @@ -9,10 +9,15 @@ abstract class ContributionDocument extends Document abstract public static function getName(): string; /** - * @param array $request + * @param ContributionRequestArray $request */ abstract public static function fromRequest(array $request): self; + /** + * @param ContributionApiRequestArray $request + */ + abstract public static function fromApiRequest(array $request): self; + /** * @return array */ diff --git a/app/Contribution/Documents/DvDocument.php b/app/Contribution/Documents/DvDocument.php index 412233c8..ec0f4709 100644 --- a/app/Contribution/Documents/DvDocument.php +++ b/app/Contribution/Documents/DvDocument.php @@ -2,8 +2,8 @@ namespace App\Contribution\Documents; +use App\Contribution\Data\MemberData; use App\Country; -use App\Member\Member; use Carbon\Carbon; use Illuminate\Support\Collection; use Zoomyboy\Tex\Engine; @@ -12,7 +12,7 @@ use Zoomyboy\Tex\Template; class DvDocument extends ContributionDocument { /** - * @param Collection> $members + * @param Collection> $members */ public function __construct( public string $dateFrom, @@ -33,7 +33,7 @@ class DvDocument extends ContributionDocument } /** - * @param array $request + * {@inheritdoc} */ public static function fromRequest(array $request): self { @@ -42,7 +42,21 @@ class DvDocument extends ContributionDocument dateUntil: $request['dateUntil'], zipLocation: $request['zipLocation'], country: Country::where('id', $request['country'])->firstOrFail(), - members: Member::whereIn('id', $request['members'])->orderByRaw('lastname, firstname')->get()->toBase()->chunk(17), + members: MemberData::fromModels($request['members'])->chunk(17), + ); + } + + /** + * {@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), ); } @@ -51,22 +65,22 @@ class DvDocument extends ContributionDocument return $this->country->name; } - public function memberShort(Member $member): string + public function memberShort(MemberData $member): string { - return $member->isLeader() ? 'L' : ''; + return $member->isLeader ? 'L' : ''; } - public function memberName(Member $member): string + public function memberName(MemberData $member): string { - return $member->lastname.', '.$member->firstname; + return $member->separatedName(); } - public function memberAddress(Member $member): string + public function memberAddress(MemberData $member): string { - return $member->fullAddress; + return $member->fullAddress(); } - public function memberGender(Member $member): string + public function memberGender(MemberData $member): string { if (!$member->gender) { return ''; @@ -75,9 +89,9 @@ class DvDocument extends ContributionDocument return strtolower(substr($member->gender->name, 0, 1)); } - public function memberAge(Member $member): string + public function memberAge(MemberData $member): string { - return (string) $member->getAge(); + return $member->age(); } public function basename(): string diff --git a/app/Contribution/Documents/RemscheidDocument.php b/app/Contribution/Documents/RemscheidDocument.php index f0c2d280..1211c35b 100644 --- a/app/Contribution/Documents/RemscheidDocument.php +++ b/app/Contribution/Documents/RemscheidDocument.php @@ -2,6 +2,7 @@ namespace App\Contribution\Documents; +use App\Contribution\Data\MemberData; use App\Country; use App\Member\Member; use Carbon\Carbon; @@ -38,11 +39,29 @@ class RemscheidDocument extends ContributionDocument } /** - * @param array $request + * {@inheritdoc} */ public static function fromRequest(array $request): self { - [$leaders, $children] = Member::whereIn('id', $request['members'])->orderByRaw('lastname, firstname')->get()->partition(fn ($member) => $member->isLeader()); + [$leaders, $children] = MemberData::fromModels($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(), + leaders: $leaders->values()->toBase()->chunk(6), + children: $children->values()->toBase()->chunk(20), + ); + } + + /** + * {@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'], diff --git a/app/Contribution/Documents/SolingenDocument.php b/app/Contribution/Documents/SolingenDocument.php index 2a82ba00..fd478fc3 100644 --- a/app/Contribution/Documents/SolingenDocument.php +++ b/app/Contribution/Documents/SolingenDocument.php @@ -2,7 +2,7 @@ namespace App\Contribution\Documents; -use App\Member\Member; +use App\Contribution\Data\MemberData; use Carbon\Carbon; use Illuminate\Support\Collection; use Illuminate\Support\Str; @@ -12,20 +12,20 @@ use Zoomyboy\Tex\Template; class SolingenDocument extends ContributionDocument { /** - * @param array $members + * @param Collection $members */ final private function __construct( public string $dateFrom, public string $dateUntil, public string $zipLocation, - public array $members, + public Collection $members, public string $eventName, public string $type = 'F', ) { } /** - * @param array $request + * {@inheritdoc} */ public static function fromRequest(array $request): static { @@ -33,17 +33,31 @@ class SolingenDocument extends ContributionDocument dateFrom: $request['dateFrom'], dateUntil: $request['dateUntil'], zipLocation: $request['zipLocation'], - members: $request['members'], + members: MemberData::fromModels($request['members']), eventName: $request['eventName'], ); } /** - * @return Collection> + * {@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'], + ); + } + + /** + * @return Collection> */ public function memberModels(): Collection { - return Member::whereIn('id', $this->members)->orderByRaw('lastname, firstname')->get()->toBase()->chunk(14); + return $this->members->chunk(14); } public function niceEventFrom(): string diff --git a/app/Gender.php b/app/Gender.php index 5d8a9d86..54da643d 100644 --- a/app/Gender.php +++ b/app/Gender.php @@ -21,4 +21,9 @@ class Gender extends Model default => '' }; } + + public static function fromString(string $title): self + { + return self::firstWhere('name', $title); + } } diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php index 7971bf7c..d5a193fb 100644 --- a/app/Providers/AuthServiceProvider.php +++ b/app/Providers/AuthServiceProvider.php @@ -3,6 +3,7 @@ namespace App\Providers; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; +use Laravel\Passport\Passport; class AuthServiceProvider extends ServiceProvider { @@ -23,5 +24,11 @@ class AuthServiceProvider extends ServiceProvider public function boot() { $this->registerPolicies(); + Passport::tokensExpireIn(now()->addYears(999)); + Passport::refreshTokensExpireIn(now()->addYears(999)); + Passport::personalAccessTokensExpireIn(now()->addYears(999)); + Passport::tokensCan([ + 'contribution-generate' => 'Create Contribution PDFs', + ]); } } diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index ac05f5d6..05eb825c 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -54,5 +54,8 @@ class RouteServiceProvider extends ServiceProvider { Route::middleware('web') ->group(base_path('routes/web.php')); + Route::middleware('api') + ->prefix('api') + ->group(base_path('routes/api.php')); } } diff --git a/composer.lock b/composer.lock index 4c9f83d5..4d8cf5dc 100644 --- a/composer.lock +++ b/composer.lock @@ -4,11 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], -<<<<<<< HEAD - "content-hash": "197eb805e29cfeafb2f8611bb77d83f7", -======= - "content-hash": "d14aa35776e0ce92076f351f339308b5", ->>>>>>> d93f710 (Add passport package) + "content-hash": "5f8672056a6119e2d1ba2c60245e0b21", "packages": [ { "name": "beyondcode/laravel-dump-server", @@ -1196,25 +1192,25 @@ }, { "name": "firebase/php-jwt", - "version": "v6.4.0", + "version": "v6.5.0", "source": { "type": "git", "url": "https://github.com/firebase/php-jwt.git", - "reference": "4dd1e007f22a927ac77da5a3fbb067b42d3bc224" + "reference": "e94e7353302b0c11ec3cfff7180cd0b1743975d2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/firebase/php-jwt/zipball/4dd1e007f22a927ac77da5a3fbb067b42d3bc224", - "reference": "4dd1e007f22a927ac77da5a3fbb067b42d3bc224", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/e94e7353302b0c11ec3cfff7180cd0b1743975d2", + "reference": "e94e7353302b0c11ec3cfff7180cd0b1743975d2", "shasum": "" }, "require": { - "php": "^7.1||^8.0" + "php": "^7.4||^8.0" }, "require-dev": { "guzzlehttp/guzzle": "^6.5||^7.4", - "phpspec/prophecy-phpunit": "^1.1", - "phpunit/phpunit": "^7.5||^9.5", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.5", "psr/cache": "^1.0||^2.0", "psr/http-client": "^1.0", "psr/http-factory": "^1.0" @@ -1253,9 +1249,9 @@ ], "support": { "issues": "https://github.com/firebase/php-jwt/issues", - "source": "https://github.com/firebase/php-jwt/tree/v6.4.0" + "source": "https://github.com/firebase/php-jwt/tree/v6.5.0" }, - "time": "2023-02-09T21:01:23+00:00" + "time": "2023-05-12T15:47:07+00:00" }, { "name": "fruitcake/php-cors", @@ -4635,23 +4631,22 @@ }, { "name": "nyholm/psr7", - "version": "1.6.1", + "version": "1.8.0", "source": { "type": "git", "url": "https://github.com/Nyholm/psr7.git", - "reference": "e874c8c4286a1e010fb4f385f3a55ac56a05cc93" + "reference": "3cb4d163b58589e47b35103e8e5e6a6a475b47be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Nyholm/psr7/zipball/e874c8c4286a1e010fb4f385f3a55ac56a05cc93", - "reference": "e874c8c4286a1e010fb4f385f3a55ac56a05cc93", + "url": "https://api.github.com/repos/Nyholm/psr7/zipball/3cb4d163b58589e47b35103e8e5e6a6a475b47be", + "reference": "3cb4d163b58589e47b35103e8e5e6a6a475b47be", "shasum": "" }, "require": { - "php": ">=7.1", - "php-http/message-factory": "^1.0", + "php": ">=7.2", "psr/http-factory": "^1.0", - "psr/http-message": "^1.0" + "psr/http-message": "^1.1 || ^2.0" }, "provide": { "php-http/message-factory-implementation": "1.0", @@ -4660,14 +4655,15 @@ }, "require-dev": { "http-interop/http-factory-tests": "^0.9", + "php-http/message-factory": "^1.0", "php-http/psr7-integration-tests": "^1.0", - "phpunit/phpunit": "^7.5 || 8.5 || 9.4", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.4", "symfony/error-handler": "^4.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.6-dev" + "dev-master": "1.8-dev" } }, "autoload": { @@ -4697,7 +4693,7 @@ ], "support": { "issues": "https://github.com/Nyholm/psr7/issues", - "source": "https://github.com/Nyholm/psr7/tree/1.6.1" + "source": "https://github.com/Nyholm/psr7/tree/1.8.0" }, "funding": [ { @@ -4709,7 +4705,7 @@ "type": "github" } ], - "time": "2023-04-17T16:03:48+00:00" + "time": "2023-05-02T11:26:24+00:00" }, { "name": "paragonie/constant_time_encoding", @@ -4898,60 +4894,6 @@ }, "time": "2023-02-10T20:32:41+00:00" }, - { - "name": "php-http/message-factory", - "version": "1.1.0", - "source": { - "type": "git", - "url": "https://github.com/php-http/message-factory.git", - "reference": "4d8778e1c7d405cbb471574821c1ff5b68cc8f57" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-http/message-factory/zipball/4d8778e1c7d405cbb471574821c1ff5b68cc8f57", - "reference": "4d8778e1c7d405cbb471574821c1ff5b68cc8f57", - "shasum": "" - }, - "require": { - "php": ">=5.4", - "psr/http-message": "^1.0 || ^2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com" - } - ], - "description": "Factory interfaces for PSR-7 HTTP Message", - "homepage": "http://php-http.org", - "keywords": [ - "factory", - "http", - "message", - "stream", - "uri" - ], - "support": { - "issues": "https://github.com/php-http/message-factory/issues", - "source": "https://github.com/php-http/message-factory/tree/1.1.0" - }, - "time": "2023-04-14T14:16:17+00:00" - }, { "name": "phpdocumentor/reflection-common", "version": "2.2.0", @@ -5139,39 +5081,6 @@ "time": "2023-02-25T19:38:58+00:00" }, { -<<<<<<< HEAD - "name": "phpstan/phpdoc-parser", - "version": "1.20.4", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "7d568c87a9df9c5f7e8b5f075fc469aa8cb0a4cd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/7d568c87a9df9c5f7e8b5f075fc469aa8cb0a4cd", - "reference": "7d568c87a9df9c5f7e8b5f075fc469aa8cb0a4cd", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^1.5", - "phpstan/phpstan-phpunit": "^1.1", - "phpstan/phpstan-strict-rules": "^1.0", - "phpunit/phpunit": "^9.5", - "symfony/process": "^5.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "PHPStan\\PhpDocParser\\": [ - "src/" - ] -======= "name": "phpseclib/phpseclib", "version": "3.0.19", "source": { @@ -5207,21 +5116,12 @@ ], "psr-4": { "phpseclib3\\": "phpseclib/" ->>>>>>> d93f710 (Add passport package) } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], -<<<<<<< HEAD - "description": "PHPDoc parser with support for nullable, intersection and generic types", - "support": { - "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.20.4" - }, - "time": "2023-05-02T09:19:37+00:00" -======= "authors": [ { "name": "Jim Wigginton", @@ -5289,7 +5189,51 @@ } ], "time": "2023-03-05T17:13:09+00:00" ->>>>>>> d93f710 (Add passport package) + }, + { + "name": "phpstan/phpdoc-parser", + "version": "1.20.4", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "7d568c87a9df9c5f7e8b5f075fc469aa8cb0a4cd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/7d568c87a9df9c5f7e8b5f075fc469aa8cb0a4cd", + "reference": "7d568c87a9df9c5f7e8b5f075fc469aa8cb0a4cd", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.5", + "phpstan/phpstan-phpunit": "^1.1", + "phpstan/phpstan-strict-rules": "^1.0", + "phpunit/phpunit": "^9.5", + "symfony/process": "^5.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "support": { + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.20.4" + }, + "time": "2023-05-02T09:19:37+00:00" }, { "name": "psr/cache", @@ -5600,16 +5544,16 @@ }, { "name": "psr/http-message", - "version": "2.0", + "version": "1.1", "source": { "type": "git", "url": "https://github.com/php-fig/http-message.git", - "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", - "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba", "shasum": "" }, "require": { @@ -5618,7 +5562,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "1.1.x-dev" } }, "autoload": { @@ -5633,7 +5577,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "homepage": "http://www.php-fig.org/" } ], "description": "Common interface for HTTP messages", @@ -5647,9 +5591,9 @@ "response" ], "support": { - "source": "https://github.com/php-fig/http-message/tree/2.0" + "source": "https://github.com/php-fig/http-message/tree/1.1" }, - "time": "2023-04-04T09:54:51+00:00" + "time": "2023-04-04T09:50:52+00:00" }, { "name": "psr/log", @@ -10527,7 +10471,7 @@ "dist": { "type": "path", "url": "./packages/tex", - "reference": "48251272de62e3fea044a7ad31e1a411c15eb4c6" + "reference": "6f162102ef7ceca41822d18c3e694abd926f550b" }, "type": "library", "extra": { diff --git a/packages/laravel-nami b/packages/laravel-nami index a41b190c..33875d36 160000 --- a/packages/laravel-nami +++ b/packages/laravel-nami @@ -1 +1 @@ -Subproject commit a41b190cc2509ee940967b6c108a557b0a9c5def +Subproject commit 33875d36fa5bd6fab4147e95f4aa705092f42d93 diff --git a/phpstan.neon b/phpstan.neon index ef12ddb1..d7c61fce 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -14,6 +14,11 @@ parameters: # The level 8 is the highest level level: 6 + typeAliases: + ContributionMemberData: 'array' + ContributionRequestArray: 'array{dateFrom: string, dateUntil: string, zipLocation: string, country: int, eventName: string, members: array}' + ContributionApiRequestArray: 'array{dateFrom: string, dateUntil: string, zipLocation: string, country: int, eventName: string, member_data: array}' + ignoreErrors: - message: "#^Method App\\\\Activity\\:\\:sluggable\\(\\) return type has no value type specified in iterable type array\\.$#" diff --git a/resources/views/tex/zuschuss-remscheid.tex b/resources/views/tex/zuschuss-remscheid.tex index 345c7636..b5c19866 100644 --- a/resources/views/tex/zuschuss-remscheid.tex +++ b/resources/views/tex/zuschuss-remscheid.tex @@ -22,7 +22,7 @@ \node[anchor=base, text width=7.75mm, align=center] at ($(18.35mm, 61.3mm + 5.91mm * <<<$i % 20>>>)$) {<<<$i+1>>>}; \node[anchor=base, text width=29mm, align=center] at ($(43.7mm, 61.3mm + 5.91mm * <<<$i % 20>>>)$) {<<<$member->lastname>>>}; \node[anchor=base, text width=29mm, align=center] at ($(76.2mm, 61.3mm + 5.91mm * <<<$i % 20>>>)$) {<<<$member->firstname>>>}; - \node[anchor=base, text width=84mm, align=center] at ($(136.2mm, 61.3mm + 5.91mm * <<<$i % 20>>>)$) {<<<$member->fullAddress>>>}; + \node[anchor=base, text width=84mm, align=center] at ($(136.2mm, 61.3mm + 5.91mm * <<<$i % 20>>>)$) {<<<$member->fullAddress()>>>}; \node[anchor=base, text width=19mm, align=center] at ($(191.2mm, 61.3mm + 5.91mm * <<<$i % 20>>>)$) {<<<$member->birthday->format('d.m.Y')>>>}; @endforeach \end{tikzpicture} @@ -41,7 +41,7 @@ \node[anchor=base, text width=7.75mm, align=center] at ($(18.35mm, 78.3mm + 5.91mm * <<<$i % 6>>>)$) {<<<$i+1>>>}; \node[anchor=base, text width=29mm, align=center] at ($(43.7mm, 78.3mm + 5.91mm * <<<$i % 6>>>)$) {<<<$member->lastname>>>}; \node[anchor=base, text width=29mm, align=center] at ($(76.2mm, 78.3mm + 5.91mm * <<<$i % 6>>>)$) {<<<$member->firstname>>>}; - \node[anchor=base, text width=84mm, align=center] at ($(136.2mm, 78.3mm + 5.91mm * <<<$i % 6>>>)$) {<<<$member->fullAddress>>>}; + \node[anchor=base, text width=84mm, align=center] at ($(136.2mm, 78.3mm + 5.91mm * <<<$i % 6>>>)$) {<<<$member->fullAddress()>>>}; \node[anchor=base, text width=19mm, align=center] at ($(190.2mm, 78.3mm + 5.91mm * <<<$i % 6>>>)$) {<<<$member->birthday->format('d.m.Y')>>>}; @endforeach \end{tikzpicture} diff --git a/resources/views/tex/zuschuss-stadt.tex b/resources/views/tex/zuschuss-stadt.tex index 7b22a98d..c083c738 100644 --- a/resources/views/tex/zuschuss-stadt.tex +++ b/resources/views/tex/zuschuss-stadt.tex @@ -108,7 +108,7 @@ \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>>> & \\ + <<<$i+1>>> & <<<$member->fullname()>>> & <<<$member->address>>> & <<<$member->zip>>> & <<<$member->location>>> & <<<$member->birthday->year>>> & \\ @endforeach }; diff --git a/routes/api.php b/routes/api.php new file mode 100644 index 00000000..f061076a --- /dev/null +++ b/routes/api.php @@ -0,0 +1,5 @@ +name('api.contribution.generate')->middleware('client:contribution-generate'); diff --git a/tests/Feature/Contribution/StoreTest.php b/tests/Feature/Contribution/StoreTest.php index 77b1c2ba..e9bae489 100644 --- a/tests/Feature/Contribution/StoreTest.php +++ b/tests/Feature/Contribution/StoreTest.php @@ -6,9 +6,13 @@ use App\Contribution\Documents\ContributionDocument; use App\Contribution\Documents\DvDocument; use App\Contribution\Documents\SolingenDocument; use App\Country; +use App\Gender; use App\Member\Member; use Generator; use Illuminate\Foundation\Testing\DatabaseTransactions; +use Laravel\Passport\Client; +use Laravel\Passport\Passport; +use Tests\RequestFactories\ContributionMemberApiRequestFactory; use Tests\RequestFactories\ContributionRequestFactory; use Tests\TestCase; use Zoomyboy\Tex\Tex; @@ -24,14 +28,14 @@ class StoreTest extends TestCase * * @param array $bodyChecks */ - public function testItCompilesContributionDocuments(string $type, array $bodyChecks): void + public function testItCompilesContributionDocumentsViaRequest(string $type, array $bodyChecks): void { $this->withoutExceptionHandling(); Tex::spy(); $this->login()->loginNami(); $country = Country::factory()->create(); - $member1 = Member::factory()->defaults()->create(['address' => 'Maxstr 44', 'zip' => '42719', 'firstname' => 'Max', 'lastname' => 'Muster']); - $member2 = Member::factory()->defaults()->create(['address' => 'Maxstr 44', 'zip' => '42719', 'firstname' => 'Jane', 'lastname' => 'Muster']); + $member1 = Member::factory()->defaults()->for(Gender::factory())->create(['address' => 'Maxstr 44', 'zip' => '42719', 'firstname' => 'Max', 'lastname' => 'Muster']); + $member2 = Member::factory()->defaults()->for(Gender::factory())->create(['address' => 'Maxstr 44', 'zip' => '42719', 'firstname' => 'Jane', 'lastname' => 'Muster']); $response = $this->call('GET', '/contribution-generate', [ 'payload' => base64_encode(json_encode([ @@ -50,6 +54,35 @@ class StoreTest extends TestCase Tex::assertCompiled($type, fn ($document) => $document->hasAllContent($bodyChecks)); } + public function testItCompilesContributionDocumentsViaApi(): void + { + $this->withoutExceptionHandling(); + Tex::spy(); + Gender::factory()->create(['name' => 'Weiblich']); + Gender::factory()->create(['name' => 'Männlich']); + Passport::actingAsClient(Client::factory()->create(), ['contribution-generate']); + $country = Country::factory()->create(); + $member1 = Member::factory()->defaults()->create(['address' => 'Maxstr 44', 'zip' => '42719', 'firstname' => 'Max', 'lastname' => 'Muster']); + $member2 = Member::factory()->defaults()->create(['address' => 'Maxstr 44', 'zip' => '42719', 'firstname' => 'Jane', 'lastname' => 'Muster']); + + $response = $this->postJson('/api/contribution-generate', [ + 'country' => $country->id, + 'dateFrom' => '1991-06-15', + 'dateUntil' => '1991-06-16', + 'eventName' => 'Super tolles Lager', + 'type' => SolingenDocument::class, + 'zipLocation' => '42777 SG', + 'member_data' => [ + ContributionMemberApiRequestFactory::new()->create(), + ContributionMemberApiRequestFactory::new()->create(), + ], + ]); + + $response->assertSessionDoesntHaveErrors(); + $response->assertOk(); + Tex::assertCompiled(SolingenDocument::class, fn ($document) => $document->hasAllContent(['Super'])); + } + /** * @testWith [""] * ["aaaa"] diff --git a/tests/RequestFactories/ContributionMemberApiRequestFactory.php b/tests/RequestFactories/ContributionMemberApiRequestFactory.php new file mode 100644 index 00000000..ec6bd65b --- /dev/null +++ b/tests/RequestFactories/ContributionMemberApiRequestFactory.php @@ -0,0 +1,22 @@ + $this->faker->firstName(), + 'lastname' => $this->faker->lastName(), + 'address' => $this->faker->streetAddress(), + 'zip' => $this->faker->postcode, + 'location' => $this->faker->city(), + 'gender' => $this->faker->randomElement(['Männlich', 'Weiblich']), + 'birthday' => $this->faker->date(), + 'is_leader' => $this->faker->boolean(), + ]; + } +}