Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
91.18% covered (success)
91.18%
31 / 34
0.00% covered (danger)
0.00%
0 / 1
CRAP
0.00% covered (danger)
0.00%
0 / 1
SplitInvoiceItemService
91.18% covered (success)
91.18%
31 / 34
0.00% covered (danger)
0.00%
0 / 1
8.04
0.00% covered (danger)
0.00%
0 / 1
 split
91.18% covered (success)
91.18%
31 / 34
0.00% covered (danger)
0.00%
0 / 1
8.04
1<?php
2
3namespace Domain\Invoice\Services;
4
5use App\Models\Invoice\InvoiceItem;
6use Domain\Invoice\DTOs\SeniorProcessInvoiceItemDivisionDTO;
7use Domain\Invoice\Exceptions\InvoiceItemAmountExceedException;
8use Domain\Shared\Integrations\Senior\SeniorProcessInvoiceItemDivision;
9
10readonly class SplitInvoiceItemService
11{
12    /**
13     * @throws InvoiceItemAmountExceedException
14     */
15    public function split(InvoiceItem $invoiceItem, array $items): void
16    {
17        $additionalAmounts = collect($items)
18            ->map(fn (array $item) => (float) ($item['amount'] ?? 0))
19            ->values();
20
21        if ($additionalAmounts->isEmpty()) {
22            throw new InvoiceItemAmountExceedException(__('At least one additional amount is required'));
23        }
24
25        if ($additionalAmounts->contains(fn (float $amount) => $amount <= 0)) {
26            throw new InvoiceItemAmountExceedException(__('The informed amount must be greater than zero'));
27        }
28
29        $invoiceAmount = round((float) $invoiceItem->getAmount(), 2);
30        $additionalTotal = round((float) $additionalAmounts->sum(), 2);
31
32        if ($additionalTotal >= $invoiceAmount) {
33            throw new InvoiceItemAmountExceedException(__('The informed amount exceeds the amount of invoice item'));
34        }
35
36        $invoice = $invoiceItem->invoice()->with('integration')->first();
37        $invoiceItem->loadMissing('integration');
38
39        $invoiceParameters = $invoice?->integration?->parameters ?? [];
40        $invoiceItemParameters = $invoiceItem->integration?->parameters ?? [];
41
42        $codEmp = $invoiceParameters['codEmp'] ?? $invoiceParameters['CODEMP'] ?? null;
43        $codFil = $invoiceParameters['codFil'] ?? $invoiceParameters['CODFIL'] ?? null;
44        $chvNel = $invoiceParameters['chvNel'] ?? $invoiceParameters['CHVNEL'] ?? $invoice?->getAttribute('key');
45        $seqIpc = $invoiceItemParameters['seqIpc'] ?? $invoiceItemParameters['SEQIPC'] ?? null;
46
47        if ($codEmp === null || $codFil === null || $chvNel === null || $seqIpc === null) {
48            throw new InvoiceItemAmountExceedException(__('Could not process invoice item division due missing integration parameters'));
49        }
50
51        $divisionItems = $additionalAmounts
52            ->map(fn (float $amount) => ['qtdIte' => $amount])
53            ->values()
54            ->all();
55
56        app(SeniorProcessInvoiceItemDivision::class)->execute(
57            new SeniorProcessInvoiceItemDivisionDTO([
58                'codEmp' => $codEmp,
59                'codFil' => $codFil,
60                'chvNel' => $chvNel,
61                'seqIpc' => $seqIpc,
62                'itens' => $divisionItems,
63            ])
64        );
65    }
66}
67