Passed
Pull Request — master (#11)
by Fatih
04:48
created

InvoiceService::findByRelated()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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