From a5fc80f40828d59e6f62e996e9873b2a9ee3227b Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 23 Mar 2023 13:03:37 +1100 Subject: [PATCH 1/5] Dynamically apply the mailgun endpoint --- app/DataMapper/CompanySettings.php | 3 +++ app/Jobs/Mail/NinjaMailerJob.php | 8 +++++++- app/Providers/AppServiceProvider.php | 5 ++--- app/Services/Email/Email.php | 9 ++++++++- openapi/api-docs.yaml | 7 ++----- openapi/components/parameters.yaml | 2 +- openapi/paths/clients.yaml | 2 +- openapi/paths/recurring_invoices.yaml | 3 --- 8 files changed, 24 insertions(+), 15 deletions(-) diff --git a/app/DataMapper/CompanySettings.php b/app/DataMapper/CompanySettings.php index 1e64f0ec1c10..37eea6e463e0 100644 --- a/app/DataMapper/CompanySettings.php +++ b/app/DataMapper/CompanySettings.php @@ -449,6 +449,8 @@ class CompanySettings extends BaseSettings public $mailgun_domain = ''; + public $mailgun_endpoint = 'api.mailgun.net'; //api.eu.mailgun.net + public $auto_bill_standard_invoices = false; public $email_alignment = 'center'; // center , left, right @@ -476,6 +478,7 @@ class CompanySettings extends BaseSettings public $sync_invoice_quote_columns = true; public static $casts = [ + 'mailgun_endpoint' => 'string', // 'client_initiated_payments_recurring'=> 'bool', 'client_initiated_payments' => 'bool', 'client_initiated_payments_minimum' => 'float', diff --git a/app/Jobs/Mail/NinjaMailerJob.php b/app/Jobs/Mail/NinjaMailerJob.php index 871595f1c0ef..72ce0a95d6d1 100644 --- a/app/Jobs/Mail/NinjaMailerJob.php +++ b/app/Jobs/Mail/NinjaMailerJob.php @@ -128,7 +128,13 @@ class NinjaMailerJob implements ShouldQueue } if ($this->client_mailgun_secret) { - $mailer->mailgun_config($this->client_mailgun_secret, $this->client_mailgun_domain); + + $endpoint = 'api.mailgun.net'; + + if(strpos($this->client_mailgun_secret, 'key') !== false) + $endpoint = 'api.eu.mailgun.net'; + + $mailer->mailgun_config($this->client_mailgun_secret, $this->client_mailgun_domain, $endpoint); } $mailer diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index ed8b2a643c0c..8e2071a6ff3e 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -101,12 +101,12 @@ class AppServiceProvider extends ServiceProvider return $this; }); - Mailer::macro('mailgun_config', function (string $secret, string $domain) { + Mailer::macro('mailgun_config', function (string $secret, string $domain, string $endpoint = 'api.mailgun.net') { Mailer::setSymfonyTransport(app('mail.manager')->createSymfonyTransport([ 'transport' => 'mailgun', 'secret' => $secret, 'domain' => $domain, - 'endpoint' => config('services.mailgun.endpoint'), + 'endpoint' => $endpoint, 'scheme' => config('services.mailgun.scheme'), ])); @@ -114,7 +114,6 @@ class AppServiceProvider extends ServiceProvider }); /* Extension for custom mailers */ - /* Convenience helper for testing s*/ ParallelTesting::setUpTestDatabase(function ($database, $token) { diff --git a/app/Services/Email/Email.php b/app/Services/Email/Email.php index 7c8d7f072aee..d47d3c5f6b16 100644 --- a/app/Services/Email/Email.php +++ b/app/Services/Email/Email.php @@ -233,7 +233,14 @@ class Email implements ShouldQueue } if ($this->client_mailgun_secret) { - $mailer->mailgun_config($this->client_mailgun_secret, $this->client_mailgun_domain); + + $endpoint = 'api.mailgun.net'; + + if (strpos($this->client_mailgun_secret, 'key') !== false) { + $endpoint = 'api.eu.mailgun.net'; + } + + $mailer->mailgun_config($this->client_mailgun_secret, $this->client_mailgun_domain, $endpoint); } /* Attempt the send! */ diff --git a/openapi/api-docs.yaml b/openapi/api-docs.yaml index 7531e69a90ce..37e00cfc09fd 100644 --- a/openapi/api-docs.yaml +++ b/openapi/api-docs.yaml @@ -8776,7 +8776,7 @@ paths: multipart/form-data: schema: type: object - properties: + items: _method: type: string example: POST @@ -12386,10 +12386,7 @@ paths: Archives the recurring invoice. The recurring invoice will not fire in this state. - `delete` Deletes a recurring invoice. - - required: true ids: - required: true type: array items: description: "Array of hashed IDs to be bulk 'actioned - ['D2J234DFA','D2J234DFA','D2J234DFA']" @@ -13015,7 +13012,7 @@ components: name: include in: query description: Include child relations of the BankIntegration object. Format is comma separated. - require: false + required: false schema: type: string examples: diff --git a/openapi/components/parameters.yaml b/openapi/components/parameters.yaml index 2ec66fbb7dc9..c5de428986f5 100644 --- a/openapi/components/parameters.yaml +++ b/openapi/components/parameters.yaml @@ -36,7 +36,7 @@ name: include in: query description: Include child relations of the BankIntegration object. Format is comma separated. - require: false + required: false schema: type: string examples: diff --git a/openapi/paths/clients.yaml b/openapi/paths/clients.yaml index ba4fb19277a4..7bc0bf95b8d8 100644 --- a/openapi/paths/clients.yaml +++ b/openapi/paths/clients.yaml @@ -390,7 +390,7 @@ multipart/form-data: schema: type: object - properties: + items: _method: type: string example: POST diff --git a/openapi/paths/recurring_invoices.yaml b/openapi/paths/recurring_invoices.yaml index bb3a30f28fab..5fa973116856 100644 --- a/openapi/paths/recurring_invoices.yaml +++ b/openapi/paths/recurring_invoices.yaml @@ -333,10 +333,7 @@ Archives the recurring invoice. The recurring invoice will not fire in this state. - `delete` Deletes a recurring invoice. - - required: true ids: - required: true type: array items: description: "Array of hashed IDs to be bulk 'actioned - ['D2J234DFA','D2J234DFA','D2J234DFA']" From 745993253637478bb8fcddbbf55faa542bd09f4f Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 23 Mar 2023 16:51:45 +1100 Subject: [PATCH 2/5] Add checks for stale gateway fees --- .../Controllers/ClientPortal/InvoiceController.php | 2 -- app/Jobs/Subscription/CleanStaleInvoiceOrder.php | 14 ++++++++++++++ app/Mail/Engine/PaymentEmailEngine.php | 7 ++++++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/ClientPortal/InvoiceController.php b/app/Http/Controllers/ClientPortal/InvoiceController.php index 3bfa90b48ac5..d13445b8d057 100644 --- a/app/Http/Controllers/ClientPortal/InvoiceController.php +++ b/app/Http/Controllers/ClientPortal/InvoiceController.php @@ -80,8 +80,6 @@ class InvoiceController extends Controller /** * Pay one or more invoices. * - * @param ProcessInvoicesInBulkRequest $request - * @return mixed */ public function catch_bulk() { diff --git a/app/Jobs/Subscription/CleanStaleInvoiceOrder.php b/app/Jobs/Subscription/CleanStaleInvoiceOrder.php index f0912aefbcfc..7d8e6c517353 100644 --- a/app/Jobs/Subscription/CleanStaleInvoiceOrder.php +++ b/app/Jobs/Subscription/CleanStaleInvoiceOrder.php @@ -50,6 +50,20 @@ class CleanStaleInvoiceOrder implements ShouldQueue $repo->delete($invoice); }); + Invoice::query() + ->withTrashed() + ->where('status_id', Invoice::STATUS_SENT) + ->where('created_at', '<', now()->subHours(2)) + ->where('balance', '>', 0) + ->cursor() + ->each(function ($invoice){ + + if (collect($invoice->line_items)->contains('type_id', 3)) { + $invoice->service()->removeUnpaidGatewayFees(); + } + + }); + return; } diff --git a/app/Mail/Engine/PaymentEmailEngine.php b/app/Mail/Engine/PaymentEmailEngine.php index bda1dfc226ad..6893a24e2d46 100644 --- a/app/Mail/Engine/PaymentEmailEngine.php +++ b/app/Mail/Engine/PaymentEmailEngine.php @@ -261,7 +261,7 @@ class PaymentEmailEngine extends BaseEmailEngine $data['$invoices.balance'] = ['value' => $this->formatInvoiceField('balance'), 'label' => ctrans('texts.invoices')]; $data['$invoices.due_date'] = ['value' => $this->formatInvoiceField('due_date'), 'label' => ctrans('texts.invoices')]; $data['$invoices.po_number'] = ['value' => $this->formatInvoiceField('po_number'), 'label' => ctrans('texts.invoices')]; - + $data['$invoice_numbers'] = ['value' => $this->formatInvoiceNumbersRaw(), 'label' => ctrans('texts.invoices')]; if ($this->payment->status_id == 4) { $data['$status_logo'] = ['value' => '
' . ctrans('texts.paid') .'
', 'label' => '']; @@ -347,6 +347,11 @@ class PaymentEmailEngine extends BaseEmailEngine } + private function formatInvoiceNumbersRaw(){ + + return collect($this->payment->invoices->pluck('number')->toArray())->implode(', '); + + } private function formatInvoiceReferences() { From ed6575b5aa48f055dc32621e479d86e58b358a7e Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 23 Mar 2023 17:37:27 +1100 Subject: [PATCH 3/5] Minor updates for open api spec --- openapi/api-docs.yaml | 12 ++++++------ openapi/paths/clients.yaml | 7 +++---- openapi/paths/invoices.yaml | 2 +- openapi/paths/products.yaml | 3 ++- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/openapi/api-docs.yaml b/openapi/api-docs.yaml index 37e00cfc09fd..d3d1cf37a28f 100644 --- a/openapi/api-docs.yaml +++ b/openapi/api-docs.yaml @@ -8768,21 +8768,20 @@ paths: type: string format: string example: D2J234DFA - produces: - - application/json requestBody: required: true content: multipart/form-data: schema: type: object - items: + properties: _method: type: string example: POST documents: type: array - format: binary + items: + format: binary responses: 200: description: 'Returns the client object' @@ -9784,7 +9783,8 @@ paths: example: POST documents: type: array - format: binary + items: + format: binary responses: 200: description: "Returns the Product object" @@ -11797,6 +11797,7 @@ paths: type: object properties: action: + required: true type: string description: | The action to be performed, options include: @@ -11828,7 +11829,6 @@ paths: Emails an array of invoices - `send_email` Emails an array of invoices. Requires additional properties to be sent. `email_type` - required: true ids: required: true type: array diff --git a/openapi/paths/clients.yaml b/openapi/paths/clients.yaml index 7bc0bf95b8d8..de23fd9c1d6e 100644 --- a/openapi/paths/clients.yaml +++ b/openapi/paths/clients.yaml @@ -382,21 +382,20 @@ type: string format: string example: D2J234DFA - produces: - - application/json requestBody: required: true content: multipart/form-data: schema: type: object - items: + properties: _method: type: string example: POST documents: type: array - format: binary + items: + format: binary responses: 200: description: 'Returns the client object' diff --git a/openapi/paths/invoices.yaml b/openapi/paths/invoices.yaml index e9f8d75ef96b..44a9aa3320c5 100644 --- a/openapi/paths/invoices.yaml +++ b/openapi/paths/invoices.yaml @@ -371,6 +371,7 @@ type: object properties: action: + required: true type: string description: | The action to be performed, options include: @@ -402,7 +403,6 @@ Emails an array of invoices - `send_email` Emails an array of invoices. Requires additional properties to be sent. `email_type` - required: true ids: required: true type: array diff --git a/openapi/paths/products.yaml b/openapi/paths/products.yaml index cb87d455447f..e8a527feee96 100644 --- a/openapi/paths/products.yaml +++ b/openapi/paths/products.yaml @@ -362,7 +362,8 @@ example: POST documents: type: array - format: binary + items: + format: binary responses: 200: description: "Returns the Product object" From d55e41b77220b18a5dd4a97e1a3b550d761107e6 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 23 Mar 2023 18:28:12 +1100 Subject: [PATCH 4/5] Minor fixes for bank transfer - Stripe --- app/PaymentDrivers/Stripe/BankTransfer.php | 3 +-- .../stripe/bank_transfer/bank_details_container.blade.php | 4 +++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/PaymentDrivers/Stripe/BankTransfer.php b/app/PaymentDrivers/Stripe/BankTransfer.php index 7e110e9f8844..dd22cca8d771 100644 --- a/app/PaymentDrivers/Stripe/BankTransfer.php +++ b/app/PaymentDrivers/Stripe/BankTransfer.php @@ -106,8 +106,7 @@ class BankTransfer /** * paymentResponse * - * @param mixed $request - * @return void + * @param PaymentResponseRequest $request */ public function paymentResponse(PaymentResponseRequest $request) { diff --git a/resources/views/portal/ninja2020/gateways/stripe/bank_transfer/bank_details_container.blade.php b/resources/views/portal/ninja2020/gateways/stripe/bank_transfer/bank_details_container.blade.php index 81d9337bf59c..d1fbfd71d402 100644 --- a/resources/views/portal/ninja2020/gateways/stripe/bank_transfer/bank_details_container.blade.php +++ b/resources/views/portal/ninja2020/gateways/stripe/bank_transfer/bank_details_container.blade.php @@ -2,4 +2,6 @@ @section('meta_title', ctrans('texts.bank_transfer')) -@include('portal.ninja2020.gateways.stripe.bank_transfer.bank_details') \ No newline at end of file +@section('body') +@include('portal.ninja2020.gateways.stripe.bank_transfer.bank_details') +@endsection \ No newline at end of file From f8754744590839dcb1c32d4b3383a2f56931f624 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Fri, 24 Mar 2023 10:10:35 +1100 Subject: [PATCH 5/5] Fixes for react build --- app/Console/Commands/ReactBuilder.php | 4 ++-- app/Services/Email/Email.php | 2 ++ app/Services/Email/EmailDefaults.php | 5 +++-- resources/views/pdf-designs/playful.html | 4 ++-- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/app/Console/Commands/ReactBuilder.php b/app/Console/Commands/ReactBuilder.php index 7e75e59887b7..430b16d90542 100644 --- a/app/Console/Commands/ReactBuilder.php +++ b/app/Console/Commands/ReactBuilder.php @@ -51,8 +51,8 @@ class ReactBuilder extends Command $directoryIterator = new \RecursiveDirectoryIterator(public_path('react'), \RecursiveDirectoryIterator::SKIP_DOTS); foreach (new \RecursiveIteratorIterator($directoryIterator) as $file) { - if (str_contains($file->getFileName(), '.js') && !strpos($file->getFileName(), '.json')) { - if (str_contains($file->getFileName(), 'index.')) { + if ($file->getExtension() == 'js') { + if (str_contains($file->getFileName(), 'index-')) { $includes .= ''."\n"; } else { $includes .= ''."\n"; diff --git a/app/Services/Email/Email.php b/app/Services/Email/Email.php index d47d3c5f6b16..46f1016a993b 100644 --- a/app/Services/Email/Email.php +++ b/app/Services/Email/Email.php @@ -143,6 +143,8 @@ class Email implements ShouldQueue $this->email_object->signature = $this->email_object->settings->email_signature; + $this->email_object->invitation_key = $this->email_object->invitation ? $this->email_object->invitation->key : null; + $this->resolveVariables(); return $this; diff --git a/app/Services/Email/EmailDefaults.php b/app/Services/Email/EmailDefaults.php index b63b506c7d2f..1b08585f64c6 100644 --- a/app/Services/Email/EmailDefaults.php +++ b/app/Services/Email/EmailDefaults.php @@ -76,7 +76,8 @@ class EmailDefaults ->setReplyTo() ->setBcc() ->setAttachments() - ->setVariables(); + ->setVariables() + ->setHeaders(); return $this->email->email_object; } @@ -369,7 +370,7 @@ class EmailDefaults private function setHeaders(): self { if ($this->email->email_object->invitation_key) { - $this->email->email_object->headers = array_merge($this->email->email_object->headers, ['x-invitation-key' => $this->email->email_object->invitation_key]); + $this->email->email_object->headers = array_merge($this->email->email_object->headers, ['x-invitation' => $this->email->email_object->invitation_key]); } return $this; diff --git a/resources/views/pdf-designs/playful.html b/resources/views/pdf-designs/playful.html index 57df2ca3181e..30053f64a249 100644 --- a/resources/views/pdf-designs/playful.html +++ b/resources/views/pdf-designs/playful.html @@ -206,7 +206,7 @@ gap: 80px; padding-left: 2rem; padding-right: 0rem; - page-break-inside:auto; + break-inside: avoid; overflow: visible !important; } @@ -271,7 +271,7 @@ #footer { margin-top: 1rem; - page-break-inside:auto; + break-inside: avoid; overflow: visible !important; }