Pdf Service Refactor

This commit is contained in:
David Bomba 2022-12-28 21:28:58 +11:00
parent 2fe91b5707
commit ca853d29e5
4 changed files with 77 additions and 43 deletions

View File

@ -52,7 +52,11 @@ class PdfBuilder
{ {
$this->getTemplate() $this->getTemplate()
->buildSections() ->buildSections();
nlog($this->sections);
$this
->getEmptyElements() ->getEmptyElements()
->updateElementProperties() ->updateElementProperties()
->updateVariables(); ->updateVariables();
@ -85,9 +89,11 @@ class PdfBuilder
$document = new DOMDocument(); $document = new DOMDocument();
$document->validateOnParse = true; $document->validateOnParse = true;
@$document->loadHTML(mb_convert_encoding($this->service->config->designer->template, 'HTML-ENTITIES', 'UTF-8'));
@$document->loadHTML(mb_convert_encoding($this->service->designer->template, 'HTML-ENTITIES', 'UTF-8'));
$this->document = $document; $this->document = $document;
$this->xpath = new DOMXPath($document); $this->xpath = new DOMXPath($document);
return $this; return $this;
@ -112,6 +118,13 @@ class PdfBuilder
} }
private function mergeSections(array $section) :self
{
$this->sections = array_merge($this->sections, $section);
return $this;
}
/** /**
* Generates delivery note sections * Generates delivery note sections
* *
@ -124,7 +137,7 @@ class PdfBuilder
$this->genericSectionBuilder() $this->genericSectionBuilder()
->getProductTotals(); ->getProductTotals();
$this->sections[] = [ $this->mergeSections([
'client-details' => [ 'client-details' => [
'id' => 'client-details', 'id' => 'client-details',
'elements' => $this->clientDeliveryDetails(), 'elements' => $this->clientDeliveryDetails(),
@ -137,7 +150,7 @@ class PdfBuilder
'id' => 'entity-details', 'id' => 'entity-details',
'elements' => $this->deliveryNoteDetails(), 'elements' => $this->deliveryNoteDetails(),
], ],
]; ]);
return $this; return $this;
@ -154,7 +167,7 @@ class PdfBuilder
$this->genericSectionBuilder(); $this->genericSectionBuilder();
$this->sections[] = [ $this->mergeSections( [
'statement-invoice-table' => [ 'statement-invoice-table' => [
'id' => 'statement-invoice-table', 'id' => 'statement-invoice-table',
'elements' => $this->statementInvoiceTable(), 'elements' => $this->statementInvoiceTable(),
@ -179,7 +192,7 @@ class PdfBuilder
'id' => 'table-totals', 'id' => 'table-totals',
'elements' => $this->statementTableTotals(), 'elements' => $this->statementTableTotals(),
], ],
]; ]);
return $this; return $this;
@ -308,7 +321,7 @@ class PdfBuilder
$this->genericSectionBuilder() $this->genericSectionBuilder()
->getProductTotals(); ->getProductTotals();
$this->sections[] = [ $this->mergeSections([
'vendor-details' => [ 'vendor-details' => [
'id' => 'vendor-details', 'id' => 'vendor-details',
'elements' => $this->vendorDetails(), 'elements' => $this->vendorDetails(),
@ -317,7 +330,7 @@ class PdfBuilder
'id' => 'entity-details', 'id' => 'entity-details',
'elements' => $this->purchaseOrderDetails(), 'elements' => $this->purchaseOrderDetails(),
], ],
]; ]);
return $this; return $this;
@ -333,7 +346,7 @@ class PdfBuilder
private function genericSectionBuilder(): self private function genericSectionBuilder(): self
{ {
$this->sections[] = [ $this->mergeSections([
'company-details' => [ 'company-details' => [
'id' => 'company-details', 'id' => 'company-details',
'elements' => $this->companyDetails(), 'elements' => $this->companyDetails(),
@ -348,7 +361,7 @@ class PdfBuilder
$this->sharedFooterElements(), $this->sharedFooterElements(),
], ],
], ],
]; ]);
return $this; return $this;
} }
@ -394,7 +407,7 @@ class PdfBuilder
{ {
$elements = []; $elements = [];
$items = $this->transformLineItems($this->entity->line_items, $type); $items = $this->transformLineItems($this->service->config->entity->line_items, $type);
$this->processNewLines($items); $this->processNewLines($items);
@ -436,12 +449,12 @@ class PdfBuilder
$element = ['element' => 'tr', 'elements' => []]; $element = ['element' => 'tr', 'elements' => []];
if ( if (
array_key_exists($type, $this->context) && array_key_exists($type, $this->service->options) &&
!empty($this->context[$type]) && !empty($this->service->options[$type]) &&
!is_null($this->context[$type]) !is_null($this->service->options[$type])
) { ) {
$document = new DOMDocument(); $document = new DOMDocument();
$document->loadHTML($this->context[$type], LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); $document->loadHTML($this->service->options[$type], LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$td = $document->getElementsByTagName('tr')->item(0); $td = $document->getElementsByTagName('tr')->item(0);
@ -751,12 +764,12 @@ class PdfBuilder
private function getProductTotals(): self private function getProductTotals(): self
{ {
$this->sections[] = [ $this->mergeSections([
'table-totals' => [ 'table-totals' => [
'id' => 'table-totals', 'id' => 'table-totals',
'elements' => $this->getTableTotals(), 'elements' => $this->getTableTotals(),
], ],
]; ]);
return $this; return $this;
} }
@ -776,33 +789,33 @@ class PdfBuilder
if($this->service->config->entity_string == 'invoice') if($this->service->config->entity_string == 'invoice')
{ {
$this->sections[] = [ $this->mergeSections( [
'entity-details' => [ 'entity-details' => [
'id' => 'entity-details', 'id' => 'entity-details',
'elements' => $this->invoiceDetails(), 'elements' => $this->invoiceDetails(),
], ],
]; ]);
} }
elseif($this->service->config->entity_string == 'quote') elseif($this->service->config->entity_string == 'quote')
{ {
$this->sections[] = [ $this->mergeSections( [
'entity-details' => [ 'entity-details' => [
'id' => 'entity-details', 'id' => 'entity-details',
'elements' => $this->quoteDetails(), 'elements' => $this->quoteDetails(),
], ],
]; ]);
} }
elseif($this->service->config->entity_string == 'credit') elseif($this->service->config->entity_string == 'credit')
{ {
$this->sections[] = [ $this->mergeSections( [
'entity-details' => [ 'entity-details' => [
'id' => 'entity-details', 'id' => 'entity-details',
'elements' => $this->creditDetails(), 'elements' => $this->creditDetails(),
], ],
]; ]);
} }
@ -820,8 +833,8 @@ class PdfBuilder
private function buildSections() :self private function buildSections() :self
{ {
return match ($this->service->config->document_type) { return match ($this->service->document_type) {
PdfService::PRODUCT => $this->getProductSections, PdfService::PRODUCT => $this->getProductSections(),
PdfService::DELIVERY_NOTE => $this->getDeliveryNoteSections(), PdfService::DELIVERY_NOTE => $this->getDeliveryNoteSections(),
PdfService::STATEMENT => $this->getStatementSections(), PdfService::STATEMENT => $this->getStatementSections(),
PdfService::PURCHASE_ORDER => $this->getPurchaseOrderSections(), PdfService::PURCHASE_ORDER => $this->getPurchaseOrderSections(),
@ -919,7 +932,7 @@ class PdfBuilder
]; ];
if ($this->service->config->document_type == PdfService::DELIVERY_NOTE) { if ($this->service->document_type == PdfService::DELIVERY_NOTE) {
return $elements; return $elements;
} }
@ -1028,7 +1041,7 @@ class PdfBuilder
public function getProductAndTaskTables(): self public function getProductAndTaskTables(): self
{ {
$this->sections[] = [ $this->mergeSections( [
'product-table' => [ 'product-table' => [
'id' => 'product-table', 'id' => 'product-table',
'elements' => $this->productTable(), 'elements' => $this->productTable(),
@ -1037,7 +1050,7 @@ class PdfBuilder
'id' => 'task-table', 'id' => 'task-table',
'elements' => $this->taskTable(), 'elements' => $this->taskTable(),
], ],
]; ]);
return $this; return $this;
} }
@ -1050,12 +1063,12 @@ class PdfBuilder
*/ */
public function getClientDetails(): self public function getClientDetails(): self
{ {
$this->sections[] = [ $this->mergeSections( [
'client-details' => [ 'client-details' => [
'id' => 'client-details', 'id' => 'client-details',
'elements' => $this->clientDetails(), 'elements' => $this->clientDetails(),
], ],
]; ]);
return $this; return $this;
} }
@ -1317,7 +1330,7 @@ class PdfBuilder
['element' => 'th', 'content' => '$product.quantity_label', 'properties' => ['data-ref' => 'delivery_note-product.quantity_label']], ['element' => 'th', 'content' => '$product.quantity_label', 'properties' => ['data-ref' => 'delivery_note-product.quantity_label']],
]; ];
$items = $this->transformLineItems($this->service->config->entity->line_items, $this->service->config->document_type); $items = $this->transformLineItems($this->service->config->entity->line_items, $this->service->document_type);
$this->processNewLines($items); $this->processNewLines($items);
@ -1424,7 +1437,7 @@ class PdfBuilder
//////////////////////////////////////// ////////////////////////////////////////
// Dom Traversal // Dom Traversal
/////////////// ///////////////////////////////////////
public function getSectionNode(string $selector) public function getSectionNode(string $selector)
@ -1482,7 +1495,7 @@ class PdfBuilder
$contains_html = false; $contains_html = false;
if ($child['element'] !== 'script') { if ($child['element'] !== 'script') {
if (array_key_exists('process_markdown', $this->data) && array_key_exists('content', $child) && $this->data['process_markdown']) { if (array_key_exists('process_markdown', $this->service->options) && array_key_exists('content', $child) && $this->service->options['process_markdown']) {
$child['content'] = str_replace('<br>', "\r", $child['content']); $child['content'] = str_replace('<br>', "\r", $child['content']);
$child['content'] = $this->commonmark->convert($child['content'] ?? ''); $child['content'] = $this->commonmark->convert($child['content'] ?? '');
} }
@ -1530,9 +1543,9 @@ class PdfBuilder
public function updateVariables() public function updateVariables()
{ {
$html = strtr($this->getCompiledHTML(), $this->service->config->html_variables['labels']); $html = strtr($this->getCompiledHTML(), $this->service->html_variables['labels']);
$html = strtr($html, $this->service->config->html_variables['values']); $html = strtr($html, $this->service->html_variables['values']);
@$this->document->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8')); @$this->document->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
@ -1562,7 +1575,7 @@ class PdfBuilder
{ {
foreach ($this->sections as $element) { foreach ($this->sections as $element) {
if (isset($element['elements'])) { if (isset($element['elements'])) {
$this->getEmptyChildrens($element['elements'], $this->service->config->html_variables); $this->getEmptyChildrens($element['elements'], $this->service->html_variables);
} }
} }
@ -1573,7 +1586,7 @@ class PdfBuilder
{ {
foreach ($children as $key => $child) { foreach ($children as $key => $child) {
if (isset($child['content']) && isset($child['show_empty']) && $child['show_empty'] === false) { if (isset($child['content']) && isset($child['show_empty']) && $child['show_empty'] === false) {
$value = strtr($child['content'], $this->service->config->html_variables['values']); $value = strtr($child['content'], $this->service->html_variables['values']);
if ($value === '' || $value === '&nbsp;') { if ($value === '' || $value === '&nbsp;') {
$child['is_empty'] = true; $child['is_empty'] = true;
} }

View File

@ -61,6 +61,15 @@ class PdfDesigner
/** /**
* If the user has implemented a custom design, then we need to rebuild the design at this point * If the user has implemented a custom design, then we need to rebuild the design at this point
*/ */
/**
* Returns the custom HTML design as
* a string
*
* @param array
* @return string
*
*/
private function composeFromPartials(array $partials) :string private function composeFromPartials(array $partials) :string
{ {
$html = ''; $html = '';
@ -73,8 +82,4 @@ class PdfDesigner
return $html; return $html;
} }
} }

View File

@ -69,6 +69,8 @@ class PdfService
{ {
$this->builder->build(); $this->builder->build();
return $this;
} }
public function getPdf() public function getPdf()
@ -78,7 +80,7 @@ class PdfService
public function getHtml() public function getHtml()
{ {
return $this->builder->getCompiledHTML();
} }

View File

@ -33,6 +33,19 @@ class PdfServiceTest extends TestCase
$this->makeTestData(); $this->makeTestData();
} }
public function testHtmlGeneration()
{
$invitation = $this->invoice->invitations->first();
$service = new PdfService($invitation);
$this->assertIsString($service->build()->getHtml());
nlog($service->build()->getHtml());
}
public function testInitOfClass() public function testInitOfClass()
{ {
@ -85,4 +98,5 @@ class PdfServiceTest extends TestCase
$this->assertIsString($service->designer->template); $this->assertIsString($service->designer->template);
} }
} }