From feea8052172f559925feb605ea445ab1daa2e726 Mon Sep 17 00:00:00 2001
From: philipp lang <philipp@aweos.de>
Date: Sun, 30 Mar 2025 04:06:32 +0200
Subject: [PATCH] --wip-- [skip ci]

---
 app/Actions/InsertMemberAction.php            | 13 +++++--
 app/Member/BankAccount.php                    | 14 ++++++++
 app/Member/Member.php                         |  9 +++++
 .../factories/Member/BankAccountFactory.php   | 33 ++++++++++++++++++
 ...3_30_035130_create_bank_accounts_table.php | 34 +++++++++++++++++++
 tests/Feature/Member/PullMemberActionTest.php | 20 +++++++++++
 6 files changed, 121 insertions(+), 2 deletions(-)
 create mode 100644 app/Member/BankAccount.php
 create mode 100644 database/factories/Member/BankAccountFactory.php
 create mode 100644 database/migrations/2025_03_30_035130_create_bank_accounts_table.php

diff --git a/app/Actions/InsertMemberAction.php b/app/Actions/InsertMemberAction.php
index 47d913fc..d2ea1ecc 100644
--- a/app/Actions/InsertMemberAction.php
+++ b/app/Actions/InsertMemberAction.php
@@ -22,7 +22,6 @@ class InsertMemberAction
     {
         $region = Region::firstWhere('nami_id', $member->regionId ?: -1);
 
-
         $payload = [
             'firstname' => $member->firstname,
             '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
diff --git a/app/Member/BankAccount.php b/app/Member/BankAccount.php
new file mode 100644
index 00000000..2af3341b
--- /dev/null
+++ b/app/Member/BankAccount.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace App\Member;
+
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+
+class BankAccount extends Model
+{
+    /** @use HasFactory<\Database\Factories\\App\Member\BankAccountFactory> */
+    use HasFactory;
+
+    public $guarded = [];
+}
diff --git a/app/Member/Member.php b/app/Member/Member.php
index cfe280a3..105e31da 100644
--- a/app/Member/Member.php
+++ b/app/Member/Member.php
@@ -34,6 +34,7 @@ use Zoomyboy\Osm\HasGeolocation;
 use Zoomyboy\Phone\HasPhoneNumbers;
 use App\Prevention\Enums\Prevention;
 use Database\Factories\Member\MemberFactory;
+use Illuminate\Database\Eloquent\Relations\HasOne;
 
 /**
  * @property string $subscription_name
@@ -293,6 +294,14 @@ class Member extends Model implements Geolocatable
         return $this->memberships()->isAgeGroup()->active();
     }
 
+    /**
+     * @return HasOne<BankAccount>
+     */
+    public function bankAccount(): HasOne
+    {
+        return $this->hasOne(BankAccount::class);
+    }
+
     public static function booted()
     {
         static::deleting(function (self $model): void {
diff --git a/database/factories/Member/BankAccountFactory.php b/database/factories/Member/BankAccountFactory.php
new file mode 100644
index 00000000..34dcdfd2
--- /dev/null
+++ b/database/factories/Member/BankAccountFactory.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace Database\Factories;
+
+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 [
+            //
+        ];
+    }
+}
diff --git a/database/migrations/2025_03_30_035130_create_bank_accounts_table.php b/database/migrations/2025_03_30_035130_create_bank_accounts_table.php
new file mode 100644
index 00000000..cf436128
--- /dev/null
+++ b/database/migrations/2025_03_30_035130_create_bank_accounts_table.php
@@ -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');
+    }
+};
diff --git a/tests/Feature/Member/PullMemberActionTest.php b/tests/Feature/Member/PullMemberActionTest.php
index 891f5ca3..8d5a5bfe 100644
--- a/tests/Feature/Member/PullMemberActionTest.php
+++ b/tests/Feature/Member/PullMemberActionTest.php
@@ -88,6 +88,26 @@ it('testFetchWiederverwendenFlag', function (array $memberAttributes, array $sto
     [['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 () {
     $this->loginNami();
     Region::factory()->inNami(999)->name('nicht-de')->create(['is_null' => true]);