Compare commits

...

24 Commits

Author SHA1 Message Date
philipp lang abf4158256 Fix phpstan
continuous-integration/drone/push Build is passing Details
2025-04-03 00:11:32 +02:00
philipp lang f2d59e4535 Update phpstan baseline 2025-04-03 00:11:32 +02:00
philipp lang a75b4a7808 Lint 2025-04-03 00:11:32 +02:00
philipp lang ecf3cc998c Update tex package 2025-04-03 00:11:32 +02:00
philipp lang 7202cd60f5 Add doctypes 2025-04-03 00:11:32 +02:00
philipp lang 9d5c71adcd Add Data Eloquent casting 2025-04-03 00:11:32 +02:00
philipp lang eb00d928fc Remove deprecated willReturnVar 2025-04-03 00:11:32 +02:00
philipp lang 6683990755 Lint 2025-04-03 00:11:32 +02:00
philipp lang 2a5f4832e1 Add configs for User Seeder 2025-04-03 00:11:32 +02:00
philipp lang 719b1920c9 Lint 2025-04-03 00:11:32 +02:00
philipp lang 3260202465 Update larastan 2025-04-03 00:11:32 +02:00
philipp lang 9b995641b6 Update laravel-nami 2025-04-03 00:11:32 +02:00
philipp lang 2d5921fe1d Mod copydb 2025-04-03 00:11:32 +02:00
philipp lang efa9eeccbe Update laravel-nami 2025-04-03 00:11:32 +02:00
philipp lang b33072ad20 Lint 2025-04-03 00:11:32 +02:00
philipp lang 2e77823c3a --wip-- [skip ci] 2025-04-03 00:11:32 +02:00
philipp lang 9a5d9ae30e Add Bank account to NAmi put action 2025-04-03 00:11:32 +02:00
philipp lang d607c8beac Add scout driver config to tests 2025-04-03 00:11:32 +02:00
philipp lang 1a86ea7ea5 Update laravel-nami 2025-04-03 00:11:32 +02:00
philipp lang a157f2b656 Update composer packages 2025-04-03 00:11:32 +02:00
philipp lang e3c7dad51e Update npm packages 2025-04-03 00:11:32 +02:00
philipp lang 749e3dcd7c Mod stammsilva server name
continuous-integration/drone/push Build is passing Details
2025-04-01 21:14:00 +02:00
philipp lang 4417008d22 Update CHANGELOG
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is failing Details
2025-04-01 20:49:50 +02:00
philipp lang b38591b87c Remove page limit when synching maildispatchers
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build was killed Details
2025-04-01 20:26:41 +02:00
46 changed files with 2825 additions and 3012 deletions

View File

@ -1,5 +1,9 @@
# Letzte Änderungen # Letzte Änderungen
### 1.12.7
- Fix: Synchronisation von allen Mitgliedern bei Mail-Verteilern - nicht nur den ersten 20
### 1.12.6 ### 1.12.6
- Fix: Beiträge von Familienmitgliedern splitten - Fix: Beiträge von Familienmitgliedern splitten

View File

@ -1,4 +1,4 @@
@servers(['docker' => ['stammsilva@zoomyboy.de', 'stammgallier@stamm-gallier.de', 'dpsg-lennep@zoomyboy.de', 'dpsgbergischland@zoomyboy.de', 'dpsg-koeln@dpsg-koeln.de']]) @servers(['docker' => ['stamm-silva@zoomyboy.de', 'stammgallier@stamm-gallier.de', 'dpsg-lennep@zoomyboy.de', 'dpsgbergischland@zoomyboy.de', 'dpsg-koeln@dpsg-koeln.de']])
@task('deploy', ['on' => 'docker']) @task('deploy', ['on' => 'docker'])
cd $ADREMA_PATH cd $ADREMA_PATH

View File

@ -22,7 +22,6 @@ class InsertMemberAction
{ {
$region = Region::firstWhere('nami_id', $member->regionId ?: -1); $region = Region::firstWhere('nami_id', $member->regionId ?: -1);
$payload = [ $payload = [
'firstname' => $member->firstname, 'firstname' => $member->firstname,
'lastname' => $member->lastname, 'lastname' => $member->lastname,
@ -61,7 +60,17 @@ class InsertMemberAction
} }
} }
return Member::updateOrCreate(['nami_id' => $member->id], $payload); return tap(Member::updateOrCreate(['nami_id' => $member->id], $payload), function ($insertedMember) use ($member) {
$insertedMember->bankAccount()->updateOrCreate([
'iban' => $member->bankAccount->iban,
'bic' => $member->bankAccount->bic,
'blz' => $member->bankAccount->blz,
'account_number' => $member->bankAccount->accountNumber,
'person' => $member->bankAccount->person,
'bank_name' => $member->bankAccount->bankName,
'nami_id' => $member->bankAccount->id,
]);
});
} }
public function getSubscription(NamiMember $member): ?Subscription public function getSubscription(NamiMember $member): ?Subscription

View File

