Completed
Push — master ( b96a07...d3cdb3 )
by Hannes
04:22 queued 03:33
created

PaperInvoice::drawTotals()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 43

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 43
c 0
b 0
f 0
rs 9.232
cc 3
nc 4
nop 0
1
<?php
2
3
namespace byrokrat\paperinvoice;
4
5
use byrokrat\paperinvoice\I18n\Swedish as DefaultI18n;
6
use byrokrat\billing\Invoice;
7
use byrokrat\amount\Currency;
8
9
/**
10
 * Pdf representation of invoice
11
 */
12
class PaperInvoice extends FPDF
13
{
14
    /**
15
     * Bottom margin of document pages
16
     */
17
    const MARGIN_BOTTOM = 20;
18
19
    /**
20
     * @var Invoice Object to print
21
     */
22
    private $invoice;
23
24
    /**
25
     * @var I18nInterface Translator and formatter
26
     */
27
    private $i18n;
28
29
    /**
30
     * Contact information fields. Alter values to print on invoice
31
     */
32
    public $buyerAddress = '';
33
    public $sellerAddress = '';
34
    public $sellerPhone = '';
35
    public $sellerMail = '';
36
37
    public $sellerAccount;
38
    public $sellerId;
39
40
    /**
41
     * @param Invoice       $invoice Invoice object to print
42
     * @param I18nInterface $i18n    Translator and formatter
43
     */
44
    public function __construct(Invoice $invoice, I18nInterface $i18n = null)
45
    {
46
        parent::__construct(10);
47
        $this->invoice = $invoice;
48
        $this->i18n = $i18n ?: new DefaultI18n;
49
        $this->setTitle($this->getInvoiceTitle());
50
        $this->setCreator($invoice->getSeller()->getName());
51
    }
52
53
    public function getInvoiceTitle()
54
    {
55
        return implode(
56
            ' ',
57
            array(
58
                $this->i18n->translate('INVOICE'),
59
                $this->invoice->getSerial(),
60
                $this->i18n->formateDate($this->invoice->getBillDate()),
61
                $this->invoice->getSeller()->getName()
62
            )
63
        );
64
    }
65
66
    protected function draw()
67
    {
68
        $this->AddPage();
69
        $this->drawInvoiceInfo();
70
        $this->drawVatRates();
71
        $this->drawTotals();
72
        $this->drawMessage();
73
        $this->drawPostHeaders(63);
74
        $this->drawPosts();
75
    }
76
77
    private function drawInvoiceInfo()
78
    {
79
        $info = array(
80
            $this->i18n->translate('Invoice date')   => $this->i18n->formateDate($this->invoice->getBillDate()),
81
            $this->i18n->translate('Invoice number') => $this->invoice->getSerial(),
82
            $this->i18n->translate('Reference')      => $this->invoice->getOCR(),
83
            $this->i18n->translate('Payment term')   => $this->invoice->getAttribute('payment-term', '30') . $this->i18n->translate(' days'),
84
            $this->i18n->translate('Expiry date')    => $this->i18n->formateDate($this->invoice->getExpirationDate())
85
        );
86
87
        $this->SetFont('Helvetica', '', 12);
88
89
        $this->setXY(12, 35);
90
        $this->MultiCell(0, 5, implode("\n", array_keys($info)));
91
92
        $this->setXY(50, 35);
93
        $this->MultiCell(0, 5, implode("\n", $info));
94
95
        $buyer = array(
96
            $this->invoice->getBuyer()->getName(),
97
            $this->buyerAddress
98
        );
99
100
        $this->setXY(120, 35);
101
        $this->MultiCell(0, 5, implode("\n", $buyer));
102
    }
103
104
    private function drawPostHeaders($y)
105
    {
106
        $this->Line(10, $y, 200, $y);
107
108
        $this->SetFont('Helvetica', '', 10);
109
        $y += 3;
110
111
        $this->writeXY(105, $y, 5, $this->i18n->translate('VAT rate'));
112
        $this->writeXY(125, $y, 5, $this->i18n->translate('Amount'));
113
        $this->writeXY(137, $y, 5, $this->i18n->translate('Unit cost'));
114
        $this->writeXY(165, $y, 5, $this->i18n->translate('Total'));
115
        $this->ln(7);
116
    }
117
118
    private function drawPosts()
119
    {
120
        $this->SetFont('Courier', '', 11);
121
122
        foreach ($this->invoice->getItems() as $item) {
123
            $this->setX(105);
124
            $this->write(5, $this->i18n->formatPercentage($item->getVatRate()));
125
            $this->setX(125);
126
            $this->write(5, $this->i18n->formatUnits($item->getNrOfUnits()));
127
            $this->setX(137);
128
            $this->write(5, $this->i18n->formatCurrency($item->getCostPerUnit()));
129
            $this->setX(165);
130
            $this->write(5, $this->i18n->formatCurrency($item->getTotalUnitCost()));
131
132
            $this->setX(10);
133
            $this->MultiCell(90, 4, $item->getBillingDescription());
134
135
            $this->ln(5);
136
137
            $margin = 275 + ((self::MARGIN_BOTTOM + 80) * -1);
138
139
            if ($this->getY()+20 > $margin && $this->PagesAdded() == 1) {
140
                $this->Write(5, $this->i18n->translate('Continues on next page..'));
141
                $this->AddPage();
142
                $this->SetAutoPageBreak(true, 45);
143
                $this->SetFont('Courier', '', 11);
144
            }
145
        }
146
    }
147
148
    private function drawVatRates()
149
    {
150
        $x = 10;
151
        $y = (self::MARGIN_BOTTOM + 80) * -1;
152
153
        $rates = $this->invoice->getItems()->getVatRates();
154
155
        if (count($rates) > 4) {
156
            $msg = "PaperInvoice can handle a maximum of 4 different VAT rates in a single invoice.";
157
            throw new Exception($msg);
158
        }
159
160
        foreach ($rates as $rate => $rateData) {
161
            $data = array(
162
                $this->i18n->translate('VAT rate') => $this->i18n->formatPercentage($rate),
163
                $this->i18n->translate('Basis')    => $this->i18n->formatCurrency($rateData['unit_total']),
164
                $this->i18n->translate('To pay')   => $this->i18n->formatCurrency($rateData['vat_total'])
165
            );
166
167
            $this->SetFont('Helvetica', '', 10);
168
            $this->setXY($x, $y);
169
            $this->MultiCell(0, 5, implode("\n", array_keys($data)));
170
171
            $this->SetFont('Helvetica', '', 12);
172
            $this->setXY($x + 20, $y);
173
            $this->MultiCell(0, 5, implode("\n", $data));
174
175
            $x += 48;
176
        }
177
    }
178
179
    private function drawTotals()
180
    {
181
        $rows = array(
182
            (self::MARGIN_BOTTOM + 56) * -1,
183
            (self::MARGIN_BOTTOM + 49) * -1
184
        );
185
186
        $cols = array(15, 60, 100, 160);
187
188
        $this->SetFont('Helvetica', '', 12);
189
190
        $this->writeXY($cols[0], $rows[0], 5, $this->i18n->translate('Total ex. VAT'));
191
        $this->writeXY($cols[1], $rows[0], 5, $this->i18n->translate('Total VAT'));
192
193
        $deduction = $this->invoice->getDeduction();
194
195
        if ($deduction->isPositive()) {
196
            $this->writeXY($cols[2], $rows[0], 5, $this->i18n->translate('Deduction'));
197
            $this->SetFont('Helvetica', '', 14);
198
            $this->writeXY($cols[2], $rows[1], 5, $this->i18n->formatCurrency($deduction));
199
        }
200
201
        $this->SetFont('Helvetica', '', 14);
202
203
        $this->writeXY($cols[0], $rows[1], 5, $this->i18n->formatCurrency($this->invoice->getItems()->getTotalUnitCost()));
204
        $this->writeXY($cols[1], $rows[1], 5, $this->i18n->formatCurrency($this->invoice->getItems()->getTotalVatCost()));
205
206
        $this->SetFont('Helvetica', 'B', 14);
207
208
        $totalCost = $this->invoice->getItems()->getTotalCost();
209
210
        $currency = 'SEK';
211
212
        if ($totalCost instanceof Currency) {
213
            $currency = $totalCost->getCurrencyCode();
214
        }
215
216
        $this->writeXY($cols[3], $rows[0], 5, $this->i18n->translate('To pay'));
217
        $this->writeXY($cols[3], $rows[1], 5, $this->i18n->formatCurrencySymbol($totalCost, $currency));
218
219
        $this->Rect(10, 297-self::MARGIN_BOTTOM-60, 190, 20);
220
        $this->Rect(11, 297-self::MARGIN_BOTTOM-59, 188, 18);
221
    }
222
223
    private function drawMessage()
224
    {
225
        $message = $this->invoice->getAttribute('message', '');
226
227
        if ($this->invoice->getAttribute('tax-registered')) {
228
            $message .= ' ' . $this->i18n->translate('Tax registered');
229
        }
230
231
        $this->SetFont('Helvetica', '', 12);
232
        $this->setXY(10, (self::MARGIN_BOTTOM + 37) * -1);
233
        $this->MultiCell(0, 5, trim($message));
234
    }
235
236
    public function header()
237
    {
238
        $this->setFont('Helvetica','B',28);
239
        $this->writeXY(10, 10, 10, $this->invoice->getSeller()->getName());
240
241
        $x = floor(-12 - $this->GetStringWidth($this->i18n->translate('INVOICE')));
242
243
        $this->setFont('Helvetica', '', 18);
244
        $this->writeXY($x, 10, 10, $this->i18n->translate('INVOICE'));
245
246
        $this->setFont('Helvetica', '', 10);
247
        $this->writeXY($x, 19, 5, $this->i18n->translate('Page ') . $this->PaginationStr($this->i18n->translate(' of ')));
248
249
        if ($this->PagesAdded() > 1) {
250
            $this->drawPostHeaders(29);
251
        }
252
    }
253
254
    public function footer()
255
    {
256
        $rows = array(
257
            297-self::MARGIN_BOTTOM-19,
258
            (self::MARGIN_BOTTOM + 16) * -1,
259
            (self::MARGIN_BOTTOM + 11) * -1,
260
            (self::MARGIN_BOTTOM + 5) * -1,
261
            self::MARGIN_BOTTOM * -1
262
        );
263
264
        $cols = array(10, 60, 105, 140);
265
266
        $this->Line(10, $rows[0], 200, $rows[0]);
267
268
        $this->SetFont('Helvetica', '', 10);
269
270
        $this->writeXY($cols[0], $rows[1], 5, $this->i18n->translate('Address'));
271
        $this->writeXY($cols[1], $rows[1], 5, $this->i18n->translate('Identification'));
272
        $this->writeXY($cols[1], $rows[3], 5, $this->i18n->translate('VAT number'));
273
        $this->writeXY($cols[2], $rows[1], 5, $this->sellerAccount->getBankName());
274
        $this->writeXY($cols[3], $rows[1], 5, $this->i18n->translate('Phone'));
275
        $this->writeXY($cols[3], $rows[3], 5, $this->i18n->translate('E-mail'));
276
277
        $this->SetFont('Helvetica', '', 12);
278
279
        $this->writeXY($cols[0], $rows[2], 5, $this->sellerAddress);
280
        $this->writeXY($cols[1], $rows[2], 5, $this->sellerId);
281
        $this->writeXY($cols[1], $rows[4], 5, $this->sellerId);
282
        $this->writeXY($cols[2], $rows[2], 5, $this->sellerAccount);
283
        $this->writeXY($cols[3], $rows[2], 5, $this->sellerPhone);
284
        $this->writeXY($cols[3], $rows[4], 5, $this->sellerMail);
285
    }
286
}
287