mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-06-03 17:44:37 -04:00
Refactor for PDF Generation
This commit is contained in:
parent
ca853d29e5
commit
3ec7f6a80d
@ -24,6 +24,7 @@ use App\Models\Quote;
|
||||
use App\Models\QuoteInvitation;
|
||||
use App\Models\RecurringInvoice;
|
||||
use App\Models\RecurringInvoiceInvitation;
|
||||
use App\Services\Pdf\PdfService;
|
||||
use App\Services\PdfMaker\Design as PdfDesignModel;
|
||||
use App\Services\PdfMaker\Design as PdfMakerDesign;
|
||||
use App\Services\PdfMaker\PdfMaker as PdfMakerService;
|
||||
@ -49,22 +50,14 @@ use setasign\Fpdi\PdfParser\StreamReader;
|
||||
|
||||
class CreateEntityPdf implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, NumberFormatter, MakesInvoiceHtml, PdfMaker, MakesHash, PageNumbering;
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
public $entity;
|
||||
|
||||
public $company;
|
||||
|
||||
public $contact;
|
||||
|
||||
private $disk;
|
||||
|
||||
public $invitation;
|
||||
|
||||
public $entity_string = '';
|
||||
|
||||
public $client;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
@ -72,145 +65,57 @@ class CreateEntityPdf implements ShouldQueue
|
||||
*/
|
||||
public function __construct($invitation, $disk = null)
|
||||
{
|
||||
|
||||
$this->invitation = $invitation;
|
||||
|
||||
if ($invitation instanceof InvoiceInvitation) {
|
||||
// $invitation->load('contact.client.company','invoice.client','invoice.user.account');
|
||||
$this->entity = $invitation->invoice;
|
||||
$this->entity_string = 'invoice';
|
||||
} elseif ($invitation instanceof QuoteInvitation) {
|
||||
// $invitation->load('contact.client.company','quote.client','quote.user.account');
|
||||
$this->entity = $invitation->quote;
|
||||
$this->entity_string = 'quote';
|
||||
} elseif ($invitation instanceof CreditInvitation) {
|
||||
// $invitation->load('contact.client.company','credit.client','credit.user.account');
|
||||
$this->entity = $invitation->credit;
|
||||
$this->entity_string = 'credit';
|
||||
} elseif ($invitation instanceof RecurringInvoiceInvitation) {
|
||||
// $invitation->load('contact.client.company','recurring_invoice');
|
||||
$this->entity = $invitation->recurring_invoice;
|
||||
$this->entity_string = 'recurring_invoice';
|
||||
}
|
||||
|
||||
$this->company = $invitation->company;
|
||||
|
||||
$this->contact = $invitation->contact;
|
||||
|
||||
$this->client = $invitation->contact->client;
|
||||
$this->client->load('company');
|
||||
|
||||
$this->disk = $disk ?? config('filesystems.default');
|
||||
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
MultiDB::setDb($this->company->db);
|
||||
|
||||
/* Forget the singleton*/
|
||||
App::forgetInstance('translator');
|
||||
$starttime = microtime(true);
|
||||
|
||||
/* Init a new copy of the translator*/
|
||||
$t = app('translator');
|
||||
|
||||
/* Set the locale*/
|
||||
App::setLocale($this->client->locale());
|
||||
MultiDB::setDb($this->invitation->company->db);
|
||||
|
||||
/* Set customized translations _NOW_ */
|
||||
$t->replace(Ninja::transformTranslations($this->client->getMergedSettings()));
|
||||
if ($this->invitation instanceof InvoiceInvitation) {
|
||||
$this->entity = $this->invitation->invoice;
|
||||
$path = $this->invitation->contact->client->invoice_filepath($this->invitation);
|
||||
} elseif ($this->invitation instanceof QuoteInvitation) {
|
||||
$this->entity = $this->invitation->quote;
|
||||
$path = $this->invitation->contact->client->quote_filepath($this->invitation);
|
||||
} elseif ($this->invitation instanceof CreditInvitation) {
|
||||
$this->entity = $this->invitation->credit;
|
||||
$path = $this->invitation->contact->client->credit_filepath($this->invitation);
|
||||
} elseif ($this->invitation instanceof RecurringInvoiceInvitation) {
|
||||
$this->entity = $this->invitation->recurring_invoice;
|
||||
$path = $this->invitation->contact->client->recurring_invoice_filepath($this->invitation);
|
||||
|
||||
if (config('ninja.phantomjs_pdf_generation') || config('ninja.pdf_generator') == 'phantom') {
|
||||
return (new Phantom)->generate($this->invitation);
|
||||
}
|
||||
|
||||
$entity_design_id = '';
|
||||
|
||||
if ($this->entity instanceof Invoice) {
|
||||
$path = $this->client->invoice_filepath($this->invitation);
|
||||
$entity_design_id = 'invoice_design_id';
|
||||
} elseif ($this->entity instanceof Quote) {
|
||||
$path = $this->client->quote_filepath($this->invitation);
|
||||
$entity_design_id = 'quote_design_id';
|
||||
} elseif ($this->entity instanceof Credit) {
|
||||
$path = $this->client->credit_filepath($this->invitation);
|
||||
$entity_design_id = 'credit_design_id';
|
||||
} elseif ($this->entity instanceof RecurringInvoice) {
|
||||
$path = $this->client->recurring_invoice_filepath($this->invitation);
|
||||
$entity_design_id = 'invoice_design_id';
|
||||
}
|
||||
|
||||
$file_path = $path.$this->entity->numberFormatter().'.pdf';
|
||||
|
||||
$entity_design_id = $this->entity->design_id ? $this->entity->design_id : $this->decodePrimaryKey($this->client->getSetting($entity_design_id));
|
||||
|
||||
$design = Design::find($entity_design_id);
|
||||
|
||||
/* Catch all in case migration doesn't pass back a valid design */
|
||||
if (! $design) {
|
||||
$design = Design::find(2);
|
||||
}
|
||||
|
||||
$html = new HtmlEngine($this->invitation);
|
||||
|
||||
if ($design->is_custom) {
|
||||
$options = [
|
||||
'custom_partials' => json_decode(json_encode($design->design), true),
|
||||
];
|
||||
$template = new PdfMakerDesign(PdfDesignModel::CUSTOM, $options);
|
||||
} else {
|
||||
$template = new PdfMakerDesign(strtolower($design->name));
|
||||
}
|
||||
|
||||
$variables = $html->generateLabelsAndValues();
|
||||
|
||||
$state = [
|
||||
'template' => $template->elements([
|
||||
'client' => $this->client,
|
||||
'entity' => $this->entity,
|
||||
'pdf_variables' => (array) $this->company->settings->pdf_variables,
|
||||
'$product' => $design->design->product,
|
||||
'variables' => $variables,
|
||||
]),
|
||||
'variables' => $variables,
|
||||
'options' => [
|
||||
'all_pages_header' => $this->entity->client->getSetting('all_pages_header'),
|
||||
'all_pages_footer' => $this->entity->client->getSetting('all_pages_footer'),
|
||||
],
|
||||
'process_markdown' => $this->entity->client->company->markdown_enabled,
|
||||
];
|
||||
|
||||
$maker = new PdfMakerService($state);
|
||||
|
||||
$maker
|
||||
->design($template)
|
||||
->build();
|
||||
|
||||
$pdf = null;
|
||||
|
||||
try {
|
||||
if (config('ninja.invoiceninja_hosted_pdf_generation') || config('ninja.pdf_generator') == 'hosted_ninja') {
|
||||
$pdf = (new NinjaPdf())->build($maker->getCompiledHTML(true));
|
||||
|
||||
$numbered_pdf = $this->pageNumbering($pdf, $this->company);
|
||||
|
||||
if ($numbered_pdf) {
|
||||
$pdf = $numbered_pdf;
|
||||
}
|
||||
} else {
|
||||
$pdf = $this->makePdf(null, null, $maker->getCompiledHTML(true));
|
||||
|
||||
$numbered_pdf = $this->pageNumbering($pdf, $this->company);
|
||||
|
||||
if ($numbered_pdf) {
|
||||
$pdf = $numbered_pdf;
|
||||
}
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
nlog(print_r($e->getMessage(), 1));
|
||||
}
|
||||
|
||||
if (config('ninja.log_pdf_html')) {
|
||||
info($maker->getCompiledHTML());
|
||||
}
|
||||
// $state = [
|
||||
// 'template' => $template->elements([
|
||||
// 'client' => $this->client,
|
||||
// 'entity' => $this->entity,
|
||||
// 'pdf_variables' => (array) $this->company->settings->pdf_variables,
|
||||
// '$product' => $design->design->product,
|
||||
// 'variables' => $variables,
|
||||
// ]),
|
||||
// 'variables' => $variables,
|
||||
// 'options' => [
|
||||
// 'all_pages_header' => $this->entity->client->getSetting('all_pages_header'),
|
||||
// 'all_pages_footer' => $this->entity->client->getSetting('all_pages_footer'),
|
||||
// ],
|
||||
// 'process_markdown' => $this->entity->client->company->markdown_enabled,
|
||||
// ];
|
||||
|
||||
$pdf = (new PdfService($this->invitation))->getPdf();
|
||||
|
||||
$endtime = microtime(true);
|
||||
nlog($endtime - $starttime);
|
||||
|
||||
if ($pdf) {
|
||||
try {
|
||||
@ -220,13 +125,6 @@ class CreateEntityPdf implements ShouldQueue
|
||||
}
|
||||
}
|
||||
|
||||
$this->invitation = null;
|
||||
$this->entity = null;
|
||||
$this->company = null;
|
||||
$this->client = null;
|
||||
$this->contact = null;
|
||||
$maker = null;
|
||||
$state = null;
|
||||
|
||||
return $file_path;
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ use DOMDocument;
|
||||
use DOMXPath;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Str;
|
||||
use League\CommonMark\CommonMarkConverter;
|
||||
|
||||
class PdfBuilder
|
||||
{
|
||||
@ -27,19 +28,35 @@ class PdfBuilder
|
||||
|
||||
public PdfService $service;
|
||||
|
||||
private CommonMarkConverter $commonmark;
|
||||
|
||||
/**
|
||||
* an array of sections to be injected into the template
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public array $sections = [];
|
||||
|
||||
/**
|
||||
* The DOM Document;
|
||||
*
|
||||
* @var $document
|
||||
*/
|
||||
public DomDocument $document;
|
||||
|
||||
/**
|
||||
* @param PdfService $service
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(PdfService $service)
|
||||
{
|
||||
|
||||
$this->service = $service;
|
||||
|
||||
$this->commonmark = new CommonMarkConverter([
|
||||
'allow_unsafe_links' => false,
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -52,11 +69,7 @@ class PdfBuilder
|
||||
{
|
||||
|
||||
$this->getTemplate()
|
||||
->buildSections();
|
||||
|
||||
nlog($this->sections);
|
||||
|
||||
$this
|
||||
->buildSections()
|
||||
->getEmptyElements()
|
||||
->updateElementProperties()
|
||||
->updateVariables();
|
||||
@ -97,6 +110,7 @@ class PdfBuilder
|
||||
$this->xpath = new DOMXPath($document);
|
||||
|
||||
return $this;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -120,9 +134,11 @@ class PdfBuilder
|
||||
|
||||
private function mergeSections(array $section) :self
|
||||
{
|
||||
|
||||
$this->sections = array_merge($this->sections, $section);
|
||||
|
||||
return $this;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -212,6 +228,7 @@ class PdfBuilder
|
||||
return [
|
||||
['element' => 'p', 'content' => '$outstanding_label: ' . Number::formatMoney($outstanding, $this->service->config->client)],
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -222,6 +239,7 @@ class PdfBuilder
|
||||
*/
|
||||
public function statementPaymentTable(): array
|
||||
{
|
||||
|
||||
if (is_null($this->service->option['payments'])) {
|
||||
return [];
|
||||
}
|
||||
@ -255,6 +273,7 @@ class PdfBuilder
|
||||
['element' => 'thead', 'elements' => $this->buildTableHeader('statement_payment')],
|
||||
['element' => 'tbody', 'elements' => $tbody],
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -666,6 +685,7 @@ class PdfBuilder
|
||||
}
|
||||
|
||||
return $elements;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -680,6 +700,7 @@ class PdfBuilder
|
||||
*/
|
||||
public function processTaxColumns(string $type): void
|
||||
{
|
||||
|
||||
if ($type == 'product') {
|
||||
$type_id = 1;
|
||||
}
|
||||
@ -722,6 +743,7 @@ class PdfBuilder
|
||||
array_splice($this->service->config->pdf_variables["{$type}_columns"], $key, 1, $taxes);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -752,6 +774,7 @@ class PdfBuilder
|
||||
['element' => 'script', 'content' => $javascript],
|
||||
['element' => 'script', 'content' => $html_decode],
|
||||
]];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -772,6 +795,7 @@ class PdfBuilder
|
||||
]);
|
||||
|
||||
return $this;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -786,7 +810,6 @@ class PdfBuilder
|
||||
private function getProductEntityDetails(): self
|
||||
{
|
||||
|
||||
|
||||
if($this->service->config->entity_string == 'invoice')
|
||||
{
|
||||
$this->mergeSections( [
|
||||
@ -821,7 +844,6 @@ class PdfBuilder
|
||||
|
||||
return $this;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -850,6 +872,7 @@ class PdfBuilder
|
||||
*/
|
||||
private function statementTableTotals(): array
|
||||
{
|
||||
|
||||
return [
|
||||
['element' => 'div', 'properties' => ['style' => 'display: flex; flex-direction: column;'], 'elements' => [
|
||||
['element' => 'div', 'properties' => ['style' => 'margin-top: 1.5rem; display: block; align-items: flex-start; page-break-inside: avoid; visible !important;'], 'elements' => [
|
||||
@ -857,6 +880,7 @@ class PdfBuilder
|
||||
]],
|
||||
]],
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -898,6 +922,7 @@ class PdfBuilder
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
//First pass done, need a second pass to abstract this content completely.
|
||||
@ -1053,6 +1078,7 @@ class PdfBuilder
|
||||
]);
|
||||
|
||||
return $this;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1063,6 +1089,7 @@ class PdfBuilder
|
||||
*/
|
||||
public function getClientDetails(): self
|
||||
{
|
||||
|
||||
$this->mergeSections( [
|
||||
'client-details' => [
|
||||
'id' => 'client-details',
|
||||
@ -1071,6 +1098,7 @@ class PdfBuilder
|
||||
]);
|
||||
|
||||
return $this;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1080,6 +1108,7 @@ class PdfBuilder
|
||||
*/
|
||||
public function productTable(): array
|
||||
{
|
||||
|
||||
$product_items = collect($this->service->config->entity->line_items)->filter(function ($item) {
|
||||
return $item->type_id == 1 || $item->type_id == 6 || $item->type_id == 5;
|
||||
});
|
||||
@ -1092,6 +1121,7 @@ class PdfBuilder
|
||||
['element' => 'thead', 'elements' => $this->buildTableHeader('product')],
|
||||
['element' => 'tbody', 'elements' => $this->buildTableBody('$product')],
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1101,6 +1131,7 @@ class PdfBuilder
|
||||
*/
|
||||
public function taskTable(): array
|
||||
{
|
||||
|
||||
$task_items = collect($this->service->config->entity->line_items)->filter(function ($item) {
|
||||
return $item->type_id == 2;
|
||||
});
|
||||
@ -1113,6 +1144,7 @@ class PdfBuilder
|
||||
['element' => 'thead', 'elements' => $this->buildTableHeader('task')],
|
||||
['element' => 'tbody', 'elements' => $this->buildTableBody('$task')],
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1156,6 +1188,7 @@ class PdfBuilder
|
||||
$variables = $this->service->config->pdf_variables['invoice_details'];
|
||||
|
||||
return $this->genericDetailsBuilder($variables);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1166,6 +1199,7 @@ class PdfBuilder
|
||||
*/
|
||||
public function quoteDetails(): array
|
||||
{
|
||||
|
||||
$variables = $this->service->config->pdf_variables['quote_details'];
|
||||
|
||||
if ($this->service->config->entity->partial > 0) {
|
||||
@ -1173,6 +1207,7 @@ class PdfBuilder
|
||||
}
|
||||
|
||||
return $this->genericDetailsBuilder($variables);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1188,6 +1223,7 @@ class PdfBuilder
|
||||
$variables = $this->service->config->pdf_variables['credit_details'];
|
||||
|
||||
return $this->genericDetailsBuilder($variables);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1220,6 +1256,7 @@ class PdfBuilder
|
||||
});
|
||||
|
||||
return $this->genericDetailsBuilder($variables);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1255,6 +1292,7 @@ class PdfBuilder
|
||||
}
|
||||
|
||||
return $elements;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1301,6 +1339,7 @@ class PdfBuilder
|
||||
*/
|
||||
public function clientDetails(): array
|
||||
{
|
||||
|
||||
$elements = [];
|
||||
|
||||
if(!$this->service->config->client)
|
||||
@ -1313,6 +1352,7 @@ class PdfBuilder
|
||||
}
|
||||
|
||||
return $elements;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1323,7 +1363,6 @@ class PdfBuilder
|
||||
public function deliveryNoteTable(): array
|
||||
{
|
||||
/* Static array of delivery note columns*/
|
||||
|
||||
$thead = [
|
||||
['element' => 'th', 'content' => '$item_label', 'properties' => ['data-ref' => 'delivery_note-item_label']],
|
||||
['element' => 'th', 'content' => '$description_label', 'properties' => ['data-ref' => 'delivery_note-description_label']],
|
||||
@ -1354,6 +1393,7 @@ class PdfBuilder
|
||||
['element' => 'thead', 'elements' => $thead],
|
||||
['element' => 'tbody', 'elements' => $this->buildTableBody(PdfService::DELIVERY_NOTE)],
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1366,6 +1406,7 @@ class PdfBuilder
|
||||
*/
|
||||
public function processNewLines(array &$items): void
|
||||
{
|
||||
|
||||
foreach ($items as $key => $item) {
|
||||
foreach ($item as $variable => $value) {
|
||||
$item[$variable] = str_replace("\n", '<br>', $value);
|
||||
@ -1373,6 +1414,7 @@ class PdfBuilder
|
||||
|
||||
$items[$key] = $item;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1383,6 +1425,7 @@ class PdfBuilder
|
||||
*/
|
||||
public function companyDetails(): array
|
||||
{
|
||||
|
||||
$variables = $this->service->config->pdf_variables['company_details'];
|
||||
|
||||
$elements = [];
|
||||
@ -1392,6 +1435,7 @@ class PdfBuilder
|
||||
}
|
||||
|
||||
return $elements;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1403,6 +1447,7 @@ class PdfBuilder
|
||||
*/
|
||||
public function companyAddress(): array
|
||||
{
|
||||
|
||||
$variables = $this->service->config->pdf_variables['company_address'];
|
||||
|
||||
$elements = [];
|
||||
@ -1412,6 +1457,7 @@ class PdfBuilder
|
||||
}
|
||||
|
||||
return $elements;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1423,6 +1469,7 @@ class PdfBuilder
|
||||
*/
|
||||
public function vendorDetails(): array
|
||||
{
|
||||
|
||||
$elements = [];
|
||||
|
||||
$variables = $this->service->config->pdf_variables['vendor_details'];
|
||||
@ -1432,6 +1479,7 @@ class PdfBuilder
|
||||
}
|
||||
|
||||
return $elements;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1442,11 +1490,14 @@ class PdfBuilder
|
||||
|
||||
public function getSectionNode(string $selector)
|
||||
{
|
||||
|
||||
return $this->document->getElementById($selector);
|
||||
|
||||
}
|
||||
|
||||
public function updateElementProperties() :self
|
||||
{
|
||||
|
||||
foreach ($this->sections as $element) {
|
||||
if (isset($element['tag'])) {
|
||||
$node = $this->document->getElementsByTagName($element['tag'])->item(0);
|
||||
@ -1468,6 +1519,7 @@ class PdfBuilder
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
||||
}
|
||||
|
||||
public function updateElementProperty($element, string $attribute, ?string $value)
|
||||
@ -1487,15 +1539,17 @@ class PdfBuilder
|
||||
}
|
||||
|
||||
return $element;
|
||||
|
||||
}
|
||||
|
||||
public function createElementContent($element, $children) :self
|
||||
{
|
||||
|
||||
foreach ($children as $child) {
|
||||
$contains_html = false;
|
||||
|
||||
if ($child['element'] !== 'script') {
|
||||
if (array_key_exists('process_markdown', $this->service->options) && array_key_exists('content', $child) && $this->service->options['process_markdown']) {
|
||||
if ($this->service->company->markdown_enabled && array_key_exists('content', $child)) {
|
||||
$child['content'] = str_replace('<br>', "\r", $child['content']);
|
||||
$child['content'] = $this->commonmark->convert($child['content'] ?? '');
|
||||
}
|
||||
@ -1539,10 +1593,12 @@ class PdfBuilder
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
||||
}
|
||||
|
||||
public function updateVariables()
|
||||
{
|
||||
|
||||
$html = strtr($this->getCompiledHTML(), $this->service->html_variables['labels']);
|
||||
|
||||
$html = strtr($html, $this->service->html_variables['values']);
|
||||
@ -1552,10 +1608,12 @@ class PdfBuilder
|
||||
$this->document->saveHTML();
|
||||
|
||||
return $this;
|
||||
|
||||
}
|
||||
|
||||
public function updateVariable(string $element, string $variable, string $value)
|
||||
{
|
||||
|
||||
$element = $this->document->getElementById($element);
|
||||
|
||||
$original = $element->nodeValue;
|
||||
@ -1569,10 +1627,12 @@ class PdfBuilder
|
||||
);
|
||||
|
||||
return $element;
|
||||
|
||||
}
|
||||
|
||||
public function getEmptyElements() :self
|
||||
{
|
||||
|
||||
foreach ($this->sections as $element) {
|
||||
if (isset($element['elements'])) {
|
||||
$this->getEmptyChildrens($element['elements'], $this->service->html_variables);
|
||||
@ -1580,10 +1640,12 @@ class PdfBuilder
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
||||
}
|
||||
|
||||
public function getEmptyChildrens(array $children)
|
||||
{
|
||||
|
||||
foreach ($children as $key => $child) {
|
||||
if (isset($child['content']) && isset($child['show_empty']) && $child['show_empty'] === false) {
|
||||
$value = strtr($child['content'], $this->service->html_variables['values']);
|
||||
@ -1598,6 +1660,7 @@ class PdfBuilder
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -29,7 +29,9 @@ use App\Models\RecurringInvoiceInvitation;
|
||||
use App\Models\Vendor;
|
||||
use App\Models\VendorContact;
|
||||
use App\Services\Pdf\PdfService;
|
||||
use App\Utils\Ninja;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Support\Facades\App;
|
||||
|
||||
class PdfConfiguration
|
||||
{
|
||||
@ -61,7 +63,9 @@ class PdfConfiguration
|
||||
|
||||
/**
|
||||
* The parent object of the currency
|
||||
*
|
||||
* @var App\Models\Client | App\Models\Vendor
|
||||
*
|
||||
*/
|
||||
public $currency_entity;
|
||||
|
||||
@ -72,20 +76,36 @@ class PdfConfiguration
|
||||
|
||||
}
|
||||
|
||||
public function init()
|
||||
public function init(): self
|
||||
{
|
||||
|
||||
$this->setEntityType()
|
||||
->setEntityProperties()
|
||||
->setPdfVariables()
|
||||
->setDesign()
|
||||
->setCurrency();
|
||||
->setCurrency()
|
||||
->setLocale();
|
||||
|
||||
return $this;
|
||||
|
||||
}
|
||||
|
||||
private function setCurrency() :self
|
||||
private function setLocale(): self
|
||||
{
|
||||
|
||||
App::forgetInstance('translator');
|
||||
|
||||
$t = app('translator');
|
||||
|
||||
App::setLocale($this->settings_object->locale());
|
||||
|
||||
$t->replace(Ninja::transformTranslations($this->settings));
|
||||
|
||||
return $this;
|
||||
|
||||
}
|
||||
|
||||
private function setCurrency(): self
|
||||
{
|
||||
|
||||
$this->currency = $this->client ? $this->client->currency() : $this->vendor->currency();
|
||||
@ -100,6 +120,7 @@ class PdfConfiguration
|
||||
{
|
||||
|
||||
$default = (array) CompanySettings::getEntityVariableDefaults();
|
||||
|
||||
$variables = (array)$this->service->company->settings->pdf_variables;
|
||||
|
||||
foreach ($default as $property => $value) {
|
||||
@ -139,11 +160,13 @@ class PdfConfiguration
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
||||
}
|
||||
|
||||
private function setEntityProperties()
|
||||
{
|
||||
$entity_design_id = '';
|
||||
|
||||
$entity_design_id = '';
|
||||
|
||||
if ($this->entity instanceof Invoice) {
|
||||
|
||||
@ -198,6 +221,7 @@ class PdfConfiguration
|
||||
$this->path = $this->path.$this->entity->numberFormatter().'.pdf';
|
||||
|
||||
return $this;
|
||||
|
||||
}
|
||||
|
||||
private function setDesign()
|
||||
|
@ -12,13 +12,19 @@
|
||||
namespace App\Services\Pdf;
|
||||
|
||||
use App\Models\Account;
|
||||
use App\Services\Pdf\PdfConfiguration;
|
||||
use App\Utils\HtmlEngine;
|
||||
use App\Models\Company;
|
||||
use App\Services\Pdf\PdfConfiguration;
|
||||
use App\Utils\HostedPDF\NinjaPdf;
|
||||
use App\Utils\HtmlEngine;
|
||||
use App\Utils\PhantomJS\Phantom;
|
||||
use App\Utils\Traits\Pdf\PageNumbering;
|
||||
use App\Utils\Traits\Pdf\PdfMaker;
|
||||
|
||||
class PdfService
|
||||
{
|
||||
|
||||
use PdfMaker, PageNumbering;
|
||||
|
||||
public $invitation;
|
||||
|
||||
public Company $company;
|
||||
@ -55,58 +61,90 @@ class PdfService
|
||||
|
||||
$this->html_variables = (new HtmlEngine($invitation))->generateLabelsAndValues();
|
||||
|
||||
$this->builder = (new PdfBuilder($this));
|
||||
|
||||
$this->designer = (new PdfDesigner($this))->build();
|
||||
|
||||
$this->document_type = $document_type;
|
||||
|
||||
$this->options = $options;
|
||||
|
||||
}
|
||||
|
||||
public function build()
|
||||
{
|
||||
$this->builder->build();
|
||||
|
||||
return $this;
|
||||
$this->builder = (new PdfBuilder($this))->build();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the PDF generation type and
|
||||
* attempts to generate a PDF from the HTML
|
||||
* string.
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
*/
|
||||
public function getPdf()
|
||||
{
|
||||
|
||||
try {
|
||||
|
||||
if (config('ninja.phantomjs_pdf_generation') || config('ninja.pdf_generator') == 'phantom')
|
||||
{
|
||||
|
||||
$pdf = (new Phantom)->convertHtmlToPdf($this->getHtml());
|
||||
|
||||
}
|
||||
elseif (config('ninja.invoiceninja_hosted_pdf_generation') || config('ninja.pdf_generator') == 'hosted_ninja')
|
||||
{
|
||||
|
||||
$pdf = (new NinjaPdf())->build($this->getHtml());
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
$pdf = $this->makePdf(null, null, $this->getHtml());
|
||||
|
||||
}
|
||||
|
||||
$numbered_pdf = $this->pageNumbering($pdf, $this->company);
|
||||
|
||||
if ($numbered_pdf)
|
||||
{
|
||||
|
||||
$pdf = $numbered_pdf;
|
||||
|
||||
}
|
||||
|
||||
|
||||
} catch (\Exception $e) {
|
||||
|
||||
nlog(print_r($e->getMessage(), 1));
|
||||
|
||||
throw new \Exception($e->getMessage(), $e->getCode());
|
||||
|
||||
}
|
||||
|
||||
return $pdf;
|
||||
|
||||
}
|
||||
|
||||
public function getHtml()
|
||||
/**
|
||||
* Renders the dom document to HTML
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
*/
|
||||
public function getHtml(): string
|
||||
{
|
||||
return $this->builder->getCompiledHTML();
|
||||
|
||||
$html = $this->builder->getCompiledHTML();
|
||||
|
||||
if (config('ninja.log_pdf_html'))
|
||||
{
|
||||
|
||||
info($html);
|
||||
|
||||
}
|
||||
|
||||
return $html;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// $state = [
|
||||
// 'template' => $template->elements([
|
||||
// 'client' => $this->client,
|
||||
// 'entity' => $this->entity,
|
||||
// 'pdf_variables' => (array) $this->company->settings->pdf_variables,
|
||||
// '$product' => $design->design->product,
|
||||
// 'variables' => $variables,
|
||||
// ]),
|
||||
// 'variables' => $variables,
|
||||
// 'options' => [
|
||||
// 'all_pages_header' => $this->entity->client->getSetting('all_pages_header'),
|
||||
// 'all_pages_footer' => $this->entity->client->getSetting('all_pages_footer'),
|
||||
// ],
|
||||
// 'process_markdown' => $this->entity->client->company->markdown_enabled,
|
||||
// ];
|
||||
|
||||
// $maker = new PdfMakerService($state);
|
||||
|
||||
// $maker
|
||||
// ->design($template)
|
||||
// ->build();
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -33,6 +33,17 @@ class PdfServiceTest extends TestCase
|
||||
$this->makeTestData();
|
||||
}
|
||||
|
||||
public function testPdfGeneration()
|
||||
{
|
||||
|
||||
$invitation = $this->invoice->invitations->first();
|
||||
|
||||
$service = new PdfService($invitation);
|
||||
|
||||
$this->assertNotNull($service->getPdf());
|
||||
|
||||
}
|
||||
|
||||
public function testHtmlGeneration()
|
||||
{
|
||||
|
||||
@ -40,9 +51,7 @@ class PdfServiceTest extends TestCase
|
||||
|
||||
$service = new PdfService($invitation);
|
||||
|
||||
$this->assertIsString($service->build()->getHtml());
|
||||
|
||||
nlog($service->build()->getHtml());
|
||||
$this->assertIsString($service->getHtml());
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user