2020-09-04 10:18:41 +02:00
< ? php
/**
2020-09-06 11:38:10 +02:00
* Invoice Ninja ( https :// invoiceninja . com ) .
2020-09-04 10:18:41 +02:00
*
* @ link https :// github . com / invoiceninja / invoiceninja source repository
*
* @ copyright Copyright ( c ) 2020. Invoice Ninja LLC ( https :// invoiceninja . com )
*
* @ license https :// opensource . org / licenses / AAL
*/
namespace App\Services\PdfMaker ;
use App\Services\PdfMaker\Designs\Utilities\BaseDesign ;
use App\Services\PdfMaker\Designs\Utilities\DesignHelpers ;
2020-09-11 10:07:59 +02:00
use App\Utils\Number ;
2020-09-06 11:38:10 +02:00
use App\Utils\Traits\MakesInvoiceValues ;
2020-10-06 12:49:00 +02:00
use DOMDocument ;
2020-09-06 11:38:10 +02:00
use Illuminate\Support\Str ;
2020-09-04 10:18:41 +02:00
class Design extends BaseDesign
{
use MakesInvoiceValues , DesignHelpers ;
/** @var App\Models\Invoice || @var App\Models\Quote */
public $entity ;
2020-09-11 10:07:59 +02:00
/** @var App\Models\Client */
public $client ;
2020-09-04 10:18:41 +02:00
/** Global state of the design, @var array */
public $context ;
/** Type of entity => product||task */
public $type ;
/** Design string */
public $design ;
/** Construct options */
public $options ;
2020-09-04 13:17:30 +02:00
const BOLD = 'bold' ;
const BUSINESS = 'business' ;
const CLEAN = 'clean' ;
const CREATIVE = 'creative' ;
const ELEGANT = 'elegant' ;
const HIPSTER = 'hipster' ;
const MODERN = 'modern' ;
const PLAIN = 'plain' ;
const PLAYFUL = 'playful' ;
2020-09-08 13:21:07 +02:00
const CUSTOM = 'custom' ;
2020-09-04 10:18:41 +02:00
public function __construct ( string $design = null , array $options = [])
{
2020-09-04 13:17:30 +02:00
Str :: endsWith ( '.html' , $design ) ? $this -> design = $design : $this -> design = " { $design } .html " ;
2020-09-04 10:18:41 +02:00
$this -> options = $options ;
}
public function html () : ? string
{
2020-09-08 13:21:07 +02:00
if ( $this -> design == 'custom.html' ) {
return $this -> composeFromPartials (
$this -> options [ 'custom_partials' ]
);
}
2020-09-04 10:18:41 +02:00
$path = isset ( $this -> options [ 'custom_path' ])
? $this -> options [ 'custom_path' ]
: config ( 'ninja.designs.base_path' );
return file_get_contents (
2020-09-09 14:47:26 +02:00
$path . $this -> design
2020-09-04 10:18:41 +02:00
);
}
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 (),
],
2020-09-08 14:30:20 +02:00
'product-table-footer' => [
'id' => 'product-table-footer' ,
'elements' => $this -> tableFooter (),
],
2020-09-04 10:18:41 +02:00
'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 ) {
2020-10-20 12:46:08 +02:00
$_variable = explode ( '.' , $variable )[ 1 ];
2020-10-20 13:01:07 +02:00
$_customs = [ 'custom1' , 'custom2' , 'custom3' , 'custom4' ];
if ( in_array ( $_variable , $_customs )) {
2020-10-20 12:46:08 +02:00
$elements [] = [ 'element' => 'tr' , 'elements' => [
[ 'element' => 'th' , 'content' => $variable . '_label' ],
[ 'element' => 'th' , 'content' => $variable ],
]];
} else {
$elements [] = [ 'element' => 'tr' , 'properties' => [ 'hidden' => $this -> entityVariableCheck ( $variable )], 'elements' => [
[ 'element' => 'th' , 'content' => $variable . '_label' ],
[ 'element' => 'th' , 'content' => $variable ],
]];
}
2020-09-04 10:18:41 +02:00
}
return $elements ;
}
public function productTable () : array
{
return [
[ 'element' => 'thead' , 'elements' => $this -> buildTableHeader ()],
[ 'element' => 'tbody' , 'elements' => $this -> buildTableBody ()],
];
}
public function buildTableHeader () : array
{
$this -> processTaxColumns ();
$elements = [];
foreach ( $this -> context [ 'pdf_variables' ][ " { $this -> type } _columns " ] as $column ) {
2020-09-09 14:47:26 +02:00
$elements [] = [ 'element' => 'th' , 'content' => $column . '_label' ];
2020-09-04 10:18:41 +02:00
}
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' => []];
2020-10-06 12:49:00 +02:00
if (
isset ( $this -> context [ 'products' ]) &&
! empty ( $this -> context [ 'products' ]) &&
! is_null ( $this -> context [ 'products' ])
) {
$document = new DOMDocument ();
$document -> loadHTML ( $this -> context [ 'products' ], LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD );
$td = $document -> getElementsByTagName ( 'tr' ) -> item ( 0 );
if ( $td ) {
foreach ( $td -> childNodes as $child ) {
if ( $child -> nodeType !== 1 ) {
continue ;
}
if ( $child -> tagName !== 'td' ) {
continue ;
}
$element [ 'elements' ][] = [ 'element' => 'td' , 'content' => strtr ( $child -> nodeValue , $row )];
}
}
} else {
foreach ( $this -> context [ 'pdf_variables' ][ " { $this -> type } _columns " ] as $key => $cell ) {
$element [ 'elements' ][] = [ 'element' => 'td' , 'content' => $row [ $cell ]];
}
2020-09-04 10:18:41 +02:00
}
$elements [] = $element ;
}
return $elements ;
}
public function tableFooter ()
{
$variables = $this -> context [ 'pdf_variables' ][ 'total_columns' ];
$elements = [
2020-09-08 14:30:20 +02:00
[ 'element' => 'div' , 'elements' => [
[ 'element' => 'span' , 'content' => '$entity.public_notes' , 'properties' => [ 'data-element' => 'product-table-public-notes-label' ]],
2020-09-04 10:18:41 +02:00
]],
];
2020-09-09 14:47:26 +02:00
foreach ([ 'discount' , 'custom_surcharge1' , 'custom_surcharge2' , 'custom_surcharge3' , 'custom_surcharge4' ] as $property ) {
$variable = sprintf ( '%s%s' , '$' , $property );
if (
2020-09-11 16:46:49 +02:00
! is_null ( $this -> entity -> { $property }) &&
! empty ( $this -> entity -> { $property }) &&
$this -> entity -> { $property } != 0
2020-09-09 14:47:26 +02:00
) {
continue ;
}
$variables = array_filter ( $variables , function ( $m ) use ( $variable ) {
return $m != $variable ;
});
}
2020-09-04 10:18:41 +02:00
foreach ( $variables as $variable ) {
2020-09-11 10:07:59 +02:00
if ( $variable == '$total_taxes' ) {
$taxes = $this -> entity -> calc () -> getTotalTaxMap ();
if ( ! $taxes ) {
continue ;
}
foreach ( $taxes as $tax ) {
$elements [] = [ 'element' => 'div' , 'elements' => [
[ 'element' => 'span' , 'content' => 'This is placeholder for the 3rd fraction of element.' , 'properties' => [ 'style' => 'opacity: 0%' ]], // Placeholder for fraction of element (3fr)
[ 'element' => 'span' , 'content' , 'content' => $tax [ 'name' ]],
[ 'element' => 'span' , 'content' , 'content' => Number :: formatMoney ( $tax [ 'total' ], $this -> context [ 'client' ])],
]];
}
} elseif ( $variable == '$line_taxes' ) {
$taxes = $this -> entity -> calc () -> getTaxMap ();
if ( ! $taxes ) {
continue ;
}
foreach ( $taxes as $tax ) {
$elements [] = [ 'element' => 'div' , 'elements' => [
[ 'element' => 'span' , 'content' => 'This is placeholder for the 3rd fraction of element.' , 'properties' => [ 'style' => 'opacity: 0%' ]], // Placeholder for fraction of element (3fr)
[ 'element' => 'span' , 'content' , 'content' => $tax [ 'name' ]],
[ 'element' => 'span' , 'content' , 'content' => Number :: formatMoney ( $tax [ 'total' ], $this -> context [ 'client' ])],
]];
}
} else {
$elements [] = [ 'element' => 'div' , 'elements' => [
[ 'element' => 'span' , 'content' => 'This is placeholder for the 3rd fraction of element.' , 'properties' => [ 'style' => 'opacity: 0%' ]], // Placeholder for fraction of element (3fr)
[ 'element' => 'span' , 'content' => $variable . '_label' ],
[ 'element' => 'span' , 'content' => $variable ],
]];
2020-09-04 13:17:30 +02:00
}
2020-09-04 10:18:41 +02:00
}
return $elements ;
}
}