From 5945857033189cb74555d947319d3a4ddf074b61 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Fri, 15 Sep 2023 20:12:39 +1000 Subject: [PATCH 1/7] Fixes for recurring expense factory --- app/Factory/RecurringExpenseFactory.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/Factory/RecurringExpenseFactory.php b/app/Factory/RecurringExpenseFactory.php index 15d000334c17..d39942fea679 100644 --- a/app/Factory/RecurringExpenseFactory.php +++ b/app/Factory/RecurringExpenseFactory.php @@ -36,6 +36,7 @@ class RecurringExpenseFactory $recurring_expense->tax_amount3 = 0; $recurring_expense->date = now()->format('Y-m-d'); $recurring_expense->next_send_date = now()->format('Y-m-d'); + $recurring_expense->next_send_date_client = now()->format('Y-m-d'); $recurring_expense->payment_date = null; $recurring_expense->amount = 0; $recurring_expense->foreign_amount = 0; From 59130006b98e91981e3851d3d90d6b8398fbf0df Mon Sep 17 00:00:00 2001 From: David Bomba Date: Fri, 15 Sep 2023 22:44:55 +1000 Subject: [PATCH 2/7] Updated lock --- composer.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index 49dc0b294acd..c6198f956b1f 100644 --- a/composer.lock +++ b/composer.lock @@ -10112,16 +10112,16 @@ }, { "name": "spatie/laravel-data", - "version": "3.8.1", + "version": "3.9.0", "source": { "type": "git", "url": "https://github.com/spatie/laravel-data.git", - "reference": "7ead3d8f761846185a94d06e584bfe17e43b9239" + "reference": "21bad55113a1e1e5180a0f89b695f02ce1732aef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-data/zipball/7ead3d8f761846185a94d06e584bfe17e43b9239", - "reference": "7ead3d8f761846185a94d06e584bfe17e43b9239", + "url": "https://api.github.com/repos/spatie/laravel-data/zipball/21bad55113a1e1e5180a0f89b695f02ce1732aef", + "reference": "21bad55113a1e1e5180a0f89b695f02ce1732aef", "shasum": "" }, "require": { @@ -10183,7 +10183,7 @@ ], "support": { "issues": "https://github.com/spatie/laravel-data/issues", - "source": "https://github.com/spatie/laravel-data/tree/3.8.1" + "source": "https://github.com/spatie/laravel-data/tree/3.9.0" }, "funding": [ { @@ -10191,7 +10191,7 @@ "type": "github" } ], - "time": "2023-08-11T11:59:07+00:00" + "time": "2023-09-15T12:04:39+00:00" }, { "name": "spatie/laravel-package-tools", From d308173500817aed2fca0cb37cea891c513c48d7 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sun, 17 Sep 2023 12:40:24 +1000 Subject: [PATCH 3/7] Fixes for tax providers and blank credentials --- app/Services/Tax/Providers/TaxProvider.php | 24 ++++++++------- composer.lock | 36 +++++++++++----------- 2 files changed, 31 insertions(+), 29 deletions(-) diff --git a/app/Services/Tax/Providers/TaxProvider.php b/app/Services/Tax/Providers/TaxProvider.php index 980a9d292641..9598813b80f9 100644 --- a/app/Services/Tax/Providers/TaxProvider.php +++ b/app/Services/Tax/Providers/TaxProvider.php @@ -75,18 +75,20 @@ class TaxProvider */ public function updateCompanyTaxData(): self { - $this->configureProvider($this->provider, $this->company->country()->iso_3166_2); //hard coded for now to one provider, but we'll be able to swap these out later - - $company_details = [ - 'address2' => $this->company->settings->address2, - 'address1' => $this->company->settings->address1, - 'city' => $this->company->settings->city, - 'state' => $this->company->settings->state, - 'postal_code' => $this->company->settings->postal_code, - 'country' => $this->company->country()->name, - ]; try { + + $this->configureProvider($this->provider, $this->company->country()->iso_3166_2); //hard coded for now to one provider, but we'll be able to swap these out later + + $company_details = [ + 'address2' => $this->company->settings->address2, + 'address1' => $this->company->settings->address1, + 'city' => $this->company->settings->city, + 'state' => $this->company->settings->state, + 'postal_code' => $this->company->settings->postal_code, + 'country' => $this->company->country()->name, + ]; + $tax_provider = new $this->provider($company_details); $tax_provider->setApiCredentials($this->api_credentials); @@ -143,7 +145,7 @@ class TaxProvider $tax_data = $tax_provider->run(); - nlog($tax_data); + // nlog($tax_data); if($tax_data) { $this->client->tax_data = $tax_data; diff --git a/composer.lock b/composer.lock index c6198f956b1f..9dbe7b09487b 100644 --- a/composer.lock +++ b/composer.lock @@ -525,16 +525,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.281.7", + "version": "3.281.8", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "926cea9a41a545ca9801ac304f2a9ffd23ac68c9" + "reference": "eb349b9f31502a05c70362f57913b9fed6b65b1f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/926cea9a41a545ca9801ac304f2a9ffd23ac68c9", - "reference": "926cea9a41a545ca9801ac304f2a9ffd23ac68c9", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/eb349b9f31502a05c70362f57913b9fed6b65b1f", + "reference": "eb349b9f31502a05c70362f57913b9fed6b65b1f", "shasum": "" }, "require": { @@ -614,9 +614,9 @@ "support": { "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.281.7" + "source": "https://github.com/aws/aws-sdk-php/tree/3.281.8" }, - "time": "2023-09-14T18:05:11+00:00" + "time": "2023-09-15T18:34:59+00:00" }, { "name": "bacon/bacon-qr-code", @@ -8062,16 +8062,16 @@ }, { "name": "phpseclib/phpseclib", - "version": "3.0.21", + "version": "3.0.22", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "4580645d3fc05c189024eb3b834c6c1e4f0f30a1" + "reference": "b6bd1c5f79b2c39e144770eb6d9180fbdb00d09b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/4580645d3fc05c189024eb3b834c6c1e4f0f30a1", - "reference": "4580645d3fc05c189024eb3b834c6c1e4f0f30a1", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/b6bd1c5f79b2c39e144770eb6d9180fbdb00d09b", + "reference": "b6bd1c5f79b2c39e144770eb6d9180fbdb00d09b", "shasum": "" }, "require": { @@ -8152,7 +8152,7 @@ ], "support": { "issues": "https://github.com/phpseclib/phpseclib/issues", - "source": "https://github.com/phpseclib/phpseclib/tree/3.0.21" + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.22" }, "funding": [ { @@ -8168,7 +8168,7 @@ "type": "tidelift" } ], - "time": "2023-07-09T15:24:48+00:00" + "time": "2023-09-16T11:49:37+00:00" }, { "name": "phpstan/phpdoc-parser", @@ -15793,16 +15793,16 @@ }, { "name": "phpmyadmin/sql-parser", - "version": "5.8.0", + "version": "5.8.1", "source": { "type": "git", "url": "https://github.com/phpmyadmin/sql-parser.git", - "reference": "db1b3069b5dbc220d393d67ff911e0ae76732755" + "reference": "b877ee6262a00f0f498da5e01335e8a5dc01d203" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpmyadmin/sql-parser/zipball/db1b3069b5dbc220d393d67ff911e0ae76732755", - "reference": "db1b3069b5dbc220d393d67ff911e0ae76732755", + "url": "https://api.github.com/repos/phpmyadmin/sql-parser/zipball/b877ee6262a00f0f498da5e01335e8a5dc01d203", + "reference": "b877ee6262a00f0f498da5e01335e8a5dc01d203", "shasum": "" }, "require": { @@ -15824,7 +15824,7 @@ "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", "psalm/plugin-phpunit": "^0.16.1", "vimeo/psalm": "^4.11", - "zumba/json-serializer": "^3.0" + "zumba/json-serializer": "~3.0.2" }, "suggest": { "ext-mbstring": "For best performance", @@ -15876,7 +15876,7 @@ "type": "other" } ], - "time": "2023-06-05T18:19:38+00:00" + "time": "2023-09-15T18:21:22+00:00" }, { "name": "phpstan/phpstan", From eda0044c429f7c1a1b945ce085069d57119783ad Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sun, 17 Sep 2023 18:44:05 +1000 Subject: [PATCH 4/7] Add webhooks for gocardless --- app/Models/Gateway.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/Models/Gateway.php b/app/Models/Gateway.php index 80c5b391d7c0..681889a68e88 100644 --- a/app/Models/Gateway.php +++ b/app/Models/Gateway.php @@ -175,10 +175,10 @@ class Gateway extends StaticModel ]; case 52: return [ - GatewayType::BANK_TRANSFER => ['refund' => false, 'token_billing' => true, 'webhooks' => [' ']], // GoCardless - GatewayType::DIRECT_DEBIT => ['refund' => false, 'token_billing' => true, 'webhooks' => [' ']], - GatewayType::SEPA => ['refund' => false, 'token_billing' => true, 'webhooks' => [' ']], - GatewayType::INSTANT_BANK_PAY => ['refund' => false, 'token_billing' => true, 'webhooks' => [' ']], + GatewayType::BANK_TRANSFER => ['refund' => false, 'token_billing' => true, 'webhooks' => ['confirmed','paid_out','failed','fulfilled']], // GoCardless + GatewayType::DIRECT_DEBIT => ['refund' => false, 'token_billing' => true, 'webhooks' => ['confirmed','paid_out','failed','fulfilled']], + GatewayType::SEPA => ['refund' => false, 'token_billing' => true, 'webhooks' => ['confirmed','paid_out','failed','fulfilled']], + GatewayType::INSTANT_BANK_PAY => ['refund' => false, 'token_billing' => true, 'webhooks' => ['confirmed','paid_out','failed','fulfilled']], ]; case 58: return [ From 21862adbae2c434f375760e91697f51288fde14b Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sun, 17 Sep 2023 19:11:04 +1000 Subject: [PATCH 5/7] Fixes for tess --- .../PaymentAppliedValidAmount.php | 6 + tests/Feature/PaymentTest.php | 387 +++++++++--------- 2 files changed, 195 insertions(+), 198 deletions(-) diff --git a/app/Http/ValidationRules/PaymentAppliedValidAmount.php b/app/Http/ValidationRules/PaymentAppliedValidAmount.php index 1d674e07d8c5..2958f04229cf 100644 --- a/app/Http/ValidationRules/PaymentAppliedValidAmount.php +++ b/app/Http/ValidationRules/PaymentAppliedValidAmount.php @@ -90,6 +90,12 @@ class PaymentAppliedValidAmount implements Rule return false; } } + + if(count($this->input['invoices']) >=1 && $payment->status_id == Payment::STATUS_PENDING){ + $this->message = 'Cannot apply a payment until the status is completed.'; + return false; + } + } if (round($payment_amounts, 3) >= round($invoice_amounts, 3)) { diff --git a/tests/Feature/PaymentTest.php b/tests/Feature/PaymentTest.php index 25cd22f894b2..e62ea4502b05 100644 --- a/tests/Feature/PaymentTest.php +++ b/tests/Feature/PaymentTest.php @@ -42,6 +42,8 @@ class PaymentTest extends TestCase use DatabaseTransactions; use MockAccountData; + public $faker; + protected function setUp() :void { parent::setUp(); @@ -53,13 +55,49 @@ class PaymentTest extends TestCase Model::reguard(); $this->makeTestData(); - $this->withoutExceptionHandling(); + // $this->withoutExceptionHandling(); $this->withoutMiddleware( ThrottleRequests::class ); } + public function testPendingPaymentLogic() + { + $payment = Payment::factory()->create([ + 'company_id' => $this->company->id, + 'user_id' => $this->user->id, + 'client_id' => $this->client->id, + 'status_id' => Payment::STATUS_PENDING, + 'amount' => 100 + ]); + + $data = [ + 'amount' => $this->invoice->amount, + 'client_id' => $this->client->hashed_id, + 'invoices' => [ + [ + 'invoice_id' => $this->invoice->hashed_id, + 'amount' => $this->invoice->amount, + ], + ], + 'date' => '2020/12/11', + 'idempotency_key' => 'dsjafhajklsfhlaksjdhlkajsdjdfjdfljasdfhkjlsafhljfkfhsjlfhiuwayerfiuwaskjgbzmvnjzxnjcbgfkjhdgfoiwwrasdfasdfkashjdfkaskfjdasfda' + + ]; + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->putJson('/api/v1/payments/'.$payment->hashed_id, $data); + + $response->assertStatus(422); + + } + + + + public function testPaymentGetBetweenQuery1() { $response = $this->withHeaders([ @@ -185,16 +223,15 @@ class PaymentTest extends TestCase ]; $response = false; - try { - $response = $this->withHeaders([ - 'X-API-SECRET' => config('ninja.api_secret'), - 'X-API-TOKEN' => $this->token, - ])->post('/api/v1/payments/', $data); - } catch (ValidationException $e) { - // $message = json_decode($e->validator->getMessageBag(), 1); - } + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->postJson('/api/v1/payments/', $data); + + $response->assertStatus(422); - $this->assertFalse($response); + // $this->assertFalse($response); } @@ -245,7 +282,7 @@ class PaymentTest extends TestCase $response = $this->withHeaders([ 'X-API-SECRET' => config('ninja.api_secret'), 'X-API-TOKEN' => $this->token, - ])->put('/api/v1/payments/'.$this->encodePrimaryKey($Payment->id), $Payment->toArray()); + ])->putJson('/api/v1/payments/'.$this->encodePrimaryKey($Payment->id), $Payment->toArray()); $response->assertStatus(200); @@ -287,16 +324,17 @@ class PaymentTest extends TestCase ]; - try { $response = $this->withHeaders([ 'X-API-SECRET' => config('ninja.api_secret'), 'X-API-TOKEN' => $this->token, - ])->post('/api/v1/payments/', $data); - } catch (ValidationException $e) { - $message = json_decode($e->validator->getMessageBag(), 1); + ])->postJson('/api/v1/payments/', $data); + // } catch (ValidationException $e) { + // $message = json_decode($e->validator->getMessageBag(), 1); - $this->assertTrue(array_key_exists('client_id', $message)); - } + $response->assertStatus(422); + + // $this->assertTrue(array_key_exists('client_id', $message)); + // } } public function testStorePaymentWithClientId() @@ -339,15 +377,17 @@ class PaymentTest extends TestCase $response = null; - try { + // try { $response = $this->withHeaders([ 'X-API-SECRET' => config('ninja.api_secret'), 'X-API-TOKEN' => $this->token, - ])->post('/api/v1/payments?include=invoices,paymentables', $data); - } catch (ValidationException $e) { - $message = json_decode($e->validator->getMessageBag(), 1); - $this->assertNotNull($message); - } + ])->postJson('/api/v1/payments?include=invoices,paymentables', $data); + // } catch (ValidationException $e) { + // $message = json_decode($e->validator->getMessageBag(), 1); + // $this->assertNotNull($message); + // } + + if ($response) { $arr = $response->json(); @@ -399,19 +439,19 @@ class PaymentTest extends TestCase $response = false; - try { + // try { $response = $this->withHeaders([ 'X-API-SECRET' => config('ninja.api_secret'), 'X-API-TOKEN' => $this->token, - ])->post('/api/v1/payments?include=invoices', $data); - } catch (ValidationException $e) { - $message = json_decode($e->validator->getMessageBag(), 1); - $this->assertNotNull($message); - } + ])->postJson('/api/v1/payments?include=invoices', $data); + // } catch (ValidationException $e) { + // $message = json_decode($e->validator->getMessageBag(), 1); + // $this->assertNotNull($message); + // } - if ($response) { + // if ($response) { $response->assertStatus(200); - } + // } } public function testPartialPaymentAmount() @@ -455,37 +495,29 @@ class PaymentTest extends TestCase 'date' => '2019/12/12', ]; - $response = false; + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->postJson('/api/v1/payments?include=invoices', $data); + + $response->assertStatus(200); - try { - $response = $this->withHeaders([ - 'X-API-SECRET' => config('ninja.api_secret'), - 'X-API-TOKEN' => $this->token, - ])->post('/api/v1/payments?include=invoices', $data); - } catch (ValidationException $e) { - $message = json_decode($e->validator->getMessageBag(), 1); - $this->assertNotNull($message); - } + $arr = $response->json(); - if ($response) { - $response->assertStatus(200); + $payment_id = $arr['data']['id']; - $arr = $response->json(); + $payment = Payment::whereId($this->decodePrimaryKey($payment_id))->first(); - $payment_id = $arr['data']['id']; + $this->assertNotNull($payment); + $this->assertNotNull($payment->invoices()); + $this->assertEquals(1, $payment->invoices()->count()); - $payment = Payment::whereId($this->decodePrimaryKey($payment_id))->first(); - - $this->assertNotNull($payment); - $this->assertNotNull($payment->invoices()); - $this->assertEquals(1, $payment->invoices()->count()); - - $pivot_invoice = $payment->invoices()->first(); - $this->assertEquals($pivot_invoice->pivot->amount, 2); - $this->assertEquals($pivot_invoice->partial, 0); - $this->assertEquals($pivot_invoice->amount, 10.0000); - $this->assertEquals($pivot_invoice->balance, 8.0000); - } + $pivot_invoice = $payment->invoices()->first(); + $this->assertEquals($pivot_invoice->pivot->amount, 2); + $this->assertEquals($pivot_invoice->partial, 0); + $this->assertEquals($pivot_invoice->amount, 10.0000); + $this->assertEquals($pivot_invoice->balance, 8.0000); + } public function testPaymentGreaterThanPartial() @@ -539,14 +571,14 @@ class PaymentTest extends TestCase $response = false; - try { + // try { $response = $this->withHeaders([ 'X-API-SECRET' => config('ninja.api_secret'), 'X-API-TOKEN' => $this->token, - ])->post('/api/v1/payments?include=invoices', $data); - } catch (ValidationException $e) { - $message = json_decode($e->validator->getMessageBag(), 1); - } + ])->postJson('/api/v1/payments?include=invoices', $data); + // } catch (ValidationException $e) { + // $message = json_decode($e->validator->getMessageBag(), 1); + // } $arr = $response->json(); $response->assertStatus(200); @@ -618,7 +650,7 @@ class PaymentTest extends TestCase $response = $this->withHeaders([ 'X-API-SECRET' => config('ninja.api_secret'), 'X-API-TOKEN' => $this->token, - ])->post('/api/v1/payments?include=invoices', $data); + ])->postJson('/api/v1/payments?include=invoices', $data); $arr = $response->json(); $response->assertStatus(200); @@ -691,16 +723,17 @@ class PaymentTest extends TestCase 'date' => '2019/12/12', ]; - try { + // try { $response = $this->withHeaders([ 'X-API-SECRET' => config('ninja.api_secret'), 'X-API-TOKEN' => $this->token, - ])->post('/api/v1/payments?include=invoices', $data); - } catch (ValidationException $e) { - $message = json_decode($e->validator->getMessageBag(), 1); + ])->postJson('/api/v1/payments?include=invoices', $data); + // } catch (ValidationException $e) { + // $message = json_decode($e->validator->getMessageBag(), 1); + $response->assertStatus(422); - $this->assertTrue(array_key_exists('amount', $message)); - } + // $this->assertTrue(array_key_exists('amount', $message)); + // } } public function testPaymentChangesBalancesCorrectly() @@ -745,18 +778,18 @@ class PaymentTest extends TestCase $response = false; - try { + // try { $response = $this->withHeaders([ 'X-API-SECRET' => config('ninja.api_secret'), 'X-API-TOKEN' => $this->token, - ])->post('/api/v1/payments?include=invoices', $data); - } catch (ValidationException $e) { - $message = json_decode($e->validator->getMessageBag(), 1); + ])->postJson('/api/v1/payments?include=invoices', $data); + // } catch (ValidationException $e) { + // $message = json_decode($e->validator->getMessageBag(), 1); - $this->assertTrue(array_key_exists('amount', $message)); - } + // $this->assertTrue(array_key_exists('amount', $message)); + // } - if ($response) { + // if ($response) { $response->assertStatus(200); $invoice = Invoice::find($this->decodePrimaryKey($invoice->hashed_id)); @@ -766,7 +799,7 @@ class PaymentTest extends TestCase $payment = $invoice->payments()->first(); $this->assertEquals($payment->applied, 2); - } + // } } public function testUpdatePaymentValidationWorks() @@ -812,20 +845,20 @@ class PaymentTest extends TestCase $response = false; - try { + // try { $response = $this->withHeaders([ 'X-API-SECRET' => config('ninja.api_secret'), 'X-API-TOKEN' => $this->token, - ])->put('/api/v1/payments/'.$this->encodePrimaryKey($payment->id), $data); - } catch (ValidationException $e) { - $message = json_decode($e->validator->getMessageBag(), 1); + ])->putJson('/api/v1/payments/'.$this->encodePrimaryKey($payment->id), $data); + // } catch (ValidationException $e) { + // $message = json_decode($e->validator->getMessageBag(), 1); - $this->assertTrue(array_key_exists('invoices', $message)); - } + // $this->assertTrue(array_key_exists('invoices', $message)); + // }/ - if ($response) { + // if ($response) { $response->assertStatus(200); - } + // } } public function testUpdatePaymentValidationPasses() @@ -876,21 +909,21 @@ class PaymentTest extends TestCase $response = false; - try { + // try { $response = $this->withHeaders([ 'X-API-SECRET' => config('ninja.api_secret'), 'X-API-TOKEN' => $this->token, - ])->put('/api/v1/payments/'.$this->encodePrimaryKey($payment->id), $data); - } catch (ValidationException $e) { - $message = json_decode($e->validator->getMessageBag(), 1); - \Log::error(print_r($e->validator->getMessageBag(), 1)); + ])->putJson('/api/v1/payments/'.$this->encodePrimaryKey($payment->id), $data); + // } catch (ValidationException $e) { + // $message = json_decode($e->validator->getMessageBag(), 1); + // \Log::error(print_r($e->validator->getMessageBag(), 1)); - $this->assertTrue(array_key_exists('invoices', $message)); - } + // $this->assertTrue(array_key_exists('invoices', $message)); + // } - if ($response) { - $response->assertStatus(200); - } + // if ($response) { + $response->assertStatus(422); + // } } public function testDoublePaymentTestWithInvalidAmounts() @@ -935,15 +968,15 @@ class PaymentTest extends TestCase $response = false; - try { + // try { $response = $this->withHeaders([ 'X-API-SECRET' => config('ninja.api_secret'), 'X-API-TOKEN' => $this->token, - ])->post('/api/v1/payments/', $data); - } catch (ValidationException $e) { - $message = json_decode($e->validator->getMessageBag(), 1); - \Log::error(print_r($e->validator->getMessageBag(), 1)); - } + ])->postJson('/api/v1/payments/', $data); + // } catch (ValidationException $e) { + // $message = json_decode($e->validator->getMessageBag(), 1); + // \Log::error(print_r($e->validator->getMessageBag(), 1)); + // } $response->assertStatus(200); @@ -990,7 +1023,7 @@ class PaymentTest extends TestCase $response = $this->withHeaders([ 'X-API-SECRET' => config('ninja.api_secret'), 'X-API-TOKEN' => $this->token, - ])->put('/api/v1/payments/'.$this->encodePrimaryKey($payment->id), $data); + ])->putJson('/api/v1/payments/'.$this->encodePrimaryKey($payment->id), $data); } catch (ValidationException $e) { $message = json_decode($e->validator->getMessageBag(), 1); @@ -1040,7 +1073,7 @@ class PaymentTest extends TestCase $response = $this->withHeaders([ 'X-API-SECRET' => config('ninja.api_secret'), 'X-API-TOKEN' => $this->token, - ])->post('/api/v1/payments/', $data); + ])->postJson('/api/v1/payments/', $data); $response->assertStatus(200); @@ -1099,7 +1132,7 @@ class PaymentTest extends TestCase $response = $this->withHeaders([ 'X-API-SECRET' => config('ninja.api_secret'), 'X-API-TOKEN' => $this->token, - ])->post('/api/v1/payments?include=invoices', $data); + ])->postJson('/api/v1/payments?include=invoices', $data); } catch (ValidationException $e) { $message = json_decode($e->validator->getMessageBag(), 1); $this->assertNotNull($message); @@ -1163,7 +1196,7 @@ class PaymentTest extends TestCase $response = $this->withHeaders([ 'X-API-SECRET' => config('ninja.api_secret'), 'X-API-TOKEN' => $this->token, - ])->post('/api/v1/payments?include=invoices', $data); + ])->postJson('/api/v1/payments?include=invoices', $data); } catch (ValidationException $e) { $message = json_decode($e->validator->getMessageBag(), 1); $this->assertNotNull($message); @@ -1250,7 +1283,7 @@ class PaymentTest extends TestCase $response = $this->withHeaders([ 'X-API-SECRET' => config('ninja.api_secret'), 'X-API-TOKEN' => $this->token, - ])->post('/api/v1/payments?include=invoices', $data); + ])->postJson('/api/v1/payments?include=invoices', $data); } catch (ValidationException $e) { $message = json_decode($e->validator->getMessageBag(), 1); $this->assertNotNull($message); @@ -1299,19 +1332,15 @@ class PaymentTest extends TestCase ]; - $response = null; - - try { - $response = $this->withHeaders([ + + $response = $this->withHeaders([ 'X-API-SECRET' => config('ninja.api_secret'), 'X-API-TOKEN' => $this->token, - ])->post('/api/v1/payments?include=invoices', $data); - } catch (ValidationException $e) { - $message = json_decode($e->validator->getMessageBag(), 1); - $this->assertNotNull($message); - } + ])->postJson('/api/v1/payments?include=invoices', $data); + + $response->assertStatus(422); - $this->assertNull($response); + } public function testStorePaymentWithCredits() @@ -1351,7 +1380,7 @@ class PaymentTest extends TestCase $credit_calc = new InvoiceSum($credit); $credit_calc->build(); - $credit = $this->credit_calc->getCredit(); + $credit = $credit_calc->getCredit(); $credit->save(); //$10 credit $data = [ @@ -1365,7 +1394,7 @@ class PaymentTest extends TestCase ], 'credits' => [ [ - 'credit_id' => $credit->id, + 'credit_id' => $credit->hashed_id, 'amount' => 5, ], ], @@ -1373,30 +1402,22 @@ class PaymentTest extends TestCase ]; - $response = null; + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->postJson('/api/v1/payments?include=invoices', $data); - try { - $response = $this->withHeaders([ - 'X-API-SECRET' => config('ninja.api_secret'), - 'X-API-TOKEN' => $this->token, - ])->post('/api/v1/payments?include=invoices', $data); - } catch (ValidationException $e) { - $message = json_decode($e->validator->getMessageBag(), 1); - $this->assertNotNull($message); - } + $arr = $response->json(); + $response->assertStatus(200); - if ($response) { - $arr = $response->json(); - $response->assertStatus(200); + $payment_id = $arr['data']['id']; - $payment_id = $arr['data']['id']; + $payment = Payment::find($this->decodePrimaryKey($payment_id)); + + $this->assertNotNull($payment); + $this->assertNotNull($payment->invoices()); + $this->assertEquals(1, $payment->invoices()->count()); - $payment = Payment::find($this->decodePrimaryKey($payment_id))->first(); - - $this->assertNotNull($payment); - $this->assertNotNull($payment->invoices()); - $this->assertEquals(1, $payment->invoices()->count()); - } } public function testStorePaymentExchangeRate() @@ -1443,30 +1464,22 @@ class PaymentTest extends TestCase ]; - $response = null; + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->postJson('/api/v1/payments?include=invoices', $data); - try { - $response = $this->withHeaders([ - 'X-API-SECRET' => config('ninja.api_secret'), - 'X-API-TOKEN' => $this->token, - ])->post('/api/v1/payments?include=invoices', $data); - } catch (ValidationException $e) { - $message = json_decode($e->validator->getMessageBag(), 1); - $this->assertNotNull($message); - } + $arr = $response->json(); + $response->assertStatus(200); - if ($response) { - $arr = $response->json(); - $response->assertStatus(200); + $payment_id = $arr['data']['id']; - $payment_id = $arr['data']['id']; + $payment = Payment::find($this->decodePrimaryKey($payment_id)); - $payment = Payment::find($this->decodePrimaryKey($payment_id)); + $this->assertNotNull($payment); + $this->assertNotNull($payment->invoices()); + $this->assertEquals(1, $payment->invoices()->count()); - $this->assertNotNull($payment); - $this->assertNotNull($payment->invoices()); - $this->assertEquals(1, $payment->invoices()->count()); - } } public function testPaymentActionArchive() @@ -1512,7 +1525,7 @@ class PaymentTest extends TestCase $response = $this->withHeaders([ 'X-API-SECRET' => config('ninja.api_secret'), 'X-API-TOKEN' => $this->token, - ])->post('/api/v1/payments/', $data); + ])->postJson('/api/v1/payments/', $data); $response->assertStatus(200); @@ -1529,7 +1542,7 @@ class PaymentTest extends TestCase $response = $this->withHeaders([ 'X-API-SECRET' => config('ninja.api_secret'), 'X-API-TOKEN' => $this->token, - ])->post('/api/v1/payments/bulk?action=archive', $data); + ])->postJson('/api/v1/payments/bulk?action=archive', $data); $arr = $response->json(); @@ -1538,7 +1551,7 @@ class PaymentTest extends TestCase $response = $this->withHeaders([ 'X-API-SECRET' => config('ninja.api_secret'), 'X-API-TOKEN' => $this->token, - ])->post('/api/v1/payments/bulk?action=restore', $data); + ])->postJson('/api/v1/payments/bulk?action=restore', $data); $arr = $response->json(); @@ -1547,7 +1560,7 @@ class PaymentTest extends TestCase $response = $this->withHeaders([ 'X-API-SECRET' => config('ninja.api_secret'), 'X-API-TOKEN' => $this->token, - ])->post('/api/v1/payments/bulk?action=delete', $data); + ])->postJson('/api/v1/payments/bulk?action=delete', $data); $arr = $response->json(); @@ -1618,17 +1631,11 @@ class PaymentTest extends TestCase ], ]; - $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); - } + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->postJson('/api/v1/payments/refund', $data); + $arr = $response->json(); @@ -1644,7 +1651,7 @@ class PaymentTest extends TestCase $response = $this->withHeaders([ 'X-API-SECRET' => config('ninja.api_secret'), 'X-API-TOKEN' => $this->token, - ])->post('/api/v1/payments/bulk?action=delete', $data); + ])->postJson('/api/v1/payments/bulk?action=delete', $data); $this->assertEquals(10, $invoice->fresh()->balance); $this->assertEquals(10, $invoice->fresh()->balance); @@ -1659,34 +1666,18 @@ class PaymentTest extends TestCase 'number' => 'duplicate', ]; - try { - $response = $this->withHeaders([ - 'X-API-SECRET' => config('ninja.api_secret'), - 'X-API-TOKEN' => $this->token, - ])->post('/api/v1/payments', $data); - } catch (ValidationException $e) { - $message = json_decode($e->validator->getMessageBag(), 1); - nlog($message); - } - - $arr = $response->json(); + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->postJson('/api/v1/payments', $data); $response->assertStatus(200); - $response = false; + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->postJson('/api/v1/payments', $data); - try { - $response = $this->withHeaders([ - 'X-API-SECRET' => config('ninja.api_secret'), - 'X-API-TOKEN' => $this->token, - ])->post('/api/v1/payments', $data); - } catch (ValidationException $e) { - $message = json_decode($e->validator->getMessageBag(), 1); - nlog($message); - } - - if ($response) { - $response->assertStatus(302); - } + $response->assertStatus(422); } } From f5dfb69776f1ccacd1e9e1cc65ce27780100c7f8 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sun, 17 Sep 2023 19:24:15 +1000 Subject: [PATCH 6/7] Tests for payments --- tests/Feature/PaymentTest.php | 37 ++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/tests/Feature/PaymentTest.php b/tests/Feature/PaymentTest.php index e62ea4502b05..1dcdd8f49fa9 100644 --- a/tests/Feature/PaymentTest.php +++ b/tests/Feature/PaymentTest.php @@ -62,6 +62,40 @@ class PaymentTest extends TestCase ); } + + public function testCompletedPaymentLogic() + { + $payment = Payment::factory()->create([ + 'company_id' => $this->company->id, + 'user_id' => $this->user->id, + 'client_id' => $this->client->id, + 'status_id' => Payment::STATUS_COMPLETED, + 'amount' => 100 + ]); + + $data = [ + 'amount' => $this->invoice->amount, + 'client_id' => $this->client->hashed_id, + 'invoices' => [ + [ + 'invoice_id' => $this->invoice->hashed_id, + 'amount' => $this->invoice->amount, + ], + ], + 'date' => '2020/12/11', + 'idempotency_key' => 'dsjafhajklsfhlaksjdhlkajsdjdfjdfljasdfhkjlsafhljfkfhsjlfhiuwayerfiuwaskjgbzmvnjzxnjcbgfkjhdgfoiwwrasdfasdfkashjdfkaskfjdasfda' + + ]; + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->putJson('/api/v1/payments/'.$payment->hashed_id, $data); + + $response->assertStatus(200); + + } + public function testPendingPaymentLogic() { $payment = Payment::factory()->create([ @@ -95,9 +129,6 @@ class PaymentTest extends TestCase } - - - public function testPaymentGetBetweenQuery1() { $response = $this->withHeaders([ From 4e77b1072ce6b48d12b116579086b3ab7db9953c Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 18 Sep 2023 11:20:01 +1000 Subject: [PATCH 7/7] Checks for missing props --- app/Http/Controllers/SelfUpdateController.php | 29 +++++++++++++++++-- app/Http/Livewire/PdfSlot.php | 6 ++-- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/app/Http/Controllers/SelfUpdateController.php b/app/Http/Controllers/SelfUpdateController.php index f304482fac6b..75d2442fcdae 100644 --- a/app/Http/Controllers/SelfUpdateController.php +++ b/app/Http/Controllers/SelfUpdateController.php @@ -11,13 +11,14 @@ namespace App\Http\Controllers; -use App\Exceptions\FilePermissionsFailure; use App\Utils\Ninja; +use App\Models\Company; use App\Utils\Traits\AppSetup; -use App\Utils\Traits\ClientGroupSettingsSaver; -use Illuminate\Foundation\Bus\DispatchesJobs; use Illuminate\Support\Facades\Artisan; use Illuminate\Support\Facades\Storage; +use App\Exceptions\FilePermissionsFailure; +use Illuminate\Foundation\Bus\DispatchesJobs; +use App\Utils\Traits\ClientGroupSettingsSaver; class SelfUpdateController extends BaseController { @@ -109,11 +110,33 @@ class SelfUpdateController extends BaseController $this->buildCache(true); + $this->runModelChecks(); + nlog('Called Artisan commands'); return response()->json(['message' => 'Update completed'], 200); } + private function runModelChecks() + { + Company::query() + ->cursor() + ->each(function ($company){ + + $settings = $company->settings; + + if(property_exists($settings->pdf_variables, 'purchase_order_details')) + return; + + $pdf_variables = $settings->pdf_variables; + $pdf_variables->purchase_order_details = []; + $settings->pdf_variables = $pdf_variables; + $company->settings = $settings; + $company->save(); + + }); + } + private function clearCacheDir() { $directoryIterator = new \RecursiveDirectoryIterator(base_path('bootstrap/cache'), \RecursiveDirectoryIterator::SKIP_DOTS); diff --git a/app/Http/Livewire/PdfSlot.php b/app/Http/Livewire/PdfSlot.php index a97444ba89ee..edb8c2e2aa5a 100644 --- a/app/Http/Livewire/PdfSlot.php +++ b/app/Http/Livewire/PdfSlot.php @@ -195,15 +195,15 @@ class PdfSlot extends Component } elseif($this->entity_type == 'quote'){ - foreach($this->settings->pdf_variables->quote_details as $variable) + foreach($this->settings->pdf_variables->quote_details ?? [] as $variable) $entity_details .= "

{$variable}_label

{$variable}

"; } elseif($this->entity_type == 'credit') { - foreach($this->settings->pdf_variables->credit_details as $variable) + foreach($this->settings->pdf_variables->credit_details ?? [] as $variable) $entity_details .= "

{$variable}_label

{$variable}

"; } elseif($this->entity_type == 'purchase_order'){ - foreach($this->settings->pdf_variables->purchase_order_details as $variable) + foreach($this->settings->pdf_variables->purchase_order_details ?? [] as $variable) $entity_details .= "

{$variable}_label

{$variable}

"; }