Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
82.61% covered (warning)
82.61%
19 / 23
33.33% covered (danger)
33.33%
1 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
TransferTaskUpdateService
82.61% covered (warning)
82.61%
19 / 23
33.33% covered (danger)
33.33%
1 / 3
5.13
0.00% covered (danger)
0.00%
0 / 1
 update
76.92% covered (warning)
76.92%
10 / 13
0.00% covered (danger)
0.00%
0 / 1
2.05
 processTransferTaskProducts
83.33% covered (warning)
83.33%
5 / 6
0.00% covered (danger)
0.00%
0 / 1
2.02
 destroyRemovedTransferTaskProducts
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace Domain\TransferTask\Services;
4
5use App\Events\ServiceProcessed;
6use App\Models\TransferTask\TransferTask;
7use App\Models\TransferTask\TransferTaskProduct;
8use App\Models\User;
9use Domain\TransferTask\DTOs\TransferTaskDTO;
10use Domain\TransferTask\DTOs\TransferTaskProductDTO;
11use Illuminate\Support\Facades\DB;
12use Throwable;
13
14readonly class TransferTaskUpdateService
15{
16
17    /**
18     * @param TransferTaskDTO $taskDTO
19     * @param TransferTask $transferTask
20     * @param User $user
21     * @return TransferTask
22     * @throws Throwable
23     */
24    public function update(TransferTaskDTO $taskDTO, TransferTask $transferTask, User $user): TransferTask
25    {
26        try {
27            DB::beginTransaction();
28
29            $transferTask->fill($taskDTO->toArray());
30            $transferTask->responsible()->associate($taskDTO->responsible);
31            $transferTask->team()->associate($taskDTO->team);
32            $transferTask->save();
33
34            $this->destroyRemovedTransferTaskProducts($taskDTO, $transferTask);
35            $this->processTransferTaskProducts($taskDTO, $transferTask, $user);
36
37            DB::commit();
38        } catch (Throwable $throwable) {
39            DB::rollBack();
40            throw $throwable;
41        }
42
43        ServiceProcessed::dispatch(self::class, $user);
44        return $transferTask;
45    }
46
47    /**
48     * @param TransferTaskDTO $taskDTO
49     * @param TransferTask $transferTask
50     * @param User $user
51     * @return void
52     * @throws Throwable
53     */
54    private function processTransferTaskProducts(TransferTaskDTO $taskDTO, TransferTask $transferTask, User $user): void
55    {
56        $taskDTO->products->each(function (TransferTaskProductDTO $transferTaskProductDTO) use ($transferTask, $user) {
57            /** @var TransferTaskProduct|null $transferTaskProduct */
58            $transferTaskProduct = $transferTask->TransferTaskProducts()->where('product_id', $transferTaskProductDTO->product->getKey())->first();
59
60            $transferTaskProduct ?
61                (new TransferTaskProductUpdateService())->update($transferTaskProductDTO, $transferTaskProduct, $user) :
62                (new TransferTaskProductStoreService())->store($transferTaskProductDTO, $transferTask, $user);
63        });
64    }
65
66    /**
67     * @param TransferTaskDTO $taskDTO
68     * @param TransferTask $transferTask
69     * @return void
70     */
71    private function destroyRemovedTransferTaskProducts(TransferTaskDTO $taskDTO, TransferTask $transferTask): void
72    {
73        $existingProductIds = $taskDTO->products->map(fn(TransferTaskProductDTO $dto) => $dto->product->getKey());
74        $transferTask->TransferTaskProducts()
75            ->whereNotIn('product_id', $existingProductIds)
76            ->delete();
77    }
78}