From bf8f6c87a89df8afb31cdf86662482062745dd4a Mon Sep 17 00:00:00 2001 From: Philipp Lang Date: Sun, 17 Dec 2023 01:49:12 +0100 Subject: [PATCH] Fix MemberPaymentsBlock --- app/Dashboard/DashboardFactory.php | 2 +- .../MemberPaymentBlock.php | 11 +++--- app/Invoice/Models/Invoice.php | 11 ++++++ app/Member/Member.php | 4 +- .../Invoice/Models/InvoicePositionFactory.php | 6 ++- .../Invoice/MemberPaymentBlockTest.php | 38 ++++++++++++++++++ .../Payment/MemberPaymentsBlockTest.php | 39 ------------------- 7 files changed, 61 insertions(+), 50 deletions(-) rename app/{Payment => Invoice}/MemberPaymentBlock.php (59%) create mode 100644 tests/Feature/Invoice/MemberPaymentBlockTest.php delete mode 100644 tests/Feature/Payment/MemberPaymentsBlockTest.php diff --git a/app/Dashboard/DashboardFactory.php b/app/Dashboard/DashboardFactory.php index 58f97cb2..2a430fc1 100644 --- a/app/Dashboard/DashboardFactory.php +++ b/app/Dashboard/DashboardFactory.php @@ -4,10 +4,10 @@ namespace App\Dashboard; use App\Dashboard\Blocks\Block; use App\Efz\EfzPendingBlock; +use App\Invoice\MemberPaymentBlock; use App\Member\PsPendingBlock; use App\Membership\AgeGroupCountBlock; use App\Membership\TestersBlock; -use App\Payment\MemberPaymentBlock; class DashboardFactory { diff --git a/app/Payment/MemberPaymentBlock.php b/app/Invoice/MemberPaymentBlock.php similarity index 59% rename from app/Payment/MemberPaymentBlock.php rename to app/Invoice/MemberPaymentBlock.php index a512b86c..71fb4aa3 100644 --- a/app/Payment/MemberPaymentBlock.php +++ b/app/Invoice/MemberPaymentBlock.php @@ -1,8 +1,9 @@ selectRaw('sum(subscription_children.amount) AS nr') - ->join('subscriptions', 'subscriptions.id', 'payments.subscription_id') - ->join('subscription_children', 'subscriptions.id', 'subscription_children.parent_id') + $amount = InvoicePosition::whereHas('invoice', fn ($query) => $query->whereNeedsPayment()) + ->selectRaw('sum(price) AS price') ->first(); $members = Member::whereHasPendingPayment()->count(); return [ 'members' => $members, 'total_members' => Member::count(), - 'amount' => number_format((int) $amount->nr / 100, 2, ',', '.').' €', + 'amount' => number_format((int) $amount->price / 100, 2, ',', '.') . ' €', ]; } diff --git a/app/Invoice/Models/Invoice.php b/app/Invoice/Models/Invoice.php index d2e86087..062dd584 100644 --- a/app/Invoice/Models/Invoice.php +++ b/app/Invoice/Models/Invoice.php @@ -5,6 +5,7 @@ namespace App\Invoice\Models; use App\Invoice\BillKind; use App\Invoice\Enums\InvoiceStatus; use App\Member\Member; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\HasMany; @@ -55,4 +56,14 @@ class Invoice extends Model $model->positions()->delete(); }); } + + /** + * @param Builder $query + * + * @return Builder + */ + public function scopeWhereNeedsPayment(Builder $query): Builder + { + return $query->whereIn('status', [InvoiceStatus::NEW->value, InvoiceStatus::SENT->value]); + } } diff --git a/app/Member/Member.php b/app/Member/Member.php index b26d05d0..5d1921f7 100644 --- a/app/Member/Member.php +++ b/app/Member/Member.php @@ -342,9 +342,7 @@ class Member extends Model implements Geolocatable */ public function scopeWhereHasPendingPayment(Builder $query): Builder { - return $query->whereHas('payments', function (Builder $q): void { - $q->whereNeedsPayment(); - }); + return $query->whereHas('invoicePositions', fn ($q) => $q->whereHas('invoice', fn ($q) => $q->whereNeedsPayment())); } /** diff --git a/database/factories/Invoice/Models/InvoicePositionFactory.php b/database/factories/Invoice/Models/InvoicePositionFactory.php index 0cc65f23..7708b418 100644 --- a/database/factories/Invoice/Models/InvoicePositionFactory.php +++ b/database/factories/Invoice/Models/InvoicePositionFactory.php @@ -22,7 +22,6 @@ class InvoicePositionFactory extends Factory { return [ 'description' => $this->faker->words(4, true), - 'member_id' => Member::factory()->defaults()->create()->id, 'price' => $this->faker->numberBetween(1000, 2000), ]; } @@ -31,4 +30,9 @@ class InvoicePositionFactory extends Factory { return $this->state(['price' => $price]); } + + public function withMember(): self + { + return $this->state(['member_id' => Member::factory()->defaults()->create()->id]); + } } diff --git a/tests/Feature/Invoice/MemberPaymentBlockTest.php b/tests/Feature/Invoice/MemberPaymentBlockTest.php new file mode 100644 index 00000000..60e59832 --- /dev/null +++ b/tests/Feature/Invoice/MemberPaymentBlockTest.php @@ -0,0 +1,38 @@ +login()->loginNami(); + + $member = Member::factory()->defaults()->create(); + Member::factory()->defaults()->create(); + Invoice::factory() + ->has(InvoicePosition::factory()->price(3500)->for($member), 'positions') + ->has(InvoicePosition::factory()->price(1000)->for($member), 'positions') + ->status(InvoiceStatus::SENT)->create(); + Invoice::factory()->has(InvoicePosition::factory()->price(600)->for($member), 'positions')->status(InvoiceStatus::NEW)->create(); + Invoice::factory()->has(InvoicePosition::factory()->price(1000)->for($member), 'positions')->status(InvoiceStatus::PAID)->create(); + + $data = app(MemberPaymentBlock::class)->render()['data']; + + $this->assertEquals([ + 'amount' => '51,00 €', + 'members' => 1, + 'total_members' => 2, + ], $data); + } +} diff --git a/tests/Feature/Payment/MemberPaymentsBlockTest.php b/tests/Feature/Payment/MemberPaymentsBlockTest.php deleted file mode 100644 index c006d0bf..00000000 --- a/tests/Feature/Payment/MemberPaymentsBlockTest.php +++ /dev/null @@ -1,39 +0,0 @@ -login()->loginNami(); - - Member::factory() - ->defaults() - ->has(Payment::factory()->notPaid()->subscription('example', [ - new Child('gg', 3400), - new Child('gg', 100), - ])) - ->create(); - Member::factory() - ->defaults() - ->create(); - - $data = app(MemberPaymentBlock::class)->render()['data']; - - $this->assertEquals([ - 'amount' => '35,00 €', - 'members' => 1, - 'total_members' => 2, - ], $data); - } -}