From 3b508f656b5f0f2d26be0588790e71172b2f0958 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Thu, 5 May 2016 09:35:39 +0300 Subject: [PATCH 01/24] Fix for travis test --- tests/acceptance/TaxRatesCest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/acceptance/TaxRatesCest.php b/tests/acceptance/TaxRatesCest.php index ebe68f7b5880..e4db10b15909 100644 --- a/tests/acceptance/TaxRatesCest.php +++ b/tests/acceptance/TaxRatesCest.php @@ -84,7 +84,8 @@ class TaxRatesCest // check total is right after saving $I->see("\${$total}"); $I->amOnPage('/invoices'); - + $I->wait(2); + // check total is right in list view $I->see("\${$total}"); } From ef2bc3d811be4140198b91baacdc0440f83ecaa4 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Thu, 5 May 2016 09:52:59 +0300 Subject: [PATCH 02/24] White label changes --- resources/lang/en/texts.php | 2 +- resources/views/accounts/management.blade.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index f101c79564e7..25eaa81de8e2 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -992,7 +992,7 @@ $LANG = array( 'overdue' => 'Overdue', - 'white_label_text' => 'Purchase a ONE YEAR white label license for $'.WHITE_LABEL_PRICE.' to remove the Invoice Ninja branding from the client portal and help support our project.', + 'white_label_text' => 'Purchase a ONE YEAR white label license for $'.WHITE_LABEL_PRICE.' to remove the Invoice Ninja branding from the client portal and emails.', 'user_email_footer' => 'To adjust your email notification settings please visit '.SITE_URL.'/settings/notifications', 'reset_password_footer' => 'If you did not request this password reset please email our support: '.CONTACT_EMAIL, 'limit_users' => 'Sorry, this will exceed the limit of '.MAX_NUM_USERS.' users', diff --git a/resources/views/accounts/management.blade.php b/resources/views/accounts/management.blade.php index cf9917deb005..cfb7b6eb28ee 100644 --- a/resources/views/accounts/management.blade.php +++ b/resources/views/accounts/management.blade.php @@ -94,9 +94,9 @@ @endif @if (Utils::isNinjaProd()) - {!! Former::actions( Button::success(trans('texts.plan_upgrade'))->large()->withAttributes(['onclick' => 'showChangePlan()'])->appendIcon(Icon::create('plus-sign'))) !!} - @else - {!! Former::actions( Button::success(trans('texts.white_label_button'))->large()->withAttributes(['onclick' => 'loadImages("#whiteLabelModal");$("#whiteLabelModal").modal("show");'])->appendIcon(Icon::create('plus-sign'))) !!} + {!! Former::actions( Button::success(trans('texts.plan_upgrade'))->large()->withAttributes(['onclick' => 'showChangePlan()'])->appendIcon(Icon::create('plus-sign'))) !!} + @elseif (!$account->hasFeature(FEATURE_WHITE_LABEL)) + {!! Former::actions( Button::success(trans('texts.white_label_button'))->large()->withAttributes(['onclick' => 'loadImages("#whiteLabelModal");$("#whiteLabelModal").modal("show");'])->appendIcon(Icon::create('plus-sign'))) !!} @endif @endif From 7744c6c41ccbdadf1b40758576cdb53db5ad4f36 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Thu, 5 May 2016 09:58:14 +0300 Subject: [PATCH 03/24] White label changes --- resources/lang/en/texts.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index 25eaa81de8e2..f101c79564e7 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -992,7 +992,7 @@ $LANG = array( 'overdue' => 'Overdue', - 'white_label_text' => 'Purchase a ONE YEAR white label license for $'.WHITE_LABEL_PRICE.' to remove the Invoice Ninja branding from the client portal and emails.', + 'white_label_text' => 'Purchase a ONE YEAR white label license for $'.WHITE_LABEL_PRICE.' to remove the Invoice Ninja branding from the client portal and help support our project.', 'user_email_footer' => 'To adjust your email notification settings please visit '.SITE_URL.'/settings/notifications', 'reset_password_footer' => 'If you did not request this password reset please email our support: '.CONTACT_EMAIL, 'limit_users' => 'Sorry, this will exceed the limit of '.MAX_NUM_USERS.' users', From 2a5de605dcddd4c944d8aee124647e7151307dca Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Thu, 5 May 2016 10:15:51 +0300 Subject: [PATCH 04/24] Added relationLoaded checks to optimize queries --- app/Http/Requests/ClientRequest.php | 2 +- app/Http/Requests/ExpenseRequest.php | 6 +++--- app/Http/Requests/InvoiceRequest.php | 4 ++-- app/Http/Requests/VendorRequest.php | 2 +- app/Models/Account.php | 6 ++++-- app/Models/Client.php | 10 +++++++--- 6 files changed, 18 insertions(+), 12 deletions(-) diff --git a/app/Http/Requests/ClientRequest.php b/app/Http/Requests/ClientRequest.php index adbe2d4c2ae6..ec28cdb77d1d 100644 --- a/app/Http/Requests/ClientRequest.php +++ b/app/Http/Requests/ClientRequest.php @@ -9,7 +9,7 @@ class ClientRequest extends EntityRequest { $client = parent::entity(); // eager load the contacts - if ($client && ! count($client->contacts)) { + if ($client && ! $client->relationLoaded('contacts')) { $client->load('contacts'); } diff --git a/app/Http/Requests/ExpenseRequest.php b/app/Http/Requests/ExpenseRequest.php index d5e2c793c371..ae2e83b6d12f 100644 --- a/app/Http/Requests/ExpenseRequest.php +++ b/app/Http/Requests/ExpenseRequest.php @@ -8,11 +8,11 @@ class ExpenseRequest extends EntityRequest { { $expense = parent::entity(); - // eager load the contacts - if ($expense && ! count($expense->documents)) { + // eager load the documents + if ($expense && ! $expense->relationLoaded('documents')) { $expense->load('documents'); } - + return $expense; } } \ No newline at end of file diff --git a/app/Http/Requests/InvoiceRequest.php b/app/Http/Requests/InvoiceRequest.php index bf24c38839a9..5e2d93139003 100644 --- a/app/Http/Requests/InvoiceRequest.php +++ b/app/Http/Requests/InvoiceRequest.php @@ -8,8 +8,8 @@ class InvoiceRequest extends EntityRequest { { $invoice = parent::entity(); - // eager load the contacts - if ($invoice && ! count($invoice->invoice_items)) { + // eager load the invoice items + if ($invoice && ! $invoice->relationLoaded('invoice_items')) { $invoice->load('invoice_items'); } diff --git a/app/Http/Requests/VendorRequest.php b/app/Http/Requests/VendorRequest.php index a06e5ad808e6..8f96e7c55025 100644 --- a/app/Http/Requests/VendorRequest.php +++ b/app/Http/Requests/VendorRequest.php @@ -9,7 +9,7 @@ class VendorRequest extends EntityRequest { $vendor = parent::entity(); // eager load the contacts - if ($vendor && ! count($vendor->vendor_contacts)) { + if ($vendor && ! $vendor->relationLoaded('vendor_contacts')) { $vendor->load('vendor_contacts'); } diff --git a/app/Models/Account.php b/app/Models/Account.php index c8ece3b4da95..5814ec76423a 100644 --- a/app/Models/Account.php +++ b/app/Models/Account.php @@ -212,7 +212,9 @@ class Account extends Eloquent public function isGatewayConfigured($gatewayId = 0) { - $this->load('account_gateways'); + if ( ! $this->relationLoaded('account_gateways')) { + $this->load('account_gateways'); + } if ($gatewayId) { return $this->getGatewayConfig($gatewayId) != false; @@ -241,7 +243,7 @@ class Account extends Eloquent return $this->name; } - $this->load('users'); + //$this->load('users'); $user = $this->users()->first(); return $user->getDisplayName(); diff --git a/app/Models/Client.php b/app/Models/Client.php index 85cb543a6b03..4b26f40df0a7 100644 --- a/app/Models/Client.php +++ b/app/Models/Client.php @@ -256,13 +256,17 @@ class Client extends EntityModel public function getGatewayToken() { - $this->account->load('account_gateways'); + $account = $this->account; + + if ( ! $account->relationLoaded('account_gateways')) { + $account->load('account_gateways'); + } - if (!count($this->account->account_gateways)) { + if (!count($account->account_gateways)) { return false; } - $accountGateway = $this->account->getGatewayConfig(GATEWAY_STRIPE); + $accountGateway = $account->getGatewayConfig(GATEWAY_STRIPE); if (!$accountGateway) { return false; From a00a86a57898b52b4679c2b15b82c9e448c8f2fd Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Thu, 5 May 2016 10:23:09 +0300 Subject: [PATCH 05/24] Fix for travis --- tests/acceptance/OnlinePaymentCest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/acceptance/OnlinePaymentCest.php b/tests/acceptance/OnlinePaymentCest.php index 44bb04ea6498..7e85f2cc6b5a 100644 --- a/tests/acceptance/OnlinePaymentCest.php +++ b/tests/acceptance/OnlinePaymentCest.php @@ -96,7 +96,7 @@ class OnlinePaymentCest $I->click('table.invoice-table tbody tr:nth-child(1) .tt-selectable'); $I->checkOption('#auto_bill'); $I->executeJS('preparePdfData(\'email\')'); - $I->wait(2); + $I->wait(3); $I->see("$0.00"); } From 9f8865d0f22d55c59a1d6606e6148ab543f4ad33 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Thu, 5 May 2016 10:28:23 +0300 Subject: [PATCH 06/24] Added pages to navigation search --- app/Ninja/Repositories/AccountRepository.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/Ninja/Repositories/AccountRepository.php b/app/Ninja/Repositories/AccountRepository.php index e8fe2d041843..e650b28a419e 100644 --- a/app/Ninja/Repositories/AccountRepository.php +++ b/app/Ninja/Repositories/AccountRepository.php @@ -167,6 +167,7 @@ class AccountRepository ENTITY_QUOTE, ENTITY_TASK, ENTITY_EXPENSE, + ENTITY_VENDOR, ENTITY_RECURRING_INVOICE, ENTITY_PAYMENT, ENTITY_CREDIT @@ -192,6 +193,10 @@ class AccountRepository $settings = array_merge(Account::$basicSettings, Account::$advancedSettings); + if ( ! Utils::isNinjaProd()) { + $settings[] = ACCOUNT_SYSTEM_SETTINGS; + } + foreach ($settings as $setting) { $features[] = [ $setting, From 501958cc1ec013cad8e11183d38880f8b577016c Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Thu, 5 May 2016 11:55:09 +0300 Subject: [PATCH 07/24] Added language seeder --- app/Http/Controllers/AppController.php | 13 +------- database/seeds/DatabaseSeeder.php | 1 + database/seeds/LanguageSeeder.php | 41 ++++++++++++++++++++++++++ database/seeds/UpdateSeeder.php | 1 + 4 files changed, 44 insertions(+), 12 deletions(-) create mode 100644 database/seeds/LanguageSeeder.php diff --git a/app/Http/Controllers/AppController.php b/app/Http/Controllers/AppController.php index 568cb4d45f5b..a602ae7ecb85 100644 --- a/app/Http/Controllers/AppController.php +++ b/app/Http/Controllers/AppController.php @@ -266,18 +266,7 @@ class AppController extends BaseController Cache::flush(); Session::flush(); Artisan::call('migrate', array('--force' => true)); - foreach ([ - 'PaymentLibraries', - 'Fonts', - 'Banks', - 'InvoiceStatus', - 'Currencies', - 'DateFormats', - 'InvoiceDesigns', - 'PaymentTerms', - ] as $seeder) { - Artisan::call('db:seed', array('--force' => true, '--class' => "{$seeder}Seeder")); - } + Artisan::call('db:seed', array('--force' => true, '--class' => "UpdateSeeder")); Event::fire(new UserSettingsChanged()); Session::flash('message', trans('texts.processed_updates')); } catch (Exception $e) { diff --git a/database/seeds/DatabaseSeeder.php b/database/seeds/DatabaseSeeder.php index 8791f30e71fb..d7f38d3e1e53 100644 --- a/database/seeds/DatabaseSeeder.php +++ b/database/seeds/DatabaseSeeder.php @@ -23,5 +23,6 @@ class DatabaseSeeder extends Seeder $this->call('DateFormatsSeeder'); $this->call('InvoiceDesignsSeeder'); $this->call('PaymentTermsSeeder'); + $this->call('LanguageSeeder'); } } diff --git a/database/seeds/LanguageSeeder.php b/database/seeds/LanguageSeeder.php new file mode 100644 index 000000000000..c82b2630771c --- /dev/null +++ b/database/seeds/LanguageSeeder.php @@ -0,0 +1,41 @@ + 'English', 'locale' => 'en'], + ['name' => 'Italian', 'locale' => 'it'], + ['name' => 'German', 'locale' => 'de'], + ['name' => 'French', 'locale' => 'fr'], + ['name' => 'Brazilian Portuguese', 'locale' => 'pt_BR'], + ['name' => 'Dutch', 'locale' => 'nl'], + ['name' => 'Spanish', 'locale' => 'es'], + ['name' => 'Norwegian', 'locale' => 'nb_NO'], + ['name' => 'Danish', 'locale' => 'da'], + ['name' => 'Japanese', 'locale' => 'ja'], + ['name' => 'Swedish', 'locale' => 'sv'], + ['name' => 'Spanish - Spain', 'locale' => 'es_ES'], + ['name' => 'French - Canada', 'locale' => 'fr_CA'], + ['name' => 'Lithuanian', 'locale' => 'lt'], + ['name' => 'Polish', 'locale' => 'pl'], + ]; + + foreach ($languages as $language) { + $record = Language::whereLocale($language['locale'])->first(); + if ($record) { + $record->name = $language['name']; + $record->save(); + } else { + Language::create($language); + } + } + + Eloquent::reguard(); + } +} diff --git a/database/seeds/UpdateSeeder.php b/database/seeds/UpdateSeeder.php index e4d43f78e512..d445811de506 100644 --- a/database/seeds/UpdateSeeder.php +++ b/database/seeds/UpdateSeeder.php @@ -19,5 +19,6 @@ class UpdateSeeder extends Seeder $this->call('DateFormatsSeeder'); $this->call('InvoiceDesignsSeeder'); $this->call('PaymentTermsSeeder'); + $this->call('LanguageSeeder'); } } From c79d9fe24cf3fc776a69ceb1479111bf1d4e00fc Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Thu, 5 May 2016 17:46:22 +0300 Subject: [PATCH 08/24] Added preview for email templates --- app/Http/Controllers/AccountController.php | 25 +++++ app/Http/routes.php | 1 + app/Models/Account.php | 5 + app/Ninja/Mailers/ContactMailer.php | 103 ++---------------- app/Services/TemplateService.php | 80 ++++++++++++++ resources/lang/en/texts.php | 1 + resources/views/accounts/template.blade.php | 7 +- .../templates_and_reminders.blade.php | 36 ++++++ resources/views/emails/design2_html.blade.php | 22 ++-- ..._html.blade.php => design3_html.blade.php} | 22 ++-- ..._text.blade.php => design3_text.blade.php} | 0 .../emails/partials/account_logo.blade.php | 2 +- 12 files changed, 188 insertions(+), 116 deletions(-) create mode 100644 app/Services/TemplateService.php rename resources/views/emails/{design1_html.blade.php => design3_html.blade.php} (72%) rename resources/views/emails/{design1_text.blade.php => design3_text.blade.php} (100%) diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php index 3f8917b65427..a55188338073 100644 --- a/app/Http/Controllers/AccountController.php +++ b/app/Http/Controllers/AccountController.php @@ -1301,4 +1301,29 @@ class AccountController extends BaseController return Redirect::to("/settings/$section/", 301); } + + public function previewEmail(\App\Services\TemplateService $templateService) + { + $template = Input::get('template'); + $invoice = Invoice::scope()->first(); + $account = Auth::user()->account; + + // replace the variables with sample data + $data = [ + 'account' => $account, + 'invoice' => $invoice, + 'invitation' => $invoice->invitations->first(), + 'client' => $invoice->client, + 'amount' => $invoice->amount + ]; + + // create the email view + $view = 'emails.' . $account->getTemplateView() . '_html'; + $data = array_merge($data, [ + 'body' => $templateService->processVariables($template, $data), + 'entityType' => ENTITY_INVOICE, + ]); + + return Response::view($view, $data); + } } diff --git a/app/Http/routes.php b/app/Http/routes.php index df1f1add4bb8..c1162db275c1 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -208,6 +208,7 @@ Route::group([ Route::resource('tax_rates', 'TaxRateController'); Route::post('tax_rates/bulk', 'TaxRateController@bulk'); + Route::get('settings/email_preview', 'AccountController@previewEmail'); Route::get('company/{section}/{subSection?}', 'AccountController@redirectLegacy'); Route::get('settings/data_visualizations', 'ReportController@d3'); Route::get('settings/charts_and_reports', 'ReportController@showReports'); diff --git a/app/Models/Account.php b/app/Models/Account.php index 5814ec76423a..92e2a623ff7b 100644 --- a/app/Models/Account.php +++ b/app/Models/Account.php @@ -1169,6 +1169,11 @@ class Account extends Eloquent return str_replace('/>', ' />', $template); } + public function getTemplateView($view = '') + { + return $this->getEmailDesignId() == EMAIL_DESIGN_PLAIN ? $view : 'design' . $this->getEmailDesignId(); + } + public function getEmailFooter() { if ($this->email_footer) { diff --git a/app/Ninja/Mailers/ContactMailer.php b/app/Ninja/Mailers/ContactMailer.php index 4b176628ebf0..fbebd0c5fdfd 100644 --- a/app/Ninja/Mailers/ContactMailer.php +++ b/app/Ninja/Mailers/ContactMailer.php @@ -1,17 +1,13 @@ templateService = $templateService; + } + public function sendInvoice(Invoice $invoice, $reminder = false, $pdfString = false) { $invoice->load('invitations', 'client.language', 'account'); @@ -144,7 +145,7 @@ class ContactMailer extends Mailer } $data = [ - 'body' => $this->processVariables($body, $variables), + 'body' => $this->templateService->processVariables($body, $variables), 'link' => $invitation->getLink(), 'entityType' => $invoice->getEntityType(), 'invoiceId' => $invoice->id, @@ -160,14 +161,9 @@ class ContactMailer extends Mailer $data['pdfFileName'] = $invoice->getFileName(); } - $subject = $this->processVariables($subject, $variables); + $subject = $this->templateService->processVariables($subject, $variables); $fromEmail = $user->email; - - if ($account->getEmailDesignId() == EMAIL_DESIGN_PLAIN) { - $view = ENTITY_INVOICE; - } else { - $view = 'design' . ($account->getEmailDesignId() - 1); - } + $view = $account->getTemplateView(ENTITY_INVOICE); $response = $this->sendTo($invitation->contact->email, $fromEmail, $account->getDisplayName(), $subject, $view, $data); @@ -230,7 +226,7 @@ class ContactMailer extends Mailer ]; $data = [ - 'body' => $this->processVariables($emailTemplate, $variables), + 'body' => $this->templateService->processVariables($emailTemplate, $variables), 'link' => $invitation->getLink(), 'invoice' => $invoice, 'client' => $client, @@ -244,14 +240,10 @@ class ContactMailer extends Mailer $data['pdfFileName'] = $invoice->getFileName(); } - $subject = $this->processVariables($emailSubject, $variables); + $subject = $this->templateService->processVariables($emailSubject, $variables); $data['invoice_id'] = $payment->invoice->id; - if ($account->getEmailDesignId() == EMAIL_DESIGN_PLAIN) { - $view = 'payment_confirmation'; - } else { - $view = 'design' . ($account->getEmailDesignId() - 1); - } + $view = $account->getTemplateView('payment_confirmation'); if ($user->email && $contact->email) { $this->sendTo($contact->email, $user->email, $accountName, $subject, $view, $data); @@ -281,75 +273,4 @@ class ContactMailer extends Mailer $this->sendTo($email, CONTACT_EMAIL, CONTACT_NAME, $subject, $view, $data); } - - private function processVariables($template, $data) - { - $account = $data['account']; - $client = $data['client']; - $invitation = $data['invitation']; - $invoice = $invitation->invoice; - $passwordHTML = isset($data['password'])?'

'.trans('texts.password').': '.$data['password'].'

':false; - $documentsHTML = ''; - - if($account->hasFeature(FEATURE_DOCUMENTS) && $invoice->hasDocuments()){ - $documentsHTML .= trans('texts.email_documents_header').'

'; - } - - $variables = [ - '$footer' => $account->getEmailFooter(), - '$client' => $client->getDisplayName(), - '$account' => $account->getDisplayName(), - '$dueDate' => $account->formatDate($invoice->due_date), - '$invoiceDate' => $account->formatDate($invoice->invoice_date), - '$contact' => $invitation->contact->getDisplayName(), - '$firstName' => $invitation->contact->first_name, - '$amount' => $account->formatMoney($data['amount'], $client), - '$invoice' => $invoice->invoice_number, - '$quote' => $invoice->invoice_number, - '$link' => $invitation->getLink(), - '$password' => $passwordHTML, - '$viewLink' => $invitation->getLink().'$password', - '$viewButton' => Form::emailViewButton($invitation->getLink(), $invoice->getEntityType()).'$password', - '$paymentLink' => $invitation->getLink('payment').'$password', - '$paymentButton' => Form::emailPaymentButton($invitation->getLink('payment')).'$password', - '$customClient1' => $account->custom_client_label1, - '$customClient2' => $account->custom_client_label2, - '$customInvoice1' => $account->custom_invoice_text_label1, - '$customInvoice2' => $account->custom_invoice_text_label2, - '$documents' => $documentsHTML, - ]; - - // Add variables for available payment types - foreach (Gateway::$paymentTypes as $type) { - $camelType = Gateway::getPaymentTypeName($type); - $type = Utils::toSnakeCase($camelType); - $variables["\${$camelType}Link"] = $invitation->getLink('payment') . "/{$type}"; - $variables["\${$camelType}Button"] = Form::emailPaymentButton($invitation->getLink('payment') . "/{$type}"); - } - - $includesPasswordPlaceholder = strpos($template, '$password') !== false; - - $str = str_replace(array_keys($variables), array_values($variables), $template); - - if(!$includesPasswordPlaceholder && $passwordHTML){ - $pos = strrpos($str, '$password'); - if($pos !== false) - { - $str = substr_replace($str, $passwordHTML, $pos, 9/* length of "$password" */); - } - } - $str = str_replace('$password', '', $str); - $str = autolink($str, 100); - - return $str; - } } diff --git a/app/Services/TemplateService.php b/app/Services/TemplateService.php new file mode 100644 index 000000000000..5a41c705352d --- /dev/null +++ b/app/Services/TemplateService.php @@ -0,0 +1,80 @@ +invoice; + $passwordHTML = isset($data['password'])?'

'.trans('texts.password').': '.$data['password'].'

':false; + $documentsHTML = ''; + + if ($account->hasFeature(FEATURE_DOCUMENTS) && $invoice->hasDocuments()) { + $documentsHTML .= trans('texts.email_documents_header').'

'; + } + + $variables = [ + '$footer' => $account->getEmailFooter(), + '$client' => $client->getDisplayName(), + '$account' => $account->getDisplayName(), + '$dueDate' => $account->formatDate($invoice->due_date), + '$invoiceDate' => $account->formatDate($invoice->invoice_date), + '$contact' => $invitation->contact->getDisplayName(), + '$firstName' => $invitation->contact->first_name, + '$amount' => $account->formatMoney($data['amount'], $client), + '$invoice' => $invoice->invoice_number, + '$quote' => $invoice->invoice_number, + '$link' => $invitation->getLink(), + '$password' => $passwordHTML, + '$viewLink' => $invitation->getLink().'$password', + '$viewButton' => Form::emailViewButton($invitation->getLink(), $invoice->getEntityType()).'$password', + '$paymentLink' => $invitation->getLink('payment').'$password', + '$paymentButton' => Form::emailPaymentButton($invitation->getLink('payment')).'$password', + '$customClient1' => $account->custom_client_label1, + '$customClient2' => $account->custom_client_label2, + '$customInvoice1' => $account->custom_invoice_text_label1, + '$customInvoice2' => $account->custom_invoice_text_label2, + '$documents' => $documentsHTML, + ]; + + // Add variables for available payment types + foreach (Gateway::$paymentTypes as $type) { + $camelType = Gateway::getPaymentTypeName($type); + $type = Utils::toSnakeCase($camelType); + $variables["\${$camelType}Link"] = $invitation->getLink('payment') . "/{$type}"; + $variables["\${$camelType}Button"] = Form::emailPaymentButton($invitation->getLink('payment') . "/{$type}"); + } + + $includesPasswordPlaceholder = strpos($template, '$password') !== false; + + $str = str_replace(array_keys($variables), array_values($variables), $template); + + if (!$includesPasswordPlaceholder && $passwordHTML) { + $pos = strrpos($str, '$password'); + if ($pos !== false) + { + $str = substr_replace($str, $passwordHTML, $pos, 9/* length of "$password" */); + } + } + $str = str_replace('$password', '', $str); + $str = autolink($str, 100); + + return $str; + } +} \ No newline at end of file diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index f101c79564e7..6d6f3229b059 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -1176,6 +1176,7 @@ $LANG = array( 'page_size' => 'Page Size', 'live_preview_disabled' => 'Live preview has been disabled to support selected font', 'invoice_number_padding' => 'Padding', + 'preview' => 'Preview', ); diff --git a/resources/views/accounts/template.blade.php b/resources/views/accounts/template.blade.php index 0d4294af5b6f..68279299f607 100644 --- a/resources/views/accounts/template.blade.php +++ b/resources/views/accounts/template.blade.php @@ -62,11 +62,14 @@
+

 

-
-

 

+

@include('partials/quill_toolbar', ['name' => $field])
+
+ {!! Button::primary(trans('texts.preview'))->withAttributes(['onclick' => 'serverPreview("'.$field.'")'])->small() !!} +
diff --git a/resources/views/accounts/templates_and_reminders.blade.php b/resources/views/accounts/templates_and_reminders.blade.php index 067433a21763..d8032f352a92 100644 --- a/resources/views/accounts/templates_and_reminders.blade.php +++ b/resources/views/accounts/templates_and_reminders.blade.php @@ -80,6 +80,26 @@ + + +