Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 191 |
n/a |
0 / 0 |
CRAP | n/a |
0 / 0 |
1 | <?php |
2 | /** |
3 | * Jingga |
4 | * |
5 | * PHP Version 8.1 |
6 | * |
7 | * @package Modules\Media |
8 | * @copyright Dennis Eichhorn |
9 | * @license OMS License 2.0 |
10 | * @version 1.0.0 |
11 | * @link https://jingga.app |
12 | */ |
13 | declare(strict_types=1); |
14 | |
15 | use Modules\Billing\Models\NullBill; |
16 | use phpOMS\Localization\ISO3166NameEnum; |
17 | use phpOMS\Localization\ISO3166TwoEnum; |
18 | use phpOMS\Localization\Money; |
19 | |
20 | /** @var \phpOMS\Views\View $this */ |
21 | /** @var \Modules\Media\Models\Collection $media */ |
22 | $media = $this->getData('defaultTemplates'); |
23 | |
24 | require_once $media->findFile('.pdf.php')->getAbsolutePath(); |
25 | |
26 | /** @var \Modules\Billing\Models\Bill $bill */ |
27 | $bill = $this->data['bill'] ?? new NullBill(); |
28 | |
29 | // Set up default pdf template |
30 | /** @phpstan-import-type DefaultPdf from ../../../../Admin/Install/Media/PdfDefaultTemplate/pdfTemplate.pdf.php */ |
31 | $pdf = new DefaultPdf(); |
32 | |
33 | $lang = include __DIR__ . '/lang.php'; |
34 | |
35 | $pdf->attributes['title_name'] = (string) ($this->data['bill_logo_name'] ?? 'Jingga'); |
36 | $pdf->attributes['slogan'] = (string) ($this->data['bill_slogan'] ?? 'Business solutions made simple.'); |
37 | |
38 | $pdf->setHeaderData( |
39 | __DIR__ . '/logo.png', 15, |
40 | $pdf->attributes['title_name'], |
41 | $pdf->attributes['slogan'], |
42 | ); |
43 | $pdf->setCreator((string) ($this->data['bill_creator'] ?? 'Jingga')); |
44 | $pdf->setAuthor((string) ($this->data['bill_creator'] ?? 'Jingga')); |
45 | $pdf->setTitle((string) ($this->data['bill_title'] ?? $bill->type->getL11n())); |
46 | $pdf->setSubject((string) ($this->data['bill_subtitle'] ?? '')); |
47 | $pdf->setKeywords(\implode(', ', (array) ($this->data['keywords'] ?? []))); |
48 | $pdf->language = $bill->language; |
49 | |
50 | $pdf->attributes['legal_name'] = (string) ($this->data['legal_company_name'] ?? 'Jingga e. K.'); |
51 | $pdf->attributes['address'] = (string) ($this->data['bill_company_address'] ?? 'Kirchstr. 33'); |
52 | $pdf->attributes['city'] = (string) ($this->data['bill_company_city'] ?? '61191 Rosbach'); |
53 | |
54 | $pdf->attributes['ceo'] = (string) ($this->data['bill_company_ceo'] ?? 'Dennis Eichhorn'); |
55 | $pdf->attributes['tax_office'] = (string) ($this->data['bill_company_tax_office'] ?? 'HRA 5058'); |
56 | $pdf->attributes['tax_number'] = (string) ($this->data['bill_company_tax_id'] ?? 'DE362646968'); |
57 | $pdf->attributes['terms'] = (string) ($this->data['bill_company_terms'] ?? 'https://jingga.app/terms'); |
58 | |
59 | $pdf->attributes['bank_name'] = (string) ($this->data['bill_company_bank_name'] ?? 'Volksbank Mittelhessen'); |
60 | $pdf->attributes['swift'] = (string) ($this->data['bill_company_swift'] ?? 'VBMHDE5F'); |
61 | $pdf->attributes['bank_account'] = (string) ($this->data['bill_company_bank_account'] ?? 'DE62 5139 0000 0084 8044 10'); |
62 | |
63 | $pdf->attributes['website'] = (string) ($this->data['bill_company_website'] ?? 'www.jingga.app'); |
64 | $pdf->attributes['email'] = (string) ($this->data['bill_company_email'] ?? 'info@jingga.app'); |
65 | $pdf->attributes['phone'] = (string) ($this->data['bill_company_phone'] ?? '+49 152 04337728'); |
66 | |
67 | $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO); |
68 | |
69 | // add a page |
70 | $pdf->AddPage(); |
71 | $topPos = $pdf->getY(); |
72 | |
73 | // Set up default bill template |
74 | $billTypeName = \strtoupper($bill->type->getL11n()); |
75 | |
76 | // @todo: depending on amount of lines, there is a solution (html, or use backtracking of tcpdf) |
77 | |
78 | // Address |
79 | $pdf->setY(50); |
80 | $pdf->setFont('helvetica', '', 10); |
81 | |
82 | $countries = ISO3166NameEnum::getConstants(); |
83 | $countryEnumName = ISO3166TwoEnum::getName($bill->billCountry); |
84 | $toCountry = \is_string($countryEnumName) && ($country = ISO3166NameEnum::getByName($countryEnumName)) !== null |
85 | ? $country |
86 | : ''; |
87 | |
88 | $addressString = \trim( |
89 | $bill->billTo . "\n" |
90 | . (empty($bill->billAddress) ? '' : ($bill->billAddress . "\n")) |
91 | . (empty($bill->billCity) ? '' : ($bill->billCity . "\n")) |
92 | . (empty($toCountry) ? '' : ($toCountry . "\n")), |
93 | "\n " |
94 | ); |
95 | |
96 | // Count the char "\n" in $addressString |
97 | $addressLineCount = \substr_count($addressString, "\n") + 1; |
98 | |
99 | $lineHeight = $pdf->getY(); |
100 | $pdf->Write( |
101 | 0, |
102 | $addressString, |
103 | '', false, 'L', false, 0, false, false, 0 |
104 | ); |
105 | $lineHeight = ($lineHeight - $pdf->getY()) / $addressLineCount; |
106 | |
107 | // Bill head |
108 | $pdf->setFont('helvetica', 'B', 16); |
109 | $titleWidth = $pdf->getStringWidth($billTypeName, 'helvetica', 'B', 16); |
110 | $titleWidth = \is_array($titleWidth) ? \array_sum($titleWidth) : $titleWidth; |
111 | |
112 | $pdf->setXY( |
113 | $rightPos = ($pdf->getPageWidth() - $titleWidth - \max(60 - $titleWidth, 0) - 15 - 2), |
114 | $topPos + 50 + $lineHeight * $addressLineCount - 38, |
115 | true |
116 | ); |
117 | |
118 | $pdf->setTextColor(255, 255, 255); |
119 | $pdf->setFillColor(255, 162, 7); |
120 | $pdf->Cell($pdf->getPageWidth() - $rightPos - 15, 0, $billTypeName, 0, 0, 'L', true); |
121 | |
122 | $pdf->setFont('helvetica', '', 10); |
123 | $pdf->setTextColor(255, 162, 7); |
124 | |
125 | $pdf->setXY($rightPos, $tempY = $pdf->getY() + 10, true); |
126 | $pdf->MultiCell( |
127 | 26, 30, |
128 | $lang[$pdf->language]['InvoiceNo'] . "\n" |
129 | . $lang[$pdf->language]['InvoiceDate'] . "\n" |
130 | . $lang[$pdf->language]['ServiceDate'] . "\n" |
131 | . $lang[$pdf->language]['CustomerNo'] . "\n" |
132 | . $lang[$pdf->language]['PO'] . "\n" |
133 | . $lang[$pdf->language]['DueDate'], |
134 | 0, 'L' |
135 | ); |
136 | |
137 | $pdf->setFont('helvetica', '', 10); |
138 | $pdf->setTextColor(0, 0, 0); |
139 | |
140 | $pdf->setXY($rightPos + 26 + 2, $tempY, true); |
141 | $pdf->MultiCell( |
142 | 25, 30, |
143 | $bill->number . "\n" |
144 | . ($bill->billDate?->format('Y-m-d') ?? '0') . "\n" |
145 | . ($bill->performanceDate?->format('Y-m-d') ?? '0') . "\n" |
146 | . $bill->accountNumber . "\n" |
147 | . '' . "\n" /* @todo: implement customer / supplier reference as string */ |
148 | . ($bill->billDate?->format('Y-m-d') ?? '0'), /* Consider to add dueDate in addition */ |
149 | 0, 'L' |
150 | ); |
151 | $pdf->Ln(); |
152 | |
153 | $pdf->setY($pdf->getY() - 30); |
154 | |
155 | /* |
156 | $pdf->writeHTMLCell( |
157 | $pdf->getPageWidth() - 15 * 2, 0, null, null, |
158 | "<strong>Lorem ipsum dolor sit amet,</strong><br \><br \>Consectetur adipiscing elit. Vivamus ac massa sit amet eros posuere accumsan feugiat vel est. Maecenas ultricies enim eu eros rhoncus, volutpat cursus enim imperdiet. Aliquam et odio ipsum. Quisque dapibus scelerisque tempor. Phasellus purus lorem, venenatis eget pretium ac, convallis et ante. Aenean pulvinar justo consectetur mi tincidunt venenatis. Suspendisse ultricies enim id nulla facilisis lacinia. <br /><br />Nam congue nunc nunc, eu pellentesque eros aliquam ac. Nunc placerat elementum turpis, quis facilisis diam volutpat at. Suspendisse enim leo, convallis nec ornare eu, auctor nec purus. Nunc neque metus, feugiat quis justo nec, mollis dignissim risus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. In at ornare sem. Cras placerat, sapien sed ornare lacinia, mauris nulla volutpat nisl, eget dapibus nisl ipsum non est. Suspendisse ut nisl a ipsum rhoncus sodales.", |
159 | 0, 0, false, true, 'J' |
160 | ); |
161 | $pdf->Ln(); |
162 | */ |
163 | |
164 | $pdf->setY($pdf->getY() + 10); |
165 | |
166 | $header = [ |
167 | $lang[$pdf->language]['Item'], |
168 | $lang[$pdf->language]['Quantity'], |
169 | $lang[$pdf->language]['UnitPrice'], |
170 | $lang[$pdf->language]['Total'], |
171 | ]; |
172 | |
173 | $lines = $bill->getElements(); |
174 | |
175 | // Header |
176 | $headerCount = \count($header); |
177 | $w = [$pdf->getPageWidth() - 20 - 20 - 20 - 2 * 15, 20, 20, 20]; |
178 | |
179 | $pdf->setCellPadding(1); |
180 | |
181 | $taxes = []; |
182 | $first = true; |
183 | |
184 | // Data |
185 | $fill = false; |
186 | foreach($lines as $line) { |
187 | // @todo: add support for empty lines (row = line) |
188 | if (/*$row === null || */$first || $pdf->getY() > $pdf->getPageHeight() - 40) { |
189 | $pdf->setFillColor(255, 162, 7); |
190 | $pdf->setTextColor(255); |
191 | $pdf->setDrawColor(255, 162, 7); |
192 | //$pdf->SetLineWidth(0.3); |
193 | $pdf->setFont('helvetica', 'B', 10); |
194 | |
195 | if (!$first/* || $row === null*/) { |
196 | $pdf->AddPage(); |
197 | $pdf->Ln(); |
198 | } |
199 | |
200 | for($i = 0; $i < $headerCount; ++$i) { |
201 | $pdf->Cell($w[$i], 7, $header[$i], 1, 0, 'L', true); |
202 | } |
203 | |
204 | $pdf->Ln(); |
205 | $pdf->setFillColor(245, 245, 245); |
206 | $pdf->setTextColor(0); |
207 | $pdf->setFont('helvetica', '', 10); |
208 | |
209 | $first = false; |
210 | } |
211 | |
212 | $tempY = $pdf->getY(); |
213 | $pdf->writeHTMLCell($w[0], 10, null, null, $line->itemNumber . ' ' . $line->itemName, 0, 2, $fill); |
214 | $height = $pdf->getY() - $tempY; |
215 | |
216 | $singleSalesPriceNet = Money::fromFloatInt($line->singleSalesPriceNet); |
217 | $totalSalesPriceNet = Money::fromFloatInt($line->totalSalesPriceNet); |
218 | |
219 | $pdf->MultiCell($w[1], $height, (string) $line->getQuantity(), 0, 'L', $fill, 0, 15 + $w[0], $tempY, true, 0, false, true, 0, 'M', true); |
220 | $pdf->MultiCell($w[2], $height, $singleSalesPriceNet->getCurrency(2, symbol: ''), 0, 'L', $fill, 0, 15 + $w[0] + $w[1], $tempY, true, 0, false, true, 0, 'M', true); |
221 | $pdf->MultiCell($w[3], $height, $totalSalesPriceNet->getCurrency(2, symbol: ''), 0, 'L', $fill, 1, 15 + $w[0] + $w[1] + $w[2], $tempY, true, 0, false, true, 0, 'M', true); |
222 | |
223 | $fill = !$fill; |
224 | |
225 | // get taxes |
226 | if (!isset($taxes[$line->taxR->getInt() / 100])) { |
227 | $taxes[$line->taxR->getInt() / 100] = $line->taxP; |
228 | } else { |
229 | $taxes[$line->taxR->getInt() / 100]->add($line->taxP); |
230 | } |
231 | } |
232 | |
233 | $pdf->Cell(\array_sum($w), 0, '', 'T'); |
234 | $pdf->Ln(); |
235 | |
236 | if ($pdf->getY() > $pdf->getPageHeight() - 40) { |
237 | $pdf->AddPage(); |
238 | } |
239 | |
240 | $pdf->setFillColor(240, 240, 240); |
241 | $pdf->setTextColor(0); |
242 | $pdf->setDrawColor(240, 240, 240); |
243 | $pdf->setFont('helvetica', 'B', 10); |
244 | |
245 | $tempY = $pdf->getY(); |
246 | |
247 | $netSales = Money::fromFloatInt($bill->netSales); |
248 | |
249 | $pdf->setX($w[0] + $w[1] + 15); |
250 | $pdf->Cell($w[2], 7, $lang[$pdf->language]['Subtotal'], 0, 0, 'L', false); |
251 | $pdf->Cell($w[3], 7, $netSales->getCurrency(2, symbol: ''), 0, 0, 'L', false); |
252 | $pdf->Ln(); |
253 | |
254 | foreach ($taxes as $rate => $tax) { |
255 | $tax = Money::fromFloatInt($tax); |
256 | |
257 | $pdf->setX($w[0] + $w[1] + 15); |
258 | $pdf->Cell($w[2], 7, $lang[$pdf->language]['Taxes'] . ' (' . $rate . '%)', 0, 0, 'L', false); |
259 | $pdf->Cell($w[3], 7, $tax->getCurrency(2, symbol: ''), 0, 0, 'L', false); |
260 | $pdf->Ln(); |
261 | } |
262 | |
263 | // @todo: add currency |
264 | |
265 | $pdf->setFillColor(255, 162, 7); |
266 | $pdf->setTextColor(255); |
267 | $pdf->setDrawColor(255, 162, 7); |
268 | $pdf->setFont('helvetica', 'B', 10); |
269 | |
270 | $grossSales = Money::fromFloatInt($bill->grossSales); |
271 | |
272 | $pdf->setX($w[0] + $w[1] + 15); |
273 | $pdf->Cell($w[2], 7, \strtoupper($lang[$pdf->language]['Total']), 1, 0, 'L', true); |
274 | $pdf->Cell($w[3], 7, $grossSales->getCurrency(2, symbol: ''), 1, 0, 'L', true); |
275 | $pdf->Ln(); |
276 | |
277 | $tempY2 = $pdf->getY(); |
278 | |
279 | // @todo: fix payment terms |
280 | $pdf->setTextColor(0); |
281 | $pdf->setFont('helvetica', 'B', 8); |
282 | $pdf->setY($tempY); |
283 | $pdf->Write(0, $lang[$pdf->language]['PaymentTerms'] . ': CreditCard', '', false, 'L', false, 0, false, false, 0); |
284 | |
285 | $pdf->setFont('helvetica', '', 8); |
286 | $pdf->Write(0, $bill->paymentText, '', false, 'L', false, 0, false, false, 0); |
287 | $pdf->Ln(); |
288 | |
289 | // @todo: fix terms |
290 | $pdf->setFont('helvetica', 'B', 8); |
291 | $pdf->Write(0, $lang[$pdf->language]['Terms'] . ': ' . $pdf->attributes['terms'], '', false, 'L', false, 0, false, false, 0); |
292 | $pdf->Ln(); |
293 | |
294 | $pdf->setFont('helvetica', 'B', 8); |
295 | $pdf->Write(0, $lang[$pdf->language]['Currency'] . ': ' . $bill->currency, '', false, 'L', false, 0, false, false, 0); |
296 | $pdf->Ln(); |
297 | |
298 | $pdf->setFont('helvetica', 'B', 8); |
299 | $pdf->Write(0, $lang[$pdf->language]['TaxRemark'], '', false, 'L', false, 0, false, false, 0); |
300 | $pdf->Ln(); |
301 | |
302 | $pdf->setFont('helvetica', '', 8); |
303 | $pdf->Write(0, $bill->termsText, '', false, 'L', false, 0, false, false, 0); |
304 | $pdf->Ln(); |
305 | |
306 | $pdf->setY($tempY2); |
307 | $pdf->Ln(); |
308 | |
309 | /* |
310 | $pdf->writeHTMLCell( |
311 | $pdf->getPageWidth() - 15 * 2, 0, null, null, |
312 | "Consectetur adipiscing elit. Vivamus ac massa sit amet eros posuere accumsan feugiat vel est. Maecenas ultricies enim eu eros rhoncus, volutpat cursus enim imperdiet. Aliquam et odio ipsum. Quisque dapibus scelerisque tempor. Phasellus purus lorem, venenatis eget pretium ac, convallis et ante. Aenean pulvinar justo consectetur mi tincidunt venenatis. Suspendisse ultricies enim id nulla facilisis lacinia. Nam congue nunc nunc, eu pellentesque eros aliquam ac.<br /><br />Nunc placerat elementum turpis, quis facilisis diam volutpat at. Suspendisse enim leo, convallis nec ornare eu, auctor nec purus. Nunc neque metus, feugiat quis justo nec, mollis dignissim risus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. In at ornare sem. Cras placerat, sapien sed ornare lacinia, mauris nulla volutpat nisl, eget dapibus nisl ipsum non est. Suspendisse ut nisl a ipsum rhoncus sodales.", |
313 | 0, 0, false, true, 'J' |
314 | ); |
315 | $pdf->Ln(); |
316 | */ |
317 | |
318 | //Close and output PDF document |
319 | $path = (string) ($this->data['path'] ?? (($bill->billDate?->format('Y-m-d') ?? '0') . '_' . $bill->number . '.pdf')); |
320 | $pdf->Output($path, 'I'); |