From 9349eb04148bf2570c567f5419b4081e31b1291b Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sun, 12 Apr 2020 21:51:27 +1000 Subject: [PATCH] Repeating headers and footers for PDF (#3622) * Subclass Notification class * Subclass Notification class * Working on invoice design * Working on page headers and footers * Fixes for headers and footers * Fixes for invoices --- app/DataMapper/CompanySettings.php | 2 +- app/Designs/Bold.php | 43 +++--- app/Designs/Business.php | 41 +++--- app/Designs/Clean.php | 40 +++--- app/Designs/Creative.php | 41 +++--- app/Designs/Designer.php | 1 + app/Designs/Elegant.php | 40 +++--- app/Designs/Hipster.php | 40 +++--- app/Designs/Modern.php | 133 ++++++++---------- app/Designs/Photo.php | 40 +++--- app/Designs/Plain.php | 9 +- app/Designs/Playful.php | 40 +++--- app/Http/Controllers/EmailController.php | 11 -- app/Http/Controllers/SelfUpdateController.php | 20 --- app/Notifications/BaseNotification.php | 117 +++++++++++++++ app/Notifications/SendGenericNotification.php | 45 +----- app/Repositories/InvoiceRepository.php | 4 +- app/Utils/Traits/MakesInvoiceHtml.php | 2 + app/Utils/Traits/MakesInvoiceValues.php | 75 ++++++++++ app/Utils/Traits/Pdf/PdfMaker.php | 2 + config/self-update.php | 2 +- tests/Integration/DesignTest.php | 8 ++ 22 files changed, 463 insertions(+), 293 deletions(-) create mode 100644 app/Notifications/BaseNotification.php diff --git a/app/DataMapper/CompanySettings.php b/app/DataMapper/CompanySettings.php index b6e0e25b1d30..4fcc144a53c6 100644 --- a/app/DataMapper/CompanySettings.php +++ b/app/DataMapper/CompanySettings.php @@ -216,7 +216,7 @@ class CompanySettings extends BaseSettings public $vat_number = ''; public $id_number = ''; - public $page_size = 'A4'; + public $page_size = 'A4'; //Letter, Legal, Tabloid, Ledger, A0, A1, A2, A3, A4, A5, A6 public $font_size = 9; public $primary_font = 'Roboto'; public $secondary_font = 'Roboto'; diff --git a/app/Designs/Bold.php b/app/Designs/Bold.php index fdb2410b5c93..42656c54b72a 100644 --- a/app/Designs/Bold.php +++ b/app/Designs/Bold.php @@ -30,6 +30,7 @@ class Bold extends AbstractDesign .table_header_thead_class {text-align:left;} .table_header_td_class {padding-left:3rem; padding-right:3rem; font-size:1rem; padding-left:1rem;padding-right:1rem; padding-top:.5rem;padding-bottom:.5rem} .table_body_td_class {background-color:#edf2f7; adding-top:1.25rem;padding-bottom:1.25rem; padding-left:3rem;} + $custom_css '; } @@ -87,22 +88,8 @@ class Bold extends AbstractDesign $task_table_body -'; - } - - public function task() - { - return ''; - } - - public function product() - { - return ''; - } - - public function footer() - { - return '
+
+
$entity.public_notes
@@ -129,6 +116,28 @@ class Bold extends AbstractDesign $balance_due
-'; + +'; + } + + public function task() + { + return ''; + } + + public function product() + { + return ''; + } + + public function footer() + { + return ' + + +'; } } diff --git a/app/Designs/Business.php b/app/Designs/Business.php index e7e970955f0f..53474b01b9c2 100644 --- a/app/Designs/Business.php +++ b/app/Designs/Business.php @@ -41,7 +41,7 @@ class Business extends AbstractDesign .table_header_thead_class { border-top-left-radius: .5rem; text-align: left } .table_header_td_class { color: white; padding: .5rem 1rem; font-weight: 800; background-color: #2a4365; } .table_body_td_class { color: #c05621; padding: 1rem; border-width: 4px; border-color: white; background-color: white; } - +$custom_css '; } @@ -89,22 +89,8 @@ class Business extends AbstractDesign $task_table_body -'; - } - - public function task() - { - return ''; - } - - public function product() - { - return ''; - } - - public function footer() - { - return '
+ +

$entity.public_notes

@@ -139,7 +125,26 @@ class Business extends AbstractDesign
-
+
'; + } + + public function task() + { + return ''; + } + + public function product() + { + return ''; + } + + public function footer() + { + return ' + '; } diff --git a/app/Designs/Clean.php b/app/Designs/Clean.php index 5bb945f2dca3..527513fd3db5 100644 --- a/app/Designs/Clean.php +++ b/app/Designs/Clean.php @@ -35,6 +35,7 @@ class Clean extends AbstractDesign .table_header_thead_class { text-align: left; } .table_header_td_class { padding: .5rem 1rem;} .table_body_td_class { border-bottom-width: 1px; border-top-width: 1px; border-color: #cbd5e0; padding: 1rem;} + $custom_css '; } @@ -94,22 +95,8 @@ class Clean extends AbstractDesign $task_table_body -'; - } - - public function task() - { - return ''; - } - - public function product() - { - return ''; - } - - public function footer() - { - return '
+ +
$entity.public_notes
@@ -141,7 +128,26 @@ class Clean extends AbstractDesign
- +'; + } + + public function task() + { + return ''; + } + + public function product() + { + return ''; + } + + public function footer() + { + return ' + '; } diff --git a/app/Designs/Creative.php b/app/Designs/Creative.php index 4dd13ac6295c..040abd3a89f5 100644 --- a/app/Designs/Creative.php +++ b/app/Designs/Creative.php @@ -38,6 +38,7 @@ margin-top: 6mm; .table_header_thead_class { text-align: left; border-radius: .5rem; } .table_header_td_class { text-transform: uppercase; font-size: 1.25rem; color: #b83280; font-weight: 500 } .table_body_td_class { padding: 1rem;} +$custom_css '; } @@ -78,23 +79,7 @@ margin-top: 6mm; $task_table_body -'; - } - - public function task() - { - return ''; - } - - - public function product() - { - return ''; - } - - public function footer() - { - return '
+

$entity.public_notes

@@ -121,7 +106,27 @@ margin-top: 6mm;

$balance_due_label

$balance

-
+
'; + } + + public function task() + { + return ''; + } + + + public function product() + { + return ''; + } + + public function footer() + { + return ' +
+ +
'; } diff --git a/app/Designs/Designer.php b/app/Designs/Designer.php index 0b7dc0fa985e..3ca02c54ba19 100644 --- a/app/Designs/Designer.php +++ b/app/Designs/Designer.php @@ -143,6 +143,7 @@ class Designer //$s = microtime(true); $company = $this->entity->company; + $this->exported_variables['$custom_css'] = $this->entity->generateCustomCSS(); $this->exported_variables['$app_url'] = $this->entity->generateAppUrl(); $this->exported_variables['$client_details'] = $this->processVariables($this->input_variables['client_details'], $this->clientDetails($company)); $this->exported_variables['$company_details'] = $this->processVariables($this->input_variables['company_details'], $this->companyDetails($company)); diff --git a/app/Designs/Elegant.php b/app/Designs/Elegant.php index c6ce44a4f02d..71581bdd126f 100644 --- a/app/Designs/Elegant.php +++ b/app/Designs/Elegant.php @@ -35,6 +35,7 @@ class Elegant extends AbstractDesign .table_header_thead_class { text-align: left; border-bottom-width: 1px; border-style: dashed; border-color: black; } .table_header_td_class { font-weight: normal; color: #2f855a; padding: .5rem 1rem; } .table_body_td_class { padding: 1rem; } + $custom_css '; } @@ -81,22 +82,8 @@ class Elegant extends AbstractDesign $task_table_body -'; - } - - public function task() - { - return ''; - } - - public function product() - { - return ''; - } - - public function footer() - { - return '
+ +

$entity.public_notes

@@ -137,4 +124,25 @@ class Elegant extends AbstractDesign
'; } + + public function task() + { + return ''; + } + + public function product() + { + return ''; + } + + public function footer() + { + return ' +
+ +
+ +'; + } } diff --git a/app/Designs/Hipster.php b/app/Designs/Hipster.php index 3e6397b46050..66842b0a6568 100644 --- a/app/Designs/Hipster.php +++ b/app/Designs/Hipster.php @@ -36,6 +36,7 @@ body {font-size:90%} .table_header_thead_class { text-align: left } .table_header_td_class { text-transform: uppercase; padding: .5rem 1rem; font-weight: 600; border-color: black; } .table_body_td_class { border-left-width: 2px; border-color: black; padding: 1rem; } +$custom_css '; } @@ -100,22 +101,8 @@ body {font-size:90%} $task_table_body -'; - } - - public function task() - { - return ''; - } - - public function product() - { - return ''; - } - - public function footer() - { - return '
+ +

$entity.public_notes

@@ -144,7 +131,26 @@ body {font-size:90%}
-
+
'; + } + + public function task() + { + return ''; + } + + public function product() + { + return ''; + } + + public function footer() + { + return ' +
+ +
'; } diff --git a/app/Designs/Modern.php b/app/Designs/Modern.php index 759d1f616430..1649c31cd61e 100644 --- a/app/Designs/Modern.php +++ b/app/Designs/Modern.php @@ -30,31 +30,7 @@ class Modern extends AbstractDesign .table_header_thead_class {text-align:left; text-align:left; color:#fff; background-color:#1a202c;} .table_header_td_class {padding-left:1rem;padding-right:1rem; padding-top:.5rem;padding-bottom:.5rem} .table_body_td_class {border-top-width:1px; border-bottom-width:1px; border-color:#1a202c; padding-left:1rem;padding-right:1rem; padding-top:1rem;padding-bottom:1rem;} - - @media screen { - div.div_header { - display: flex; - } - div.div_footer { - display: flex; - } - } - @media print { - div.div_footer { - display: flex; - position: running(footer); - width: 100%; - } - div.div_header { - display: flex; - position: running(header); - width:100%; - } - } - - footer, header, hgroup, menu, nav, section { - display: block; - } +$custom_css '; @@ -63,7 +39,8 @@ class Modern extends AbstractDesign public function header() { - return '
+ return ' +

$company.name

@@ -75,13 +52,14 @@ class Modern extends AbstractDesign $entity_details
-
'; } public function body() { return ' + + $task_table_body -
$company_logo @@ -107,7 +85,45 @@ class Modern extends AbstractDesign
'; + +
+
+ $entity.public_notes +
+
+
+ $discount_label + $total_tax_labels + $line_tax_labels +
+
+ $discount + $total_tax_values + $line_tax_values +
+
+
+
+
+
+

$terms_label

+ $terms +
+
+ +
+
+
+
+

$balance_due_label

+
+

$balance_due

+
+
+
+
+ +'; } public function task() @@ -123,56 +139,17 @@ class Modern extends AbstractDesign public function footer() { return ' -
-
- $entity.public_notes -
-
-
- $discount_label - $total_tax_labels - $line_tax_labels -
-
- $discount - $total_tax_values - $line_tax_values -
-
-
- -
-
-

$terms_label

- $terms -
-
- -
-
-
-
-

$balance_due_label

-
-

$balance_due

-
-
- -
- -
- -
- + + '; } } diff --git a/app/Designs/Photo.php b/app/Designs/Photo.php index 445a72092982..07a6be6dcaae 100644 --- a/app/Designs/Photo.php +++ b/app/Designs/Photo.php @@ -39,6 +39,7 @@ body {font-size:90%} .table_header_thead_class { text-align: left; border-bottom-width: 4px; border-color: black; } .table_header_td_class { font-weight: 400; text-transform: uppercase; padding: 1rem .5rem; } .table_body_td_class { padding: 1rem; } +$custom_css '; } @@ -94,22 +95,8 @@ body {font-size:90%} $task_table_body -'; - } - - public function task() - { - return ''; - } - - public function product() - { - return ''; - } - - public function footer() - { - return '
+ +

$entity.public_notes

