Compare commits
	
		
			3 Commits
		
	
	
		
			f150abd1ca
			...
			978cc48385
		
	
	| Author | SHA1 | Date | 
|---|---|---|
|  | 978cc48385 | |
|  | 668555aff5 | |
|  | 2bc576d3f6 | 
|  | @ -0,0 +1,38 @@ | ||||||
|  | <?php | ||||||
|  | 
 | ||||||
|  | namespace App\Contribution\Actions; | ||||||
|  | 
 | ||||||
|  | use App\Contribution\Documents\ContributionDocument; | ||||||
|  | use Lorisleiva\Actions\ActionRequest; | ||||||
|  | use Lorisleiva\Actions\Concerns\AsAction; | ||||||
|  | use Zoomyboy\Tex\BaseCompiler; | ||||||
|  | use Zoomyboy\Tex\Tex; | ||||||
|  | 
 | ||||||
|  | class GenerateApiAction | ||||||
|  | { | ||||||
|  |     use AsAction; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * @param class-string<ContributionDocument> $document | ||||||
|  |      * @param array<string, mixed>               $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<string, mixed> | ||||||
|  |      */ | ||||||
|  |     public function rules(): array | ||||||
|  |     { | ||||||
|  |         return []; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,74 @@ | ||||||
|  | <?php | ||||||
|  | 
 | ||||||
|  | namespace App\Contribution\Data; | ||||||
|  | 
 | ||||||
|  | use App\Gender; | ||||||
|  | use App\Member\Member; | ||||||
|  | use Carbon\Carbon; | ||||||
|  | use Illuminate\Support\Collection; | ||||||
|  | use Spatie\LaravelData\Data; | ||||||
|  | 
 | ||||||
|  | class MemberData extends Data | ||||||
|  | { | ||||||
|  |     public function __construct( | ||||||
|  |         public string $firstname, | ||||||
|  |         public string $lastname, | ||||||
|  |         public string $address, | ||||||
|  |         public string $zip, | ||||||
|  |         public string $location, | ||||||
|  |         public Carbon $birthday, | ||||||
|  |         public ?Gender $gender, | ||||||
|  |         public bool $isLeader | ||||||
|  |     ) { | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * @param array<int, int> $ids | ||||||
|  |      * | ||||||
|  |      * @return Collection<int, static> | ||||||
|  |      */ | ||||||
|  |     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<int, ContributionMemberData> $data | ||||||
|  |      * | ||||||
|  |      * @return Collection<int, static> | ||||||
|  |      */ | ||||||
|  |     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()) ?: ''; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -9,10 +9,15 @@ abstract class ContributionDocument extends Document | ||||||
|     abstract public static function getName(): string; |     abstract public static function getName(): string; | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * @param array<string, mixed> $request |      * @param ContributionRequestArray $request | ||||||
|      */ |      */ | ||||||
|     abstract public static function fromRequest(array $request): self; |     abstract public static function fromRequest(array $request): self; | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * @param ContributionApiRequestArray $request | ||||||
|  |      */ | ||||||
|  |     abstract public static function fromApiRequest(array $request): self; | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * @return array<string, mixed> |      * @return array<string, mixed> | ||||||
|      */ |      */ | ||||||
|  |  | ||||||
|  | @ -2,8 +2,8 @@ | ||||||
| 
 | 
 | ||||||
| namespace App\Contribution\Documents; | namespace App\Contribution\Documents; | ||||||
| 
 | 
 | ||||||
|  | use App\Contribution\Data\MemberData; | ||||||
| use App\Country; | use App\Country; | ||||||
| use App\Member\Member; |  | ||||||
| use Carbon\Carbon; | use Carbon\Carbon; | ||||||
| use Illuminate\Support\Collection; | use Illuminate\Support\Collection; | ||||||
| use Zoomyboy\Tex\Engine; | use Zoomyboy\Tex\Engine; | ||||||
|  | @ -12,7 +12,7 @@ use Zoomyboy\Tex\Template; | ||||||
| class DvDocument extends ContributionDocument | class DvDocument extends ContributionDocument | ||||||
| { | { | ||||||
|     /** |     /** | ||||||
|      * @param Collection<int, Collection<int, Member>> $members |      * @param Collection<int, Collection<int, MemberData>> $members | ||||||
|      */ |      */ | ||||||
|     public function __construct( |     public function __construct( | ||||||
|         public string $dateFrom, |         public string $dateFrom, | ||||||
|  | @ -33,7 +33,7 @@ class DvDocument extends ContributionDocument | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * @param array<string, string|int> $request |      * {@inheritdoc} | ||||||
|      */ |      */ | ||||||
|     public static function fromRequest(array $request): self |     public static function fromRequest(array $request): self | ||||||
|     { |     { | ||||||
|  | @ -42,7 +42,21 @@ class DvDocument extends ContributionDocument | ||||||
|             dateUntil: $request['dateUntil'], |             dateUntil: $request['dateUntil'], | ||||||
|             zipLocation: $request['zipLocation'], |             zipLocation: $request['zipLocation'], | ||||||
|             country: Country::where('id', $request['country'])->firstOrFail(), |             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; |         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) { |         if (!$member->gender) { | ||||||
|             return ''; |             return ''; | ||||||
|  | @ -75,9 +89,9 @@ class DvDocument extends ContributionDocument | ||||||
|         return strtolower(substr($member->gender->name, 0, 1)); |         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 |     public function basename(): string | ||||||
|  |  | ||||||
|  | @ -2,6 +2,7 @@ | ||||||
| 
 | 
 | ||||||
| namespace App\Contribution\Documents; | namespace App\Contribution\Documents; | ||||||
| 
 | 
 | ||||||
|  | use App\Contribution\Data\MemberData; | ||||||
| use App\Country; | use App\Country; | ||||||
| use App\Member\Member; | use App\Member\Member; | ||||||
| use Carbon\Carbon; | use Carbon\Carbon; | ||||||
|  | @ -38,11 +39,29 @@ class RemscheidDocument extends ContributionDocument | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * @param array<string, string|int> $request |      * {@inheritdoc} | ||||||
|      */ |      */ | ||||||
|     public static function fromRequest(array $request): self |     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( |         return new self( | ||||||
|             dateFrom: $request['dateFrom'], |             dateFrom: $request['dateFrom'], | ||||||
|  |  | ||||||
|  | @ -2,7 +2,7 @@ | ||||||
| 
 | 
 | ||||||
| namespace App\Contribution\Documents; | namespace App\Contribution\Documents; | ||||||
| 
 | 
 | ||||||
| use App\Member\Member; | use App\Contribution\Data\MemberData; | ||||||
| use Carbon\Carbon; | use Carbon\Carbon; | ||||||
| use Illuminate\Support\Collection; | use Illuminate\Support\Collection; | ||||||
| use Illuminate\Support\Str; | use Illuminate\Support\Str; | ||||||
|  | @ -12,20 +12,20 @@ use Zoomyboy\Tex\Template; | ||||||
| class SolingenDocument extends ContributionDocument | class SolingenDocument extends ContributionDocument | ||||||
| { | { | ||||||
|     /** |     /** | ||||||
|      * @param array<int, int> $members |      * @param Collection<int, MemberData> $members | ||||||
|      */ |      */ | ||||||
|     final private function __construct( |     final private function __construct( | ||||||
|         public string $dateFrom, |         public string $dateFrom, | ||||||
|         public string $dateUntil, |         public string $dateUntil, | ||||||
|         public string $zipLocation, |         public string $zipLocation, | ||||||
|         public array $members, |         public Collection $members, | ||||||
|         public string $eventName, |         public string $eventName, | ||||||
|         public string $type = 'F', |         public string $type = 'F', | ||||||
|     ) { |     ) { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * @param array<string, mixed|int> $request |      * {@inheritdoc} | ||||||
|      */ |      */ | ||||||
|     public static function fromRequest(array $request): static |     public static function fromRequest(array $request): static | ||||||
|     { |     { | ||||||
|  | @ -33,17 +33,31 @@ class SolingenDocument extends ContributionDocument | ||||||
|             dateFrom: $request['dateFrom'], |             dateFrom: $request['dateFrom'], | ||||||
|             dateUntil: $request['dateUntil'], |             dateUntil: $request['dateUntil'], | ||||||
|             zipLocation: $request['zipLocation'], |             zipLocation: $request['zipLocation'], | ||||||
|             members: $request['members'], |             members: MemberData::fromModels($request['members']), | ||||||
|             eventName: $request['eventName'], |             eventName: $request['eventName'], | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * @return Collection<int, Collection<int, Member>> |      * {@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<int, Collection<int, MemberData>> | ||||||
|      */ |      */ | ||||||
|     public function memberModels(): 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 |     public function niceEventFrom(): string | ||||||
|  |  | ||||||
|  | @ -21,4 +21,9 @@ class Gender extends Model | ||||||
|             default => '' |             default => '' | ||||||
|         }; |         }; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     public static function fromString(string $title): self | ||||||
|  |     { | ||||||
|  |         return self::firstWhere('name', $title); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -3,6 +3,7 @@ | ||||||
| namespace App\Http; | namespace App\Http; | ||||||
| 
 | 
 | ||||||
| use Illuminate\Foundation\Http\Kernel as HttpKernel; | use Illuminate\Foundation\Http\Kernel as HttpKernel; | ||||||
|  | use Laravel\Passport\Http\Middleware\CheckClientCredentials; | ||||||
| 
 | 
 | ||||||
| class Kernel extends HttpKernel | class Kernel extends HttpKernel | ||||||
| { | { | ||||||
|  | @ -64,5 +65,6 @@ class Kernel extends HttpKernel | ||||||
|         'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class, |         'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class, | ||||||
|         'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, |         'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, | ||||||
|         'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, |         'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, | ||||||
|  |         'client' => CheckClientCredentials::class, | ||||||
|     ]; |     ]; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -3,6 +3,7 @@ | ||||||
| namespace App\Providers; | namespace App\Providers; | ||||||
| 
 | 
 | ||||||
| use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; | use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; | ||||||
|  | use Laravel\Passport\Passport; | ||||||
| 
 | 
 | ||||||
| class AuthServiceProvider extends ServiceProvider | class AuthServiceProvider extends ServiceProvider | ||||||
| { | { | ||||||
|  | @ -23,5 +24,11 @@ class AuthServiceProvider extends ServiceProvider | ||||||
|     public function boot() |     public function boot() | ||||||
|     { |     { | ||||||
|         $this->registerPolicies(); |         $this->registerPolicies(); | ||||||
|  |         Passport::tokensExpireIn(now()->addYears(999)); | ||||||
|  |         Passport::refreshTokensExpireIn(now()->addYears(999)); | ||||||
|  |         Passport::personalAccessTokensExpireIn(now()->addYears(999)); | ||||||
|  |         Passport::tokensCan([ | ||||||
|  |             'contribution-generate' => 'Create Contribution PDFs', | ||||||
|  |         ]); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -54,5 +54,8 @@ class RouteServiceProvider extends ServiceProvider | ||||||
|     { |     { | ||||||
|         Route::middleware('web') |         Route::middleware('web') | ||||||
|             ->group(base_path('routes/web.php')); |             ->group(base_path('routes/web.php')); | ||||||
|  |         Route::middleware('api') | ||||||
|  |             ->prefix('api') | ||||||
|  |             ->group(base_path('routes/api.php')); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -32,6 +32,7 @@ | ||||||
|         "inertiajs/inertia-laravel": "^0.2.5", |         "inertiajs/inertia-laravel": "^0.2.5", | ||||||
|         "laravel/framework": "^9.0", |         "laravel/framework": "^9.0", | ||||||
|         "laravel/horizon": "^5.0", |         "laravel/horizon": "^5.0", | ||||||
|  |         "laravel/passport": "^11.8", | ||||||
|         "laravel/scout": "^9.8", |         "laravel/scout": "^9.8", | ||||||
|         "laravel/telescope": "^4.13", |         "laravel/telescope": "^4.13", | ||||||
|         "laravel/tinker": "^2.0", |         "laravel/tinker": "^2.0", | ||||||
|  |  | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -3,7 +3,6 @@ | ||||||
| use App\User; | use App\User; | ||||||
| 
 | 
 | ||||||
| return [ | return [ | ||||||
| 
 |  | ||||||
|     /* |     /* | ||||||
|     |-------------------------------------------------------------------------- |     |-------------------------------------------------------------------------- | ||||||
|     | Authentication Defaults |     | Authentication Defaults | ||||||
|  | @ -40,11 +39,11 @@ return [ | ||||||
|     'guards' => [ |     'guards' => [ | ||||||
|         'web' => [ |         'web' => [ | ||||||
|             'driver' => 'session', |             'driver' => 'session', | ||||||
|             'provider' => 'database', |             'provider' => 'users', | ||||||
|         ], |         ], | ||||||
| 
 | 
 | ||||||
|         'api' => [ |         'api' => [ | ||||||
|             'driver' => 'token', |             'driver' => 'passport', | ||||||
|             'provider' => 'users', |             'provider' => 'users', | ||||||
|             'hash' => false, |             'hash' => false, | ||||||
|         ], |         ], | ||||||
|  | @ -68,7 +67,7 @@ return [ | ||||||
|     */ |     */ | ||||||
| 
 | 
 | ||||||
|     'providers' => [ |     'providers' => [ | ||||||
|         'database' => [ |         'users' => [ | ||||||
|             'driver' => 'eloquent', |             'driver' => 'eloquent', | ||||||
|             'model' => User::class, |             'model' => User::class, | ||||||
|         ], |         ], | ||||||
|  | @ -110,5 +109,4 @@ return [ | ||||||
|     */ |     */ | ||||||
| 
 | 
 | ||||||
|     'password_timeout' => 10800, |     'password_timeout' => 10800, | ||||||
| 
 |  | ||||||
| ]; | ]; | ||||||
|  |  | ||||||
|  | @ -14,6 +14,11 @@ parameters: | ||||||
|     # The level 8 is the highest level |     # The level 8 is the highest level | ||||||
|     level: 6 |     level: 6 | ||||||
| 
 | 
 | ||||||
|  |     typeAliases: | ||||||
|  |         ContributionMemberData: 'array<string, mixed>' | ||||||
|  |         ContributionRequestArray: 'array{dateFrom: string, dateUntil: string, zipLocation: string, country: int, eventName: string, members: array<int, int>}' | ||||||
|  |         ContributionApiRequestArray: 'array{dateFrom: string, dateUntil: string, zipLocation: string, country: int, eventName: string, member_data: array<int, ContributionMemberData>}' | ||||||
|  | 
 | ||||||
|     ignoreErrors: |     ignoreErrors: | ||||||
|         - |         - | ||||||
|             message: "#^Method App\\\\Activity\\:\\:sluggable\\(\\) return type has no value type specified in iterable type array\\.$#" |             message: "#^Method App\\\\Activity\\:\\:sluggable\\(\\) return type has no value type specified in iterable type array\\.$#" | ||||||
|  |  | ||||||
|  | @ -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=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 ($(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=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')>>>}; |             \node[anchor=base, text width=19mm, align=center] at ($(191.2mm, 61.3mm + 5.91mm * <<<$i % 20>>>)$) {<<<$member->birthday->format('d.m.Y')>>>}; | ||||||
|         @endforeach |         @endforeach | ||||||
|     \end{tikzpicture} |     \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=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 ($(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=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')>>>}; |             \node[anchor=base, text width=19mm, align=center] at ($(190.2mm, 78.3mm + 5.91mm * <<<$i % 6>>>)$) {<<<$member->birthday->format('d.m.Y')>>>}; | ||||||
|         @endforeach |         @endforeach | ||||||
|     \end{tikzpicture} |     \end{tikzpicture} | ||||||
|  |  | ||||||
|  | @ -108,7 +108,7 @@ | ||||||
|     \matrix (table) at ($(datefrom.south west) + (0,-2.3cm)$) [table,below right] { |     \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} \\ |         \uline{Lfd. Nr.} & \uline{Name / Vorname}  & \uline{Straße} & \uline{PLZ} & \uline{Wohnort} & \uline{Geburtsjahr} & \uline{Unterschrift} \\ | ||||||
|         @foreach($chunk as $i => $member) |         @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 |         @endforeach | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,5 @@ | ||||||
|  | <?php | ||||||
|  | 
 | ||||||
|  | use App\Contribution\Actions\GenerateApiAction as ContributionGenerateApiAction; | ||||||
|  | 
 | ||||||
|  | Route::post('/contribution-generate', ContributionGenerateApiAction::class)->name('api.contribution.generate')->middleware('client:contribution-generate'); | ||||||
|  | @ -6,9 +6,13 @@ use App\Contribution\Documents\ContributionDocument; | ||||||
| use App\Contribution\Documents\DvDocument; | use App\Contribution\Documents\DvDocument; | ||||||
| use App\Contribution\Documents\SolingenDocument; | use App\Contribution\Documents\SolingenDocument; | ||||||
| use App\Country; | use App\Country; | ||||||
|  | use App\Gender; | ||||||
| use App\Member\Member; | use App\Member\Member; | ||||||
| use Generator; | use Generator; | ||||||
| use Illuminate\Foundation\Testing\DatabaseTransactions; | use Illuminate\Foundation\Testing\DatabaseTransactions; | ||||||
|  | use Laravel\Passport\Client; | ||||||
|  | use Laravel\Passport\Passport; | ||||||
|  | use Tests\RequestFactories\ContributionMemberApiRequestFactory; | ||||||
| use Tests\RequestFactories\ContributionRequestFactory; | use Tests\RequestFactories\ContributionRequestFactory; | ||||||
| use Tests\TestCase; | use Tests\TestCase; | ||||||
| use Zoomyboy\Tex\Tex; | use Zoomyboy\Tex\Tex; | ||||||
|  | @ -24,14 +28,14 @@ class StoreTest extends TestCase | ||||||
|      * |      * | ||||||
|      * @param array<int, string> $bodyChecks |      * @param array<int, string> $bodyChecks | ||||||
|      */ |      */ | ||||||
|     public function testItCompilesContributionDocuments(string $type, array $bodyChecks): void |     public function testItCompilesContributionDocumentsViaRequest(string $type, array $bodyChecks): void | ||||||
|     { |     { | ||||||
|         $this->withoutExceptionHandling(); |         $this->withoutExceptionHandling(); | ||||||
|         Tex::spy(); |         Tex::spy(); | ||||||
|         $this->login()->loginNami(); |         $this->login()->loginNami(); | ||||||
|         $country = Country::factory()->create(); |         $country = Country::factory()->create(); | ||||||
|         $member1 = Member::factory()->defaults()->create(['address' => 'Maxstr 44', 'zip' => '42719', 'firstname' => 'Max', 'lastname' => 'Muster']); |         $member1 = Member::factory()->defaults()->for(Gender::factory())->create(['address' => 'Maxstr 44', 'zip' => '42719', 'firstname' => 'Max', 'lastname' => 'Muster']); | ||||||
|         $member2 = Member::factory()->defaults()->create(['address' => 'Maxstr 44', 'zip' => '42719', 'firstname' => 'Jane', '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', [ |         $response = $this->call('GET', '/contribution-generate', [ | ||||||
|             'payload' => base64_encode(json_encode([ |             'payload' => base64_encode(json_encode([ | ||||||
|  | @ -50,6 +54,35 @@ class StoreTest extends TestCase | ||||||
|         Tex::assertCompiled($type, fn ($document) => $document->hasAllContent($bodyChecks)); |         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 [""] |      * @testWith [""] | ||||||
|      *           ["aaaa"] |      *           ["aaaa"] | ||||||
|  |  | ||||||
|  | @ -0,0 +1,22 @@ | ||||||
|  | <?php | ||||||
|  | 
 | ||||||
|  | namespace Tests\RequestFactories; | ||||||
|  | 
 | ||||||
|  | use Worksome\RequestFactories\RequestFactory; | ||||||
|  | 
 | ||||||
|  | class ContributionMemberApiRequestFactory extends RequestFactory | ||||||
|  | { | ||||||
|  |     public function definition(): array | ||||||
|  |     { | ||||||
|  |         return [ | ||||||
|  |             'firstname' => $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(), | ||||||
|  |         ]; | ||||||
|  |     } | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue