From a1b324694a1b3c479d81a9039fa23abb54569fc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Beganovi=C4=87?= Date: Thu, 20 Aug 2020 17:32:00 +0200 Subject: [PATCH 01/14] Replace old designs with new --- database/seeds/DesignSeeder.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/database/seeds/DesignSeeder.php b/database/seeds/DesignSeeder.php index 129a308de848..6b217387baf6 100644 --- a/database/seeds/DesignSeeder.php +++ b/database/seeds/DesignSeeder.php @@ -36,16 +36,17 @@ class DesignSeeder extends Seeder } foreach (Design::all() as $design) { - $class = 'App\Designs\\'.$design->name; + $class = 'App\Services\PdfMaker\Designs\\'.$design->name; $invoice_design = new $class(); + $invoice_design->document(); $design_object = new \stdClass; - $design_object->includes = $invoice_design->includes() ?: ''; - $design_object->header = $invoice_design->header() ?: ''; - $design_object->body = $invoice_design->body() ?: ''; - $design_object->product = $invoice_design->product() ?: ''; - $design_object->task = $invoice_design->task() ?: ''; - $design_object->footer = $invoice_design->footer() ?: ''; + $design_object->includes = $invoice_design->getSectionHTML('includes'); + $design_object->header = $invoice_design->getSectionHTML('head', false); + $design_object->body = $invoice_design->getSectionHTML('body', false); + $design_object->product = $invoice_design->getSectionHTML('product-table'); + $design_object->task = $invoice_design->getSectionHTML('task-table'); + $design_object->footer = $invoice_design->getSectionHTML('footer', false); $design->design = $design_object; $design->save(); From 0a38a52617b76c308ff9e3df2ee97d7e6a941e3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Beganovi=C4=87?= Date: Thu, 20 Aug 2020 17:48:10 +0200 Subject: [PATCH 02/14] Fix serialization issue --- app/Services/PdfMaker/Designs/Utilities/DesignHelpers.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Services/PdfMaker/Designs/Utilities/DesignHelpers.php b/app/Services/PdfMaker/Designs/Utilities/DesignHelpers.php index 844842b542e7..03c73a2dedaa 100644 --- a/app/Services/PdfMaker/Designs/Utilities/DesignHelpers.php +++ b/app/Services/PdfMaker/Designs/Utilities/DesignHelpers.php @@ -79,10 +79,10 @@ trait DesignHelpers $document->importNode($element, true) ); - return $document->saveHTML(); + return $document->saveXML(); } - return null; + return ''; } /** From ba41e22b3b304537c51881d1b1e7bad7f98a7c0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Beganovi=C4=87?= Date: Fri, 21 Aug 2020 11:12:42 +0200 Subject: [PATCH 03/14] Make tests for PdfMaker green --- tests/Feature/PdfMaker/PdfMakerDesignsTest.php | 9 --------- tests/Feature/PdfMaker/PdfMakerTest.php | 18 ------------------ 2 files changed, 27 deletions(-) diff --git a/tests/Feature/PdfMaker/PdfMakerDesignsTest.php b/tests/Feature/PdfMaker/PdfMakerDesignsTest.php index 831beea78d44..4ffa480736e9 100644 --- a/tests/Feature/PdfMaker/PdfMakerDesignsTest.php +++ b/tests/Feature/PdfMaker/PdfMakerDesignsTest.php @@ -137,7 +137,6 @@ class PdfMakerDesignsTest extends TestCase ], $this->state['variables']), ]; - $this->markTestSkipped('STUB broken tests'); $maker = new PdfMaker($state); @@ -250,7 +249,6 @@ class PdfMakerDesignsTest extends TestCase ], 'variables' => array_merge([], $this->state['variables']), ]; - $this->markTestSkipped('STUB broken tests'); $maker = new PdfMaker($state); @@ -366,7 +364,6 @@ class PdfMakerDesignsTest extends TestCase ], 'variables' => array_merge([], $this->state['variables']), ]; - $this->markTestSkipped('STUB broken tests'); $maker = new PdfMaker($state); @@ -483,7 +480,6 @@ class PdfMakerDesignsTest extends TestCase ], 'variables' => array_merge([], $this->state['variables']), ]; - $this->markTestSkipped('STUB broken tests'); $maker = new PdfMaker($state); @@ -593,7 +589,6 @@ class PdfMakerDesignsTest extends TestCase ], 'variables' => array_merge([], $this->state['variables']), ]; - $this->markTestSkipped('STUB broken tests'); $maker = new PdfMaker($state); @@ -707,7 +702,6 @@ class PdfMakerDesignsTest extends TestCase ], 'variables' => array_merge([], $this->state['variables']), ]; - $this->markTestSkipped('STUB broken tests'); $maker = new PdfMaker($state); @@ -824,7 +818,6 @@ class PdfMakerDesignsTest extends TestCase ], 'variables' => array_merge([], $this->state['variables']), ]; - $this->markTestSkipped('STUB broken tests'); $maker = new PdfMaker($state); @@ -941,7 +934,6 @@ class PdfMakerDesignsTest extends TestCase ], 'variables' => array_merge([], $this->state['variables']), ]; - $this->markTestSkipped('STUB broken tests'); $maker = new PdfMaker($state); @@ -1052,7 +1044,6 @@ class PdfMakerDesignsTest extends TestCase ], 'variables' => array_merge([], $this->state['variables']), ]; - $this->markTestSkipped('STUB broken tests'); $maker = new PdfMaker($state); diff --git a/tests/Feature/PdfMaker/PdfMakerTest.php b/tests/Feature/PdfMaker/PdfMakerTest.php index cbe58711d325..47edd87a50c8 100644 --- a/tests/Feature/PdfMaker/PdfMakerTest.php +++ b/tests/Feature/PdfMaker/PdfMakerTest.php @@ -18,8 +18,6 @@ class PdfMakerTest extends TestCase public function testDesignLoadsCorrectly() { - $this->markTestSkipped('STUB broken tests'); - $maker = new PdfMaker($this->state); $maker->design(ExampleDesign::class); @@ -29,8 +27,6 @@ class PdfMakerTest extends TestCase public function testHtmlDesignLoadsCorrectly() { - $this->markTestSkipped('STUB broken tests'); - $maker = new PdfMaker($this->state); $maker @@ -42,8 +38,6 @@ class PdfMakerTest extends TestCase public function testGetSectionUtility() { - $this->markTestSkipped('STUB broken tests'); - $maker = new PdfMaker($this->state); $maker @@ -55,8 +49,6 @@ class PdfMakerTest extends TestCase public function testTableAttributesAreInjected() { - $this->markTestSkipped('STUB broken tests'); - $state = [ 'template' => [ 'product-table' => [ @@ -93,8 +85,6 @@ class PdfMakerTest extends TestCase public function testVariablesAreReplaced() { - $this->markTestSkipped('STUB broken tests'); - $state = [ 'template' => [ @@ -133,8 +123,6 @@ class PdfMakerTest extends TestCase public function testElementContentIsGenerated() { - $this->markTestSkipped('STUB broken tests'); - $state = [ 'template' => [ @@ -184,8 +172,6 @@ class PdfMakerTest extends TestCase public function testConditionalRenderingOfElements() { - $this->markTestSkipped('STUB broken tests'); - $maker1 = new PdfMaker([ 'template' => [ @@ -226,8 +212,6 @@ class PdfMakerTest extends TestCase public function testOrderingElements() { - $this->markTestSkipped('STUB broken tests'); - $maker = new PdfMaker([ 'template' => [ @@ -286,8 +270,6 @@ class PdfMakerTest extends TestCase public function testGeneratingPdf() { - $this->markTestSkipped('STUB broken tests'); - $state = [ 'template' => [ From 23577a5f0f0ae62b4dd466fbd723ea92585eb075 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Beganovi=C4=87?= Date: Fri, 21 Aug 2020 11:59:39 +0200 Subject: [PATCH 04/14] Refactor context['product-table-columns'] to generic pdf_variables: - Pass 'pdf_variables' to CreateQuotePdf & CreateInvoicPdf - Update Playful & Plain to support new variable engine - Update DesignHelpers trait to support new variable engine - Make tests pass for ExampleIntegrationTest --- app/Jobs/Invoice/CreateInvoicePdf.php | 4 +--- app/Jobs/Quote/CreateQuotePdf.php | 2 +- app/Services/PdfMaker/Designs/Plain.php | 12 ++++++------ app/Services/PdfMaker/Designs/Playful.php | 14 +++++++------- .../PdfMaker/Designs/Utilities/DesignHelpers.php | 14 +++++++------- tests/Feature/PdfMaker/ExampleIntegrationTest.php | 7 +------ 6 files changed, 23 insertions(+), 30 deletions(-) diff --git a/app/Jobs/Invoice/CreateInvoicePdf.php b/app/Jobs/Invoice/CreateInvoicePdf.php index 5b3ecbdfe724..8a55f9d9a426 100644 --- a/app/Jobs/Invoice/CreateInvoicePdf.php +++ b/app/Jobs/Invoice/CreateInvoicePdf.php @@ -90,13 +90,11 @@ class CreateInvoicePdf implements ShouldQueue $design_class = new $design_namespace(); - $pdf_variables = json_decode(json_encode($this->invoice->company->settings->pdf_variables), 1); - $state = [ 'template' => $design_class->elements([ 'client' => $this->invoice->client, 'entity' => $this->invoice, - 'product-table-columns' => $pdf_variables['product_columns'], + 'pdf_variables' => (array)$this->invoice->company->settings->pdf_variables, ]), 'variables' => $html->generateLabelsAndValues(), ]; diff --git a/app/Jobs/Quote/CreateQuotePdf.php b/app/Jobs/Quote/CreateQuotePdf.php index d1b759d73ef5..7bb9b2a1823e 100644 --- a/app/Jobs/Quote/CreateQuotePdf.php +++ b/app/Jobs/Quote/CreateQuotePdf.php @@ -94,7 +94,7 @@ class CreateQuotePdf implements ShouldQueue 'template' => $design_class->elements([ 'client' => $this->quote->client, 'entity' => $this->quote, - 'product-table-columns' => $pdf_variables['product_columns'], + 'pdf_variables' => (array)$this->quote->company->settings->pdf_variables, ]), 'variables' => $html->generateLabelsAndValues(), ]; diff --git a/app/Services/PdfMaker/Designs/Plain.php b/app/Services/PdfMaker/Designs/Plain.php index d08a91357ba4..09208ade0608 100644 --- a/app/Services/PdfMaker/Designs/Plain.php +++ b/app/Services/PdfMaker/Designs/Plain.php @@ -78,7 +78,7 @@ class Plain extends BaseDesign public function companyAddress(): array { - $variables = $this->entity->company->settings->pdf_variables->company_address; + $variables = $this->context['pdf_variables']['company_address']; $elements = []; @@ -91,10 +91,10 @@ class Plain extends BaseDesign public function entityDetails(): array { - $variables = $this->entity->company->settings->pdf_variables->invoice_details; + $variables = $this->context['pdf_variables']['invoice_details']; if ($this->entity instanceof \App\Models\Quote) { - $variables = $this->entity->company->settings->pdf_variables->quote_details; + $variables = $this->context['pdf_variables']['quote_details']; } $elements = []; @@ -113,7 +113,7 @@ class Plain extends BaseDesign public function clientDetails(): array { - $variables = $this->entity->company->settings->pdf_variables->client_details; + $variables = $this->context['pdf_variables']['client_details']; $elements = []; @@ -166,7 +166,7 @@ class Plain extends BaseDesign $elements = []; - foreach ($this->context['product-table-columns'] as $column) { + foreach ($this->context['pdf_variables']['product_columns'] as $column) { $elements[] = ['element' => 'th', 'content' => $column . '_label', 'properties' => ['class' => 'px-4 py-2']]; } @@ -186,7 +186,7 @@ class Plain extends BaseDesign foreach ($items as $row) { $element = ['element' => 'tr', 'content' => '', 'elements' => []]; - foreach ($this->context['product-table-columns'] as $key => $cell) { + foreach ($this->context['pdf_variables']['product_columns'] as $key => $cell) { $element['elements'][] = ['element' => 'td', 'content' => $row[$cell], 'properties' => ['class' => 'border-t-2 border-b border-gray-200 px-4 py-4']]; } diff --git a/app/Services/PdfMaker/Designs/Playful.php b/app/Services/PdfMaker/Designs/Playful.php index bc9b9c6c1881..a39c756acb00 100644 --- a/app/Services/PdfMaker/Designs/Playful.php +++ b/app/Services/PdfMaker/Designs/Playful.php @@ -82,10 +82,10 @@ class Playful extends BaseDesign public function entityDetails(): array { - $variables = $this->entity->company->settings->pdf_variables->invoice_details; + $variables = $this->context['pdf_variables']['invoice_details']; if ($this->entity instanceof \App\Models\Quote) { - $variables = $this->entity->company->settings->pdf_variables->quote_details; + $variables = $this->context['pdf_variables']['quote_details']; } $elements = []; @@ -102,7 +102,7 @@ class Playful extends BaseDesign public function companyDetails() { - $variables = $this->entity->company->settings->pdf_variables->company_details; + $variables = $this->context['pdf_variables']['company_details']; $elements = []; @@ -115,7 +115,7 @@ class Playful extends BaseDesign public function companyAddress(): array { - $variables = $this->entity->company->settings->pdf_variables->company_address; + $variables = $this->context['pdf_variables']['company_address']; $elements = []; @@ -128,7 +128,7 @@ class Playful extends BaseDesign public function clientDetails(): array { - $variables = $this->entity->company->settings->pdf_variables->client_details; + $variables = $this->context['pdf_variables']['client_details']; $elements = []; @@ -154,7 +154,7 @@ class Playful extends BaseDesign $elements = []; - foreach ($this->context['product-table-columns'] as $column) { + foreach ($this->context['pdf_variables']['product_columns'] as $column) { $elements[] = ['element' => 'th', 'content' => $column . '_label', 'properties' => ['class' => 'font-semibold text-white px-4 py-3']]; } @@ -174,7 +174,7 @@ class Playful extends BaseDesign foreach ($items as $row) { $element = ['element' => 'tr', 'properties' => ['class' => 'border-b-2 border-teal-600'], 'content' => '', 'elements' => []]; - foreach ($this->context['product-table-columns'] as $key => $cell) { + foreach ($this->context['pdf_variables']['product_columns'] as $key => $cell) { $element['elements'][] = ['element' => 'td', 'content' => $row[$cell], 'properties' => ['class' => 'px-4 py-4']]; } diff --git a/app/Services/PdfMaker/Designs/Utilities/DesignHelpers.php b/app/Services/PdfMaker/Designs/Utilities/DesignHelpers.php index 03c73a2dedaa..cf5f5127086f 100644 --- a/app/Services/PdfMaker/Designs/Utilities/DesignHelpers.php +++ b/app/Services/PdfMaker/Designs/Utilities/DesignHelpers.php @@ -96,7 +96,7 @@ trait DesignHelpers */ public function processTaxColumns(): void { - if (in_array('$product.tax', $this->context['product-table-columns'])) { + if (in_array('$product.tax', (array)$this->context['pdf_variables']['product_columns'])) { $line_items = collect($this->entity->line_items); $tax1 = $line_items->where('tax_name1', '<>', '')->where('type_id', 1)->count(); @@ -116,10 +116,10 @@ trait DesignHelpers array_push($taxes, '$product.tax_rate3'); } - $key = array_search('$product.tax', $this->context['product-table-columns'], true); + $key = array_search('$product.tax', $this->context['pdf_variables']['product_columns'], true); if ($key) { - array_splice($this->context['product-table-columns'], $key, 1, $taxes); + array_splice($this->context['pdf_variables']['product_columns'], $key, 1, $taxes); } } } @@ -132,7 +132,7 @@ trait DesignHelpers */ public function calculateColspan(int $taken): int { - $total = (int) count($this->context['product-table-columns']); + $total = (int) count($this->context['pdf_variables']['product_columns']); return (int)$total - $taken; } @@ -177,16 +177,16 @@ trait DesignHelpers } if (is_null($this->entity->{$_variable})) { - // info("{$this->entity->id} $_variable is null!"); + // info("{$this->entity->id} $_variable is null!"); return true; } if (empty($this->entity->{$_variable})) { - // info("{$this->entity->id} $_variable is empty!"); + // info("{$this->entity->id} $_variable is empty!"); return true; } - // info("{$this->entity->id} $_variable ALL GOOD!!"); + // info("{$this->entity->id} $_variable ALL GOOD!!"); return false; } } diff --git a/tests/Feature/PdfMaker/ExampleIntegrationTest.php b/tests/Feature/PdfMaker/ExampleIntegrationTest.php index 1996280fdc51..40d97b1a1d8c 100644 --- a/tests/Feature/PdfMaker/ExampleIntegrationTest.php +++ b/tests/Feature/PdfMaker/ExampleIntegrationTest.php @@ -29,16 +29,11 @@ class ExampleIntegrationTest extends TestCase $engine = new HtmlEngine(null, $invitation, 'invoice'); $design = new Playful(); - $product_table_columns = json_decode( - json_encode($invoice->company->settings->pdf_variables), - 1 - )['product_columns']; - $state = [ 'template' => $design->elements([ 'client' => $invoice->client, 'entity' => $invoice, - 'product-table-columns' => $product_table_columns, + 'pdf_variables' => (array)$invoice->company->settings->pdf_variables, ]), 'variables' => $engine->generateLabelsAndValues(), ]; From 169eb4a7662d2ae2505fcddca42a9ffc9781b78c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Beganovi=C4=87?= Date: Fri, 21 Aug 2020 12:07:33 +0200 Subject: [PATCH 05/14] Update rest of the designs with new $pdf_variables key --- app/Services/PdfMaker/Designs/Bold.php | 18 ++++++------------ app/Services/PdfMaker/Designs/Business.php | 14 +++++++------- app/Services/PdfMaker/Designs/Clean.php | 14 +++++++------- app/Services/PdfMaker/Designs/Creative.php | 14 +++++++------- app/Services/PdfMaker/Designs/Elegant.php | 14 +++++++------- app/Services/PdfMaker/Designs/Hipster.php | 14 +++++++------- app/Services/PdfMaker/Designs/Modern.php | 14 +++++++------- 7 files changed, 48 insertions(+), 54 deletions(-) diff --git a/app/Services/PdfMaker/Designs/Bold.php b/app/Services/PdfMaker/Designs/Bold.php index ffa73edf9598..1cee3415262f 100644 --- a/app/Services/PdfMaker/Designs/Bold.php +++ b/app/Services/PdfMaker/Designs/Bold.php @@ -20,12 +20,6 @@ class Bold extends BaseDesign { use MakesInvoiceValues, DesignHelpers; - /** Global list of table elements, @var array */ - public $elements; - - /** @var App\Models\Client */ - public $client; - /** @var App\Models\Invoice || @var App\Models\Quote */ public $entity; @@ -82,7 +76,7 @@ class Bold extends BaseDesign public function companyDetails() { - $variables = $this->entity->company->settings->pdf_variables->company_details; + $variables = $this->context['pdf_variables']['company_details']; $elements = []; @@ -95,7 +89,7 @@ class Bold extends BaseDesign public function companyAddress(): array { - $variables = $this->entity->company->settings->pdf_variables->company_address; + $variables = $this->context['pdf_variables']['company_address']; $elements = []; @@ -108,7 +102,7 @@ class Bold extends BaseDesign public function clientDetails(): array { - $variables = $this->entity->company->settings->pdf_variables->client_details; + $variables = $this->context['pdf_variables']['client_details']; $elements = []; @@ -121,10 +115,10 @@ class Bold extends BaseDesign public function entityDetails(): array { - $variables = $this->entity->company->settings->pdf_variables->invoice_details; + $variables = $this->context['pdf_variables']['invoice_details']; if ($this->entity instanceof \App\Models\Quote) { - $variables = $this->entity->company->settings->pdf_variables->quote_details; + $variables = $this->context['pdf_variables']['quote_details']; } $elements = []; @@ -174,7 +168,7 @@ class Bold extends BaseDesign foreach ($items as $row) { $element = ['element' => 'tr', 'content' => '', 'elements' => []]; - foreach ($this->context['product-table-columns'] as $key => $cell) { + foreach ($this->context['pdf_variables']['product_columns'] as $key => $cell) { $element['elements'][] = ['element' => 'td', 'content' => $row[$cell], 'properties' => ['class' => 'px-4 py-4']]; } diff --git a/app/Services/PdfMaker/Designs/Business.php b/app/Services/PdfMaker/Designs/Business.php index 2aa6a816afc8..6d6b8cb22cc1 100644 --- a/app/Services/PdfMaker/Designs/Business.php +++ b/app/Services/PdfMaker/Designs/Business.php @@ -82,7 +82,7 @@ class Business extends BaseDesign public function companyDetails() { - $variables = $this->entity->company->settings->pdf_variables->company_details; + $variables = $this->context['pdf_variables']['company_details']; $elements = []; @@ -95,7 +95,7 @@ class Business extends BaseDesign public function companyAddress(): array { - $variables = $this->entity->company->settings->pdf_variables->company_address; + $variables = $this->context['pdf_variables']['company_address']; $elements = []; @@ -108,7 +108,7 @@ class Business extends BaseDesign public function clientDetails(): array { - $variables = $this->entity->company->settings->pdf_variables->client_details; + $variables = $this->context['pdf_variables']['client_details']; $elements = []; @@ -121,10 +121,10 @@ class Business extends BaseDesign public function entityDetails(): array { - $variables = $this->entity->company->settings->pdf_variables->invoice_details; + $variables = $this->context['pdf_variables']['invoice_details']; if ($this->entity instanceof \App\Models\Quote) { - $variables = $this->entity->company->settings->pdf_variables->quote_details; + $variables = $this->context['pdf_variables']['quote_details']; } $elements = []; @@ -154,7 +154,7 @@ class Business extends BaseDesign $elements = []; - foreach ($this->context['product-table-columns'] as $column) { + foreach ($this->context['pdf_variables']['product_columns'] as $column) { $elements[] = ['element' => 'th', 'content' => $column . '_label', 'properties' => ['class' => 'font-semibold text-white px-4 bg-blue-900 py-5']]; } @@ -174,7 +174,7 @@ class Business extends BaseDesign foreach ($items as $row) { $element = ['element' => 'tr', 'content' => '', 'elements' => []]; - foreach ($this->context['product-table-columns'] as $key => $cell) { + foreach ($this->context['pdf_variables']['product_columns'] as $key => $cell) { $element['elements'][] = ['element' => 'td', 'content' => $row[$cell], 'properties' => ['class' => 'border-4 border-white px-4 py-4 bg-gray-200']]; } diff --git a/app/Services/PdfMaker/Designs/Clean.php b/app/Services/PdfMaker/Designs/Clean.php index 9c233f007bbd..67ef90f9e1d8 100644 --- a/app/Services/PdfMaker/Designs/Clean.php +++ b/app/Services/PdfMaker/Designs/Clean.php @@ -82,7 +82,7 @@ class Clean extends BaseDesign public function companyDetails() { - $variables = $this->entity->company->settings->pdf_variables->company_details; + $variables = $this->context['pdf_variables']['company_details']; $elements = []; @@ -95,7 +95,7 @@ class Clean extends BaseDesign public function companyAddress(): array { - $variables = $this->entity->company->settings->pdf_variables->company_address; + $variables = $this->context['pdf_variables']['company_address']; $elements = []; @@ -108,10 +108,10 @@ class Clean extends BaseDesign public function entityDetails(): array { - $variables = $this->entity->company->settings->pdf_variables->invoice_details; + $variables = $this->context['pdf_variables']['invoice_details']; if ($this->entity instanceof \App\Models\Quote) { - $variables = $this->entity->company->settings->pdf_variables->quote_details; + $variables = $this->context['pdf_variables']['quote_details']; } $elements = []; @@ -128,7 +128,7 @@ class Clean extends BaseDesign public function clientDetails(): array { - $variables = $this->entity->company->settings->pdf_variables->client_details; + $variables = $this->context['pdf_variables']['client_details']; $elements = []; @@ -154,7 +154,7 @@ class Clean extends BaseDesign $elements = []; - foreach ($this->context['product-table-columns'] as $column) { + foreach ($this->context['pdf_variables']['product_columns'] as $column) { $elements[] = ['element' => 'th', 'content' => $column . '_label', 'properties' => ['class' => 'font-semibold px-4 py-5']]; } @@ -174,7 +174,7 @@ class Clean extends BaseDesign foreach ($items as $row) { $element = ['element' => 'tr', 'content' => '', 'elements' => []]; - foreach ($this->context['product-table-columns'] as $key => $cell) { + foreach ($this->context['pdf_variables']['product_columns'] as $key => $cell) { $element['elements'][] = ['element' => 'td', 'content' => $row[$cell], 'properties' => ['class' => 'border-t border-b px-4 py-4']]; } diff --git a/app/Services/PdfMaker/Designs/Creative.php b/app/Services/PdfMaker/Designs/Creative.php index a3043a89e8c5..2faec95f9675 100644 --- a/app/Services/PdfMaker/Designs/Creative.php +++ b/app/Services/PdfMaker/Designs/Creative.php @@ -82,7 +82,7 @@ class Creative extends BaseDesign public function companyDetails() { - $variables = $this->entity->company->settings->pdf_variables->company_details; + $variables = $this->context['pdf_variables']['company_details']; $elements = []; @@ -95,7 +95,7 @@ class Creative extends BaseDesign public function companyAddress(): array { - $variables = $this->entity->company->settings->pdf_variables->company_address; + $variables = $this->context['pdf_variables']['company_address']; $elements = []; @@ -108,7 +108,7 @@ class Creative extends BaseDesign public function clientDetails(): array { - $variables = $this->entity->company->settings->pdf_variables->client_details; + $variables = $this->context['pdf_variables']['client_details']; $elements = []; @@ -121,10 +121,10 @@ class Creative extends BaseDesign public function entityDetails(): array { - $variables = $this->entity->company->settings->pdf_variables->invoice_details; + $variables = $this->context['pdf_variables']['invoice_details']; if ($this->entity instanceof \App\Models\Quote) { - $variables = $this->entity->company->settings->pdf_variables->quote_details; + $variables = $this->context['pdf_variables']['quote_details']; } $elements = []; @@ -154,7 +154,7 @@ class Creative extends BaseDesign $elements = []; - foreach ($this->context['product-table-columns'] as $column) { + foreach ($this->context['pdf_variables']['product_columns'] as $column) { $elements[] = ['element' => 'th', 'content' => $column . '_label', 'properties' => ['class' => 'font-medium uppercase text-pink-700 text-xl px-4 py-5']]; } @@ -174,7 +174,7 @@ class Creative extends BaseDesign foreach ($items as $row) { $element = ['element' => 'tr', 'content' => '', 'elements' => []]; - foreach ($this->context['product-table-columns'] as $key => $cell) { + foreach ($this->context['pdf_variables']['product_columns'] as $key => $cell) { $element['elements'][] = ['element' => 'td', 'content' => $row[$cell], 'properties' => ['class' => 'px-4 py-4']]; } diff --git a/app/Services/PdfMaker/Designs/Elegant.php b/app/Services/PdfMaker/Designs/Elegant.php index 3cc20cbe2cc2..4071c4ad0569 100644 --- a/app/Services/PdfMaker/Designs/Elegant.php +++ b/app/Services/PdfMaker/Designs/Elegant.php @@ -82,10 +82,10 @@ class Elegant extends BaseDesign public function entityDetails(): array { - $variables = $this->entity->company->settings->pdf_variables->invoice_details; + $variables = $this->context['pdf_variables']['invoice_details']; if ($this->entity instanceof \App\Models\Quote) { - $variables = $this->entity->company->settings->pdf_variables->quote_details; + $variables = $this->context['pdf_variables']['quote_details']; } $elements = []; @@ -103,7 +103,7 @@ class Elegant extends BaseDesign public function companyDetails() { - $variables = $this->entity->company->settings->pdf_variables->company_details; + $variables = $this->context['pdf_variables']['company_details']; $elements = []; @@ -116,7 +116,7 @@ class Elegant extends BaseDesign public function companyAddress(): array { - $variables = $this->entity->company->settings->pdf_variables->company_address; + $variables = $this->context['pdf_variables']['company_address']; $elements = []; @@ -129,7 +129,7 @@ class Elegant extends BaseDesign public function clientDetails(): array { - $variables = $this->entity->company->settings->pdf_variables->client_details; + $variables = $this->context['pdf_variables']['client_details']; $elements = []; @@ -155,7 +155,7 @@ class Elegant extends BaseDesign $elements = []; - foreach ($this->context['product-table-columns'] as $column) { + foreach ($this->context['pdf_variables']['product_columns'] as $column) { $elements[] = ['element' => 'th', 'content' => $column . '_label', 'properties' => ['class' => 'font-normal text-green-700 px-4 py-2']]; } @@ -175,7 +175,7 @@ class Elegant extends BaseDesign foreach ($items as $row) { $element = ['element' => 'tr', 'properties' => ['class' => 'border-dashed border-b border-black'], 'content' => '', 'elements' => []]; - foreach ($this->context['product-table-columns'] as $key => $cell) { + foreach ($this->context['pdf_variables']['product_columns'] as $key => $cell) { $element['elements'][] = ['element' => 'td', 'content' => $row[$cell], 'properties' => ['class' => 'px-4 py-3']]; } diff --git a/app/Services/PdfMaker/Designs/Hipster.php b/app/Services/PdfMaker/Designs/Hipster.php index 7c217ebb77fe..e58837bf0cf4 100644 --- a/app/Services/PdfMaker/Designs/Hipster.php +++ b/app/Services/PdfMaker/Designs/Hipster.php @@ -82,7 +82,7 @@ class Hipster extends BaseDesign public function companyDetails() { - $variables = $this->entity->company->settings->pdf_variables->company_details; + $variables = $this->context['pdf_variables']['company_details']; $elements = []; @@ -95,7 +95,7 @@ class Hipster extends BaseDesign public function companyAddress(): array { - $variables = $this->entity->company->settings->pdf_variables->company_address; + $variables = $this->context['pdf_variables']['company_address']; $elements = []; @@ -108,7 +108,7 @@ class Hipster extends BaseDesign public function clientDetails(): array { - $variables = $this->entity->company->settings->pdf_variables->client_details; + $variables = $this->context['pdf_variables']['client_details']; $elements = []; @@ -121,10 +121,10 @@ class Hipster extends BaseDesign public function entityDetails(): array { - $variables = $this->entity->company->settings->pdf_variables->invoice_details; + $variables = $this->context['pdf_variables']['invoice_details']; if ($this->entity instanceof \App\Models\Quote) { - $variables = $this->entity->company->settings->pdf_variables->quote_details; + $variables = $this->context['pdf_variables']['quote_details']; } $elements = []; @@ -154,7 +154,7 @@ class Hipster extends BaseDesign $elements = []; - foreach ($this->context['product-table-columns'] as $column) { + foreach ($this->context['pdf_variables']['product_columns'] as $column) { $elements[] = ['element' => 'th', 'content' => $column . '_label', 'properties' => ['class' => 'border-l-2 border-black px-4 py-2 uppercase']]; } @@ -174,7 +174,7 @@ class Hipster extends BaseDesign foreach ($items as $row) { $element = ['element' => 'tr', 'content' => '', 'elements' => []]; - foreach ($this->context['product-table-columns'] as $key => $cell) { + foreach ($this->context['pdf_variables']['product_columns'] as $key => $cell) { $element['elements'][] = ['element' => 'td', 'content' => $row[$cell], 'properties' => ['class' => 'border-l-2 border-black px-4 py-4']]; } diff --git a/app/Services/PdfMaker/Designs/Modern.php b/app/Services/PdfMaker/Designs/Modern.php index 4ede0c3c9e0e..338b1316b04e 100644 --- a/app/Services/PdfMaker/Designs/Modern.php +++ b/app/Services/PdfMaker/Designs/Modern.php @@ -82,10 +82,10 @@ class Modern extends BaseDesign public function entityDetails(): array { - $variables = $this->entity->company->settings->pdf_variables->invoice_details; + $variables = $this->context['pdf_variables']['invoice_details']; if ($this->entity instanceof \App\Models\Quote) { - $variables = $this->entity->company->settings->pdf_variables->quote_details; + $variables = $this->context['pdf_variables']['quote_details']; } $elements = []; @@ -102,7 +102,7 @@ class Modern extends BaseDesign public function clientDetails(): array { - $variables = $this->entity->company->settings->pdf_variables->client_details; + $variables = $this->context['pdf_variables']['client_details']; $elements = []; @@ -128,7 +128,7 @@ class Modern extends BaseDesign $elements = []; - foreach ($this->context['product-table-columns'] as $column) { + foreach ($this->context['pdf_variables']['product_columns'] as $column) { $elements[] = ['element' => 'th', 'content' => $column . '_label', 'properties' => ['class' => 'px-4 py-2']]; } @@ -148,7 +148,7 @@ class Modern extends BaseDesign foreach ($items as $row) { $element = ['element' => 'tr', 'properties' => ['class' => 'border-t border-b border-gray-900'], 'content' => '', 'elements' => []]; - foreach ($this->context['product-table-columns'] as $key => $cell) { + foreach ($this->context['pdf_variables']['product_columns'] as $key => $cell) { $element['elements'][] = ['element' => 'td', 'content' => $row[$cell], 'properties' => ['class' => 'px-4 py-4']]; } @@ -187,7 +187,7 @@ class Modern extends BaseDesign public function companyDetails() { - $variables = $this->entity->company->settings->pdf_variables->company_details; + $variables = $this->context['pdf_variables']['company_details']; $elements = []; @@ -200,7 +200,7 @@ class Modern extends BaseDesign public function companyAddress(): array { - $variables = $this->entity->company->settings->pdf_variables->company_address; + $variables = $this->context['pdf_variables']['company_address']; $elements = []; From 13e70e24d5d795c4af76e0ac55397ed39a423cf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Beganovi=C4=87?= Date: Fri, 21 Aug 2020 16:47:17 +0200 Subject: [PATCH 06/14] wip --- app/Http/Controllers/PreviewController.php | 30 +++++++++++++++++-- .../PdfMaker/ExampleIntegrationTest.php | 2 +- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/app/Http/Controllers/PreviewController.php b/app/Http/Controllers/PreviewController.php index e9f789182245..89479e571e22 100644 --- a/app/Http/Controllers/PreviewController.php +++ b/app/Http/Controllers/PreviewController.php @@ -16,6 +16,8 @@ use App\Designs\Designer; use App\Factory\InvoiceFactory; use App\Jobs\Invoice\CreateInvoicePdf; use App\Jobs\Util\PreviewPdf; +use App\Services\PdfMaker\PdfMaker; +use App\Utils\HtmlEngine; use App\Utils\Traits\MakesHash; use App\Utils\Traits\MakesInvoiceHtml; use Illuminate\Support\Facades\DB; @@ -92,11 +94,33 @@ class PreviewController extends BaseController $entity_obj->load('client'); - $designer = new Designer($entity_obj, $design_object, $entity_obj->client->getSetting('pdf_variables'), lcfirst($entity)); + info($entity_obj); - $html = $this->generateEntityHtml($designer, $entity_obj); + $html = new HtmlEngine(null, $entity_obj->invitations()->first(), request()->entity_type); - $file_path = PreviewPdf::dispatchNow($html, auth()->user()->company()); + $design_namespace = 'App\Services\PdfMaker\Designs\\' . request()->design['name']; + + $design_class = new $design_namespace(); + + // $designer = new Designer($entity_obj, $design_object, $entity_obj->client->getSetting('pdf_variables'), lcfirst($entity)); + // $html = $this->generateEntityHtml($designer, $entity_obj); + + $state = [ + 'template' => $design_class->elements([ + 'client' => $entity_obj->client, + 'entity' => $entity_obj, + 'pdf_variables' => (array) $entity_obj->company->settings->pdf_variables, + ]), + 'variables' => $html->generateLabelsAndValues(), + ]; + + $maker = new PdfMaker($state); + + $maker + ->design($design_namespace) + ->build(); + + $file_path = PreviewPdf::dispatchNow($maker->getCompiledHTML(), auth()->user()->company()); return response()->download($file_path)->deleteFileAfterSend(true); } diff --git a/tests/Feature/PdfMaker/ExampleIntegrationTest.php b/tests/Feature/PdfMaker/ExampleIntegrationTest.php index 40d97b1a1d8c..f95829a92444 100644 --- a/tests/Feature/PdfMaker/ExampleIntegrationTest.php +++ b/tests/Feature/PdfMaker/ExampleIntegrationTest.php @@ -44,7 +44,7 @@ class ExampleIntegrationTest extends TestCase ->design(Playful::class) ->build(); - exec('echo "" > storage/logs/laravel.log'); + // exec('echo "" > storage/logs/laravel.log'); info($maker->getCompiledHTML(true)); From f5cc1f0d22946ac4e15bbde805a1e7d7042f8fe0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Beganovi=C4=87?= Date: Fri, 28 Aug 2020 09:51:02 +0200 Subject: [PATCH 07/14] Preview logic for editing designs --- app/Http/Controllers/PreviewController.php | 35 +++++++++++++++++----- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/app/Http/Controllers/PreviewController.php b/app/Http/Controllers/PreviewController.php index 89479e571e22..a7f907946ad8 100644 --- a/app/Http/Controllers/PreviewController.php +++ b/app/Http/Controllers/PreviewController.php @@ -94,8 +94,6 @@ class PreviewController extends BaseController $entity_obj->load('client'); - info($entity_obj); - $html = new HtmlEngine(null, $entity_obj->invitations()->first(), request()->entity_type); $design_namespace = 'App\Services\PdfMaker\Designs\\' . request()->design['name']; @@ -171,17 +169,40 @@ class PreviewController extends BaseController return response()->json(['message' => 'Invalid custom design object'], 400); } - $designer = new Designer($invoice, $design_object, auth()->user()->company()->settings->pdf_variables, lcfirst(request()->input('entity'))); + $html = new HtmlEngine(null, $invoice->invitations()->first(), 'invoice'); - $html = $this->generateEntityHtml($designer, $invoice, $contact); -info($html); - $file_path = PreviewPdf::dispatchNow($html, auth()->user()->company()); + /** TODO: This request() does not contain design string - making it impossible to update its content. */ + $design_namespace = 'App\Services\PdfMaker\Designs\\' . request()->design['name']; + + $design_class = new $design_namespace(); + + // $designer = new Designer($entity_obj, $design_object, $entity_obj->client->getSetting('pdf_variables'), lcfirst($entity)); + // $html = $this->generateEntityHtml($designer, $entity_obj); + + $state = [ + 'template' => $design_class->elements([ + 'client' => $invoice->client, + 'entity' => $invoice, + 'pdf_variables' => (array) $invoice->company->settings->pdf_variables, + ]), + 'variables' => $html->generateLabelsAndValues(), + ]; + + $maker = new PdfMaker($state); + + $maker + ->design($design_namespace) + ->build(); + + $maker->getCompiledHTML(); + + $file_path = PreviewPdf::dispatchNow($maker->getCompiledHTML(), auth()->user()->company()); DB::rollBack(); $response = Response::make($file_path, 200); $response->header('Content-Type', 'application/pdf'); - return $response; + return $response; } } From 5b67a547d9577f435aba1d002f101e0e7c68260b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Beganovi=C4=87?= Date: Fri, 4 Sep 2020 08:42:58 +0200 Subject: [PATCH 08/14] Update new designs --- config/ninja.php | 6 +- resources/views/pdf-designs/new/bold.html | 138 +++++++++++++ resources/views/pdf-designs/new/business.html | 163 +++++++++++++++ resources/views/pdf-designs/new/clean.html | 135 +++++++++++++ resources/views/pdf-designs/new/creative.html | 134 +++++++++++++ resources/views/pdf-designs/new/elegant.html | 160 +++++++++++++++ resources/views/pdf-designs/new/hipster.html | 188 ++++++++++++++++++ resources/views/pdf-designs/new/mdoern.html | 157 +++++++++++++++ resources/views/pdf-designs/new/plain.html | 117 +++++++++++ resources/views/pdf-designs/new/playful.html | 171 ++++++++++++++++ 10 files changed, 1368 insertions(+), 1 deletion(-) create mode 100644 resources/views/pdf-designs/new/bold.html create mode 100644 resources/views/pdf-designs/new/business.html create mode 100644 resources/views/pdf-designs/new/clean.html create mode 100644 resources/views/pdf-designs/new/creative.html create mode 100644 resources/views/pdf-designs/new/elegant.html create mode 100644 resources/views/pdf-designs/new/hipster.html create mode 100644 resources/views/pdf-designs/new/mdoern.html create mode 100644 resources/views/pdf-designs/new/plain.html create mode 100644 resources/views/pdf-designs/new/playful.html diff --git a/config/ninja.php b/config/ninja.php index 29eeb1c5adbd..a93e874ae942 100644 --- a/config/ninja.php +++ b/config/ninja.php @@ -128,5 +128,9 @@ return [ 'system' => [ 'node_path' => env('NODE_PATH', false), 'npm_path' => env('NPM_PATH', false) - ] + ], + 'designs' => [ + 'base_path' => resource_path('views/pdf-designs'), + 'templates' => ['bold', 'business', 'clean', 'creative', 'elegant', 'hipster', 'modern', 'plain', 'playful'], + ], ]; diff --git a/resources/views/pdf-designs/new/bold.html b/resources/views/pdf-designs/new/bold.html new file mode 100644 index 000000000000..2ca62f371864 --- /dev/null +++ b/resources/views/pdf-designs/new/bold.html @@ -0,0 +1,138 @@ + + + + + + + + + + +
+
+ +
+
+
+ + + +
+
+ +
+
+
+
+ +
+ + diff --git a/resources/views/pdf-designs/new/business.html b/resources/views/pdf-designs/new/business.html new file mode 100644 index 000000000000..2ce57084cb53 --- /dev/null +++ b/resources/views/pdf-designs/new/business.html @@ -0,0 +1,163 @@ + + + + + + + + + + +
+ + +
+
+
+ +

$entity_issued_to_label:

+
+
+ +
+
+
+
+ +
+ + diff --git a/resources/views/pdf-designs/new/clean.html b/resources/views/pdf-designs/new/clean.html new file mode 100644 index 000000000000..e9469bb5c6cd --- /dev/null +++ b/resources/views/pdf-designs/new/clean.html @@ -0,0 +1,135 @@ + + + + + + + + + + +
+ + +
+
+
+ +

$entity_label

+
+
+ +
+
+ + +
+ + diff --git a/resources/views/pdf-designs/new/creative.html b/resources/views/pdf-designs/new/creative.html new file mode 100644 index 000000000000..0b61b6b23ca9 --- /dev/null +++ b/resources/views/pdf-designs/new/creative.html @@ -0,0 +1,134 @@ + + + + + + + + + + +
+
+ +
+
+
+
+ + +
+ +
+

+ $entity_label  + #$entity_number +

+ +
+
+ +
+ + diff --git a/resources/views/pdf-designs/new/elegant.html b/resources/views/pdf-designs/new/elegant.html new file mode 100644 index 000000000000..4a2cef17b6c2 --- /dev/null +++ b/resources/views/pdf-designs/new/elegant.html @@ -0,0 +1,160 @@ + + + + + + + + + + +
+ +
+ +
+ +
+
+
+

$balance_due_label

+ +
+
+ +
+
+
+
+
+ +
+

$details_label

+
+
+
+ +
+ +

$thanks_label!

+
+ + diff --git a/resources/views/pdf-designs/new/hipster.html b/resources/views/pdf-designs/new/hipster.html new file mode 100644 index 000000000000..105e671fad05 --- /dev/null +++ b/resources/views/pdf-designs/new/hipster.html @@ -0,0 +1,188 @@ + + + + + + + + + + +
+
+

$from_label:

+ +
+ + +
+
+ +
+ +
+

$to_label:

+
+
+ + + +
+
+ +

$entity_label

+
+ + $entity_number_label: + $entity_number + + + $entity_date_label: + $entity_date + + + $payment_due_label: + $payment_due + + + $amount_due_label: + $amount_due + +
+ +
+ + diff --git a/resources/views/pdf-designs/new/mdoern.html b/resources/views/pdf-designs/new/mdoern.html new file mode 100644 index 000000000000..38ad6a79b5bf --- /dev/null +++ b/resources/views/pdf-designs/new/mdoern.html @@ -0,0 +1,157 @@ + + + + + + + + + + +
+

$company.name

+ +
+
+ +
+ + +
+
+ +
+
+
+ + + + diff --git a/resources/views/pdf-designs/new/plain.html b/resources/views/pdf-designs/new/plain.html new file mode 100644 index 000000000000..5e2bc71b0a01 --- /dev/null +++ b/resources/views/pdf-designs/new/plain.html @@ -0,0 +1,117 @@ + + + + + + + + + + +
+

$company.name

+ +
+ +
+ + +
+
+
+ +
+ +
+ + diff --git a/resources/views/pdf-designs/new/playful.html b/resources/views/pdf-designs/new/playful.html new file mode 100644 index 000000000000..d28c36b54a14 --- /dev/null +++ b/resources/views/pdf-designs/new/playful.html @@ -0,0 +1,171 @@ + + + + + + + + + + +
+ + +
+ +
+ +
+
+
+
+ +
+
+

$to_label:

+
+
+
+
+
+ +
+

$from_label:

+ +
+
+
+ +
+ + From 50c37a87197ef80f578b76019bc4361da63bc739 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Beganovi=C4=87?= Date: Fri, 4 Sep 2020 10:18:41 +0200 Subject: [PATCH 09/14] =?UTF-8?q?Update=20logic=20to=20support=20only=20on?= =?UTF-8?q?e=20dynamic=20design=20class:=20-=20New=20Design.php=20class=20?= =?UTF-8?q?that=20will=20act=20as=20master=20template=20-=20PdfMaker->desi?= =?UTF-8?q?gn()=20now=20accepts=20design=20object=20instead=20of=20string?= =?UTF-8?q?=20-=20PdfMaker:=20Skip=20elements=20if=20no=20id|tag=20provide?= =?UTF-8?q?d=20-=20PdfMaker:=20'content'=20property=20is=20now=20optional?= =?UTF-8?q?=20-=20config/ninja.php=20now=20contains=20base=5Fpath=20for=20?= =?UTF-8?q?templates=20-=20Refactored=20tests=20to=20be=20:green:=20?= =?UTF-8?q?=E2=9C=94=20-=20Removed=20PdfMakerDesignsTest=20since=20content?= =?UTF-8?q?=20is=20same=20for=20each=20template=20now?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Services/PdfMaker/Design.php | 227 ++++ .../Designs/Utilities/DesignHelpers.php | 9 +- app/Services/PdfMaker/PdfMaker.php | 10 +- app/Services/PdfMaker/PdfMakerUtilities.php | 13 +- config/ninja.php | 3 +- .../PdfMaker/ExampleIntegrationTest.php | 10 +- .../Feature/PdfMaker/PdfMakerDesignsTest.php | 1042 ----------------- tests/Feature/PdfMaker/PdfMakerTest.php | 73 +- 8 files changed, 286 insertions(+), 1101 deletions(-) create mode 100644 app/Services/PdfMaker/Design.php delete mode 100644 tests/Feature/PdfMaker/PdfMakerDesignsTest.php diff --git a/app/Services/PdfMaker/Design.php b/app/Services/PdfMaker/Design.php new file mode 100644 index 000000000000..59a2c0cac1dc --- /dev/null +++ b/app/Services/PdfMaker/Design.php @@ -0,0 +1,227 @@ + product||task */ + public $type; + + /** Design string */ + public $design; + + /** Construct options */ + public $options; + + const BOLD = 'bold.html'; + const BUSINESS = 'business.html'; + const CLEAN = 'clean.html'; + const CREATIVE = 'creative.html'; + const ELEGANT = 'elegant.html'; + const HIPSTER = 'hipster.html'; + const MODERN = 'modern.html'; + const PLAIN = 'plain.html'; + const PLAYFUL = 'playful.html'; + + public function __construct(string $design = null, array $options = []) + { + $this->design = $design; + + $this->options = $options; + } + + public function html(): ?string + { + $path = isset($this->options['custom_path']) + ? $this->options['custom_path'] + : config('ninja.designs.base_path'); + + return file_get_contents( + $path . $this->design + ); + } + + public function elements(array $context, string $type = 'product'): array + { + $this->context = $context; + + $this->type = $type; + + $this->setup(); + + return [ + 'company-details' => [ + 'id' => 'company-details', + 'elements' => $this->companyDetails(), + ], + 'company-address' => [ + 'id' => 'company-address', + 'elements' => $this->companyAddress(), + ], + 'client-details' => [ + 'id' => 'client-details', + 'elements' => $this->clientDetails(), + ], + 'entity-details' => [ + 'id' => 'entity-details', + 'elements' => $this->entityDetails(), + ], + 'product-table' => [ + 'id' => 'product-table', + 'elements' => $this->productTable(), + ], + 'footer-elements' => [ + 'id' => 'footer', + 'elements' => [ + $this->sharedFooterElements(), + ], + ], + ]; + } + + public function companyDetails() + { + $variables = $this->context['pdf_variables']['company_details']; + + $elements = []; + + foreach ($variables as $variable) { + $elements[] = ['element' => 'p', 'content' => $variable]; + } + + return $elements; + } + + public function companyAddress(): array + { + $variables = $this->context['pdf_variables']['company_address']; + + $elements = []; + + foreach ($variables as $variable) { + $elements[] = ['element' => 'p', 'content' => $variable]; + } + + return $elements; + } + + public function clientDetails(): array + { + $variables = $this->context['pdf_variables']['client_details']; + + $elements = []; + + foreach ($variables as $variable) { + $elements[] = ['element' => 'p', 'content' => $variable]; + } + + return $elements; + } + + public function entityDetails(): array + { + $variables = $this->context['pdf_variables']['invoice_details']; + + if ($this->entity instanceof \App\Models\Quote) { + $variables = $this->context['pdf_variables']['quote_details']; + } + + $elements = []; + + foreach ($variables as $variable) { + $elements[] = ['element' => 'tr', 'properties' => ['hidden' => $this->entityVariableCheck($variable)], 'elements' => [ + ['element' => 'th', 'content' => $variable . '_label'], + ['element' => 'th', 'content' => $variable], + ]]; + } + + return $elements; + } + + public function productTable(): array + { + return [ + ['element' => 'thead', 'elements' => $this->buildTableHeader()], + ['element' => 'tbody', 'elements' => $this->buildTableBody()], + ['element' => 'tfoot', 'elements' => $this->tableFooter()], + ]; + } + + public function buildTableHeader(): array + { + $this->processTaxColumns(); + + $elements = []; + + foreach ($this->context['pdf_variables']["{$this->type}_columns"] as $column) { + $elements[] = ['element' => 'th', 'content' => $column . '_label']; + } + + return $elements; + } + + public function buildTableBody(): array + { + $elements = []; + + $items = $this->transformLineItems($this->entity->line_items); + + if (count($items) == 0) { + return []; + } + + foreach ($items as $row) { + $element = ['element' => 'tr', 'elements' => []]; + + foreach ($this->context['pdf_variables']["{$this->type}_columns"] as $key => $cell) { + $element['elements'][] = ['element' => 'td', 'content' => $row[$cell]]; + } + + $elements[] = $element; + } + + return $elements; + } + + public function tableFooter() + { + $variables = $this->context['pdf_variables']['total_columns']; + + $elements = [ + ['element' => 'tr', 'elements' => [ + ['element' => 'td', 'content' => '$entity.public_notes', 'properties' => ['colspan' => '100%']], + ]], + ]; + + foreach ($variables as $variable) { + ['element' => 'tr', 'properties' => ['hidden' => 'false'], 'elements' => [ + ['element' => 'td', 'content' => $variable . '_label', 'properties' => ['colspan' => $this->calculateColspan(1)]], + ['element' => 'td', 'content' => $variable], + ]]; + } + + return $elements; + } +} diff --git a/app/Services/PdfMaker/Designs/Utilities/DesignHelpers.php b/app/Services/PdfMaker/Designs/Utilities/DesignHelpers.php index cf5f5127086f..724db96dfb2e 100644 --- a/app/Services/PdfMaker/Designs/Utilities/DesignHelpers.php +++ b/app/Services/PdfMaker/Designs/Utilities/DesignHelpers.php @@ -159,9 +159,9 @@ trait DesignHelpers public function sharedFooterElements() { - return ['element' => 'div', 'properties' => ['class' => 'flex items-center justify-between mt-10'], 'content' => '', 'elements' => [ - ['element' => 'img', 'content' => '', 'properties' => ['src' => '$contact.signature', 'class' => 'h-32']], - ['element' => 'img', 'content' => '', 'properties' => ['src' => '$app_url/images/created-by-invoiceninja-new.png', 'class' => 'h-24', 'hidden' => $this->entity->user->account->isPaid() ? 'true' : 'false']], + return ['element' => 'div', 'properties' => ['style' => 'display: flex; justify-content: space-between'], 'elements' => [ + ['element' => 'img', 'properties' => ['src' => '$contact.signature', 'style' => 'height: 5rem;']], + ['element' => 'img', 'properties' => ['src' => '$app_url/images/created-by-invoiceninja-new.png', 'style' => 'height: 5rem;', 'hidden' => $this->entity->user->account->isPaid() ? 'true' : 'false']], ]]; } @@ -177,16 +177,13 @@ trait DesignHelpers } if (is_null($this->entity->{$_variable})) { - // info("{$this->entity->id} $_variable is null!"); return true; } if (empty($this->entity->{$_variable})) { - // info("{$this->entity->id} $_variable is empty!"); return true; } - // info("{$this->entity->id} $_variable ALL GOOD!!"); return false; } } diff --git a/app/Services/PdfMaker/PdfMaker.php b/app/Services/PdfMaker/PdfMaker.php index 7e0e793fcbcd..57460b0f565b 100644 --- a/app/Services/PdfMaker/PdfMaker.php +++ b/app/Services/PdfMaker/PdfMaker.php @@ -43,9 +43,9 @@ class PdfMaker } } - public function design(string $design) + public function design(Design $design) { - $this->design = new $design(); + $this->design = $design; $this->initializeDomDocument(); @@ -71,12 +71,12 @@ class PdfMaker { if ($final) { $html = $this->document->saveXML(); - + $filtered = strtr($html, $this->filters); - + return $filtered; } - + return $this->document->saveXML(); } } diff --git a/app/Services/PdfMaker/PdfMakerUtilities.php b/app/Services/PdfMaker/PdfMakerUtilities.php index af2444478e7b..6339d2f27b5e 100644 --- a/app/Services/PdfMaker/PdfMakerUtilities.php +++ b/app/Services/PdfMaker/PdfMakerUtilities.php @@ -48,10 +48,17 @@ trait PdfMakerUtilities public function updateElementProperties(array $elements) { foreach ($elements as $element) { + + // if (!isset($element['tag']) || !isset($element['id']) || is_null($this->document->getElementById($element['id']))) { + // continue; + // } + if (isset($element['tag'])) { $node = $this->document->getElementsByTagName($element['tag'])->item(0); - } else { + } elseif(!is_null($this->document->getElementById($element['id']))) { $node = $this->document->getElementById($element['id']); + } else { + continue; } if (isset($element['properties'])) { @@ -109,7 +116,7 @@ trait PdfMakerUtilities public function createElementContent($element, $children) { foreach ($children as $child) { - $_child = $this->document->createElement($child['element'], $child['content']); + $_child = $this->document->createElement($child['element'], isset($child['content']) ? $child['content'] : ''); $element->appendChild($_child); if (isset($child['properties'])) { @@ -259,7 +266,7 @@ trait PdfMakerUtilities } if ( - $header = $this->document->getElementById('header') && + $header = $this->document->getElementById('header') && isset($this->data['options']['all_pages_header']) && $this->data['options']['all_pages_header'] ) { diff --git a/config/ninja.php b/config/ninja.php index a93e874ae942..085a22d5b291 100644 --- a/config/ninja.php +++ b/config/ninja.php @@ -130,7 +130,6 @@ return [ 'npm_path' => env('NPM_PATH', false) ], 'designs' => [ - 'base_path' => resource_path('views/pdf-designs'), - 'templates' => ['bold', 'business', 'clean', 'creative', 'elegant', 'hipster', 'modern', 'plain', 'playful'], + 'base_path' => resource_path('views/pdf-designs/new/'), ], ]; diff --git a/tests/Feature/PdfMaker/ExampleIntegrationTest.php b/tests/Feature/PdfMaker/ExampleIntegrationTest.php index f95829a92444..c8e87bd5e4e7 100644 --- a/tests/Feature/PdfMaker/ExampleIntegrationTest.php +++ b/tests/Feature/PdfMaker/ExampleIntegrationTest.php @@ -3,6 +3,7 @@ namespace Tests\Feature\PdfMaker; use App\Models\Invoice; +use App\Services\PdfMaker\Design; use App\Services\PdfMaker\Designs\Playful; use App\Services\PdfMaker\PdfMaker; use App\Utils\HtmlEngine; @@ -27,7 +28,10 @@ class ExampleIntegrationTest extends TestCase $invitation = $invoice->invitations()->first(); $engine = new HtmlEngine(null, $invitation, 'invoice'); - $design = new Playful(); + + $design = new Design( + Design::CLEAN + ); $state = [ 'template' => $design->elements([ @@ -41,12 +45,12 @@ class ExampleIntegrationTest extends TestCase $maker = new PdfMaker($state); $maker - ->design(Playful::class) + ->design($design) ->build(); // exec('echo "" > storage/logs/laravel.log'); - info($maker->getCompiledHTML(true)); + // info($maker->getCompiledHTML(true)); $this->assertTrue(true); } diff --git a/tests/Feature/PdfMaker/PdfMakerDesignsTest.php b/tests/Feature/PdfMaker/PdfMakerDesignsTest.php deleted file mode 100644 index 8b0cb03a1a88..000000000000 --- a/tests/Feature/PdfMaker/PdfMakerDesignsTest.php +++ /dev/null @@ -1,1042 +0,0 @@ -state = [ - 'variables' => [ - 'labels' => [], - 'values' => [ - '$css' => asset('css/tailwindcss@1.4.6.css'), - '$global-margin' => 'm-12', - '$global-padding' => 'p-12', - - '$company-logo' => 'https://invoiceninja-invoice-templates.netlify.app/assets/images/invoiceninja-logo.png', - '$company-name' => 'Invoice Ninja', - '$entity-number-label' => 'Invoice number', - '$entity-number' => '10000', - '$entity-date-label' => 'Invoice date', - '$entity-date' => '3th of June, 2025.', - '$due-date-label' => 'Due date', - '$due-date' => '5th of June, 2025.', - '$balance-due-label' => 'Balance due', - '$balance-due' => '$800.50', - - '$terms-label' => 'Terms', - '$terms' => 'Trend and SEO report has been sent via email. This is really long text just to test the width of the elements.', - - '$invoice-issued-to' => 'Invoice issued to:', - - '$entity' => 'Invoice', - ], - ], - ]; - - exec('echo "" > storage/logs/laravel.log'); - } - - public function testBusiness() - { - $state = [ - 'template' => [ - 'company-details' => [ - 'id' => 'company-details', - 'elements' => [ - ['element' => 'p', 'content' => 'Ninja Sample'], - ['element' => 'p', 'content' => 'contact@invoiceninja.com'], - ['element' => 'p', 'content' => '1-800-555-Ninja'], - ], - ], - 'company-address' => [ - 'id' => 'company-address', - 'elements' => [ - ['element' => 'p', 'content' => '123 Ninja Blvd.'], - ['element' => 'p', 'content' => 'NinjaLand, 97315'], - ['element' => 'p', 'content' => 'United States'], - ], - ], - 'client-details' => [ - 'id' => 'client-details', - 'elements' => [ - ['element' => 'p', 'content' => 'Winterfield Medical Supply '], - ['element' => 'p', 'content' => '65 Medical Complex Rd., D98'], - ['element' => 'p', 'content' => 'Atlanta, GA 22546'], - ['element' => 'p', 'content' => 'United States'], - ['element' => 'p', 'content' => 'demo@invoiceninja.com'], - ], - ], - 'entity-details' => [ - 'id' => 'entity-details', - 'elements' => [ - ['element' => 'div', 'content' => '', 'elements' => [ - ['element' => 'p', 'content' => '$entity-number-label'], - ['element' => 'p', 'content' => '$entity-date-label'], - ['element' => 'p', 'content' => '$due-date-label'], - ['element' => 'p', 'content' => '$balance-due-label'], - ]], - ['element' => 'div', 'content' => '', 'elements' => [ - ['element' => 'p', 'content' => '$entity-number'], - ['element' => 'p', 'content' => '$entity-date'], - ['element' => 'p', 'content' => '$due-date'], - ['element' => 'p', 'content' => '$balance-due'], - ]], - ], - ], - 'product-table' => [ - 'id' => 'product-table', - 'elements' => [ - ['element' => 'thead', 'content' => '', 'properties' => ['class' => 'text-left rounded-t-lg'], 'elements' => [ - ['element' => 'th', 'content' => 'Item', 'properties' => ['class' => 'font-semibold text-white px-4 bg-blue-900 py-5']], - ['element' => 'th', 'content' => 'Description', 'properties' => ['class' => 'font-semibold text-white px-4 bg-blue-900 py-5']], - ['element' => 'th', 'content' => 'Unit cost', 'properties' => ['class' => 'font-semibold text-white px-4 bg-blue-900 py-5']], - ['element' => 'th', 'content' => 'Quantity', 'properties' => ['class' => 'font-semibold text-white px-4 bg-blue-900 py-5']], - ['element' => 'th', 'content' => 'Line total', 'properties' => ['class' => 'font-semibold text-white px-4 bg-blue-900 py-5']], - ]], - ['element' => 'tbody', 'content' => '', 'elements' => [ - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Painting service', 'properties' => ['class' => 'border-4 border-white text-orange-700 px-4 py-4 bg-gray-200']], - ['element' => 'td', 'content' => '25 hours of painting', 'properties' => ['class' => 'border-4 border-white text-orange-700 px-4 py-4 bg-gray-200']], - ['element' => 'td', 'content' => '885.00', 'properties' => ['class' => 'border-4 border-white text-orange-700 px-4 py-4 bg-gray-200']], - ['element' => 'td', 'content' => '1', 'properties' => ['class' => 'border-4 border-white text-orange-700 px-4 py-4 bg-gray-200']], - ['element' => 'td', 'content' => '$885.00', 'properties' => ['class' => 'border-4 border-white text-orange-700 px-4 py-4 bg-gray-200']], - ]], - ]], - ['element' => 'tfoot', 'content' => '', 'elements' => [ - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Trend and SEO report has been sent via email. This is really long text just to test the width of the elements.', 'properties' => ['class' => 'border-l-4 border-white px-4 py-4 bg-gray-200', 'colspan' => '2']], - ['element' => 'td', 'content' => 'Subtotal', 'properties' => ['class' => 'px-4 py-4 bg-gray-200 text-right', 'colspan' => '2']], - ['element' => 'td', 'content' => '$0', 'properties' => ['class' => 'px-4 py-4 bg-gray-200 text-right']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Paid to date', 'properties' => ['class' => 'border-l-4 border-white px-4 bg-gray-200 text-right', 'colspan' => '4']], - ['element' => 'td', 'content' => '$0.00', 'properties' => ['class' => 'px-4 py-4 bg-gray-200 text-right']], - ]], - ]], - ], - ], - ], - 'variables' => array_merge([ - '#invoice-issued-to' => 'Invoice issued to', - ], $this->state['variables']), - ]; - - $maker = new PdfMaker($state); - - $maker - ->design(Business::class) - ->build(); - - exec('echo "" > storage/logs/laravel.log'); - - info($maker->getCompiledHTML()); - - $this->assertTrue(true); - } - - public function testClean() - { - $state = [ - 'template' => [ - 'company-details' => [ - 'id' => 'company-details', - 'elements' => [ - ['element' => 'p', 'content' => 'Ninja Sample', 'properties' => ['class' => 'text-blue-500']], - ['element' => 'p', 'content' => 'contact@invoiceninja.com'], - ['element' => 'p', 'content' => '1-800-555-Ninja'], - ], - ], - 'company-address' => [ - 'id' => 'company-address', - 'elements' => [ - ['element' => 'p', 'content' => '123 Ninja Blvd.'], - ['element' => 'p', 'content' => 'NinjaLand, 97315'], - ['element' => 'p', 'content' => 'United States'], - ], - ], - 'entity-details' => [ - 'id' => 'entity-details', - 'elements' => [ - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'th', 'content' => '$entity-number-label', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ['element' => 'th', 'content' => '$entity-number', 'properties' => ['class' => 'text-left pr-4 font-medium']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'th', 'content' => '$entity-date-label', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ['element' => 'th', 'content' => '$entity-date', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'th', 'content' => '$due-date-label', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ['element' => 'th', 'content' => '$due-date', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'th', 'content' => '$balance-due-label', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ['element' => 'th', 'content' => '$balance-due', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ]], - ], - ], - 'client-details' => [ - 'id' => 'client-details', - 'elements' => [ - ['element' => 'p', 'content' => 'Winterfield Medical Supply', 'properties' => ['class' => 'font-medium']], - ['element' => 'p', 'content' => '65 Medical Complex Rd., D98'], - ['element' => 'p', 'content' => 'Atlanta, GA 22546'], - ['element' => 'p', 'content' => 'United States'], - ['element' => 'p', 'content' => 'demo@invoiceninja.com'], - ], - ], - 'product-table' => [ - 'id' => 'product-table', - 'elements' => [ - ['element' => 'thead', 'content' => '', 'properties' => ['class' => 'text-left rounded-t-lg'], 'elements' => [ - ['element' => 'th', 'content' => 'Item', 'properties' => ['class' => 'font-semibold px-4 py-5']], - ['element' => 'th', 'content' => 'Description', 'properties' => ['class' => 'font-semibold px-4 py-5']], - ['element' => 'th', 'content' => 'Unit cost', 'properties' => ['class' => 'font-semibold px-4 py-5']], - ['element' => 'th', 'content' => 'Quantity', 'properties' => ['class' => 'font-semibold px-4 py-5']], - ['element' => 'th', 'content' => 'Line total', 'properties' => ['class' => 'font-semibold px-4 py-5']], - ]], - ['element' => 'tbody', 'content' => '', 'elements' => [ - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Painting service', 'properties' => ['class' => 'border-t border-b px-4 py-4']], - ['element' => 'td', 'content' => '25 hours of painting', 'properties' => ['class' => 'border-t border-b px-4 py-4']], - ['element' => 'td', 'content' => '885.00', 'properties' => ['class' => 'border-t border-b px-4 py-4']], - ['element' => 'td', 'content' => '1', 'properties' => ['class' => 'border-t border-b px-4 py-4']], - ['element' => 'td', 'content' => '$885.00', 'properties' => ['class' => 'border-t border-b px-4 py-4']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Painting service', 'properties' => ['class' => 'border-t border-b px-4 py-4']], - ['element' => 'td', 'content' => '25 hours of painting', 'properties' => ['class' => 'border-t border-b px-4 py-4']], - ['element' => 'td', 'content' => '885.00', 'properties' => ['class' => 'border-t border-b px-4 py-4']], - ['element' => 'td', 'content' => '1', 'properties' => ['class' => 'border-t border-b px-4 py-4']], - ['element' => 'td', 'content' => '$885.00', 'properties' => ['class' => 'border-t border-b px-4 py-4']], - ]], - ]], - ['element' => 'tfoot', 'content' => '', 'elements' => [ - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Trend and SEO report has been sent via email. This is really long text just to test the width of the elements.', 'properties' => ['class' => 'border-l-4 border-white px-4 py-4', 'colspan' => '2']], - ['element' => 'td', 'content' => 'Subtotal', 'properties' => ['class' => 'px-4 py-4 text-right', 'colspan' => '2']], - ['element' => 'td', 'content' => '$0', 'properties' => ['class' => 'px-4 py-4 text-right']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Paid to date', 'properties' => ['class' => 'border-l-4 border-white px-4 text-right', 'colspan' => '4']], - ['element' => 'td', 'content' => '$0.00', 'properties' => ['class' => 'px-4 py-4 text-right']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Discount %20', 'properties' => ['class' => 'border-l-4 border-white px-4 text-right', 'colspan' => '4']], - ['element' => 'td', 'content' => '$2.00', 'properties' => ['class' => 'px-4 py-4 text-right']], - ]], - ]], - ], - ], - ], - 'variables' => array_merge([], $this->state['variables']), - ]; - - $maker = new PdfMaker($state); - - $maker - ->design(Clean::class) - ->build(); - - info($maker->getCompiledHTML(true)); - - $this->assertTrue(true); - } - - public function testModern() - { - $state = [ - 'template' => [ - 'entity-details' => [ - 'id' => 'entity-details', - 'elements' => [ - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'th', 'content' => '$entity-number-label', 'properties' => ['class' => 'text-left pr-16 lg:pr-24 font-normal']], - ['element' => 'th', 'content' => '$entity-number', 'properties' => ['class' => 'text-left pr-16 lg:pr-24 font-medium']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'th', 'content' => '$entity-date-label', 'properties' => ['class' => 'text-left pr-16 lg:pr-24 font-normal']], - ['element' => 'th', 'content' => '$entity-date', 'properties' => ['class' => 'text-left pr-16 lg:pr-24 font-normal']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'th', 'content' => '$due-date-label', 'properties' => ['class' => 'text-left pr-16 lg:pr-24 font-normal']], - ['element' => 'th', 'content' => '$due-date', 'properties' => ['class' => 'text-left pr-16 lg:pr-24 font-normal']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'th', 'content' => '$balance-due-label', 'properties' => ['class' => 'text-left pr-16 lg:pr-24 font-normal']], - ['element' => 'th', 'content' => '$balance-due', 'properties' => ['class' => 'text-left pr-16 lg:pr-24 font-normal']], - ]], - ], - ], - 'client-details' => [ - 'id' => 'client-details', - 'elements' => [ - ['element' => 'p', 'content' => 'Winterfield Medical Supply', 'properties' => ['class' => 'font-medium']], - ['element' => 'p', 'content' => '65 Medical Complex Rd., D98'], - ['element' => 'p', 'content' => 'Atlanta, GA 22546'], - ['element' => 'p', 'content' => 'United States'], - ['element' => 'p', 'content' => 'demo@invoiceninja.com'], - ], - ], - 'product-table' => [ - 'id' => 'product-table', - 'elements' => [ - ['element' => 'thead', 'content' => '', 'properties' => ['class' => 'text-left text-white bg-gray-900'], 'elements' => [ - ['element' => 'th', 'content' => 'Item', 'properties' => ['class' => 'px-4 py-2']], - ['element' => 'th', 'content' => 'Description', 'properties' => ['class' => 'px-4 py-2']], - ['element' => 'th', 'content' => 'Unit cost', 'properties' => ['class' => 'px-4 py-2']], - ['element' => 'th', 'content' => 'Quantity', 'properties' => ['class' => 'px-4 py-2']], - ['element' => 'th', 'content' => 'Line total', 'properties' => ['class' => 'px-4 py-2']], - ]], - ['element' => 'tbody', 'content' => '', 'elements' => [ - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Painting service', 'properties' => ['class' => 'font-bold border-t border-b border-gray-900 px-4 py-4']], - ['element' => 'td', 'content' => '25 hours of painting', 'properties' => ['class' => 'border-t border-b border-gray-900 px-4 py-4']], - ['element' => 'td', 'content' => '885.00', 'properties' => ['class' => 'border-t border-b border-gray-900 px-4 py-4']], - ['element' => 'td', 'content' => '1', 'properties' => ['class' => 'border-t border-b border-gray-900 px-4 py-4']], - ['element' => 'td', 'content' => '$885.00', 'properties' => ['class' => 'border-t border-b border-gray-900 px-4 py-4']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Painting service', 'properties' => ['class' => 'font-bold border-t border-b border-gray-900 px-4 py-4']], - ['element' => 'td', 'content' => '25 hours of painting', 'properties' => ['class' => 'border-t border-b border-gray-900 px-4 py-4']], - ['element' => 'td', 'content' => '885.00', 'properties' => ['class' => 'border-t border-b border-gray-900 px-4 py-4']], - ['element' => 'td', 'content' => '1', 'properties' => ['class' => 'border-t border-b border-gray-900 px-4 py-4']], - ['element' => 'td', 'content' => '$885.00', 'properties' => ['class' => 'border-t border-b border-gray-900 px-4 py-4']], - ]], - ]], - ['element' => 'tfoot', 'content' => '', 'elements' => [ - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Trend and SEO report has been sent via email. This is really long text just to test the width of the elements.', 'properties' => ['class' => 'border-l-4 border-white px-4 py-4', 'colspan' => '2']], - ['element' => 'td', 'content' => 'Subtotal', 'properties' => ['class' => 'px-4 py-4 text-right', 'colspan' => '2']], - ['element' => 'td', 'content' => '$0', 'properties' => ['class' => 'px-4 py-2 text-right']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Paid to date', 'properties' => ['class' => 'border-l-4 border-white px-4 text-right', 'colspan' => '4']], - ['element' => 'td', 'content' => '$0.00', 'properties' => ['class' => 'px-4 py-2 text-right']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Discount %20', 'properties' => ['class' => 'border-l-4 border-white px-4 text-right', 'colspan' => '4']], - ['element' => 'td', 'content' => '$2.00', 'properties' => ['class' => 'px-4 py-2 text-right']], - ]], - ['element' => 'tr', 'content' => '', 'properties' => ['class' => 'mt-8 px-4 py-2 bg-gray-900 text-white'], 'elements' => [ - ['element' => 'td', 'content' => 'Balance due', 'properties' => ['class' => 'border-l-4 border-white px-4 text-right', 'colspan' => '4']], - ['element' => 'td', 'content' => '$2.00', 'properties' => ['class' => 'px-4 py-2 text-right']], - ]], - ]], - ], - ], - 'company-details' => [ - 'id' => 'company-details', - 'elements' => [ - ['element' => 'p', 'content' => 'Ninja Sample'], - ['element' => 'p', 'content' => 'contact@invoiceninja.com'], - ['element' => 'p', 'content' => '1-800-555-Ninja'], - ], - ], - 'company-address' => [ - 'id' => 'company-address', - 'elements' => [ - ['element' => 'p', 'content' => '123 Ninja Blvd.'], - ['element' => 'p', 'content' => 'NinjaLand, 97315'], - ['element' => 'p', 'content' => 'United States'], - ], - ], - ], - 'variables' => array_merge([], $this->state['variables']), - ]; - - $maker = new PdfMaker($state); - - $maker - ->design(Modern::class) - ->build(); - - info($maker->getCompiledHTML()); - - //exec('echo "" > storage/logs/laravel.log'); - - //info($maker->getCompiledHTML(true)); - - $this->assertTrue(true); - } - - public function testBold() - { - $state = [ - 'template' => [ - 'company-details' => [ - 'id' => 'company-details', - 'elements' => [ - ['element' => 'p', 'content' => 'Ninja Sample'], - ['element' => 'p', 'content' => 'contact@invoiceninja.com'], - ['element' => 'p', 'content' => '1-800-555-Ninja'], - ], - ], - 'company-address' => [ - 'id' => 'company-address', - 'elements' => [ - ['element' => 'p', 'content' => '123 Ninja Blvd.'], - ['element' => 'p', 'content' => 'NinjaLand, 97315'], - ['element' => 'p', 'content' => 'United States'], - ], - ], - 'client-details' => [ - 'id' => 'client-details', - 'elements' => [ - ['element' => 'p', 'content' => 'Winterfield Medical Supply', 'properties' => ['class' => 'font-medium']], - ['element' => 'p', 'content' => '65 Medical Complex Rd., D98'], - ['element' => 'p', 'content' => 'Atlanta, GA 22546'], - ['element' => 'p', 'content' => 'United States'], - ['element' => 'p', 'content' => 'demo@invoiceninja.com'], - ], - ], - 'entity-details' => [ - 'id' => 'entity-details', - 'elements' => [ - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'th', 'content' => '$entity-number-label', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ['element' => 'th', 'content' => '$entity-number', 'properties' => ['class' => 'text-left pr-4 font-medium']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'th', 'content' => '$entity-date-label', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ['element' => 'th', 'content' => '$entity-date', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'th', 'content' => '$due-date-label', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ['element' => 'th', 'content' => '$due-date', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'th', 'content' => '$balance-due-label', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ['element' => 'th', 'content' => '$balance-due', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ]], - ], - ], - 'product-table' => [ - 'id' => 'product-table', - 'elements' => [ - ['element' => 'thead', 'content' => '', 'properties' => ['class' => 'text-left rounded-t-lg'], 'elements' => [ - ['element' => 'th', 'content' => 'Item', 'properties' => ['class' => 'text-xl px-4 py-2']], - ['element' => 'th', 'content' => 'Description', 'properties' => ['class' => 'text-xl px-4 py-2']], - ['element' => 'th', 'content' => 'Unit cost', 'properties' => ['class' => 'text-xl px-4 py-2']], - ['element' => 'th', 'content' => 'Quantity', 'properties' => ['class' => 'text-xl px-4 py-2']], - ['element' => 'th', 'content' => 'Line total', 'properties' => ['class' => 'text-xl px-4 py-2']], - ]], - ['element' => 'tbody', 'content' => '', 'elements' => [ - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Painting service', 'properties' => ['class' => 'px-4 py-4']], - ['element' => 'td', 'content' => '25 hours of painting', 'properties' => ['class' => 'px-4 py-4']], - ['element' => 'td', 'content' => '885.00', 'properties' => ['class' => 'px-4 py-4']], - ['element' => 'td', 'content' => '1', 'properties' => ['class' => 'px-4 py-4']], - ['element' => 'td', 'content' => '$885.00', 'properties' => ['class' => 'px-4 py-4']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Painting service', 'properties' => ['class' => 'px-4 py-4']], - ['element' => 'td', 'content' => '25 hours of painting', 'properties' => ['class' => 'px-4 py-4']], - ['element' => 'td', 'content' => '885.00', 'properties' => ['class' => 'px-4 py-4']], - ['element' => 'td', 'content' => '1', 'properties' => ['class' => 'px-4 py-4']], - ['element' => 'td', 'content' => '$885.00', 'properties' => ['class' => 'px-4 py-4']], - ]], - ]], - ['element' => 'tfoot', 'content' => '', 'elements' => [ - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Trend and SEO report has been sent via email. This is really long text just to test the width of the elements.', 'properties' => ['class' => 'border-l-4 border-white px-4 py-2', 'colspan' => '2']], - ['element' => 'td', 'content' => 'Subtotal', 'properties' => ['class' => 'px-4 py-2 text-right', 'colspan' => '2']], - ['element' => 'td', 'content' => '$0', 'properties' => ['class' => 'px-4 py-2 text-right']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Paid to date', 'properties' => ['class' => 'border-l-4 border-white px-4 text-right', 'colspan' => '4']], - ['element' => 'td', 'content' => '$0.00', 'properties' => ['class' => 'px-4 py-2 text-right']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Discount %20', 'properties' => ['class' => 'border-l-4 border-white px-4 text-right', 'colspan' => '4']], - ['element' => 'td', 'content' => '$2.00', 'properties' => ['class' => 'px-4 py-2 text-right']], - ]], - ['element' => 'tr', 'content' => '', 'properties' => ['class' => 'mt-8 px-4 py-2'], 'elements' => [ - ['element' => 'td', 'content' => 'Balance due', 'properties' => ['class' => 'border-l-4 border-white px-4 text-right text-xl text-teal-600 font-semibold', 'colspan' => '4']], - ['element' => 'td', 'content' => '$2.00', 'properties' => ['class' => 'px-4 py-2 text-right text-xl text-teal-600 font-semibold']], - ]], - ]], - ], - ], - ], - 'variables' => array_merge([], $this->state['variables']), - ]; - - $maker = new PdfMaker($state); - - $maker - ->design(Bold::class) - ->build(); - - info($maker->getCompiledHTML()); - - $this->assertTrue(true); - } - - public function testPlain() - { - $state = [ - 'template' => [ - 'company-address' => [ - 'id' => 'company-address', - 'elements' => [ - ['element' => 'p', 'content' => '123 Ninja Blvd.'], - ['element' => 'p', 'content' => 'NinjaLand, 97315'], - ['element' => 'p', 'content' => 'United States'], - ], - ], - 'entity-details' => [ - 'id' => 'entity-details', - 'elements' => [ - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'th', 'content' => '$entity-number-label', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ['element' => 'th', 'content' => '$entity-number', 'properties' => ['class' => 'text-left pr-4 font-medium']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'th', 'content' => '$entity-date-label', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ['element' => 'th', 'content' => '$entity-date', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'th', 'content' => '$due-date-label', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ['element' => 'th', 'content' => '$due-date', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ]], - ['element' => 'tr', 'content' => '', 'properties' => ['class' => 'bg-gray-200'], 'elements' => [ - ['element' => 'th', 'content' => '$balance-due-label', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ['element' => 'th', 'content' => '$balance-due', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ]], - ], - ], - 'client-details' => [ - 'id' => 'client-details', - 'elements' => [ - ['element' => 'p', 'content' => 'Winterfield Medical Supply', 'properties' => ['class' => 'font-medium']], - ['element' => 'p', 'content' => '65 Medical Complex Rd., D98'], - ['element' => 'p', 'content' => 'Atlanta, GA 22546'], - ['element' => 'p', 'content' => 'United States'], - ['element' => 'p', 'content' => 'demo@invoiceninja.com'], - ], - ], - 'product-table' => [ - 'id' => 'product-table', - 'elements' => [ - ['element' => 'thead', 'content' => '', 'properties' => ['class' => 'text-left bg-gray-200'], 'elements' => [ - ['element' => 'th', 'content' => 'Item', 'properties' => ['class' => 'px-4 py-2']], - ['element' => 'th', 'content' => 'Description', 'properties' => ['class' => 'px-4 py-2']], - ['element' => 'th', 'content' => 'Unit cost', 'properties' => ['class' => 'px-4 py-2']], - ['element' => 'th', 'content' => 'Quantity', 'properties' => ['class' => 'px-4 py-2']], - ['element' => 'th', 'content' => 'Line total', 'properties' => ['class' => 'px-4 py-2']], - ]], - ['element' => 'tbody', 'content' => '', 'elements' => [ - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Painting service', 'properties' => ['class' => 'border-t-2 border-b border-gray-200 px-4 py-4']], - ['element' => 'td', 'content' => '25 hours of painting', 'properties' => ['class' => 'border-t-2 border-b border-gray-200 px-4 py-4']], - ['element' => 'td', 'content' => '885.00', 'properties' => ['class' => 'border-t-2 border-b border-gray-200 px-4 py-4']], - ['element' => 'td', 'content' => '1', 'properties' => ['class' => 'border-t-2 border-b border-gray-200 px-4 py-4']], - ['element' => 'td', 'content' => '$885.00', 'properties' => ['class' => 'border-t-2 border-b border-gray-200 px-4 py-4']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Painting service', 'properties' => ['class' => 'border-t-2 border-b border-gray-200 px-4 py-4']], - ['element' => 'td', 'content' => '25 hours of painting', 'properties' => ['class' => 'border-t-2 border-b border-gray-200 px-4 py-4']], - ['element' => 'td', 'content' => '885.00', 'properties' => ['class' => 'border-t-2 border-b border-gray-200 px-4 py-4']], - ['element' => 'td', 'content' => '1', 'properties' => ['class' => 'border-t-2 border-b border-gray-200 px-4 py-4']], - ['element' => 'td', 'content' => '$885.00', 'properties' => ['class' => 'border-t-2 border-b border-gray-200 px-4 py-4']], - ]], - ]], - ['element' => 'tfoot', 'content' => '', 'elements' => [ - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Trend and SEO report has been sent via email. This is really long text just to test the width of the elements.', 'properties' => ['class' => 'border-l-4 border-white px-4 py-4', 'colspan' => '2']], - ['element' => 'td', 'content' => 'Subtotal', 'properties' => ['class' => 'px-4 py-4 text-right', 'colspan' => '2']], - ['element' => 'td', 'content' => '$0', 'properties' => ['class' => 'px-4 py-2 text-right']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Paid to date', 'properties' => ['class' => 'border-l-4 border-white px-4 text-right', 'colspan' => '4']], - ['element' => 'td', 'content' => '$0.00', 'properties' => ['class' => 'px-4 py-2 text-right']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Discount %20', 'properties' => ['class' => 'border-l-4 border-white px-4 text-right', 'colspan' => '4']], - ['element' => 'td', 'content' => '$2.00', 'properties' => ['class' => 'px-4 py-2 text-right']], - ]], - ['element' => 'tr', 'content' => '', 'properties' => ['class' => 'mt-8 px-4 py-2 bg-gray-300'], 'elements' => [ - ['element' => 'td', 'content' => 'Balance due', 'properties' => ['class' => 'border-l-4 border-white px-4 text-right', 'colspan' => '4']], - ['element' => 'td', 'content' => '$2.00', 'properties' => ['class' => 'px-4 py-2 text-right']], - ]], - ]], - ], - ], - ], - 'variables' => array_merge([], $this->state['variables']), - ]; - - $maker = new PdfMaker($state); - - $maker - ->design(Plain::class) - ->build(); - - exec('echo "" > storage/logs/laravel.log'); - - info($maker->getCompiledHTML(true)); - - $this->assertTrue(true); - } - - public function testHipster() - { - $state = [ - 'template' => [ - 'company-details' => [ - 'id' => 'company-details', - 'elements' => [ - ['element' => 'p', 'content' => 'Ninja Sample'], - ['element' => 'p', 'content' => 'contact@invoiceninja.com'], - ['element' => 'p', 'content' => '1-800-555-Ninja'], - ], - ], - 'company-address' => [ - 'id' => 'company-address', - 'elements' => [ - ['element' => 'p', 'content' => '123 Ninja Blvd.'], - ['element' => 'p', 'content' => 'NinjaLand, 97315'], - ['element' => 'p', 'content' => 'United States'], - ], - ], - 'client-details' => [ - 'id' => 'client-details', - 'elements' => [ - ['element' => 'p', 'content' => 'Winterfield Medical Supply', 'properties' => ['class' => 'font-medium']], - ['element' => 'p', 'content' => '65 Medical Complex Rd., D98'], - ['element' => 'p', 'content' => 'Atlanta, GA 22546'], - ['element' => 'p', 'content' => 'United States'], - ['element' => 'p', 'content' => 'demo@invoiceninja.com'], - ], - ], - 'entity-details' => [ - 'id' => 'entity-details', - 'elements' => [ - ['element' => 'div', 'content' => '', 'properties' => ['class' => 'space-x-4'], 'elements' => [ - ['element' => 'span', 'content' => '$entity-number-label', 'properties' => ['class' => 'font-semibold uppercase text-yellow-600']], - ['element' => 'span', 'content' => '$entity-number', 'properties' => ['class' => 'font-semibold uppercase text-yellow-600']], - ]], - ['element' => 'div', 'content' => '', 'properties' => ['class' => 'space-x-4'], 'elements' => [ - ['element' => 'span', 'content' => '$entity-date-label', 'properties' => ['class' => 'uppercase']], - ['element' => 'span', 'content' => '$entity-date'], - ]], - ['element' => 'div', 'content' => '', 'properties' => ['class' => 'space-x-4'], 'elements' => [ - ['element' => 'span', 'content' => '$balance-due-label', 'properties' => ['class' => 'uppercase']], - ['element' => 'span', 'content' => '$balance-due'], - ]], - ], - ], - 'product-table' => [ - 'id' => 'product-table', - 'elements' => [ - ['element' => 'thead', 'content' => '', 'properties' => ['class' => 'text-left'], 'elements' => [ - ['element' => 'th', 'content' => 'Item', 'properties' => ['class' => 'border-l-2 border-black px-4 py-2 uppercase']], - ['element' => 'th', 'content' => 'Description', 'properties' => ['class' => 'border-l-2 border-black px-4 py-2 uppercase']], - ['element' => 'th', 'content' => 'Unit cost', 'properties' => ['class' => 'border-l-2 border-black px-4 py-2 uppercase']], - ['element' => 'th', 'content' => 'Quantity', 'properties' => ['class' => 'border-l-2 border-black px-4 py-2 uppercase']], - ['element' => 'th', 'content' => 'Line total', 'properties' => ['class' => 'border-l-2 border-black px-4 py-2 uppercase']], - ]], - ['element' => 'tbody', 'content' => '', 'elements' => [ - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Painting service', 'properties' => ['class' => 'border-l-2 border-black px-4 py-4']], - ['element' => 'td', 'content' => '25 hours of painting', 'properties' => ['class' => 'border-l-2 border-black px-4 py-4']], - ['element' => 'td', 'content' => '885.00', 'properties' => ['class' => 'border-l-2 border-black px-4 py-4']], - ['element' => 'td', 'content' => '1', 'properties' => ['class' => 'border-l-2 border-black px-4 py-4']], - ['element' => 'td', 'content' => '$885.00', 'properties' => ['class' => 'border-l-2 border-black px-4 py-4']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Painting service', 'properties' => ['class' => 'border-l-2 border-black px-4 py-4']], - ['element' => 'td', 'content' => '25 hours of painting', 'properties' => ['class' => 'border-l-2 border-black px-4 py-4']], - ['element' => 'td', 'content' => '885.00', 'properties' => ['class' => 'border-l-2 border-black px-4 py-4']], - ['element' => 'td', 'content' => '1', 'properties' => ['class' => 'border-l-2 border-black px-4 py-4']], - ['element' => 'td', 'content' => '$885.00', 'properties' => ['class' => 'border-l-2 border-black px-4 py-4']], - ]], - ]], - ['element' => 'tfoot', 'content' => '', 'elements' => [ - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Trend and SEO report has been sent via email. This is really long text just to test the width of the elements.', 'properties' => ['class' => 'border-l-4 border-white px-4 py-4', 'colspan' => '2']], - ['element' => 'td', 'content' => 'Subtotal', 'properties' => ['class' => 'px-4 py-4 text-right', 'colspan' => '2']], - ['element' => 'td', 'content' => '$0', 'properties' => ['class' => 'px-4 py-2 text-right']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Paid to date', 'properties' => ['class' => 'border-l-4 border-white px-4 text-right', 'colspan' => '4']], - ['element' => 'td', 'content' => '$0.00', 'properties' => ['class' => 'px-4 py-2 text-right']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Discount %20', 'properties' => ['class' => 'border-l-4 border-white px-4 text-right', 'colspan' => '4']], - ['element' => 'td', 'content' => '$2.00', 'properties' => ['class' => 'px-4 py-2 text-right']], - ]], - ['element' => 'tr', 'content' => '', 'properties' => ['class' => 'mt-8 px-4 py-2 bg-black text-white'], 'elements' => [ - ['element' => 'td', 'content' => 'Balance due', 'properties' => ['class' => 'border-l-4 border-white px-4 text-right', 'colspan' => '4']], - ['element' => 'td', 'content' => '$2.00', 'properties' => ['class' => 'px-4 py-2 text-right']], - ]], - ]], - ], - ], - ], - 'variables' => array_merge([], $this->state['variables']), - ]; - - $maker = new PdfMaker($state); - - $maker - ->design(Hipster::class) - ->build(); - - info($maker->getCompiledHTML(true)); - - $this->assertTrue(true); - } - - public function testElegant() - { - $state = [ - 'template' => [ - 'entity-details' => [ - 'id' => 'entity-details', - 'elements' => [ - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'th', 'content' => '$entity-number-label', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ['element' => 'th', 'content' => '$entity-number', 'properties' => ['class' => 'text-left pr-4 font-medium']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'th', 'content' => '$entity-date-label', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ['element' => 'th', 'content' => '$entity-date', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'th', 'content' => '$due-date-label', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ['element' => 'th', 'content' => '$due-date', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'th', 'content' => '$balance-due-label', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ['element' => 'th', 'content' => '$balance-due', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ]], - ], - ], - 'company-details' => [ - 'id' => 'company-details', - 'elements' => [ - ['element' => 'p', 'content' => 'Ninja Sample'], - ['element' => 'p', 'content' => 'contact@invoiceninja.com'], - ['element' => 'p', 'content' => '1-800-555-Ninja'], - ], - ], - 'company-address' => [ - 'id' => 'company-address', - 'elements' => [ - ['element' => 'p', 'content' => '123 Ninja Blvd.'], - ['element' => 'p', 'content' => 'NinjaLand, 97315'], - ['element' => 'p', 'content' => 'United States'], - ], - ], - 'client-details' => [ - 'id' => 'client-details', - 'elements' => [ - ['element' => 'p', 'content' => 'Winterfield Medical Supply', 'properties' => ['class' => 'font-medium']], - ['element' => 'p', 'content' => '65 Medical Complex Rd., D98'], - ['element' => 'p', 'content' => 'Atlanta, GA 22546'], - ['element' => 'p', 'content' => 'United States'], - ['element' => 'p', 'content' => 'demo@invoiceninja.com'], - ], - ], - 'product-table' => [ - 'id' => 'product-table', - 'elements' => [ - ['element' => 'thead', 'content' => '', 'properties' => ['class' => 'text-left border-dashed border-b border-black'], 'elements' => [ - ['element' => 'th', 'content' => 'Item', 'properties' => ['class' => 'font-normal text-green-700 px-4 py-2']], - ['element' => 'th', 'content' => 'Description', 'properties' => ['class' => 'font-normal text-green-700 px-4 py-2']], - ['element' => 'th', 'content' => 'Unit cost', 'properties' => ['class' => 'font-normal text-green-700 px-4 py-2']], - ['element' => 'th', 'content' => 'Quantity', 'properties' => ['class' => 'font-normal text-green-700 px-4 py-2']], - ['element' => 'th', 'content' => 'Line total', 'properties' => ['class' => 'font-normal text-green-700 px-4 py-2']], - ]], - ['element' => 'tbody', 'content' => '', 'elements' => [ - ['element' => 'tr', 'content' => '', 'properties' => ['class' => 'border-dashed border-b border-black'], 'elements' => [ - ['element' => 'td', 'content' => 'Painting service', 'properties' => ['class' => 'px-4 py-3']], - ['element' => 'td', 'content' => '25 hours of painting', 'properties' => ['class' => 'px-4 py-3']], - ['element' => 'td', 'content' => '885.00', 'properties' => ['class' => 'px-4 py-3']], - ['element' => 'td', 'content' => '1', 'properties' => ['class' => 'px-4 py-3']], - ['element' => 'td', 'content' => '$885.00', 'properties' => ['class' => 'px-4 py-3']], - ]], - ['element' => 'tr', 'content' => '', 'properties' => ['class' => 'border-dashed border-b border-black'], 'elements' => [ - ['element' => 'td', 'content' => 'Painting service', 'properties' => ['class' => 'px-4 py-3']], - ['element' => 'td', 'content' => '25 hours of painting', 'properties' => ['class' => 'px-4 py-3']], - ['element' => 'td', 'content' => '885.00', 'properties' => ['class' => 'px-4 py-3']], - ['element' => 'td', 'content' => '1', 'properties' => ['class' => 'px-4 py-3']], - ['element' => 'td', 'content' => '$885.00', 'properties' => ['class' => 'px-4 py-3']], - ]], - ]], - ['element' => 'tfoot', 'content' => '', 'elements' => [ - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Trend and SEO report has been sent via email. This is really long text just to test the width of the elements.', 'properties' => ['class' => 'border-l-4 border-white px-4 py-4', 'colspan' => '2']], - ['element' => 'td', 'content' => 'Subtotal', 'properties' => ['class' => 'px-4 py-4 text-right', 'colspan' => '2']], - ['element' => 'td', 'content' => '$0', 'properties' => ['class' => 'px-4 py-2 text-right']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Paid to date', 'properties' => ['class' => 'border-l-4 border-white px-4 text-right', 'colspan' => '4']], - ['element' => 'td', 'content' => '$0.00', 'properties' => ['class' => 'px-4 py-2 text-right']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Discount %20', 'properties' => ['class' => 'border-l-4 border-white px-4 text-right', 'colspan' => '4']], - ['element' => 'td', 'content' => '$2.00', 'properties' => ['class' => 'px-4 py-2 text-right']], - ]], - ['element' => 'tr', 'content' => '', 'properties' => ['class' => 'mt-8 px-4 py-2'], 'elements' => [ - ['element' => 'td', 'content' => 'Balance due', 'properties' => ['class' => 'border-l-4 border-white px-4 text-right', 'colspan' => '4']], - ['element' => 'td', 'content' => '$2.00', 'properties' => ['class' => 'px-4 py-2 text-right']], - ]], - ]], - ], - ], - ], - 'variables' => array_merge([], $this->state['variables']), - ]; - - $maker = new PdfMaker($state); - - $maker - ->design(Elegant::class) - ->build(); - - info($maker->getCompiledHTML(true)); - - $this->assertTrue(true); - } - - public function testCreative() - { - $state = [ - 'template' => [ - 'company-details' => [ - 'id' => 'company-details', - 'elements' => [ - ['element' => 'p', 'content' => 'Ninja Sample'], - ['element' => 'p', 'content' => 'contact@invoiceninja.com'], - ['element' => 'p', 'content' => '1-800-555-Ninja'], - ], - ], - 'company-address' => [ - 'id' => 'company-address', - 'elements' => [ - ['element' => 'p', 'content' => '123 Ninja Blvd.'], - ['element' => 'p', 'content' => 'NinjaLand, 97315'], - ['element' => 'p', 'content' => 'United States'], - ], - ], - 'client-details' => [ - 'id' => 'client-details', - 'elements' => [ - ['element' => 'p', 'content' => 'Winterfield Medical Supply', 'properties' => ['class' => 'font-medium']], - ['element' => 'p', 'content' => '65 Medical Complex Rd., D98'], - ['element' => 'p', 'content' => 'Atlanta, GA 22546'], - ['element' => 'p', 'content' => 'United States'], - ['element' => 'p', 'content' => 'demo@invoiceninja.com'], - ], - ], - 'entity-details' => [ - 'id' => 'entity-details', - 'elements' => [ - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'th', 'content' => '$entity-number-label', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ['element' => 'th', 'content' => '$entity-number', 'properties' => ['class' => 'text-left pr-4 font-medium']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'th', 'content' => '$entity-date-label', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ['element' => 'th', 'content' => '$entity-date', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'th', 'content' => '$due-date-label', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ['element' => 'th', 'content' => '$due-date', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'th', 'content' => '$balance-due-label', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ['element' => 'th', 'content' => '$balance-due', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ]], - ], - ], - 'product-table' => [ - 'id' => 'product-table', - 'elements' => [ - ['element' => 'thead', 'content' => '', 'properties' => ['class' => 'text-left'], 'elements' => [ - ['element' => 'th', 'content' => 'Item', 'properties' => ['class' => 'font-medium uppercase text-pink-700 text-xl px-4 py-5']], - ['element' => 'th', 'content' => 'Description', 'properties' => ['class' => 'font-medium uppercase text-pink-700 text-xl px-4 py-5']], - ['element' => 'th', 'content' => 'Unit cost', 'properties' => ['class' => 'font-medium uppercase text-pink-700 text-xl px-4 py-5']], - ['element' => 'th', 'content' => 'Quantity', 'properties' => ['class' => 'font-medium uppercase text-pink-700 text-xl px-4 py-5']], - ['element' => 'th', 'content' => 'Line total', 'properties' => ['class' => 'font-medium uppercase text-pink-700 text-xl px-4 py-5']], - ]], - ['element' => 'tbody', 'content' => '', 'elements' => [ - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Painting service', 'properties' => ['class' => 'px-4 py-4']], - ['element' => 'td', 'content' => '25 hours of painting', 'properties' => ['class' => 'px-4 py-4']], - ['element' => 'td', 'content' => '885.00', 'properties' => ['class' => 'px-4 py-4']], - ['element' => 'td', 'content' => '1', 'properties' => ['class' => 'px-4 py-4']], - ['element' => 'td', 'content' => '$885.00', 'properties' => ['class' => 'px-4 py-4']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Painting service', 'properties' => ['class' => 'px-4 py-4']], - ['element' => 'td', 'content' => '25 hours of painting', 'properties' => ['class' => 'px-4 py-4']], - ['element' => 'td', 'content' => '885.00', 'properties' => ['class' => 'px-4 py-4']], - ['element' => 'td', 'content' => '1', 'properties' => ['class' => 'px-4 py-4']], - ['element' => 'td', 'content' => '$885.00', 'properties' => ['class' => 'px-4 py-4']], - ]], - ]], - ['element' => 'tfoot', 'content' => '', 'elements' => [ - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Trend and SEO report has been sent via email. This is really long text just to test the width of the elements.', 'properties' => ['class' => 'border-l-4 border-white px-4 py-4', 'colspan' => '2']], - ['element' => 'td', 'content' => 'Subtotal', 'properties' => ['class' => 'px-4 py-4 text-right', 'colspan' => '2']], - ['element' => 'td', 'content' => '$0', 'properties' => ['class' => 'px-4 py-2 text-right']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Paid to date', 'properties' => ['class' => 'border-l-4 border-white px-4 text-right', 'colspan' => '4']], - ['element' => 'td', 'content' => '$0.00', 'properties' => ['class' => 'px-4 py-2 text-right']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Discount %20', 'properties' => ['class' => 'border-l-4 border-white px-4 text-right', 'colspan' => '4']], - ['element' => 'td', 'content' => '$2.00', 'properties' => ['class' => 'px-4 py-2 text-right']], - ]], - ['element' => 'tr', 'content' => '', 'properties' => ['class' => 'mt-8 px-4 py-2 border-t-4 border-pink-700'], 'elements' => [ - ['element' => 'td', 'content' => 'Balance due', 'properties' => ['class' => 'border-l-4 border-white px-4 text-right', 'colspan' => '4']], - ['element' => 'td', 'content' => '$2.00', 'properties' => ['class' => 'px-4 py-2 text-right font-semibold text-pink-700']], - ]], - ]], - ], - ], - ], - 'variables' => array_merge([], $this->state['variables']), - ]; - - $maker = new PdfMaker($state); - - $maker - ->design(Creative::class) - ->build(); - - - info($maker->getCompiledHTML(true)); - - $this->assertTrue(true); - } - - public function testPlayful() - { - $state = [ - 'template' => [ - 'entity-details' => [ - 'id' => 'entity-details', - 'elements' => [ - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'th', 'content' => '$entity-number-label', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ['element' => 'th', 'content' => '$entity-number', 'properties' => ['class' => 'text-left pr-4 font-medium']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'th', 'content' => '$entity-date-label', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ['element' => 'th', 'content' => '$entity-date', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'th', 'content' => '$due-date-label', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ['element' => 'th', 'content' => '$due-date', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'th', 'content' => '$balance-due-label', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ['element' => 'th', 'content' => '$balance-due', 'properties' => ['class' => 'text-left pr-4 font-normal']], - ]], - ], - ], - 'client-details' => [ - 'id' => 'client-details', - 'elements' => [ - ['element' => 'p', 'content' => 'Winterfield Medical Supply', 'properties' => ['class' => 'text-red-700']], - ['element' => 'p', 'content' => '65 Medical Complex Rd., D98'], - ['element' => 'p', 'content' => 'Atlanta, GA 22546'], - ['element' => 'p', 'content' => 'United States'], - ['element' => 'p', 'content' => 'demo@invoiceninja.com'], - ], - ], - 'company-details' => [ - 'id' => 'company-details', - 'elements' => [ - ['element' => 'p', 'content' => 'Ninja Sample', 'properties' => ['class' => 'text-red-700']], - ['element' => 'p', 'content' => 'contact@invoiceninja.com'], - ['element' => 'p', 'content' => '1-800-555-Ninja'], - ], - ], - 'company-address' => [ - 'id' => 'company-address', - 'elements' => [ - ['element' => 'p', 'content' => '123 Ninja Blvd.'], - ['element' => 'p', 'content' => 'NinjaLand, 97315'], - ['element' => 'p', 'content' => 'United States'], - ], - ], - 'product-table' => [ - 'id' => 'product-table', - 'elements' => [ - ['element' => 'thead', 'content' => '', 'properties' => ['class' => 'text-left bg-teal-600'], 'elements' => [ - ['element' => 'th', 'content' => 'Item', 'properties' => ['class' => 'font-semibold text-white px-4 py-3']], - ['element' => 'th', 'content' => 'Description', 'properties' => ['class' => 'font-semibold text-white px-4 py-3']], - ['element' => 'th', 'content' => 'Unit cost', 'properties' => ['class' => 'font-semibold text-white px-4 py-3']], - ['element' => 'th', 'content' => 'Quantity', 'properties' => ['class' => 'font-semibold text-white px-4 py-3']], - ['element' => 'th', 'content' => 'Line total', 'properties' => ['class' => 'font-semibold text-white px-4 py-3']], - ]], - ['element' => 'tbody', 'content' => '', 'elements' => [ - ['element' => 'tr', 'content' => '', 'properties' => ['class' => 'border-b-2 border-teal-600'], 'elements' => [ - ['element' => 'td', 'content' => 'Painting service', 'properties' => ['class' => 'px-4 py-4']], - ['element' => 'td', 'content' => '25 hours of painting', 'properties' => ['class' => 'px-4 py-4']], - ['element' => 'td', 'content' => '885.00', 'properties' => ['class' => 'px-4 py-4']], - ['element' => 'td', 'content' => '1', 'properties' => ['class' => 'px-4 py-4']], - ['element' => 'td', 'content' => '$885.00', 'properties' => ['class' => 'px-4 py-4']], - ]], - ]], - ['element' => 'tfoot', 'content' => '', 'elements' => [ - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Trend and SEO report has been sent via email. This is really long text just to test the width of the elements.', 'properties' => ['class' => 'border-l-4 border-white px-4 py-4', 'colspan' => '2']], - ['element' => 'td', 'content' => 'Subtotal', 'properties' => ['class' => 'px-4 py-4 text-right', 'colspan' => '2']], - ['element' => 'td', 'content' => '$0', 'properties' => ['class' => 'px-4 py-2 text-right']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Paid to date', 'properties' => ['class' => 'border-l-4 border-white px-4 text-right', 'colspan' => '4']], - ['element' => 'td', 'content' => '$0.00', 'properties' => ['class' => 'px-4 py-2 text-right']], - ]], - ['element' => 'tr', 'content' => '', 'elements' => [ - ['element' => 'td', 'content' => 'Discount %20', 'properties' => ['class' => 'border-l-4 border-white px-4 text-right', 'colspan' => '4']], - ['element' => 'td', 'content' => '$2.00', 'properties' => ['class' => 'px-4 py-2 text-right']], - ]], - ['element' => 'tr', 'content' => '', 'properties' => ['class' => 'mt-8 px-4 py-2'], 'elements' => [ - ['element' => 'td', 'content' => 'Balance due', 'properties' => ['class' => 'px-4 text-right', 'colspan' => '4']], - ['element' => 'td', 'content' => '$2.00', 'properties' => ['class' => 'px-4 py-2 text-right font-semibold text-teal-600']], - ]], - ]], - ], - ], - ], - 'variables' => array_merge([], $this->state['variables']), - ]; - - $maker = new PdfMaker($state); - - $maker - ->design(Playful::class) - ->build(); - - info($maker->getCompiledHTML(true)); - - $this->assertTrue(true); - } -} diff --git a/tests/Feature/PdfMaker/PdfMakerTest.php b/tests/Feature/PdfMaker/PdfMakerTest.php index 147d36dd1472..76af729733c1 100644 --- a/tests/Feature/PdfMaker/PdfMakerTest.php +++ b/tests/Feature/PdfMaker/PdfMakerTest.php @@ -2,7 +2,7 @@ namespace Tests\Feature\PdfMaker; -use App\Services\PdfMaker\Designs\Plain; +use App\Services\PdfMaker\Design; use App\Services\PdfMaker\PdfMaker; use Tests\TestCase; @@ -18,30 +18,35 @@ class PdfMakerTest extends TestCase public function testDesignLoadsCorrectly() { + $design = new Design('example.html', ['custom_path' => base_path('tests/Feature/PdfMaker/')]); $maker = new PdfMaker($this->state); - $maker->design(ExampleDesign::class); + $maker->design($design); - $this->assertInstanceOf(ExampleDesign::class, $maker->design); + $this->assertInstanceOf(Design::class, $maker->design); } public function testHtmlDesignLoadsCorrectly() { + $design = new Design('example.html', ['custom_path' => base_path('tests/Feature/PdfMaker/')]); + $maker = new PdfMaker($this->state); $maker - ->design(ExampleDesign::class) + ->design($design) ->build(); - $this->assertStringContainsString('', $maker->getCompiledHTML()); + $this->assertStringContainsString('Template: Example', $maker->getCompiledHTML()); } public function testGetSectionUtility() { + $design = new Design('example.html', ['custom_path' => base_path('tests/Feature/PdfMaker/')]); + $maker = new PdfMaker($this->state); $maker - ->design(ExampleDesign::class) + ->design($design) ->build(); $this->assertEquals('table', $maker->getSectionNode('product-table')->nodeName); @@ -59,12 +64,6 @@ class PdfMakerTest extends TestCase 'script' => 'console.log(1)', ], ], - 'header' => [ - 'id' => 'header', - 'properties' => [ - 'class' => 'header-class', - ], - ], ], 'variables' => [ 'labels' => [], @@ -72,10 +71,11 @@ class PdfMakerTest extends TestCase ], ]; + $design = new Design('example.html', ['custom_path' => base_path('tests/Feature/PdfMaker/')]); $maker = new PdfMaker($state); $maker - ->design(ExampleDesign::class) + ->design($design) ->build(); $this->assertStringContainsString('my-awesome-class', $maker->getSection('product-table', 'class')); @@ -85,36 +85,25 @@ class PdfMakerTest extends TestCase public function testVariablesAreReplaced() { - $state = [ 'template' => [ 'product-table' => [ 'id' => 'product-table', - 'properties' => [ - 'class' => 'my-awesome-class', - 'style' => 'margin-top: 10px;', - 'script' => 'console.log(1)', - ], - ], - 'header' => [ - 'id' => 'header', - 'properties' => [ - 'class' => 'header-class', - ], ], ], 'variables' => [ 'labels' => [], 'values' => [ - '$title' => 'Invoice Ninja', + '$company.name' => 'Invoice Ninja', ], ], ]; + $design = new Design('example.html', ['custom_path' => base_path('tests/Feature/PdfMaker/')]); $maker = new PdfMaker($state); $maker - ->design(ExampleDesign::class) + ->design($design) ->build(); $this->assertStringContainsString('Invoice Ninja', $maker->getCompiledHTML()); @@ -123,7 +112,6 @@ class PdfMakerTest extends TestCase public function testElementContentIsGenerated() { - $state = [ 'template' => [ 'product-table' => [ @@ -159,10 +147,11 @@ class PdfMakerTest extends TestCase ], ]; + $design = new Design('example.html', ['custom_path' => base_path('tests/Feature/PdfMaker/')]); $maker = new PdfMaker($state); $maker - ->design(ExampleDesign::class) + ->design($design) ->build(); $compiled = 'contact@invoiceninja.com'; @@ -172,6 +161,7 @@ class PdfMakerTest extends TestCase public function testConditionalRenderingOfElements() { + $design1 = new Design('example.html', ['custom_path' => base_path('tests/Feature/PdfMaker/')]); $maker1 = new PdfMaker([ 'template' => [ @@ -183,13 +173,14 @@ class PdfMakerTest extends TestCase ]); $maker1 - ->design(ExampleDesign::class) + ->design($design1) ->build(); $output1 = $maker1->getCompiledHTML(); - $this->assertStringContainsString('', $output1); + $this->assertStringContainsString('
+ +
diff --git a/resources/views/pdf-designs/new/business.html b/resources/views/pdf-designs/new/business.html index 2ce57084cb53..53851b49643d 100644 --- a/resources/views/pdf-designs/new/business.html +++ b/resources/views/pdf-designs/new/business.html @@ -159,5 +159,7 @@
+ +
diff --git a/resources/views/pdf-designs/new/clean.html b/resources/views/pdf-designs/new/clean.html index e9469bb5c6cd..3fd80fc0ed83 100644 --- a/resources/views/pdf-designs/new/clean.html +++ b/resources/views/pdf-designs/new/clean.html @@ -1,3 +1,4 @@ + @@ -131,5 +132,7 @@
+ +
diff --git a/resources/views/pdf-designs/new/creative.html b/resources/views/pdf-designs/new/creative.html index 0b61b6b23ca9..ecb74b578d4f 100644 --- a/resources/views/pdf-designs/new/creative.html +++ b/resources/views/pdf-designs/new/creative.html @@ -130,5 +130,7 @@
+ +
diff --git a/resources/views/pdf-designs/new/elegant.html b/resources/views/pdf-designs/new/elegant.html index 4a2cef17b6c2..e012c23e34de 100644 --- a/resources/views/pdf-designs/new/elegant.html +++ b/resources/views/pdf-designs/new/elegant.html @@ -154,6 +154,8 @@
+
+

$thanks_label!


diff --git a/resources/views/pdf-designs/new/hipster.html b/resources/views/pdf-designs/new/hipster.html index 105e671fad05..0b04c76bb47f 100644 --- a/resources/views/pdf-designs/new/hipster.html +++ b/resources/views/pdf-designs/new/hipster.html @@ -184,5 +184,7 @@
+ +
diff --git a/resources/views/pdf-designs/new/mdoern.html b/resources/views/pdf-designs/new/modern.html similarity index 99% rename from resources/views/pdf-designs/new/mdoern.html rename to resources/views/pdf-designs/new/modern.html index 38ad6a79b5bf..cc3c9e1422df 100644 --- a/resources/views/pdf-designs/new/mdoern.html +++ b/resources/views/pdf-designs/new/modern.html @@ -145,6 +145,8 @@
+
+