@@ -146,7 +133,26 @@ body {font-size:90%}
-
+
'; + } + + public function task() + { + return ''; + } + + public function product() + { + return ''; + } + + public function footer() + { + return ' +
+ +
'; } diff --git a/app/Designs/Plain.php b/app/Designs/Plain.php index 7e0263b4e54e..46be49deadd3 100644 --- a/app/Designs/Plain.php +++ b/app/Designs/Plain.php @@ -34,6 +34,7 @@ body {font-size:90%} .table_header_thead_class { text-align: left; background-color: #e2e8f0 } .table_header_td_class { padding: 1rem .5rem; } .table_body_td_class { padding: 1rem; border-bottom-width: 1px; border-top-width: 2px; border-color: #e2e8f0 } +$custom_css '; } @@ -122,6 +123,12 @@ body {font-size:90%} public function footer() { - return ''; + return ' +
+ +
+ +'; } } diff --git a/app/Designs/Playful.php b/app/Designs/Playful.php index 97f999f3d0a5..5208738918fe 100644 --- a/app/Designs/Playful.php +++ b/app/Designs/Playful.php @@ -35,6 +35,7 @@ body {font-size:90%} .table_header_thead_class { text-align: left; background-color: #319795; border-radius: .5rem; } .table_header_td_class { padding: .75rem 1rem; font-weight: 600; color: white; } .table_body_td_class { padding: 1rem; border-bottom-width: 4px; border-style: dashed; border-color: #319795; color: black } +$custom_css '; } @@ -93,22 +94,8 @@ body {font-size:90%} $task_table_body -'; - } - - public function task() - { - return ''; - } - - public function product() - { - return ''; - } - - public function footer() - { - return '
+ +
$entity.public_notes
@@ -136,4 +123,25 @@ body {font-size:90%}
'; } + + public function task() + { + return ''; + } + + public function product() + { + return ''; + } + + public function footer() + { + return ' +
+ +
+ +'; + } } diff --git a/app/Http/Controllers/EmailController.php b/app/Http/Controllers/EmailController.php index c2df5d3470f5..b731a92b0c51 100644 --- a/app/Http/Controllers/EmailController.php +++ b/app/Http/Controllers/EmailController.php @@ -113,17 +113,6 @@ class EmailController extends BaseController $body = $request->input('body'); $entity_string = strtolower(class_basename($entity_obj)); -$company = $entity_obj->company; -$settings = $company->settings; - -$settings->reply_to_email = "Reply@example.com"; -$settings->bcc_email = "BCC@example.com"; -$settings->pdf_email_attachment = true; -$settings->ubl_email_attachment = true; - -$company->settings = $settings; -$company->save(); - $entity_obj->invitations->each(function ($invitation) use ($subject, $body, $entity_string, $entity_obj) { if ($invitation->contact->send_email && $invitation->contact->email) { $when = now()->addSeconds(1); diff --git a/app/Http/Controllers/SelfUpdateController.php b/app/Http/Controllers/SelfUpdateController.php index dc3fdcf20f5f..2566244f8b83 100644 --- a/app/Http/Controllers/SelfUpdateController.php +++ b/app/Http/Controllers/SelfUpdateController.php @@ -68,26 +68,6 @@ class SelfUpdateController extends BaseController $res = $updater->update(); - try { - Artisan::call('migrate'); - } catch (\Exception $e) { - \Log::error("I wasn't able to migrate the data."); - } - - try { - Artisan::call('optimize'); - } catch (\Exception $e) { - \Log::error("I wasn't able to optimize."); - } - - $composer = Factory::create(new NullIO(), base_path('composer.json'), false); - - $output = Installer::create(new NullIO, $composer) - ->setVerbose() - ->setUpdate(true) - ->run(); - - \Log::error(print_r($output,1)); return response()->json(['message'=>$res], 200); } diff --git a/app/Notifications/BaseNotification.php b/app/Notifications/BaseNotification.php new file mode 100644 index 000000000000..48f569075ef4 --- /dev/null +++ b/app/Notifications/BaseNotification.php @@ -0,0 +1,117 @@ +line('The introduction to the notification.') + ->action('Notification Action', url('/')) + ->line('Thank you for using our application!'); + } + + /** + * Get the array representation of the notification. + * + * @param mixed $notifiable + * @return array + */ + public function toArray($notifiable) + { + return [ + // + ]; + } + + public function buildMailMessageSettings(MailMessage $mail_message) :MailMessage + { + $mail_message->subject($this->generateEmailEntityHtml($this->entity, $this->subject, $this->contact)); + + if(strlen($this->settings->reply_to_email) > 1) + $mail_message->replyTo($this->settings->reply_to_email); + + if(strlen($this->settings->bcc_email) > 1) + $mail_message->bcc($this->settings->bcc_email); + + if($this->settings->pdf_email_attachment) + $mail_message->attach(public_path($this->entity->pdf_file_path())); + + foreach($this->entity->documents as $document){ + $mail_message->attach($document->generateUrl(), ['as' => $document->name]); + } + + if($this->entity instanceof Invoice && $this->settings->ubl_email_attachment){ + $ubl_string = CreateUbl::dispatchNow($this->entity); + $mail_message->attachData($ubl_string, $this->entity->getFileName('xml')); + } + + + return $mail_message; + } + + public function buildMailMessageData() :array + { + + $body = $this->generateEmailEntityHtml($this->entity, $this->body, $this->contact); + + $design_style = $this->settings->email_style; + + if ($design_style == 'custom') { + $email_style_custom = $this->settings->email_style_custom; + $body = str_replace("$body", $body, $email_style_custom); + } + + $data = [ + 'body' => $body, + 'design' => $design_style, + 'footer' => '', + 'title' => '', + 'settings' => '', + 'company' => '', + 'logo' => $this->entity->company->present()->logo(), + 'signature' => '', + + ]; + + return $data; + + } +} diff --git a/app/Notifications/SendGenericNotification.php b/app/Notifications/SendGenericNotification.php index b7ded38872a4..7d5656c5b044 100644 --- a/app/Notifications/SendGenericNotification.php +++ b/app/Notifications/SendGenericNotification.php @@ -15,10 +15,9 @@ use Illuminate\Notifications\Notification; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; -class SendGenericNotification extends Notification implements ShouldQueue +class SendGenericNotification extends BaseNotification implements ShouldQueue { use Queueable; - use MakesInvoiceHtml; use Dispatchable; use SerializesModels; @@ -72,49 +71,11 @@ class SendGenericNotification extends Notification implements ShouldQueue */ public function toMail($notifiable) { - $subject = $this->generateEmailEntityHtml($this->entity, $this->subject, $this->contact); - $body = $this->generateEmailEntityHtml($this->entity, $this->body, $this->contact); - - $design_style = $this->settings->email_style; - - if ($design_style == 'custom') { - $email_style_custom = $this->settings->email_style_custom; - $body = str_replace("$body", $body, $email_style_custom); - } - - $data = [ - 'body' => $body, - 'design' => $design_style, - 'footer' => '', - 'title' => '', - 'settings' => '', - 'company' => '', - 'logo' => $this->entity->company->present()->logo(), - 'signature' => '', - - ]; $mail_message = (new MailMessage) - ->subject($subject) - ->markdown('email.admin.generic_email', $data); + ->markdown('email.admin.generic_email', $this->buildMailMessageData()); - if(strlen($this->settings->reply_to_email) > 1) - $mail_message->replyTo($this->settings->reply_to_email); - - if(strlen($this->settings->bcc_email) > 1) - $mail_message->bcc($this->settings->bcc_email); - - if($this->settings->pdf_email_attachment) - $mail_message->attach(public_path($this->entity->pdf_file_path())); - - foreach($this->entity->documents as $document){ - $mail_message->attach($document->generateUrl(), ['as' => $document->name]); - } - - if($this->entity instanceof Invoice && $this->settings->ubl_email_attachment){ - $ubl_string = CreateUbl::dispatchNow($this->entity); - $mail_message->attachData($ubl_string, $this->entity->getFileName('xml')); - } + $mail_message = $this->buildMailMessageSettings($mail_message); return $mail_message; diff --git a/app/Repositories/InvoiceRepository.php b/app/Repositories/InvoiceRepository.php index e03a56dd54d2..132e981143a7 100644 --- a/app/Repositories/InvoiceRepository.php +++ b/app/Repositories/InvoiceRepository.php @@ -89,9 +89,7 @@ class InvoiceRepository extends BaseRepository $invoice->delete(); - if (class_exists($className)) { - event(new InvoiceWasDeleted($invoice)); - } + event(new InvoiceWasDeleted($invoice)); return $invoice; } diff --git a/app/Utils/Traits/MakesInvoiceHtml.php b/app/Utils/Traits/MakesInvoiceHtml.php index a5642a6f0ce7..23df06213028 100644 --- a/app/Utils/Traits/MakesInvoiceHtml.php +++ b/app/Utils/Traits/MakesInvoiceHtml.php @@ -59,6 +59,8 @@ trait MakesInvoiceHtml $html = $this->parseLabelsAndValues($labels, $values, $html); + info($html); + return $html; } diff --git a/app/Utils/Traits/MakesInvoiceValues.php b/app/Utils/Traits/MakesInvoiceValues.php index 77f692f36216..29a017889873 100644 --- a/app/Utils/Traits/MakesInvoiceValues.php +++ b/app/Utils/Traits/MakesInvoiceValues.php @@ -731,4 +731,79 @@ trait MakesInvoiceValues { return rtrim(config('ninja.app_url'), "/"); } + + public function generateCustomCSS() + { + $settings = $this->client->getMergedSettings(); + + $header_and_footer = ' +@media print { + thead {display: table-header-group;} + tfoot {display: table-footer-group;} + button {display: none;} + body {margin: 0;} +}'; + + $header = ' +@media print { + thead {display: table-header-group;} + button {display: none;} + body {margin: 0;} +}'; + + $footer = ' +@media print { + tfoot {display: table-footer-group;} + button {display: none;} + body {margin: 0;} +}'; + $css = ''; + + if($settings->all_pages_header && $settings->all_pages_footer) + $css .= $header_and_footer; + elseif($settings->all_pages_header && !$settings->all_pages_footer) + $css .= $header; + elseif(!$settings->all_pages_header && $settings->all_pages_footer) + $css .= $footer; + + $css .= ' +.header, .header-space { + height: 160px; +} + +.footer, .footer-space { + height: 160px; +} + +.footer { + position: fixed; + bottom: 0; + width: 100%; +} + +.header { + position: fixed; + top: 0mm; + width: 100%; +} + +.page { + page-break-after: always; +} + +@page { + margin: 0mm +} + +html { + '; + +// $css .= 'font-size:' . $settings->font_size . 'px;'; + $css .= 'font-size:14px;'; + + $css .= '}'; + + return $css; + + } } diff --git a/app/Utils/Traits/Pdf/PdfMaker.php b/app/Utils/Traits/Pdf/PdfMaker.php index f3c80b929794..6fea4452404f 100644 --- a/app/Utils/Traits/Pdf/PdfMaker.php +++ b/app/Utils/Traits/Pdf/PdfMaker.php @@ -49,6 +49,8 @@ trait PdfMaker $browser = Browsershot::html($html); + // $browser->format('A4'); + // $browser->landscape(); return $browser->deviceScaleFactor(1) ->showBackground() diff --git a/config/self-update.php b/config/self-update.php index fcbcbb15d40e..3d5061cce7b8 100644 --- a/config/self-update.php +++ b/config/self-update.php @@ -88,7 +88,7 @@ return [ | */ - 'log_events' => env('SELF_UPDATER_LOG_EVENTS', false), + 'log_events' => env('SELF_UPDATER_LOG_EVENTS', true), /* |-------------------------------------------------------------------------- diff --git a/tests/Integration/DesignTest.php b/tests/Integration/DesignTest.php index 6bd408644549..367f8eb0150f 100644 --- a/tests/Integration/DesignTest.php +++ b/tests/Integration/DesignTest.php @@ -67,6 +67,8 @@ class DesignTest extends TestCase $settings = $this->invoice->client->settings; $settings->invoice_design_id = "VolejRejNm"; + $settings->all_pages_header = true; + $settings->all_pages_footer = true; $this->client->settings = $settings; $this->client->save(); @@ -97,6 +99,8 @@ class DesignTest extends TestCase $settings = $this->quote->client->settings; $settings->invoice_design_id = "VolejRejNm"; + $settings->all_pages_header = true; + $settings->all_pages_footer = true; $this->client->settings = $settings; $this->client->save(); @@ -117,6 +121,8 @@ class DesignTest extends TestCase $settings = $this->invoice->client->settings; $settings->quote_design_id = "4"; + $settings->all_pages_header = true; + $settings->all_pages_footer = true; $this->credit->client_id = $this->client->id; $this->credit->setRelation('client', $this->client); @@ -133,6 +139,8 @@ class DesignTest extends TestCase for ($x=1; $x<=10; $x++) { $settings = $this->invoice->client->settings; $settings->quote_design_id = (string)$this->encodePrimaryKey($x); + $settings->all_pages_header = true; + $settings->all_pages_footer = true; $this->quote->client_id = $this->client->id; $this->quote->setRelation('client', $this->client);