1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* MÓDULO DE EMISIÓN ELECTRÓNICA F72X |
5
|
|
|
* UBL 2.1 |
6
|
|
|
* Version 1.1 |
7
|
|
|
* |
8
|
|
|
* Copyright 2018, Jaime Cruz |
9
|
|
|
*/ |
10
|
|
|
|
11
|
|
|
namespace F72X\Tools; |
12
|
|
|
|
13
|
|
|
use F72X\F72X; |
14
|
|
|
use F72X\Sunat\DataMap; |
15
|
|
|
use F72X\Sunat\SunatVars; |
16
|
|
|
use F72X\Sunat\Catalogo; |
17
|
|
|
use F72X\Sunat\Operations; |
18
|
|
|
use F72X\Company; |
19
|
|
|
use F72X\Repository; |
20
|
|
|
use Twig_Environment; |
21
|
|
|
use Twig_Loader_Filesystem; |
22
|
|
|
use Twig_Extensions_Extension_Intl; |
23
|
|
|
use Twig_Extension_Escaper; |
24
|
|
|
use Dompdf\Dompdf; |
25
|
|
|
use Codelint\QRCode\QRCode; |
26
|
|
|
|
27
|
|
|
class PdfGenerator { |
28
|
|
|
|
29
|
|
|
public static function generatePdf(DataMap $Invoice, $billName) { |
30
|
|
|
$dompdf = new Dompdf(); |
31
|
|
|
$docType = self::getTplFor($Invoice->getDocumentType()); |
32
|
|
|
$html = self::getRenderedHtml($Invoice,$docType); |
33
|
|
|
// Render the HTML as PDF |
34
|
|
|
$dompdf->loadHtml($html); |
35
|
|
|
$dompdf->render(); |
36
|
|
|
$pdf = $dompdf->output(); |
37
|
|
|
Repository::savePDF($billName, $pdf); |
38
|
|
|
} |
39
|
|
|
|
40
|
|
|
private static function getTplFor($docType) { |
41
|
|
|
if ($docType == Catalogo::DOCTYPE_FACTURA) { |
42
|
|
|
return 'factura.html'; |
43
|
|
|
} |
44
|
|
|
if ($docType == Catalogo::DOCTYPE_BOLETA) { |
45
|
|
|
return 'boleta.html'; |
46
|
|
|
} |
47
|
|
|
if ($docType == Catalogo::DOCTYPE_NOTA_CREDITO) { |
48
|
|
|
return 'nota-credito.html'; |
49
|
|
|
} |
50
|
|
|
return 'nota-debito.html'; |
51
|
|
|
} |
52
|
|
|
|
53
|
|
|
public static function getRenderedHtml(DataMap $Invoice, $tpl) { |
54
|
|
|
$invoiceData = self::getDocumentData($Invoice); |
55
|
|
|
$renderer = self::getRenderer(); |
56
|
|
|
return $renderer->render($tpl, $invoiceData); |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
private static function getDocumentData(DataMap $inv) { |
60
|
|
|
$currency = Catalogo::getCurrencyPlural($inv->getCurrencyCode()); |
61
|
|
|
$payableAmount = $inv->getPayableAmount(); |
62
|
|
|
$payableInWords = Operations::getAmountInWords($payableAmount, $currency); |
63
|
|
|
return [ |
64
|
|
|
'companyRuc' => Company::getRUC(), |
65
|
|
|
'companyAddress' => Company::getAddress(), |
66
|
|
|
'companyCity' => Company::getCity(), |
67
|
|
|
'companyContactInfo' => Company::getContactInfo(), |
68
|
|
|
'documentSeries' => $inv->getDocumentSeries(), |
69
|
|
|
'documentNumber' => $inv->getDocumentNumber(), |
70
|
|
|
'documentName' => $inv->getDocumentName(), |
71
|
|
|
'currency' => $currency, |
72
|
|
|
'customerRegName' => $inv->getCustomerRegName(), |
73
|
|
|
'customerDocNumber' => $inv->getCustomerDocNumber(), |
74
|
|
|
'customerAddress' => $inv->getCustomerAddress(), |
75
|
|
|
'issueDate' => $inv->getIssueDate()->format('d-m-Y'), |
76
|
|
|
'igvPercent' => SunatVars::IGV_PERCENT, |
77
|
|
|
'logo' => self::getLogoString(), |
78
|
|
|
'qr' => self::getQrString($inv), // QR Code |
79
|
|
|
'taxableOperations' => $inv->getTotalTaxableOperations(), // Total operaciones gravadas |
80
|
|
|
'freeOperations' => $inv->getTotalFreeOperations(), // Total operaciones gratuitas |
81
|
|
|
'unaffectedOperations' => $inv->getTotalUnaffectedOperations(), // Total operaciones inafectas |
82
|
|
|
'exemptedOperations' => $inv->getTotalExemptedOperations(), // Total operaciones exoneradas |
83
|
|
|
'totalAllowances' => $inv->getTotalAllowances(), // Total operaciones exoneradas |
84
|
|
|
'igvAmount' => $inv->getIGV(), // Total a pagar |
85
|
|
|
'payableAmount' => $payableAmount, // Total a pagar |
86
|
|
|
'payableInWords' => $payableInWords, // Monto en palabras |
87
|
|
|
'items' => self::getDocumentDataItems($inv) // Items |
88
|
|
|
|
89
|
|
|
]; |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
private static function getDocumentDataItems(DataMap $inv) { |
93
|
|
|
$Items = $inv->getItems(); |
94
|
|
|
$ln = $Items->getCount(); |
95
|
|
|
$items2 = []; |
96
|
|
|
for ($i = 0; $i < $ln; $i++) { |
97
|
|
|
$items2[]= [ |
98
|
|
|
'productCode' => $Items->getProductCode($i), |
99
|
|
|
'quantity' => $Items->getQunatity($i), |
100
|
|
|
'unitName' => Catalogo::getUnitName($Items->getUnitCode($i)), |
101
|
|
|
'unitBillableValue' => $Items->getUnitBillableValue($i), |
102
|
|
|
'itemPayableAmount' => $Items->getPayableAmount($i), |
103
|
|
|
'description' => $Items->getDescription($i) |
104
|
|
|
]; |
105
|
|
|
} |
106
|
|
|
return $items2; |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
private static function getLogoString() { |
110
|
|
|
$customLogoPath = Company::getPdfTemplatesPath() . '/company-logo.png'; |
111
|
|
|
if (file_exists($customLogoPath)) { |
112
|
|
|
return base64_encode(file_get_contents($customLogoPath)); |
113
|
|
|
} |
114
|
|
|
$defaultLogoPath = F72X::getDefaultPdfTemplatesPath() . '/company-logo.png'; |
115
|
|
|
return base64_encode(file_get_contents($defaultLogoPath)); |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
private static function getQrString(DataMap $inv) { |
119
|
|
|
$billName = $inv->getBillName(); |
120
|
|
|
$qr = new QRCode(); |
121
|
|
|
$qrContent = self::getQrContent($inv); |
122
|
|
|
$qrTempPath = F72X::getTempDir() . "/QR-$billName.png"; |
123
|
|
|
$qr->png($qrContent, $qrTempPath, 'Q', 8, 2); |
124
|
|
|
$qrs = base64_encode(file_get_contents($qrTempPath)); |
125
|
|
|
unlink($qrTempPath); |
126
|
|
|
return $qrs; |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
private static function getQrContent(DataMap $inv) { |
130
|
|
|
$ruc = Company::getRUC(); |
131
|
|
|
$invoiveType = $inv->getDocumentType(); |
132
|
|
|
$documentSeries = $inv->getDocumentSeries(); |
133
|
|
|
$seriesNumber = $inv->getDocumentNumber(); |
134
|
|
|
$igv = Operations::formatAmount($inv->getIGV()); |
135
|
|
|
$payableAmount = Operations::formatAmount($inv->getPayableAmount()); |
136
|
|
|
$issueDate = $inv->getIssueDate()->format('Y-m-d'); |
137
|
|
|
$customerDocType = $inv->getCustomerDocType(); |
138
|
|
|
$customerDocNumber = $inv->getCustomerDocNumber(); |
139
|
|
|
return "$ruc|$invoiveType|$documentSeries|$seriesNumber|$igv|$payableAmount|$issueDate|$customerDocType|$customerDocNumber"; |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
private static function getRenderer() { |
143
|
|
|
$loader = new Twig_Loader_Filesystem(); |
144
|
|
|
// Custom |
145
|
|
|
$loader->addPath(Company::getPdfTemplatesPath()); |
146
|
|
|
// Defaults |
147
|
|
|
$loader->addPath(F72X::getDefaultPdfTemplatesPath()); |
148
|
|
|
$view = new Twig_Environment($loader, ['cache' => false]); |
149
|
|
|
// I18n ext |
150
|
|
|
$view->addExtension(new Twig_Extensions_Extension_Intl()); |
151
|
|
|
// Scape html ext |
152
|
|
|
$view->addExtension(new Twig_Extension_Escaper('html')); |
153
|
|
|
return $view; |
154
|
|
|
} |
155
|
|
|
|
156
|
|
|
} |
157
|
|
|
|