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

BillService   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 249
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 95
dl 0
loc 249
rs 10
c 0
b 0
f 0
wmc 22

16 Methods

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