Passed
Push — master ( a8b594...f799ef )
by
unknown
02:38 queued 11s
created

InvoiceService::findByInvoiceable()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 8
ccs 3
cts 3
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
4
namespace NeptuneSoftware\Invoice\Services;
5
6
use Dompdf\Dompdf;
7
use Illuminate\Database\Eloquent\Model;
8
use Illuminate\Support\Collection;
9
use Illuminate\Support\Facades\View;
10
use NeptuneSoftware\Invoice\Models\Invoice;
11
use NeptuneSoftware\Invoice\MoneyFormatter;
12
use NeptuneSoftware\Invoice\Interfaces\InvoiceServiceInterface;
13
use Symfony\Component\HttpFoundation\Response;
14
15
class InvoiceService implements InvoiceServiceInterface
16
{
17
    /**
18
     * @var Invoice $invoice
19
     */
20
    private $invoice;
21
22
    /**
23
     * @var bool $is_free
24
     */
25
    private $is_free = false;
26
27
    /**
28
     * @var bool $is_comp
29
     */
30
    private $is_comp = false;
31
32
    /**
33
     * @var array $taxes
34
     */
35
    private $taxes = [];
36
37
    /**
38
     * @inheritDoc
39
     */
40 23
    public function create(Model $model, ?array $invoice = []): InvoiceServiceInterface
41
    {
42 23
        $this->invoice = $model->invoices()->create($invoice);
43
44 23
        return $this;
45
    }
46
47
    /**
48
     * @inheritDoc
49
     */
50 23
    public function getInvoice(): Invoice
51
    {
52 23
        return $this->invoice;
53
    }
54
55
    /**
56
     * @inheritDoc
57
     */
58 18
    public function getLines(): Collection
59
    {
60 18
        return $this->getInvoice()->lines()->get();
61
    }
62
63
    /**
64
     * @inheritDoc
65
     */
66 3
    public function setFree(): InvoiceServiceInterface
67
    {
68 3
        $this->is_free = true;
69 3
        $this->is_comp = false;
70
71 3
        return $this;
72
    }
73
74
    /**
75
     * @inheritDoc
76
     */
77 3
    public function setComplimentary(): InvoiceServiceInterface
78
    {
79 3
        $this->is_comp = true;
80 3
        $this->is_free = false;
81
82 3
        return $this;
83
    }
84
85
    /**
86
     * @inheritDoc
87
     */
88 16
    public function addTaxPercentage(string $identifier, float $taxPercentage = 0): InvoiceServiceInterface
89
    {
90 16
        array_push($this->taxes, [
91 16
            'identifier' => $identifier,
92
            'tax_fixed' => null,
93 16
            'tax_percentage' => $taxPercentage,
94
        ]);
95 16
        return $this;
96
    }
97
98
    /**
99
     * @inheritDoc
100
     */
101 6
    public function addTaxFixed(string $identifier, int $taxFixed = 0): InvoiceServiceInterface
102
    {
103 6
        array_unshift($this->taxes, [
104 6
            'identifier' => $identifier,
105 6
            'tax_fixed' => $taxFixed,
106
            'tax_percentage' => null,
107
        ]);
108 6
        return $this;
109
    }
110
111
    /**
112
     * @inheritDoc
113
     */
114 8
    public function addAmountExclTax(Model $model, int $amount, string $description): InvoiceServiceInterface
115
    {
116 8
        $tax = 0;
117 8
        foreach ($this->taxes as $each) {
118 8
            $tax += (null === $each['tax_fixed']) ? $amount * $each['tax_percentage'] : $each['tax_fixed'];
119
        }
120
121 8
        $this->invoice->lines()->create([
122 8
            'amount' => $amount + $tax,
123 8
            'description' => $description,
124 8
            'tax' => $tax,
125 8
            'tax_details' => $this->taxes,
126 8
            'invoiceable_id' => $model->id,
127 8
            'invoiceable_type' => get_class($model),
128 8
            'is_free' => $this->is_free,
129 8
            'is_complimentary' => $this->is_comp,
130
        ]);
131
132 8
        $this->recalculate();
133
134 8
        return $this;
135
    }
136
137
    /**
138
     * @inheritDoc
139
     */
140 12
    public function addAmountInclTax(Model $model, int $amount, string $description): InvoiceServiceInterface
141
    {
142 12
        $exc = $amount;
143 12
        $tax = 0;
144 12
        foreach ($this->taxes as $each) {
145 12
            if (null !== $each['tax_fixed']) {
146 3
                $exc -= $each['tax_fixed'];
147 3
                $tax += $each['tax_fixed'];
148
            } else {
149 12
                $tax += ($exc * $each['tax_percentage']) / (1 + $each['tax_percentage']);
150
            }
151
        }
152
153 12
        $this->invoice->lines()->create([
154 12
            'amount' => $amount,
155 12
            'description' => $description,
156 12
            'tax' => $tax,
157 12
            'invoiceable_id' => $model->id,
158 12
            'invoiceable_type' => get_class($model),
159 12
            'is_free' => $this->is_free,
160 12
            'is_complimentary' => $this->is_comp,
161
        ]);
162
163 12
        $this->recalculate();
164
165 12
        return $this;
166
    }
167
168
    /**
169
     * @inheritDoc
170
     */
171 18
    public function recalculate(): Invoice
172
    {
173 18
        $lines = $this->getLines();
174 18
        $free = $lines->where('is_free', true)->toBase();
175 18
        $complimentary = $lines->where('is_complimentary', true)->toBase();
176 18
        $other = $lines->where('is_free', false)
177 18
            ->where('is_complimentary', false)
178 18
            ->toBase();
179
180 18
        $this->invoice->total = $other->sum('amount');
181 18
        $this->invoice->tax = $other->sum('tax');
182 18
        $this->invoice->discount = $free->sum('amount') + $complimentary->sum('amount') + $other->sum('discount');
183
184 18
        $this->invoice->save();
185
186 18
        $this->is_free = false;
187 18
        $this->is_comp = false;
188 18
        $this->taxes = [];
189
190 18
        return $this->invoice;
191
    }
192
193
    /**
194
     * @inheritDoc
195
     */
196 3
    public function view(array $data = []): \Illuminate\Contracts\View\View
197
    {
198 3
        return View::make('invoice::receipt', array_merge($data, [
199 3
            'invoice' => $this->invoice,
200 3
            'moneyFormatter' => new MoneyFormatter(
201 3
                $this->invoice->currency,
202 3
                config('invoice.locale')
203
            ),
204
        ]));
205
    }
206
207
    /**
208
     * @inheritDoc
209
     */
210 2
    public function pdf(array $data = []): string
211
    {
212 2
        if (!defined('DOMPDF_ENABLE_AUTOLOAD')) {
213
            define('DOMPDF_ENABLE_AUTOLOAD', false);
214
        }
215
216 2
        if (file_exists($configPath = base_path() . '/vendor/dompdf/dompdf/dompdf_config.inc.php')) {
217
            require_once $configPath;
218
        }
219
220 2
        $dompdf = new Dompdf;
221 2
        $dompdf->loadHtml($this->view($data)->render());
222 2
        $dompdf->render();
223 2
        return $dompdf->output();
224
    }
225
226
    /**
227
     * @inheritDoc
228
     */
229 1
    public function download(array $data = []): Response
230
    {
231 1
        $filename = $this->invoice->reference . '.pdf';
232
233 1
        return new Response($this->pdf($data), 200, [
234 1
            'Content-Description' => 'File Transfer',
235 1
            'Content-Disposition' => 'attachment; filename="' . $filename . '"',
236 1
            'Content-Transfer-Encoding' => 'binary',
237 1
            'Content-Type' => 'application/pdf',
238
        ]);
239
    }
240
241
    /**
242
     * @inheritDoc
243
     */
244 1
    public function findByReference(string $reference): ?Invoice
245
    {
246 1
        return Invoice::where('reference', $reference)->first();
247
    }
248
249
    /**
250
     * @inheritDoc
251
     */
252 2
    public function findByReferenceOrFail(string $reference): Invoice
253
    {
254 2
        return Invoice::where('reference', $reference)->firstOrFail();
255
    }
256
257
    /**
258
     * @inheritDoc
259
     */
260 1
    public function findByInvoiceable(Model $model): Collection
261
    {
262
        /*
263
         * In order to receive invoices by polymorphic relationship, we pluck invoice ids to find invoices.
264
         */
265 1
        $invoices = $model->invoiceLines()->get('invoice_id')->pluck('invoice_id')->unique();
266
267 1
        return Invoice::find($invoices);
268
    }
269
270
    /**
271
     * @inheritDoc
272
     */
273 1
    public function findByRelated(Model $model): Collection
274
    {
275 1
        return $model->invoices()->get();
276
    }
277
}
278