@ -34,7 +34,7 @@ class Activity extends Model
} }
/** /**
* @return BelongsToMany<Subactivity> * @return BelongsToMany<Subactivity, $this>
*/ */
public function subactivities(): BelongsToMany public function subactivities(): BelongsToMany
{ {

View File

@ -17,7 +17,7 @@ class CourseMember extends Model
public $guarded = []; public $guarded = [];
/** /**
* @return BelongsTo<Course, self> * @return BelongsTo<Course, $this>
*/ */
public function course(): BelongsTo public function course(): BelongsTo
{ {
@ -25,7 +25,7 @@ class CourseMember extends Model
} }
/** /**
* @return BelongsTo<Member, self> * @return BelongsTo<Member, $this>
*/ */
public function member(): BelongsTo public function member(): BelongsTo
{ {

View File

@ -129,6 +129,7 @@ class Principal implements PrincipalBackendInterface
*/ */
public function findByUri($uri, $principalPrefix) public function findByUri($uri, $principalPrefix)
{ {
return null;
} }
/** /**

View File

@ -15,14 +15,13 @@ class Fee extends Model
use HasFactory; use HasFactory;
use HasNamiField; use HasNamiField;
/** @var array<int, string> */
public $fillable = ['name', 'nami_id']; public $fillable = ['name', 'nami_id'];
/** @var bool */ /** @var bool */
public $timestamps = false; public $timestamps = false;
/** /**
* @return HasMany<Subscription> * @return HasMany<Subscription, $this>
*/ */
public function subscriptions(): HasMany public function subscriptions(): HasMany
{ {

View File

@ -3,11 +3,11 @@
namespace App\Form\Data; namespace App\Form\Data;
use App\Fileshare\Data\FileshareResourceData; use App\Fileshare\Data\FileshareResourceData;
use App\Form\Fields\Field;
use Spatie\LaravelData\Attributes\MapInputName; use Spatie\LaravelData\Attributes\MapInputName;
use Spatie\LaravelData\Attributes\MapOutputName; use Spatie\LaravelData\Attributes\MapOutputName;
use Spatie\LaravelData\Data; use Spatie\LaravelData\Data;
use Spatie\LaravelData\Mappers\SnakeCaseMapper; use Spatie\LaravelData\Mappers\SnakeCaseMapper;
use Spatie\LaravelData\Support\EloquentCasts\DataEloquentCast;
#[MapInputName(SnakeCaseMapper::class)] #[MapInputName(SnakeCaseMapper::class)]
#[MapOutputName(SnakeCaseMapper::class)] #[MapOutputName(SnakeCaseMapper::class)]
@ -16,4 +16,13 @@ class ExportData extends Data
public function __construct(public ?FileshareResourceData $root = null, public ?string $groupBy = null, public ?string $toGroupField = null) public function __construct(public ?FileshareResourceData $root = null, public ?string $groupBy = null, public ?string $toGroupField = null)
{ {
} }
/**
* @param array<int, mixed> $arguments
* @return DataEloquentCast<self>
*/
public static function castUsing(array $arguments): DataEloquentCast
{
return new DataEloquentCast(static::class, $arguments);
}
} }

View File

@ -8,6 +8,7 @@ use Illuminate\Support\Collection;
use Spatie\LaravelData\Data; use Spatie\LaravelData\Data;
use Spatie\LaravelData\Attributes\WithCast; use Spatie\LaravelData\Attributes\WithCast;
use Spatie\LaravelData\Attributes\WithTransformer; use Spatie\LaravelData\Attributes\WithTransformer;
use Spatie\LaravelData\Support\EloquentCasts\DataEloquentCast;
class FormConfigData extends Data class FormConfigData extends Data
{ {
@ -29,4 +30,13 @@ class FormConfigData extends Data
new FieldCollection([]) new FieldCollection([])
); );
} }
/**
* @param array<int, mixed> $arguments
* @return DataEloquentCast<self>
*/
public static function castUsing(array $arguments): DataEloquentCast
{
return new DataEloquentCast(static::class, $arguments);
}
} }

View File

@ -62,7 +62,7 @@ class Form extends Model implements HasMedia
} }
/** /**
* @return HasMany<Participant> * @return HasMany<Participant, $this>
*/ */
public function participants(): HasMany public function participants(): HasMany
{ {

View File

@ -33,7 +33,7 @@ class Participant extends Model implements Preventable
]; ];
/** /**
* @return BelongsTo<Form, self> * @return BelongsTo<Form, $this>
*/ */
public function form(): BelongsTo public function form(): BelongsTo
{ {
@ -41,7 +41,7 @@ class Participant extends Model implements Preventable
} }
/** /**
* @return HasMany<self> * @return HasMany<Participant, $this>
*/ */
public function children(): HasMany public function children(): HasMany
{ {
@ -49,7 +49,7 @@ class Participant extends Model implements Preventable
} }
/** /**
* @return BelongsTo<Member, self> * @return BelongsTo<Member, $this>
*/ */
public function member(): BelongsTo public function member(): BelongsTo
{ {

View File

@ -26,7 +26,7 @@ class Group extends Model
]; ];
/** /**
* @return BelongsTo<self, self> * @return BelongsTo<Group, $this>
*/ */
public function parent(): BelongsTo public function parent(): BelongsTo
{ {
@ -34,7 +34,7 @@ class Group extends Model
} }
/** /**
* @return HasMany<self> * @return HasMany<Group, $this>
*/ */
public function children(): HasMany public function children(): HasMany
{ {

View File

@ -18,5 +18,7 @@ class Authenticate extends Middleware
if (!$request->expectsJson()) { if (!$request->expectsJson()) {
return route('login'); return route('login');
} }
return null;
} }
} }

