From 7cef74350dea96d77d040dfcf835a4678c651b6e Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 22 Apr 2021 09:35:31 +1000 Subject: [PATCH] Fix for accounting error when deleting a refunded payment --- app/Services/Payment/DeletePayment.php | 12 ++-- tests/Feature/PaymentTest.php | 96 ++++++++++++++++++++++++++ tests/Unit/InvoiceTest.php | 6 -- 3 files changed, 103 insertions(+), 11 deletions(-) diff --git a/app/Services/Payment/DeletePayment.php b/app/Services/Payment/DeletePayment.php index b0fd8aeab657..3a598e547eaf 100644 --- a/app/Services/Payment/DeletePayment.php +++ b/app/Services/Payment/DeletePayment.php @@ -80,19 +80,21 @@ class DeletePayment $this->payment->invoices()->each(function ($paymentable_invoice) { + $net_deletable = $paymentable_invoice->pivot->amount - $paymentable_invoice->pivot->refunded; + $paymentable_invoice->service() - ->updateBalance($paymentable_invoice->pivot->amount) - ->updatePaidToDate($paymentable_invoice->pivot->amount * -1) + ->updateBalance($net_deletable) + ->updatePaidToDate($net_deletable * -1) ->save(); $paymentable_invoice->ledger() - ->updateInvoiceBalance($paymentable_invoice->pivot->amount, "Adjusting invoice {$paymentable_invoice->number} due to deletion of Payment {$this->payment->number}") + ->updateInvoiceBalance($net_deletable, "Adjusting invoice {$paymentable_invoice->number} due to deletion of Payment {$this->payment->number}") ->save(); $paymentable_invoice->client ->service() - ->updateBalance($paymentable_invoice->pivot->amount) - ->updatePaidToDate($paymentable_invoice->pivot->amount * -1) + ->updateBalance($net_deletable) + ->updatePaidToDate($net_deletable * -1) ->save(); if ($paymentable_invoice->balance == $paymentable_invoice->amount) { diff --git a/tests/Feature/PaymentTest.php b/tests/Feature/PaymentTest.php index 11a1387256af..8afad2a18e9f 100644 --- a/tests/Feature/PaymentTest.php +++ b/tests/Feature/PaymentTest.php @@ -14,6 +14,7 @@ use App\DataMapper\ClientSettings; use App\Factory\ClientFactory; use App\Factory\CreditFactory; use App\Factory\InvoiceFactory; +use App\Factory\InvoiceItemFactory; use App\Factory\PaymentFactory; use App\Helpers\Invoice\InvoiceSum; use App\Models\Client; @@ -1385,4 +1386,99 @@ class PaymentTest extends TestCase $this->assertEquals(1, $arr['data'][0]['is_deleted']); } + + + public function testDeleteRefundedPayment() + { + + $this->invoice = null; + + $client = ClientFactory::create($this->company->id, $this->user->id); + $client->save(); + + $this->invoice = InvoiceFactory::create($this->company->id, $this->user->id); //stub the company and user_id + $this->invoice->client_id = $client->id; + + + $item = InvoiceItemFactory::create(); + $item->quantity = 1; + $item->cost = 10; + $item->product_key = 'test'; + $item->notes = 'test'; + $item->custom_value1 = ''; + $item->custom_value2 = ''; + $item->custom_value3 = ''; + $item->custom_value4 = ''; + + $line_items[] = $item; + + $this->invoice->line_items = $line_items; + $this->invoice->uses_inclusive_taxes = false; + + $this->invoice->save(); + + $this->invoice_calc = new InvoiceSum($this->invoice); + $this->invoice_calc->build(); + + $this->invoice = $this->invoice_calc->getInvoice(); + $this->invoice->save(); + $this->invoice->service()->markSent()->save(); + + + $this->assertEquals(10, $this->invoice->balance); + $this->assertEquals(10, $this->invoice->client->balance); + + $this->invoice->service()->markPaid()->save(); + + $this->assertEquals(0, $this->invoice->balance); + $this->assertEquals(0, $this->invoice->client->balance); + + $this->assertTrue($this->invoice->payments()->exists()); + + $payment = $this->invoice->payments()->first(); + + $data = [ + 'id' => $this->encodePrimaryKey($payment->id), + 'amount' => 10, + 'date' => '2021/12/12', + 'invoices' => [ + [ + 'invoice_id' => $this->invoice->hashed_id, + 'amount' => 10, + ], + ], + ]; + + $response = false; + + try { + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->post('/api/v1/payments/refund', $data); + } catch (ValidationException $e) { + $message = json_decode($e->validator->getMessageBag(), 1); + nlog($message); + } + + $arr = $response->json(); + + $response->assertStatus(200); + + $this->assertEquals(10, $this->invoice->fresh()->balance); + $this->assertEquals(10, $this->invoice->fresh()->balance); + + $data = [ + 'ids' => [$this->encodePrimaryKey($payment->id)], + ]; + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->post('/api/v1/payments/bulk?action=delete', $data); + + $this->assertEquals(10, $this->invoice->fresh()->balance); + $this->assertEquals(10, $this->invoice->fresh()->balance); + } } + diff --git a/tests/Unit/InvoiceTest.php b/tests/Unit/InvoiceTest.php index ed8c26308f03..034d27a16c7c 100644 --- a/tests/Unit/InvoiceTest.php +++ b/tests/Unit/InvoiceTest.php @@ -222,11 +222,5 @@ class InvoiceTest extends TestCase //$this->assertEquals(count($this->invoice_calc->getTaxMap()), 1); } - public function testSentStatus() - { - $this->invoice->due_date = now()->addMonth(); - $this->invoice->status_id = Invoice::STATUS_SENT; - $this->assertEquals(Invoice::STATUS_SENT, $this->invoice->getStatusAttribute()); - } }