Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 56
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
MarkInvoiceItemsWithDisagreementService
0.00% covered (danger)
0.00%
0 / 56
0.00% covered (danger)
0.00%
0 / 2
72
0.00% covered (danger)
0.00%
0 / 1
 update
0.00% covered (danger)
0.00%
0 / 46
0.00% covered (danger)
0.00%
0 / 1
56
 processInvoiceActivetyLog
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace Domain\Invoice\Services;
4
5use Throwable;
6
7use Illuminate\Support\Facades\DB;
8
9use App\Events\ServiceProcessed;
10
11use App\Models\Invoice\Invoice;
12use App\Models\Invoice\InvoiceItem;
13use App\Models\User;
14
15use Domain\Invoice\DTOs\InvoiceItemsDisagreementDTO;
16use Domain\Invoice\DTOs\StoreInvoiceActivityLogDTO;
17
18use Domain\Invoice\Enums\InvoiceActivetyLogOperationEnum;
19use Domain\Invoice\Enums\InvoiceItemStatusEnum;
20use Domain\Invoice\Enums\InvoicePurchaseOrderStatusEnum;
21
22use Domain\Invoice\Exceptions\InvoicePendingException;
23use Domain\Invoice\Exceptions\InvoicePurchaseOrderValidatedException;
24use Domain\Invoice\Exceptions\NotExistsInvoiceVerificationException;
25
26readonly class MarkInvoiceItemsWithDisagreementService
27{
28    /**
29     * @param Invoice $invoice
30     * @param User $user
31     * @throws Throwable
32     */
33    public function update(InvoiceItemsDisagreementDTO $invoiceItemsDisagreementDTO, User $user): void
34    {
35        try {
36            DB::beginTransaction();
37
38                $invoiceItems = InvoiceItem::where('invoice_id', $invoiceItemsDisagreementDTO->invoice_id)
39                    ->where('status', InvoiceItemStatusEnum::PENDING)
40                    ->get();
41
42                $invoice = Invoice::find($invoiceItemsDisagreementDTO->invoice_id);
43
44                if ($invoiceItems->isEmpty()) {
45                    throw new NotExistsInvoiceVerificationException(
46                        __('There are no pending items related to this invoice.')
47                    );
48                }
49
50                if(!$invoice->isPending()){
51                    throw new InvoicePendingException(
52                        __('Invoice is not pending')
53                    );
54                }
55
56                if($invoice->isValidatedPurchaseOrder()){
57                    throw new InvoicePurchaseOrderValidatedException(
58                        __('Invoice purchase order is validated.')
59                    );
60                }
61
62                $itemArrayDetails = [];
63                foreach($invoiceItems as $item){
64                    $item->status = InvoiceItemStatusEnum::WITH_DISAGREEMENT;
65                    $item->save();
66
67                    array_push($itemArrayDetails, $item->toJson(JSON_PRETTY_PRINT));
68                }
69
70                if ($invoice->purchase_order_status !== InvoicePurchaseOrderStatusEnum::WITH_DISAGREEMENT) {
71                    $invoice->purchase_order_status  = InvoicePurchaseOrderStatusEnum::WITH_DISAGREEMENT;
72
73                    $invoice->save();
74
75                    $this->processInvoiceActivetyLog(
76                        $invoice,
77                        Invoice::class,
78                        $invoice->getKey(),
79                        $user,
80                        $invoiceItemsDisagreementDTO->observation,
81                        $invoice->getAttributes()
82                    );
83
84                    $this->processInvoiceActivetyLog(
85                        $invoice,
86                        InvoiceItem::class,
87                        0,
88                        $user,
89                        $invoiceItemsDisagreementDTO->observation,
90                        $itemArrayDetails
91                    );
92                }
93
94            DB::commit();
95        } catch (Throwable $exception) {
96            DB::rollBack();
97            throw $exception;
98        }
99
100        ServiceProcessed::dispatch(self::class, $user);
101    }
102
103    private function processInvoiceActivetyLog(
104        Invoice $invoice,
105        string $entity_type,
106        int $entity_id,
107        User $user,
108        string $observation,
109        array $details
110    ) {
111        $invoiceActivityLogDTO = new StoreInvoiceActivityLogDTO([
112            'entity_type' => $entity_type,
113            'entity_id'   => $entity_id,
114            'operation'   => InvoiceActivetyLogOperationEnum::UPDATE,
115            'user'        => $user,
116            'detail'      => json_encode($details),
117            'observation' => $observation
118            ]
119        );
120
121        (new InvoiceActivityLogStoreService())->store($invoiceActivityLogDTO, $invoice, $user);
122    }
123}