View File

@ -39,7 +39,7 @@ class MassStoreAction
foreach ($memberGroup as $members) { foreach ($memberGroup as $members) {
$invoice = Invoice::createForMember($members->first(), $members, $year); $invoice = Invoice::createForMember($members->first(), $members, $year);
$invoice->save(); $invoice->save();
$invoice->positions()->createMany($invoice->positions); $invoice->positions()->createMany($invoice->positions->toArray());
$invoices->push($invoice->fresh('positions')); $invoices->push($invoice->fresh('positions'));
} }

View File

@ -37,7 +37,7 @@ class Invoice extends Model
]; ];
/** /**
* @return HasMany<InvoicePosition> * @return HasMany<InvoicePosition, $this>
*/ */
public function positions(): HasMany public function positions(): HasMany
{ {

View File

@ -16,7 +16,7 @@ class InvoicePosition extends Model
public $guarded = []; public $guarded = [];
/** /**
* @return BelongsTo<Member, self> * @return BelongsTo<Member, $this>
*/ */
public function member(): BelongsTo public function member(): BelongsTo
{ {
@ -24,7 +24,7 @@ class InvoicePosition extends Model
} }
/** /**
* @return BelongsTo<Invoice, self> * @return BelongsTo<Invoice, $this>
*/ */
public function invoice(): BelongsTo public function invoice(): BelongsTo
{ {

View File

@ -6,6 +6,7 @@ use Spatie\LaravelData\Data;
use Spatie\LaravelData\DataCollection; use Spatie\LaravelData\DataCollection;
use Spatie\MediaLibrary\MediaCollections\Models\Media; use Spatie\MediaLibrary\MediaCollections\Models\Media;
use Spatie\LaravelData\Attributes\DataCollectionOf; use Spatie\LaravelData\Attributes\DataCollectionOf;
use Spatie\LaravelData\Support\EloquentCasts\DataEloquentCast;
class Condition extends Data class Condition extends Data
{ {
@ -42,4 +43,13 @@ class Condition extends Data
{ {
return $this->mode === ConditionMode::ALL; return $this->mode === ConditionMode::ALL;
} }
/**
* @param array<int, mixed> $arguments
* @return DataEloquentCast<self>
*/
public static function castUsing(array $arguments): DataEloquentCast
{
return new DataEloquentCast(static::class, $arguments);
}
} }

View File

@ -3,6 +3,7 @@
namespace App\Lib\Editor; namespace App\Lib\Editor;
use Spatie\LaravelData\Data; use Spatie\LaravelData\Data;
use Spatie\LaravelData\Support\EloquentCasts\DataEloquentCast;
/** @todo replace blocks with actual block data classes */ /** @todo replace blocks with actual block data classes */
class EditorData extends Data implements Editorable class EditorData extends Data implements Editorable
@ -83,4 +84,13 @@ class EditorData extends Data implements Editorable
{ {
return $this; return $this;
} }
/**
* @param array<int, mixed> $arguments
* @return DataEloquentCast<self>
*/
public static function castUsing(array $arguments): DataEloquentCast
{
return new DataEloquentCast(static::class, $arguments);
}
} }

View File

@ -8,7 +8,7 @@ use Spatie\LaravelData\Data;
/** /**
* @template T of Model * @template T of Model
* @property Builder $query * @property Builder<T> $query
*/ */
abstract class Filter extends Data abstract class Filter extends Data
{ {
@ -40,7 +40,7 @@ abstract class Filter extends Data
} }
/** /**
* @return static(self<T>) * @return static
*/ */
public function toDefault(): self public function toDefault(): self
{ {

View File

@ -8,7 +8,7 @@ use Spatie\LaravelData\Data;
/** /**
* @template T of Model * @template T of Model
* @property Builder $query * @property Builder<T> $query
*/ */
abstract class ScoutFilter extends Data abstract class ScoutFilter extends Data
{ {

View File

@ -25,7 +25,7 @@ class ResyncAction
*/ */
public function getResults(Maildispatcher $dispatcher): Collection public function getResults(Maildispatcher $dispatcher): Collection
{ {
return FilterScope::fromPost($dispatcher->filter)->getQuery()->get() return FilterScope::fromPost($dispatcher->filter)->noPageLimit()->getQuery()->get()
->filter(fn ($member) => $member->email || $member->email_parents) ->filter(fn ($member) => $member->email || $member->email_parents)
->map(fn ($member) => MailEntry::from(['email' => $member->email ?: $member->email_parents])) ->map(fn ($member) => MailEntry::from(['email' => $member->email ?: $member->email_parents]))
->unique(fn ($member) => $member->email); ->unique(fn ($member) => $member->email);

View File

@ -23,7 +23,7 @@ class Maildispatcher extends Model
]; ];
/** /**
* @return BelongsTo<Mailgateway, self> * @return BelongsTo<Mailgateway, $this>
*/ */
public function gateway(): BelongsTo public function gateway(): BelongsTo
{ {

View File

@ -68,9 +68,9 @@ abstract class Type
} }
/** /**
* @return array<string, array<string, mixed>> * @return mixed
*/ */
public function toResource(): array public function toResource()
{ {
return [ return [
'cls' => get_class($this), 'cls' => get_class($this),
@ -93,8 +93,8 @@ abstract class Type
} }
$this->list($name, $domain) $this->list($name, $domain)
->filter(fn ($listEntry) => $results->doesntContain(fn ($r) => $r->is($listEntry))) ->filter(fn ($listEntry) => $results->doesntContain(fn ($r) => $r->is($listEntry)))
->each(fn ($listEntry) => $this->remove($name, $domain, $listEntry->email)); ->each(fn ($listEntry) => $this->remove($name, $domain, $listEntry->email));
} }
/** /**

View File

@ -10,6 +10,7 @@ use App\Member\Member;
use App\Setting\NamiSettings; use App\Setting\NamiSettings;
use App\Subactivity; use App\Subactivity;
use Lorisleiva\Actions\Concerns\AsAction; use Lorisleiva\Actions\Concerns\AsAction;
use Zoomyboy\LaravelNami\Data\BankAccount;
use Zoomyboy\LaravelNami\Data\Member as NamiMember; use Zoomyboy\LaravelNami\Data\Member as NamiMember;
class NamiPutMemberAction class NamiPutMemberAction
@ -47,6 +48,7 @@ class NamiPutMemberAction
'id' => $member->nami_id, 'id' => $member->nami_id,
'version' => $member->version, 'version' => $member->version,
'keepdata' => $member->keepdata, 'keepdata' => $member->keepdata,
'bankAccount' => BankAccount::from([]),
]); ]);
$response = $api->putMember($namiMember, $activity ? $activity->nami_id : null, $subactivity ? $subactivity->nami_id : null); $response = $api->putMember($namiMember, $activity ? $activity->nami_id : null, $subactivity ? $subactivity->nami_id : null);
Member::withoutEvents(function () use ($response, $member) { Member::withoutEvents(function () use ($response, $member) {

View File

@ -0,0 +1,15 @@
<?php
namespace App\Member;
use Database\Factories\Member\BankAccountFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class BankAccount extends Model
{
/** @use HasFactory<BankAccountFactory> */
use HasFactory;
public $guarded = [];
}

View File

@ -34,6 +34,7 @@ use Zoomyboy\Osm\HasGeolocation;
use Zoomyboy\Phone\HasPhoneNumbers; use Zoomyboy\Phone\HasPhoneNumbers;
use App\Prevention\Enums\Prevention; use App\Prevention\Enums\Prevention;
use Database\Factories\Member\MemberFactory; use Database\Factories\Member\MemberFactory;
use Illuminate\Database\Eloquent\Relations\HasOne;
/** /**
* @property string $subscription_name * @property string $subscription_name
@ -195,7 +196,7 @@ class Member extends Model implements Geolocatable
// ---------------------------------- Relations ---------------------------------- // ---------------------------------- Relations ----------------------------------
/** /**
* @return BelongsTo<Country, self> * @return BelongsTo<Country, $this>
*/ */
public function country(): BelongsTo public function country(): BelongsTo
{ {
@ -203,7 +204,7 @@ class Member extends Model implements Geolocatable
} }
/** /**
* @return BelongsTo<Gender, self> * @return BelongsTo<Gender, $this>
*/ */
public function gender(): BelongsTo public function gender(): BelongsTo
{ {
@ -211,7 +212,7 @@ class Member extends Model implements Geolocatable
} }
/** /**
* @return BelongsTo<Region, self> * @return BelongsTo<Region, $this>
*/ */
public function region(): BelongsTo public function region(): BelongsTo
{ {
@ -222,7 +223,7 @@ class Member extends Model implements Geolocatable
} }
/** /**
* @return HasMany<InvoicePosition> * @return HasMany<InvoicePosition, $this>
*/ */
public function invoicePositions(): HasMany public function invoicePositions(): HasMany
{ {
@ -230,7 +231,7 @@ class Member extends Model implements Geolocatable
} }
/** /**
* @return BelongsTo<Confession, self> * @return BelongsTo<Confession, $this>
*/ */
public function confession(): BelongsTo public function confession(): BelongsTo
{ {
@ -238,7 +239,7 @@ class Member extends Model implements Geolocatable
} }
/** /**
* @return BelongsTo<Nationality, self> * @return BelongsTo<Nationality, $this>
*/ */
public function nationality(): BelongsTo public function nationality(): BelongsTo
{ {
@ -246,7 +247,7 @@ class Member extends Model implements Geolocatable
} }
/** /**
* @return BelongsTo<Subscription, self> * @return BelongsTo<Subscription, $this>
*/ */
public function subscription(): BelongsTo public function subscription(): BelongsTo
{ {
@ -254,7 +255,7 @@ class Member extends Model implements Geolocatable
} }
/** /**
* @return BelongsTo<Group, self> * @return BelongsTo<Group, $this>
*/ */
public function group(): BelongsTo public function group(): BelongsTo
{ {
@ -262,7 +263,7 @@ class Member extends Model implements Geolocatable
} }
/** /**
* @return HasMany<CourseMember> * @return HasMany<CourseMember, $this>
*/ */
public function courses(): HasMany public function courses(): HasMany
{ {
@ -270,7 +271,7 @@ class Member extends Model implements Geolocatable
} }
/** /**
* @return HasMany<Membership> * @return HasMany<Membership, $this>
*/ */
public function memberships(): HasMany public function memberships(): HasMany
{ {
@ -278,7 +279,7 @@ class Member extends Model implements Geolocatable
} }
/** /**
* @return HasMany<Membership> * @return HasMany<Membership, $this>
*/ */
public function leaderMemberships(): HasMany public function leaderMemberships(): HasMany
{ {
@ -286,13 +287,21 @@ class Member extends Model implements Geolocatable
} }
/** /**
* @return HasMany<Membership> * @return HasMany<Membership, $this>
*/ */
public function ageGroupMemberships(): HasMany public function ageGroupMemberships(): HasMany
{ {
return $this->memberships()->isAgeGroup()->active(); return $this->memberships()->isAgeGroup()->active();
} }
/**
* @return HasOne<BankAccount, $this>
*/
public function bankAccount(): HasOne
{
return $this->hasOne(BankAccount::class);
}
public static function booted() public static function booted()
{ {
static::deleting(function (self $model): void { static::deleting(function (self $model): void {

View File

@ -32,7 +32,7 @@ class Membership extends Model
]; ];
/** /**
* @return BelongsTo<Activity, self> * @return BelongsTo<Activity, $this>
*/ */
public function activity(): BelongsTo public function activity(): BelongsTo
{ {
@ -40,7 +40,7 @@ class Membership extends Model
} }
/** /**
* @return BelongsTo<Group, self> * @return BelongsTo<Group, $this>
*/ */
public function group(): BelongsTo public function group(): BelongsTo
{ {
@ -48,7 +48,7 @@ class Membership extends Model
} }
/** /**
* @return BelongsTo<Subactivity, self> * @return BelongsTo<Subactivity, $this>
*/ */
public function subactivity(): BelongsTo public function subactivity(): BelongsTo
{ {
@ -56,7 +56,7 @@ class Membership extends Model
} }
/** /**
* @return BelongsTo<Member, self> * @return BelongsTo<Member, $this>
*/ */
public function member(): BelongsTo public function member(): BelongsTo
{ {

View File

@ -14,9 +14,6 @@ class Subscription extends Model
/** @use HasFactory<SubscriptionFactory> */ /** @use HasFactory<SubscriptionFactory> */
use HasFactory; use HasFactory;
/**
* @var array<int, string>
*/
public $fillable = ['name', 'fee_id']; public $fillable = ['name', 'fee_id'];
public function getAmount(): int public function getAmount(): int
@ -25,7 +22,7 @@ class Subscription extends Model
} }
/** /**
* @return BelongsTo<Fee, self> * @return BelongsTo<Fee, $this>
*/ */
public function fee(): BelongsTo public function fee(): BelongsTo
{ {
@ -33,7 +30,7 @@ class Subscription extends Model
} }
/** /**
* @return HasMany<SubscriptionChild> * @return HasMany<SubscriptionChild, $this>
*/ */
public function children(): HasMany public function children(): HasMany
{ {

View File

@ -16,9 +16,6 @@ class Subactivity extends Model
use HasNamiField; use HasNamiField;
use Sluggable; use Sluggable;
/**
* @var array<int, string>
*/
public $fillable = ['is_age_group', 'is_filterable', 'slug', 'name', 'nami_id']; public $fillable = ['is_age_group', 'is_filterable', 'slug', 'name', 'nami_id'];
/** /**
@ -26,9 +23,6 @@ class Subactivity extends Model
*/ */
public $timestamps = false; public $timestamps = false;
/**
* @var array<string, string>
*/
public $casts = [ public $casts = [
'is_age_group' => 'boolean', 'is_age_group' => 'boolean',
'is_filterable' => 'boolean', 'is_filterable' => 'boolean',
@ -47,7 +41,7 @@ class Subactivity extends Model
} }
/** /**
* @return BelongsToMany<Activity> * @return BelongsToMany<Activity, $this>
*/ */
public function activities(): BelongsToMany public function activities(): BelongsToMany
{ {

View File

@ -3,8 +3,8 @@
echo "drop database scoutrobot;" | sudo mysql echo "drop database scoutrobot;" | sudo mysql
echo "create database scoutrobot;" | sudo mysql echo "create database scoutrobot;" | sudo mysql
ssh -l stammsilva zoomyboy.de "cd /usr/share/webapps/nami_silva && docker compose exec db mysqldump -udb -p$SCOUTROBOT_DB_PASSWORD db" > db.tmp ssh -l stamm-silva zoomyboy.de "cd /usr/share/webapps/adrema_silva && docker compose exec db mysqldump -udb -p$SCOUTROBOT_DB_PASSWORD db" > db.tmp
sudo mysql scoutrobot < db.tmp sudo mysql adrema < db.tmp
rm db.tmp rm db.tmp
echo 'app(\App\Form\FormSettings::class)->fill(["registerUrl" => "http://stammsilva.test/anmeldung/{slug}/register", "clearCacheUrl" => "http://stammsilva.test/adrema/clear-cache"])->save();' | php artisan tinker echo 'app(\App\Form\FormSettings::class)->fill(["registerUrl" => "http://stammsilva.test/anmeldung/{slug}/register", "clearCacheUrl" => "http://stammsilva.test/adrema/clear-cache"])->save();' | php artisan tinker

View File

@ -80,12 +80,12 @@
}, },
"require-dev": { "require-dev": {
"fakerphp/faker": "^1.9.1", "fakerphp/faker": "^1.9.1",
"larastan/larastan": "^2.0", "larastan/larastan": "^3.0",
"laravel/envoy": "^2.8", "laravel/envoy": "^2.8",
"mockery/mockery": "^1.4.4", "mockery/mockery": "^1.4.4",
"orchestra/testbench": "^9.0", "orchestra/testbench": "^9.0",
"pestphp/pest": "^3.0", "pestphp/pest": "^3.0",
"phpstan/phpstan-mockery": "^1.1" "phpstan/phpstan-mockery": "^2.0"
}, },
"config": { "config": {
"optimize-autoloader": true, "optimize-autoloader": true,

4016
composer.lock generated

File diff suppressed because it is too large Load Diff

6
config/init.php Normal file
View File

@ -0,0 +1,6 @@
<?php
return [
'email' => env('USER_EMAIL', 'admin@example.com'),
'password' => env('USER_PASSWORD', 'admin'),
];

View File

@ -0,0 +1,33 @@
<?php
namespace Database\Factories\Member;
use App\Member\BankAccount;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @template TModel of \App\Member\BankAccount
*
* @extends \Illuminate\Database\Eloquent\Factories\Factory<TModel>
*/
class BankAccountFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var class-string<TModel>
*/
protected $model = BankAccount::class;
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
//
];
}
}

View File

@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('bank_accounts', function (Blueprint $table) {
$table->unsignedBigInteger('member_id')->primary();
$table->unsignedBigInteger('nami_id')->nullable();
$table->string('iban')->nullable();
$table->string('bic')->nullable();
$table->string('blz')->nullable();
$table->string('bank_name')->nullable();
$table->string('person')->nullable();
$table->string('account_number')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('bank_accounts');
}
};

View File

@ -16,9 +16,9 @@ class UserSeeder extends Seeder
public function run() public function run()
{ {
User::create([ User::create([
'email' => env('USER_EMAIL', 'admin@example.com'), 'email' => config('init.email'),
'email_verified_at' => now(), 'email_verified_at' => now(),
'password' => Hash::make(env('USER_PASSWORD', 'admin')), 'password' => Hash::make(config('init.password')),
'name' => 'Adrema Benutzer', 'name' => 'Adrema Benutzer',
]); ]);
} }

1396
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -1 +1 @@
Subproject commit bc61530e510b3d41048984b7cf20b6d82c4f85fb Subproject commit f905c316ee7913cbf85c386021fbaa28b4b2a158

@ -1 +1 @@
Subproject commit 74800de149bf2ca250a17263cfaf59e48b76186f Subproject commit ed283d97ca7680b3c27b2d75da9937f4f379e321

View File

@ -7,6 +7,9 @@ parameters:
stubFiles: stubFiles:
- tests/stub/phpstan/TestResponse.stub - tests/stub/phpstan/TestResponse.stub
- tests/stub/phpstan/Settings.stub - tests/stub/phpstan/Settings.stub
- tests/stub/phpstan/DataEloquentCast.stub
- tests/stub/phpstan/File.stub
- tests/stub/phpstan/CastsAttributes.stub
paths: paths:
- app - app
@ -30,9 +33,6 @@ parameters:
ignoreErrors: ignoreErrors:
- -
message: "#but does not specify its types: TData#" message: "#but does not specify its types: TData#"
-
message: "#cast\\(\\) has parameter \\$properties#"
- -
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\\.$#"
count: 1 count: 1
@ -453,11 +453,6 @@ parameters:
count: 1 count: 1
path: app/Form/Fields/NamiField.php path: app/Form/Fields/NamiField.php
-
message: "#^Method App\\\\Fileshare\\\\ConnectionTypes\\\\ConnectionType\\:\\:types\\(\\) should return Illuminate\\\\Support\\\\Collection\\<int, class\\-string\\<App\\\\Fileshare\\\\ConnectionTypes\\\\ConnectionType\\>\\> but returns Illuminate\\\\Support\\\\Collection\\<int, string\\>\\.$#"
count: 1
path: app/Fileshare/ConnectionTypes/ConnectionType.php
- -
message: "#^Call to an undefined method Phake\\\\Proxies\\\\StubberProxy\\:\\:check\\(\\)\\.$#" message: "#^Call to an undefined method Phake\\\\Proxies\\\\StubberProxy\\:\\:check\\(\\)\\.$#"
count: 1 count: 1
@ -507,3 +502,45 @@ parameters:
message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\<\\*, \\*, \\*\\>\\:\\:isTrying\\(\\)\\.$#" message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\<\\*, \\*, \\*\\>\\:\\:isTrying\\(\\)\\.$#"
count: 1 count: 1
path: app/Membership/TestersBlock.php path: app/Membership/TestersBlock.php
-
message: '#^Call to an undefined method Illuminate\\Database\\Eloquent\\Builder\<Illuminate\\Database\\Eloquent\\Model\>\:\:isLeader\(\)\.$#'
identifier: method.notFound
count: 1
path: app/Efz/EfzPendingBlock.php
-
message: '#^Method App\\Fileshare\\ConnectionTypes\\ConnectionType\:\:types\(\) should return Illuminate\\Support\\Collection\<int, class\-string\<App\\Fileshare\\ConnectionTypes\\ConnectionType\>\> but returns Illuminate\\Support\\Collection\<int, non\-falsy\-string\>\.$#'
identifier: return.type
count: 1
path: app/Fileshare/ConnectionTypes/ConnectionType.php
-
message: '#^Unable to resolve the template type TGroupKey in call to method Illuminate\\Support\\Collection\<int,App\\Form\\Models\\Participant\>\:\:groupBy\(\)$#'
identifier: argument.templateType
count: 1
path: app/Form/Actions/ExportSyncAction.php
-
message: '#^Parameter \#1 \$callback of method Illuminate\\Support\\Collection\<\(int\|string\),mixed\>\:\:map\(\) contains unresolvable type\.$#'
identifier: argument.unresolvableType
count: 1
path: app/Mailgateway/Resources/MailgatewayResource.php
-
message: '#^Parameter \#1 \$value of method Illuminate\\Support\\Collection\<\(int\|string\),array\<string, mixed\>\>\:\:prepend\(\) contains unresolvable type\.$#'
identifier: argument.unresolvableType
count: 1
path: app/Mailgateway/Resources/MailgatewayResource.php
-
message: '#^Call to an undefined method Illuminate\\Database\\Eloquent\\Builder\<Illuminate\\Database\\Eloquent\\Model\>\:\:isLeader\(\)\.$#'
identifier: method.notFound
count: 1
path: app/Member/PsPendingBlock.php
-
message: '#^Call to an undefined method Illuminate\\Database\\Eloquent\\Builder\<TRelatedModel of Illuminate\\Database\\Eloquent\\Model\>\:\:isTrying\(\)\.$#'
identifier: method.notFound
count: 1
path: app/Membership/TestersBlock.php

View File

@ -29,6 +29,7 @@
<server name="QUEUE_CONNECTION" value="sync"/> <server name="QUEUE_CONNECTION" value="sync"/>
<server name="SESSION_DRIVER" value="array"/> <server name="SESSION_DRIVER" value="array"/>
<server name="TELESCOPE_ENABLED" value="false"/> <server name="TELESCOPE_ENABLED" value="false"/>
<server name="SCOUT_DRIVER" value="database"/>
</php> </php>
<source> <source>
<include> <include>

View File

@ -88,6 +88,26 @@ it('testFetchWiederverwendenFlag', function (array $memberAttributes, array $sto
[['regionId' => 999], ['region_id' => null]] [['regionId' => 999], ['region_id' => null]]
]); ]);
it('testFetchesKontoverbindung', function (array $memberAttributes, array $storedAttributes) {
$this->loginNami();
Region::factory()->inNami(999)->name('nicht-de')->create(['is_null' => true]);
app(MemberFake::class)->shows(1000, 1001, $memberAttributes);
app(PullMemberAction::class)->handle(1000, 1001);
$this->assertDatabaseHas('bank_accounts', [
'member_id' => Member::first()->id,
...$storedAttributes
]);
})->with([
[['kontoverbindung' => ['iban' => '3300', 'bic' => 'SOLSDE']], ['iban' => '3300', 'bic' => 'SOLSDE']],
[['kontoverbindung' => ['id' => 33003]], ['nami_id' => 33003]],
[['kontoverbindung' => ['blz' => 111]], ['blz' => 111]],
[['kontoverbindung' => ['institut' => 'Sparkasse']], ['bank_name' => 'Sparkasse']],
[['kontoverbindung' => ['kontoinhaber' => 'Max']], ['person' => 'Max']],
[['kontoverbindung' => ['kontonummer' => '333']], ['account_number' => '333']],
]);
it('testItSetsFirstSubscriptionFromFee', function () { it('testItSetsFirstSubscriptionFromFee', function () {
$this->loginNami(); $this->loginNami();
Region::factory()->inNami(999)->name('nicht-de')->create(['is_null' => true]); Region::factory()->inNami(999)->name('nicht-de')->create(['is_null' => true]);

View File

@ -35,10 +35,10 @@ class InitializeGroupsTest extends TestCase
public function testItSynchsAGroupWithASingleNodeAndNoChildren(): void public function testItSynchsAGroupWithASingleNodeAndNoChildren(): void
{ {
$parentGroup = Group::from(['id' => 150, 'name' => 'lorem', 'parentId' => null]); $parentGroup = Group::from(['id' => 150, 'name' => 'lorem', 'parentId' => null]);
$this->api->method('groups')->will($this->returnValueMap([ $this->api->method('groups')->willReturnMap([
[null, collect([$parentGroup])], [null, collect([$parentGroup])],
[$parentGroup, collect([])], [$parentGroup, collect([])],
])); ]);
$this->api->method('groups')->willReturn(collect([])); $this->api->method('groups')->willReturn(collect([]));
(new InitializeGroups($this->api))->handle(); (new InitializeGroups($this->api))->handle();
@ -55,10 +55,10 @@ class InitializeGroupsTest extends TestCase
{ {
$existingGroup = GroupModel::factory()->create(['nami_id' => 150, 'inner_name' => 'Def']); $existingGroup = GroupModel::factory()->create(['nami_id' => 150, 'inner_name' => 'Def']);
$parentGroup = Group::from(['id' => 150, 'name' => 'lorem', 'parentId' => null]); $parentGroup = Group::from(['id' => 150, 'name' => 'lorem', 'parentId' => null]);
$this->api->method('groups')->will($this->returnValueMap([ $this->api->method('groups')->willReturnMap([
[null, collect([$parentGroup])], [null, collect([$parentGroup])],
[$parentGroup, collect([])], [$parentGroup, collect([])],
])); ]);
(new InitializeGroups($this->api))->handle(); (new InitializeGroups($this->api))->handle();
@ -75,11 +75,11 @@ class InitializeGroupsTest extends TestCase
{ {
$parentGroup = Group::from(['id' => 150, 'name' => 'lorem', 'parentId' => null]); $parentGroup = Group::from(['id' => 150, 'name' => 'lorem', 'parentId' => null]);
$subgroup = Group::from(['id' => 200, 'name' => 'subgroup', 'parentId' => 150]); $subgroup = Group::from(['id' => 200, 'name' => 'subgroup', 'parentId' => 150]);
$this->api->method('groups')->will($this->returnValueMap([ $this->api->method('groups')->willReturnMap([
[null, collect([$parentGroup])], [null, collect([$parentGroup])],
[$parentGroup, collect([$subgroup])], [$parentGroup, collect([$subgroup])],
[$subgroup, collect([])], [$subgroup, collect([])],
])); ]);
(new InitializeGroups($this->api))->handle(); (new InitializeGroups($this->api))->handle();
@ -94,12 +94,12 @@ class InitializeGroupsTest extends TestCase
$parentGroup = Group::from(['id' => 150, 'name' => 'lorem', 'parentId' => null]); $parentGroup = Group::from(['id' => 150, 'name' => 'lorem', 'parentId' => null]);
$subgroup = Group::from(['id' => 200, 'name' => 'subgroup', 'parentId' => 150]); $subgroup = Group::from(['id' => 200, 'name' => 'subgroup', 'parentId' => 150]);
$subsubgroup = Group::from(['id' => 250, 'name' => 'subsubgroup', 'parentId' => 200]); $subsubgroup = Group::from(['id' => 250, 'name' => 'subsubgroup', 'parentId' => 200]);
$this->api->method('groups')->will($this->returnValueMap([ $this->api->method('groups')->willReturnMap([
[null, collect([$parentGroup])], [null, collect([$parentGroup])],
[$parentGroup, collect([$subgroup])], [$parentGroup, collect([$subgroup])],
[$subgroup, collect([$subsubgroup])], [$subgroup, collect([$subsubgroup])],
[$subsubgroup, collect([])], [$subsubgroup, collect([])],
])); ]);
(new InitializeGroups($this->api))->handle(); (new InitializeGroups($this->api))->handle();
@ -111,11 +111,11 @@ class InitializeGroupsTest extends TestCase
$existingSubgroup = GroupModel::factory()->create(['name' => 'Abc', 'inner_name' => 'Def', 'nami_id' => 200]); $existingSubgroup = GroupModel::factory()->create(['name' => 'Abc', 'inner_name' => 'Def', 'nami_id' => 200]);
$parentGroup = Group::from(['id' => 150, 'name' => 'root', 'parentId' => null]); $parentGroup = Group::from(['id' => 150, 'name' => 'root', 'parentId' => null]);
$subgroup = Group::from(['id' => 200, 'name' => 'child', 'parentId' => 150]); $subgroup = Group::from(['id' => 200, 'name' => 'child', 'parentId' => 150]);
$this->api->method('groups')->will($this->returnValueMap([ $this->api->method('groups')->willReturnMap([
[null, collect([$parentGroup])], [null, collect([$parentGroup])],
[$parentGroup, collect([$subgroup])], [$parentGroup, collect([$subgroup])],
[$subgroup, collect([])], [$subgroup, collect([])],
])); ]);
(new InitializeGroups($this->api))->handle(); (new InitializeGroups($this->api))->handle();

View File

@ -0,0 +1,35 @@
<?php
namespace Illuminate\Contracts\Database\Eloquent;
use Illuminate\Database\Eloquent\Model;
/**
* @template TGet
* @template TSet
* @copy
*/
interface CastsAttributes
{
/**
* Transform the attribute from the underlying model values.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param string $key
* @param mixed $value
* @param array<string, mixed> $attributes
* @return TGet|null
*/
public function get(Model $model, string $key, mixed $value, array $attributes);
/**
* Transform the attribute to its underlying model values.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param string $key
* @param TSet|null $value
* @param array<string, mixed> $attributes
* @return mixed
*/
public function set(Model $model, string $key, mixed $value, array $attributes);
}

View File

@ -0,0 +1,13 @@
<?php
namespace Spatie\LaravelData\Support\EloquentCasts;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
/**
* @template TDto
* @implements CastsAttributes<TDto, TDto>
*/
class DataEloquentCast implements CastsAttributes
{
}

View File

@ -0,0 +1,11 @@
<?php
namespace Symfony\Component\HttpFoundation\File;
/**
* @copy
*/
class File
{
}