From 7b4b3e3f5e30c486055a66c230d7ef23ff06b40c Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 21 Apr 2021 20:46:24 +1000 Subject: [PATCH 1/5] tests --- tests/Unit/GeneratesCounterTest.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/Unit/GeneratesCounterTest.php b/tests/Unit/GeneratesCounterTest.php index dad4066938..28ce0e90c8 100644 --- a/tests/Unit/GeneratesCounterTest.php +++ b/tests/Unit/GeneratesCounterTest.php @@ -348,6 +348,10 @@ class GeneratesCounterTest extends TestCase $this->assertEquals($vendor_number, date('Y').'-'.str_pad($vendor->user_id, 2, '0', STR_PAD_LEFT).'-0002'); } + public function testResetCounter() + { + + } /* public function testClientNextNumber() From af7939b002e0ed9259a9adde49ae570b6855ad40 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 21 Apr 2021 20:57:34 +1000 Subject: [PATCH 2/5] Small fixes for one time tokens --- app/Http/Controllers/OneTimeTokenController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/OneTimeTokenController.php b/app/Http/Controllers/OneTimeTokenController.php index d5079ce055..25f734a634 100644 --- a/app/Http/Controllers/OneTimeTokenController.php +++ b/app/Http/Controllers/OneTimeTokenController.php @@ -88,9 +88,9 @@ class OneTimeTokenController extends BaseController MultiDB::findAndSetDbByCompanyKey($data['company_key']); - $user = User::findOrFail($data['user_id']); + // $user = User::findOrFail($data['user_id']); - Auth::login($user, true); + // Auth::login($user, true); // Cache::forget($request->input('hash')); From fc223e3432f332803057cd45d0322bbe90e107ec Mon Sep 17 00:00:00 2001 From: = Date: Wed, 21 Apr 2021 22:27:08 +1000 Subject: [PATCH 3/5] Fixes for invoice status --- VERSION.txt | 2 +- app/Models/Invoice.php | 19 ++++++++--- tests/Unit/InvoiceStatusTest.php | 58 ++++++++++++++++++++++++++++++++ tests/Unit/InvoiceTest.php | 9 +++++ 4 files changed, 82 insertions(+), 6 deletions(-) create mode 100644 tests/Unit/InvoiceStatusTest.php diff --git a/VERSION.txt b/VERSION.txt index b72061af4e..0b2699b27e 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -5.1.49 \ No newline at end of file +5.1.50 \ No newline at end of file diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php index dadfa3e222..ab11b83696 100644 --- a/app/Models/Invoice.php +++ b/app/Models/Invoice.php @@ -245,21 +245,30 @@ class Invoice extends BaseModel public function getStatusAttribute() { - if ($this->status_id == self::STATUS_SENT && $this->due_date > Carbon::now()) { + $due_date = $this->due_date ? Carbon::parse($this->due_date) : false; + $partial_due_date = $this->partial_due_Date ? Carbon::parse($this->partial_due_date) : false; + + if ($this->status_id == self::STATUS_SENT && $due_date && $due_date->gt(now())) { + nlog("1 unpaid"); return self::STATUS_UNPAID; - } elseif ($this->status_id == self::STATUS_PARTIAL && $this->partial_due_date > Carbon::now()) { - return self::STATUS_UNPAID; - } elseif ($this->status_id == self::STATUS_SENT && $this->due_date < Carbon::now()) { + } elseif ($this->status_id == self::STATUS_PARTIAL && $partial_due_date && $partial_due_date->gt(now())) { + nlog("2 partial"); + return self::STATUS_PARTIAL; + } elseif ($this->status_id == self::STATUS_SENT && $due_date && $due_date->lt(now())) { + nlog("3 overdue"); return self::STATUS_OVERDUE; - } elseif ($this->status_id == self::STATUS_PARTIAL && $this->partial_due_date < Carbon::now()) { + } elseif ($this->status_id == self::STATUS_PARTIAL && $partial_due_date && $partial_due_date->lt(now())) { + nlog("4 overdue"); return self::STATUS_OVERDUE; } else { + nlog("status id "); return $this->status_id; } } public function isPayable(): bool { + if ($this->status_id == self::STATUS_DRAFT && $this->is_deleted == false) { return true; } elseif ($this->status_id == self::STATUS_SENT && $this->is_deleted == false) { diff --git a/tests/Unit/InvoiceStatusTest.php b/tests/Unit/InvoiceStatusTest.php new file mode 100644 index 0000000000..fb58f5f74d --- /dev/null +++ b/tests/Unit/InvoiceStatusTest.php @@ -0,0 +1,58 @@ +makeTestData(); + + } + + public function testSentStatus() + { + $this->invoice->due_date = now()->addMonth(); + $this->invoice->status_id = Invoice::STATUS_SENT; + + $this->assertEquals(Invoice::STATUS_UNPAID, $this->invoice->getStatusAttribute()); + } + + public function testPartialStatus() + { + $this->invoice->partial_due_date = now()->addMonth(); + $this->invoice->status_id = Invoice::STATUS_SENT; + + $this->assertEquals(Invoice::STATUS_SENT, $this->invoice->getStatusAttribute()); + } +} diff --git a/tests/Unit/InvoiceTest.php b/tests/Unit/InvoiceTest.php index 4ebd38500c..ed8c26308f 100644 --- a/tests/Unit/InvoiceTest.php +++ b/tests/Unit/InvoiceTest.php @@ -12,6 +12,7 @@ namespace Tests\Unit; use App\Factory\InvoiceItemFactory; use App\Helpers\Invoice\InvoiceSum; +use App\Models\Invoice; use Illuminate\Foundation\Testing\DatabaseTransactions; use Tests\MockAccountData; use Tests\TestCase; @@ -220,4 +221,12 @@ class InvoiceTest extends TestCase //$this->assertEquals($this->invoice_calc->getTotalTaxes(), 4); //$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()); + } } From 7cef74350dea96d77d040dfcf835a4678c651b6e Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 22 Apr 2021 09:35:31 +1000 Subject: [PATCH 4/5] 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 b0fd8aeab6..3a598e547e 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 11a1387256..8afad2a18e 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 ed8c26308f..034d27a16c 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()); - } } From 1856ed061bb961443ce67a254d74c485b58525e4 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 22 Apr 2021 10:10:20 +1000 Subject: [PATCH 5/5] Test for resetting the date --- tests/Unit/GeneratesCounterTest.php | 42 ++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/tests/Unit/GeneratesCounterTest.php b/tests/Unit/GeneratesCounterTest.php index 28ce0e90c8..5c06ed6729 100644 --- a/tests/Unit/GeneratesCounterTest.php +++ b/tests/Unit/GeneratesCounterTest.php @@ -18,6 +18,7 @@ use App\Models\Company; use App\Models\Credit; use App\Models\Invoice; use App\Models\RecurringInvoice; +use App\Models\Timezone; use App\Utils\Traits\GeneratesCounter; use App\Utils\Traits\MakesHash; use Illuminate\Database\Eloquent\Model; @@ -48,6 +49,42 @@ class GeneratesCounterTest extends TestCase $this->makeTestData(); } + public function testResetCounter() + { + $timezone = Timezone::find(1); + + $date_formatted = now($timezone->name)->format('Ymd'); + + $settings = $this->company->settings; + $settings->invoice_number_pattern = '{$date:Ymd}-{$counter}'; + $settings->timezone_id = 1; + $this->company->settings = $settings; + $this->company->save(); + + $this->client->settings = $settings; + $this->client->save(); + + $invoice_number = $this->getNextInvoiceNumber($this->client->fresh(), $this->invoice->fresh()); + $this->assertEquals($date_formatted."-0001", $invoice_number); + $invoice_number = $this->getNextInvoiceNumber($this->client->fresh(), $this->invoice->fresh()); + $this->assertEquals($date_formatted."-0002", $invoice_number); + + $settings->reset_counter_date = now($timezone->name)->format('Y-m-d'); + $settings->reset_counter_frequency_id = RecurringInvoice::FREQUENCY_DAILY; + $this->company->settings = $settings; + $this->company->save(); + + $this->client->settings = $settings; + $this->client->save(); + + $this->travel(5)->days(); + $date_formatted = now($timezone->name)->format('Ymd'); + + $invoice_number = $this->getNextInvoiceNumber($this->client->fresh(), $this->invoice->fresh()); + $this->assertEquals($date_formatted."-0001", $invoice_number); + + } + public function testHasSharedCounter() { $this->assertFalse($this->hasSharedCounter($this->client)); @@ -348,10 +385,7 @@ class GeneratesCounterTest extends TestCase $this->assertEquals($vendor_number, date('Y').'-'.str_pad($vendor->user_id, 2, '0', STR_PAD_LEFT).'-0002'); } - public function testResetCounter() - { - - } + /* public function testClientNextNumber()