FundSessionsValidator::validateDates()   B
last analyzed

Complexity

Conditions 8
Paths 20

Size

Total Lines 43
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 8
eloc 24
c 1
b 0
f 0
nc 20
nop 2
dl 0
loc 43
rs 8.4444
1
<?php
2
3
namespace Siak\Tontine\Validation\Planning;
4
5
use Illuminate\Support\Facades\Validator;
6
use Illuminate\Validation\Validator as RealValidator;
7
use Siak\Tontine\Service\Planning\FundService;
8
use Siak\Tontine\Validation\AbstractValidator;
9
use Siak\Tontine\Validation\ValidationException;
10
11
use function array_map;
12
use function jaxon;
13
14
class FundSessionsValidator extends AbstractValidator
15
{
16
    /**
17
     * @param FundService $fundService
18
     */
19
    public function __construct(private FundService $fundService)
20
    {}
21
22
    /**
23
     * @param RealValidator $validator
24
     * @param array $errors
25
     *
26
     * @return void
27
     */
28
    private function validateDates(RealValidator $validator, array $errors): void
29
    {
30
        $stash = jaxon()->di()->getStash();
31
        $guild = $stash->get('tenant.guild');
32
        $fund = $stash->get('planning.fund');
33
34
        $sessions = [
35
            'start_sid' => $fund->start,
36
            'end_sid' => $fund->end,
37
            'interest_sid' => $fund->interest,
38
        ];
39
40
        $values = $validator->validated();
41
        $allSessionsFound = true;
42
        foreach($errors as $key => $message)
43
        {
44
            if(!isset($values[$key]))
45
            {
46
                continue;
47
            }
48
            $sessions[$key] = $this->fundService
49
                ->getGuildSession($guild, (int)$values[$key]);
50
            if(!$sessions[$key])
51
            {
52
                $allSessionsFound = false;
53
                $validator->errors()->add($key, $message);
54
            }
55
        }
56
        if(!$allSessionsFound)
57
        {
58
            return;
59
        }
60
61
        // Verify that the start session comes before the end session.
62
        if($sessions['end_sid']->day_date <= $sessions['start_sid']->day_date)
63
        {
64
            $validator->errors()->add('end_sid', trans('tontine.session.errors.dates.end'));
65
        }
66
        // Verify that the interest session is between the start and end sessions.
67
        if($sessions['interest_sid']->day_date <= $sessions['start_sid']->day_date ||
68
            $sessions['interest_sid']->day_date > $sessions['end_sid']->day_date)
69
        {
70
            $validator->errors()->add('interest_sid', trans('tontine.session.errors.dates.int'));
71
        }
72
    }
73
74
    /**
75
     * @param array $values
76
     *
77
     * @return array
78
     */
79
    public function validateItem(array $values): array
80
    {
81
        $rules = [
82
            'start_sid' => 'required_without_all:end_sid,interest_sid|integer|min:1',
83
            'end_sid' => 'required_without_all:start_sid,interest_sid|integer|min:1',
84
            'interest_sid' => 'required_without_all:start_sid,end_sid|integer|min:1',
85
        ];
86
        $errors = [
87
            'start_sid' => trans('tontine.session.errors.start'),
88
            'end_sid' => trans('tontine.session.errors.end'),
89
            'interest_sid' => trans('tontine.session.errors.interest'),
90
        ];
91
        $validator = Validator::make($this->values($values), $rules, $errors);
92
        $validator->after(function($validator) use($errors) {
93
            // No more check if there's already an error.
94
            if($validator->errors()->count() === 0)
95
            {
96
                $this->validateDates($validator, $errors);
97
            }
98
        });
99
100
        if($validator->fails())
101
        {
102
            throw new ValidationException($validator);
103
        }
104
105
        return array_map(fn($sid) => (int)$sid, $validator->validated());
106
    }
107
}
108