Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
94.44% covered (success)
94.44%
51 / 54
66.67% covered (warning)
66.67%
2 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
StockIOProductUpdateService
94.44% covered (success)
94.44%
51 / 54
66.67% covered (warning)
66.67%
2 / 3
12.02
0.00% covered (danger)
0.00%
0 / 1
 update
82.35% covered (warning)
82.35%
14 / 17
0.00% covered (danger)
0.00%
0 / 1
4.09
 verifyProductAmount
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
6
 notifyUsers
100.00% covered (success)
100.00%
24 / 24
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3namespace Domain\StockIO\Services;
4
5use App\Events\ServiceProcessed;
6use App\Models\PickingOrder\PickingOrder;
7use App\Models\StockIO\StockIOProduct;
8use App\Models\User;
9use App\Notifications\StockIOProductAmountChangedNotification;
10use Domain\Integration\Services\IntegrationUpdateService;
11use Domain\StockIO\DTOs\StockIOProductDTO;
12use Domain\PickingOrder\Enums\PickingOrderStatusEnum;
13use Domain\Shared\Enums\SectorEnum;
14//use Domain\Shared\Services\SendNotificationUserExpo;
15use Domain\User\Enums\AccessLevel;
16use Illuminate\Support\Facades\DB;
17use Throwable;
18
19readonly class StockIOProductUpdateService
20{
21    /**
22     * @param StockIOProductDTO $stockIOProductDTO
23     * @param StockIOProduct $stockIOProduct
24     * @param User $user
25     * @return void
26     * @throws Throwable
27     */
28    public function update(StockIOProductDTO $stockIOProductDTO, StockIOProduct $stockIOProduct, User $user): void
29    {
30        try {
31            DB::beginTransaction();
32
33            $this->verifyProductAmount($stockIOProductDTO, $stockIOProduct);
34
35            $stockIOProduct->setAttribute('status', $stockIOProductDTO->status);
36
37            if(!$stockIOProduct->isPicked()){
38                $stockIOProduct->setAttribute('amount', $stockIOProductDTO->amount);
39            }
40
41            $stockIOProduct->save();
42
43            if ($stockIOProductDTO->dataTransferObject) {
44                (new IntegrationUpdateService())->update(
45                    $stockIOProductDTO->dataTransferObject,
46                    $stockIOProduct->integration,
47                    $user
48                );
49            }
50
51            DB::commit();
52        } catch (Throwable $throwable) {
53            DB::rollBack();
54            throw $throwable;
55        }
56
57        ServiceProcessed::dispatch(self::class, $user);
58    }
59
60    private function verifyProductAmount(StockIOProductDTO $stockIOProductDTO, StockIOProduct $stockIOProduct)
61    {
62        if((round($stockIOProductDTO->amount, 2) <> round($stockIOProduct->getAttribute('amount'), 2)) &&
63           ($stockIOProduct->pickingOrderProduct()->exists()))
64        {
65            $pickingOrderProduct = $stockIOProduct->pickingOrderProduct;
66
67            if(!$pickingOrderProduct->pickingOrder->isConcluded() && !$pickingOrderProduct->pickingOrder->isSeparated())
68            {
69                if(!$stockIOProduct->isPicked()){
70                    $oldAmount = $stockIOProduct->getAttribute('amount');
71
72                    $stockIOProduct->setAttribute('amount', $stockIOProductDTO->amount);
73                    $stockIOProduct->save();
74
75                    $this->notifyUsers($pickingOrderProduct->pickingOrder, $stockIOProduct, $oldAmount, $stockIOProductDTO->amount);
76
77                    $pickingOrderProduct->setAttribute('status', PickingOrderStatusEnum::PENDING);
78                    $pickingOrderProduct->pickingOrder->setAttribute('status', PickingOrderStatusEnum::STARTED);
79                    $pickingOrderProduct->save();
80                    $pickingOrderProduct->pickingOrder->save();
81                }
82            }
83        }
84    }
85
86    private function notifyUsers(PickingOrder $pickingOrder, StockIOProduct $stockIOProduct, float $oldAmount, float $newAmount)
87    {
88        $users = DB::table('users')
89            ->leftJoin('team_user', 'users.id', '=', 'team_user.user_id')
90            ->where(function ($query) use ($pickingOrder, $stockIOProduct) {
91                $query->where(function ($subQuery) use ($stockIOProduct) {
92                    $subQuery->whereRaw('EXISTS (
93                                SELECT 1
94                                  FROM jsonb_each(users.access_level) AS s(key, value)
95                                    JOIN jsonb_array_elements_text(value) AS level ON TRUE
96                                 WHERE level::int IN (?, ?)
97                                   AND key::int = ?
98                    )', [AccessLevel::ADMIN->value, AccessLevel::MASTER->value, SectorEnum::EXPEDITION->value])
99                    ->where('team_user.team_id', $stockIOProduct->stockIO->team->getKey());
100                })
101                ->orWhere('users.id', $pickingOrder->getAttribute('responsible_id'));
102            })
103            ->select('users.id')
104            ->get();
105
106        $numAne = $stockIOProduct->stockIO->integration->getAttribute('parameters')['NUMANE'];
107        $numPfa = $stockIOProduct->stockIO->integration->getAttribute('parameters')['NUMPFA'];
108        $productCode = $stockIOProduct->product->integration->getAttribute('parameters')['integration_code'];
109
110        foreach($users as $user){
111            $user = (User::find($user->id));
112            $user?->notify(new StockIOProductAmountChangedNotification(
113                $numAne,
114                $numPfa,
115                $productCode,
116                $oldAmount,
117                $newAmount
118            ));
119
120            // if(!is_null($user->getAttribute('expo_token'))){
121            //     (new SendNotificationUserExpo())->send(
122            //         __('The product :product of pre-invoice :preInvoice, has been changed the amount. Previous amount :oldAmount, new amount :newAmount',
123            //             [
124            //                 'preInvoice' => $numAne.'/'.$numPfa,
125            //                 'product'    => $productCode,
126            //                 'oldAmount'  => $oldAmount,
127            //                 'newAmount'  => $newAmount
128            //             ]
129            //         ),
130            //         __('Product amount change'),
131            //         $user
132            //     );
133            // }
134        }
135    }
136}