Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
95.24% covered (success)
95.24%
40 / 42
33.33% covered (danger)
33.33%
1 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
ProcessStatusStockIOService
95.24% covered (success)
95.24%
40 / 42
33.33% covered (danger)
33.33%
1 / 3
16
0.00% covered (danger)
0.00%
0 / 1
 process
95.00% covered (success)
95.00%
19 / 20
0.00% covered (danger)
0.00%
0 / 1
4
 resolveInputStatus
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
4
 resolveOutputStatus
93.75% covered (success)
93.75%
15 / 16
0.00% covered (danger)
0.00%
0 / 1
8.02
1<?php
2
3namespace Domain\StockIO\Services;
4
5use App\Events\ServiceProcessed;
6use App\Models\StockIO\StockIO;
7use App\Models\User;
8
9use Domain\StockIO\Enums\StockProductStatusEnum;
10use Domain\StockIO\Enums\StockStatusEnum;
11
12readonly class ProcessStatusStockIOService
13{
14    /**
15     * @param StockIO $stockIO
16     * @param User $user
17     * @return StockIO
18     */
19    public function process(StockIO $stockIO, User $user): StockIO
20    {
21        if ($stockIO->status === StockStatusEnum::CANCELED) {
22            return $stockIO;
23        }
24
25        $statusCounts = $stockIO->stockIOProducts()
26            ->selectRaw('status, COUNT(*) as total')
27            ->groupBy('status')
28            ->pluck('total', 'status');
29
30        $get = fn($status) => $statusCounts[$status] ?? 0;
31
32        $countAll = $statusCounts
33            ->reject(function ($_, $status) {
34                return $status == StockProductStatusEnum::CANCELED->value;
35            })
36            ->sum();
37
38        $status = $stockIO->isInput()
39            ? $this->resolveInputStatus($stockIO, $countAll, $get)
40            : $this->resolveOutputStatus($countAll, $get);
41
42        if ($status) {
43            $stockIO->setAttribute('status', $status);
44            $stockIO->save();
45        }
46
47        ServiceProcessed::dispatch(self::class, $user);
48        return $stockIO;
49    }
50
51    private function resolveInputStatus(StockIO $stockIO, int $countAll, callable $get): StockStatusEnum
52    {
53        $concluded = $get(StockProductStatusEnum::CONCLUDED->value);
54
55        if ($countAll > 0 && $concluded === $countAll) {
56            return StockStatusEnum::CONCLUDED;
57        }
58
59        return $stockIO->status === StockStatusEnum::STARTED
60            ? StockStatusEnum::STARTED
61            : StockStatusEnum::PENDING;
62    }
63
64    private function resolveOutputStatus(int $countAll, callable $get): StockStatusEnum
65    {
66        $delivered        = $get(StockProductStatusEnum::CONCLUDED->value);
67        $deliveredPartial = $get(StockProductStatusEnum::DELIVERED_PARTIAL->value);
68        $fulfilledPartial = $get(StockProductStatusEnum::PARTIAL_FULFILLED->value);
69        $separated        = $get(StockProductStatusEnum::SEPARATED->value);
70        $separatedPartial = $get(StockProductStatusEnum::SEPARATED_PARTIAL->value);
71
72        if ($delivered > 0 || $deliveredPartial > 0) {
73            return ($delivered === $countAll)
74                ? StockStatusEnum::CONCLUDED
75                : StockStatusEnum::DELIVERED_PARTIAL;
76        }
77
78        if ($fulfilledPartial > 0) {
79            return StockStatusEnum::PARTIAL_FULFILLED;
80        }
81
82        if ($separated > 0 || $separatedPartial > 0) {
83            return ($separated === $countAll)
84                ? StockStatusEnum::SEPARATED
85                : StockStatusEnum::SEPARATED_PARTIAL;
86        }
87
88        return StockStatusEnum::PENDING;
89    }
90}