diff --git a/app/Services/PdfMaker/PdfMaker.php b/app/Services/PdfMaker/PdfMaker.php index 2f50f9882ddb..55c600fe4480 100644 --- a/app/Services/PdfMaker/PdfMaker.php +++ b/app/Services/PdfMaker/PdfMaker.php @@ -77,8 +77,6 @@ class PdfMaker $this->updateVariables($this->data['variables']); } - $this->processOptions(); - return $this; } diff --git a/app/Services/PdfMaker/PdfMakerUtilities.php b/app/Services/PdfMaker/PdfMakerUtilities.php index c90005e43b28..ab72d76d3745 100644 --- a/app/Services/PdfMaker/PdfMakerUtilities.php +++ b/app/Services/PdfMaker/PdfMakerUtilities.php @@ -163,144 +163,6 @@ trait PdfMakerUtilities return $element; } - public function processOptions() - { - if (!isset($this->options['all_pages_header']) || $this->options['all_pages_header'] == false) { - return; - } - - if (!isset($this->options['all_pages_footer']) || $this->options['all_pages_footer'] == false) { - return; - } - - $this->insertPrintCSS(); - $this->wrapIntoTable(); - } - - public function insertPrintCSS() - { - $css = <<<'EOT' - table.page-container { - page-break-after: always; - min-width: 100%; - } - - thead.page-header { - display: table-header-group; - } - - tfoot.page-footer { - display: table-footer-group; - } - EOT; - - $css_node = $this->document->createTextNode($css); - - $style = $this->document->getElementsByTagName('style')->item(0); - - if ($style) { - return $style->appendChild($css_node); - } - - $head = $this->document->getElementsByTagName('head')->item(0); - - if ($head) { - $style_node = $this->document->createElement('style', $css); - - return $head->appendChild($style_node); - } - - return $this; - } - - public function wrapIntoTable() - { - $markup = <<<'EOT' - - - - - - - - - - - - - - - - -
- -
- -
- EOT; - - $document = new DOMDocument(); - $document->loadHTML($markup); - - $table = $document->getElementById('page-container'); - - $body = $this->document->getElementsByTagName('body') - ->item(0); - - $body->appendChild( - $this->document->importNode($table, true) - ); - - for ($i = 0; $i < $body->childNodes->length; $i++) { - $element = $body->childNodes->item($i); - - if ($element->nodeType !== 1) { - continue; - } - - if ( - $element->getAttribute('id') == 'header' || - $element->getAttribute('id') == 'footer' || - $element->getAttribute('id') === 'page-container' - ) { - continue; - } - - $clone = $element->cloneNode(true); - $element->parentNode->removeChild($element); - - $this->document->getElementById('repeat-content')->appendChild($clone); - } - - // info($this->data['options']); - - if ( - $header = $this->document->getElementById('header') && - isset($this->data['options']['all_pages_header']) && - $this->data['options']['all_pages_header'] - ) { - $header = $this->document->getElementById('header'); - $clone = $header->cloneNode(true); - - $header->parentNode->removeChild($header); - $this->document->getElementById('repeat-header')->appendChild($clone); - } - - if ( - $footer = $this->document->getElementById('footer') && - isset($this->data['options']['all_pages_footer']) && - $this->data['options']['all_pages_footer'] - ) { - $footer = $this->document->getElementById('footer'); - $clone = $footer->cloneNode(true); - - $footer->parentNode->removeChild($footer); - $this->document->getElementById('repeat-footer')->appendChild($clone); - } - } - public function getEmptyElements(array &$elements, array $variables) { foreach ($elements as &$element) { diff --git a/app/Utils/PhantomJS/Phantom.php b/app/Utils/PhantomJS/Phantom.php index ffd8de36823f..1c6c4d05f36e 100644 --- a/app/Utils/PhantomJS/Phantom.php +++ b/app/Utils/PhantomJS/Phantom.php @@ -82,11 +82,20 @@ class Phantom $url = config('ninja.app_url').'/phantom/'.$entity.'/'.$invitation->key.'?phantomjs_secret='.config('ninja.phantomjs_secret'); info($url); - $key = config('ninja.phantomjs_key'); - $secret = config('ninja.phantomjs_key'); - - $phantom_url = "https://phantomjscloud.com/api/browser/v2/{$key}/?request=%7Burl:%22{$url}%22,renderType:%22pdf%22%7D"; - $pdf = CurlUtils::get($phantom_url); + $key = config( 'ninja.phantomjs_key' ); + $phantom_url = "https://phantomjscloud.com/api/browser/v2/{$key}/"; + $pdf = CurlUtils::post( $phantom_url, json_encode( [ + 'url' => $url, + 'renderType' => 'pdf', + 'outputAsJson' => false, + 'renderSettings' => [ + 'emulateMedia' => 'print', + 'pdfOptions' => [ + 'preferCSSPageSize' => true, + 'printBackground' => true, + ], + ], + ] ) ); $this->checkMime($pdf, $invitation, $entity); @@ -100,14 +109,20 @@ class Phantom public function convertHtmlToPdf($html) { - $hash = Str::random(32); - Cache::put($hash, $html, 300); - - $url = route('tmp_pdf', ['hash' => $hash]); - info($url); - $key = config('ninja.phantomjs_key'); - $phantom_url = "https://phantomjscloud.com/api/browser/v2/{$key}/?request=%7Burl:%22{$url}%22,renderType:%22pdf%22%7D"; - $pdf = CurlUtils::get($phantom_url); + $key = config( 'ninja.phantomjs_key' ); + $phantom_url = "https://phantomjscloud.com/api/browser/v2/{$key}/"; + $pdf = CurlUtils::post( $phantom_url, json_encode( [ + 'content' => $html, + 'renderType' => 'pdf', + 'outputAsJson' => false, + 'renderSettings' => [ + 'emulateMedia' => 'print', + 'pdfOptions' => [ + 'preferCSSPageSize' => true, + 'printBackground' => true, + ], + ], + ] ) ); $response = Response::make($pdf, 200); $response->header('Content-Type', 'application/pdf'); diff --git a/resources/views/pdf-designs/bold.html b/resources/views/pdf-designs/bold.html index 6b98d8824369..8545f2b65c00 100644 --- a/resources/views/pdf-designs/bold.html +++ b/resources/views/pdf-designs/bold.html @@ -13,31 +13,51 @@ zoom: 80%; } + body, html { + margin: 0; + padding: 0; + } + @page { - margin: -0.25cm !important; + margin: 0 !important; size: $page_size $page_layout; } p { margin: 0; padding: 0; - /* page-break-after: always; */ } - .header-wrapper { + #spacer-table > * > tr > td { + padding: 0; + } + + #spacer-table{ + width: 100%; + } + + #header { display: grid; grid-template-columns: 1.5fr 1fr 1fr; gap: 20px; background-color: #2d2c2a; - padding: 3rem; color: white; - min-width: 100%; line-height: var(--line-height); + position: fixed; + top: 0; } + + #header, #header-spacer { + height: 160px; + padding: 3rem; + margin-bottom: 3rem; + } .company-logo { height: 100%; - padding-right: 120px; + max-width: 100%; + object-fit: contain; + object-position: left center; } #company-details, @@ -46,6 +66,12 @@ flex-direction: column; } + #company-details, + #company-address, + .logo-container { + max-height: 160px; + } + #client-details { margin: 2rem; display: flex; @@ -61,7 +87,6 @@ display: grid; grid-template-columns: 1.5fr 1fr; padding-left: 1rem; - padding-top: 3rem; } .entity-details-wrapper { @@ -86,7 +111,11 @@ table-layout: fixed; overflow-wrap: break-word; margin-top: 3rem; - /* margin-bottom: 200px; */ + margin-bottom: 200px; + } + + [data-ref="table"]:last-child{ + margin-bottom:0; } .task-time-details { @@ -138,23 +167,23 @@ gap: 80px; } - #table-totals .totals-table-right-side>* { + #table-totals .totals-table-right-side > * { display: grid; grid-template-columns: 1fr 1fr; } - #table-totals>.totals-table-right-side>*> :nth-child(1) { + #table-totals > .totals-table-right-side > * > :nth-child(1) { text-align: "$dir_text_align"; margin-top: .75rem; } - #table-totals>.totals-table-right-side> * > :not([hidden]) ~ :not([hidden]) { + #table-totals > .totals-table-right-side > * > :not([hidden]) ~ :not([hidden]) { --tw-space-y-reverse: 0; margin-top: calc(.75rem * calc(1 - var(--tw-space-y-reverse))); margin-bottom: calc(.75rem * var(--tw-space-y-reverse)); } - #table-totals>.totals-table-right-side>*> :nth-child(2) { + #table-totals > .totals-table-right-side > * > :nth-child(2) { text-align: right; } @@ -186,51 +215,40 @@ font-size: 1.5rem; } - .footer-wrapper { + #footer { margin-top: 1rem; background-color: #2d2c2a; - height: 160px; min-width: 100%; position: fixed; bottom: 0; - padding: 1rem 3rem; display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 15px; color: white; } + #footer, #footer-spacer { + height: 160px; + padding: 1rem 3rem; + margin-top: 3rem; + } + [data-ref="total_table-footer"] { padding-top: 0.5rem } - /** Repeating header & footer styling. */ table { width: 100%; } - table.print-content {} - - table.print-content th, - table.print-content td { + table[data-ref="table"] th, + table[data-ref="table"] td { padding: .2rem .4rem; text-align: left; vertical-align: top; border-top: 1px solid #dee2e6; } - @media print { - .print-footer { - position: fixed; - bottom: 0; - left: 0; - } - - .no-print { - display: none - } - } - /** Markdown-specific styles. **/ #product-table h3, #task-table h3, @@ -239,9 +257,9 @@ margin-bottom: 0; } - [data-ref="product_table-product.description-th"] { - width: 23%; - } + [data-ref="product_table-product.description-th"] { + width: 23%; + } [data-ref="statement-totals"] { margin-top: 1rem; @@ -253,10 +271,6 @@ white-space: nowrap; } - .logo-container { - max-height: 160px; - } - #statement-invoice-table-totals > p { margin-right: 2rem; margin-top: 1rem; @@ -264,101 +278,94 @@ /** Useful snippets, uncomment to enable. **/ - /** Hide company logo **/ - /* .company-logo { display: none } */ + /** Hide company logo **/ + /* .company-logo { display: none } */ - /* Hide company details */ - /* #company-details > * { display: none } */ + /* Hide company details */ + /* #company-details > * { display: none } */ - /* Hide company address */ - /* #company-address > * { display: none } */ + /* Hide company address */ + /* #company-address > * { display: none } */ - /* Hide public notes */ - /* [data-ref="total_table-public_notes"] { display: none } */ + /* Hide public notes */ + /* [data-ref="total_table-public_notes"] { display: none } */ - /* Hide terms label */ - /* [data-ref="total_table-terms-label"] { display: none } */ + /* Hide terms label */ + /* [data-ref="total_table-terms-label"] { display: none } */ - /* Hide totals table */ - /* #table-totals { display: none } */ + /* Hide totals table */ + /* #table-totals { display: none } */ - /* Hide totals table left side */ - /* #table-totals div:first-child > * { display: none !important } */ + /* Hide totals table left side */ + /* #table-totals div:first-child > * { display: none !important } */ - /* Hide totals table right side */ - /* .totals-table-right-side { display: none } */ + /* Hide totals table right side */ + /* .totals-table-right-side { display: none } */ - /** For more info, please check our docs: https://invoiceninja.github.io **/ - /** To find out selectors on your own: https://invoiceninja.github.io/docs/custom-fields/#snippets **/ + /** For more info, please check our docs: https://invoiceninja.github.io **/ + /** To find out selectors on your own: https://invoiceninja.github.io/docs/custom-fields/#snippets **/ - - - - - - - - - - + + + + + + + +
- -
-
-
-

$entity_label

-
-
+ +
+ + + + + + + + + - - - - - - - - - - - -
+
+
+
+
+

$entity_label

+
+
-
-
-
+
+
+
+
-
- - +
- +
- +
- -
+
+
- -
+
+
- -
- -
-
-
- -
- - -
+ +
+ +