diff --git a/app/Initialize/InitializeMembers.php b/app/Initialize/InitializeMembers.php index 31fd0e62..326b3b85 100644 --- a/app/Initialize/InitializeMembers.php +++ b/app/Initialize/InitializeMembers.php @@ -1,4 +1,4 @@ -<?php +<?php namespace App\Initialize; @@ -22,7 +22,7 @@ use Zoomyboy\LaravelNami\NamiException; class InitializeMembers { private $api; - + public function __construct($api) { $this->api = $api; } @@ -85,58 +85,22 @@ class InitializeMembers { } foreach ($this->api->membershipsOf($member->id) as $membership) { - if (Carbon::parse($membership['entries_aktivVon'])->addYears(200)->isPast()) { - continue; - } if ($membership['entries_aktivBis'] !== '') { continue; } - if (preg_match('/\(([0-9]+)\)/', $membership['entries_taetigkeit'], $activityMatches) !== 1) { - throw new NamiException("ID in taetigkeit string not found: {$membership['entries_taetigkeit']}"); + try { + [$activityId, $subactivityId, $groupId] = $this->fetchMembership($member, $membership); + } catch (RightException $e) { + continue; } - $group = Group::where('name', $membership['entries_gruppierung'])->first(); - if (!$group) { - preg_match('/(.*?) ([0-9]+)$/', $membership['entries_gruppierung'], $groupMatches); - [$groupAll, $groupName, $groupId] = $groupMatches; - $group = Group::create(['name' => $groupName, 'nami_id' => $groupId]); - } - if ($membership['entries_untergliederung'] === '') { - $subactivityId = null; - } else if (!Subactivity::where('name', $membership['entries_untergliederung'])->exists()) { - try { - $singleMembership = $this->api->membership($member->id, $membership['id']); - } catch (RightException $e) { - continue; - } - app(ActivityCreator::class)->createFor($this->api, $singleMembership['gruppierungId']); - $subactivity = Subactivity::where('nami_id', $singleMembership['untergliederungId'])->firstOrFail(); - $subactivityId = $subactivity->id; - $group = Group::firstOrCreate(['nami_id' => $singleMembership['gruppierungId']], [ - 'nami_id' => $singleMembership['gruppierungId'], - 'name' => $singleMembership['gruppierung'], - ]); - } else { - $subactivityId = Subactivity::where('name', $membership['entries_untergliederung'])->first()->id; - } - $activity = Activity::where('nami_id', (int) $activityMatches[1])->first(); - if (!$activity) { - try { - $singleMembership = $this->api->membership($member->id, $membership['id']); - } catch (RightException $e) { - continue; - } - app(ActivityCreator::class)->createFor($this->api, $singleMembership['gruppierungId']); - $activity = Activity::where('nami_id', $singleMembership['taetigkeitId'])->first(); - $group = Group::firstOrCreate(['nami_id' => $singleMembership['gruppierungId']], [ - 'nami_id' => $singleMembership['gruppierungId'], - 'name' => $singleMembership['gruppierung'], - ]); + if (is_null($activityId)) { + continue; } $m->memberships()->create([ 'nami_id' => $membership['id'], - 'created_at' => $membership['entries_aktivVon'], - 'group_id' => $group->id, - 'activity_id' => $activity->id, + 'from' => $membership['entries_aktivVon'], + 'group_id' => $groupId, + 'activity_id' => $activityId, 'subactivity_id' => $subactivityId, ]); } @@ -145,4 +109,54 @@ class InitializeMembers { } }); } + + private function fetchMembership($member, $membership) { + if ($this->shouldSyncMembership($membership)) { + $singleMembership = $this->api->membership($member->id, $membership['id']); + app(ActivityCreator::class)->createFor($this->api, $singleMembership['gruppierungId']); + $group = Group::firstOrCreate(['nami_id' => $singleMembership['gruppierungId']], [ + 'nami_id' => $singleMembership['gruppierungId'], + 'name' => $singleMembership['gruppierung'], + ]); + try { + $activityId = Activity::where('nami_id', $singleMembership['taetigkeitId'])->firstOrFail()->id; + $subactivityId = $singleMembership['untergliederungId'] + ? Subactivity::where('nami_id', $singleMembership['untergliederungId'])->firstOrFail()->id + : null; + return [$activityId, $subactivityId, $group->id]; + } catch (ModelNotFoundException $e) { + return [null, null, null]; + } + } + + if ($membership['entries_untergliederung'] === '') { + $subactivityId = null; + } else { + $subactivityId = Subactivity::where('name', $membership['entries_untergliederung'])->firstOrFail()->id; + } + preg_match('/\(([0-9]+)\)$/', $membership['entries_taetigkeit'], $activityMatches); + $activityId = Activity::where('nami_id', $activityMatches[1])->firstOrFail()->id; + $groupId = Group::where('name', $membership['entries_gruppierung'])->firstOrFail()->id; + + return [$activityId, $subactivityId, $groupId]; + } + + private function shouldSyncMembership($membership) { + if (!Group::where('name', $membership['entries_gruppierung'])->exists()) { + return true; + } + if (preg_match('/\(([0-9]+)\)/', $membership['entries_taetigkeit'], $activityMatches) !== 1) { + throw new NamiException("ID in taetigkeit string not found: {$membership['entries_taetigkeit']}"); + } + + if (!Activity::where('nami_id', (int) $activityMatches[1])->exists()) { + return true; + } + + if ($membership['entries_untergliederung'] === '') { + return false; + } + + return !Subactivity::where('name', $membership['entries_untergliederung'])->exists(); + } } diff --git a/app/Member/Membership.php b/app/Member/Membership.php index fb3d6af2..c7af2608 100644 --- a/app/Member/Membership.php +++ b/app/Member/Membership.php @@ -12,7 +12,7 @@ class Membership extends Model { use HasFactory; - public $fillable = ['subactivity_id', 'activity_id', 'group_id', 'member_id', 'nami_id', 'created_at']; + public $fillable = ['subactivity_id', 'activity_id', 'group_id', 'member_id', 'nami_id', 'from']; public function activity(): BelongsTo { diff --git a/database/migrations/2018_01_18_205354_create_memberships_table.php b/database/migrations/2018_01_18_205354_create_memberships_table.php index 9f0848b7..577ed091 100644 --- a/database/migrations/2018_01_18_205354_create_memberships_table.php +++ b/database/migrations/2018_01_18_205354_create_memberships_table.php @@ -1,8 +1,8 @@ <?php -use Illuminate\Support\Facades\Schema; -use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Support\Facades\Schema; class CreateMembershipsTable extends Migration { @@ -19,6 +19,7 @@ class CreateMembershipsTable extends Migration $table->integer('group_id')->nullable(); $table->integer('member_id'); $table->integer('nami_id')->nullable(); + $table->datetime('from'); $table->timestamps(); $table->unique(['activity_id', 'group_id', 'member_id', 'nami_id']); }); diff --git a/tests/Feature/Initialize/InitializeTest.php b/tests/Feature/Initialize/InitializeTest.php index f16f8f42..78e73d9c 100644 --- a/tests/Feature/Initialize/InitializeTest.php +++ b/tests/Feature/Initialize/InitializeTest.php @@ -164,6 +164,49 @@ class InitializeTest extends TestCase public function membershipDataProvider() { return [ + 'dont_fetch_activity_from_group' => [ + [ + 'gruppierung' => '::newgroup:: 22', + 'id' => 1077, + 'taetigkeit' => '::newtaetigkeit:: (9001)', + ], + function($db) { + $db->assertDatabaseCount('memberships', 0); + }, + function($backend) { + return $backend->fakeSingleMembership(116, 1077, [ + 'aktivVon' => '2021-08-22 00:00:00', + 'aktivBis' => '', + 'gruppierungId' => 9056, + 'gruppierung' => '::newgroup::', + 'id' => 1077, + 'taetigkeit' => '::newtaetigkeit::', + 'taetigkeitId' => 4000, + 'untergliederungId' => 306, + ]) + ->fakeActivities(9056, []); + } + ], + 'normal' => [ + [ + 'aktivVon' => '2021-08-22 00:00:00', + 'aktivBis' => '', + 'gruppierung' => '::group::', + 'id' => 1077, + 'taetigkeit' => '€ leiter (305)', + 'untergliederung' => 'wö', + ], + function($db) { + $db->assertDatabaseHas('memberships', [ + 'member_id' => Member::where('firstname', '::firstname::')->firstOrFail()->id, + 'activity_id' => Activity::where('nami_id', 305)->firstOrFail()->id, + 'subactivity_id' => Subactivity::where('nami_id', 306)->firstOrFail()->id, + 'nami_id' => 1077, + 'from' => '2021-08-22 00:00:00', + 'group_id' => Group::where('name', '::group::')->firstOrFail()->id, + ]); + }, + ], 'fetch_subactivity_from_group' => [ [ 'gruppierung' => '::newgroup:: 22', @@ -240,26 +283,6 @@ class InitializeTest extends TestCase ]); } ], - 'normal' => [ - [ - 'aktivVon' => '2021-08-22 00:00:00', - 'aktivBis' => '', - 'gruppierung' => '::group::', - 'id' => 1077, - 'taetigkeit' => '€ leiter (305)', - 'untergliederung' => 'wö', - ], - function($db) { - $db->assertDatabaseHas('memberships', [ - 'member_id' => Member::where('firstname', '::firstname::')->firstOrFail()->id, - 'activity_id' => Activity::where('nami_id', 305)->firstOrFail()->id, - 'subactivity_id' => Subactivity::where('nami_id', 306)->firstOrFail()->id, - 'nami_id' => 1077, - 'created_at' => '2021-08-22 00:00:00', - 'group_id' => Group::where('name', '::group::')->firstOrFail()->id, - ]); - }, - ], 'new_group' => [ [ 'gruppierung' => '::new group:: 5555', @@ -267,6 +290,22 @@ class InitializeTest extends TestCase function($db) { $db->assertDatabaseHas('groups', ['name' => '::new group::', 'nami_id' => 5555]); }, + function($backend) { + return $backend->fakeSingleMembership(116, 1077, [ + 'aktivVon' => '2021-08-22 00:00:00', + 'aktivBis' => '', + 'gruppierungId' => 5555, + 'gruppierung' => '::new group::', + 'id' => 1077, + 'taetigkeitId' => 305, + 'untergliederungId' => 306, + ]) + ->fakeActivities(5555, [['name' => 'mitglied', 'id' => 310]]) + ->fakeSubactivities([ + 310 => [['name' => 'wö', 'id' => 306]] + ]); + + } ], 'no_subactivity' => [ [ @@ -276,12 +315,14 @@ class InitializeTest extends TestCase $db->assertDatabaseHas('memberships', ['subactivity_id' => null]); }, ], - 'no_wrong_dates' => [ + 'wrong_dates' => [ [ 'aktivVon' => '1014-04-01 00:00:00', ], function($db) { - $db->assertDatabaseCount('memberships', 0); + $db->assertDatabaseHas('memberships', [ + 'from' => '1014-04-01 00:00:00', + ]); }, ], 'not_inactive' => [