Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 33
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
StoreOrUpdateInputItemService
0.00% covered (danger)
0.00%
0 / 33
0.00% covered (danger)
0.00%
0 / 4
90
0.00% covered (danger)
0.00%
0 / 1
 execute
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
12
 populateItemDTO
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
12
 fetchProduct
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
6
 generateSeqMov
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace Domain\Item\Services;
4
5use App\Events\ServiceProcessed;
6use App\Models\Item\Item;
7use App\Models\Product\Product;
8use App\Models\StockIO\StockIO;
9use App\Models\User;
10use Carbon\Carbon;
11use Domain\Item\DTOs\ItemDTO;
12use Domain\Shared\Integrations\Senior\Exceptions\IntegrationSoapSeniorException;
13use Illuminate\Database\Eloquent\Builder;
14use Illuminate\Support\Facades\DB;
15use phpDocumentor\Reflection\Types\Collection;
16use Throwable;
17
18readonly class StoreOrUpdateInputItemService
19{
20
21    /**
22     * @throws Throwable
23     * @throws IntegrationSoapSeniorException
24     */
25    public function execute(StockIO $input, array $appointment, User $user, bool $sum = false): void
26    {
27        try {
28            DB::beginTransaction();
29
30            /** @var Collection|null $item */
31            $collection = $input->items;
32
33            $itemsDTO = $this->populateItemDTO($appointment, $input->items()->first(), $sum);
34            $collection->isEmpty() ?
35                (new ItemStoreService())->store($itemsDTO, $input, $user) :
36                (new ItemUpdateService())->update($itemsDTO, $collection->first(), $user);
37
38            DB::commit();
39        } catch (Throwable $throwable) {
40            DB::rollBack();
41            throw $throwable;
42        }
43
44        ServiceProcessed::dispatch(self::class, $user);
45    }
46
47    /**
48     * @param array $appointment
49     * @param Item|null $item
50     * @param bool $sum
51     * @return ItemDTO
52     * @throws IntegrationSoapSeniorException
53     */
54    private function populateItemDTO(array $appointment, ?Item $item, bool $sum = false): ItemDTO
55    {
56        $amount = $item?->getAttribute('amount') ?? $appointment['E210MVP_QTDMOV'];
57        if ($item && $sum) {
58            $amount += $appointment['E210MVP_QTDMOV'];
59        }
60
61        return new ItemDTO([
62            'target' => $this->fetchProduct($appointment['E210MVP_CODPRO'], $appointment['E210MVP_CODDER']),
63            'amount' => $amount,
64            'production_order' => $appointment['E210MVP_NUMDOC'],
65            'movement_date' => $appointment['E210MVP_DATMOV'],
66        ]);
67    }
68
69    /**
70     * @param string $codpro
71     * @param string $codder
72     * @return Product
73     * @throws IntegrationSoapSeniorException
74     */
75    private function fetchProduct(string $codpro, string $codder): Product
76    {
77        /** @var Product|null $product */
78        $product = Product::query()
79            ->whereHas('integration', function (Builder $query) use ($codpro, $codder) {
80                $query->where('parameters->integration_product', $codpro);
81                $query->where('parameters->integration_derivation', $codder);
82            })
83            ->first();
84
85        if (!$product) {
86            throw new IntegrationSoapSeniorException(__('Product :product with derivation :derivation not found!', [
87                'product' => $codpro,
88                'derivation' => $codder
89            ]));
90        }
91
92        return $product;
93    }
94
95    /**
96     * @param array $appointment
97     * @return string
98     */
99    private function generateSeqMov(array $appointment): string
100    {
101        return Carbon::create($appointment['E210MVP_DATMOV']) . '-' . $appointment['E210MVP_SEQMOV'];
102    }
103}