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 **/
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+
-
-
-
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
-
- |
-
-
-
-
- |
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
+
+
+
+
+
+
+ |
+
+
+
+
+