Passed
Push — master ( 117e72...a20c82 )
by Vinicius Lourenço
03:37
created

Scheduler::isShouldntAdd()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 4
1
<?php namespace H4ad\Scheduler;
2
3
/**
4
 * Esse arquivo faz parte do Scheduler,
5
 * uma biblioteca para auxiliar com agendamentos.
6
 *
7
 * @license MIT
8
 * @package H4ad\Scheduler
9
 */
10
11
use Illuminate\Support\Carbon;
12
use H4ad\Scheduler\Models\Schedule;
13
use Illuminate\Support\Facades\Config;
14
15
class Scheduler
16
{
17
    /**
18
     * Laravel application
19
     *
20
     * @var \Illuminate\Foundation\Application
21
     */
22
    public $app;
23
24
    /**
25
     * Create a new confide instance.
26
     *
27
     * @param \Illuminate\Foundation\Application $app
28
     *
29
     * @return void
30
     */
31
    public function __construct($app)
32
    {
33
        $this->app = $app;
34
    }
35
36
    /**
37
     * Escopo de uma consulta que busca horarios pela data de início.
38
     *
39
     * @param string $model_type
40
     * @param string|\Carbon\Carbon $start_at
41
     * @param string|\Carbon\Carbon $end_at
42
     * @return bool
43
     */
44
    public function hasScheduleBetween($model_type, $start_at, $end_at)
45
    {
46
        if(!Config::get('scheduler.enable_schedule_conflict'))
47
            return false;
48
49
        return !is_null(
50
            Schedule::latest()
51
                ->where('model_type', $model_type)
52
                ->where('start_at', '>=', $start_at)
53
                ->where('end_at', '<=', $end_at)
54
                ->first()
55
        );
56
    }
57
58
    /**
59
     * Retorna os horários disponiveis hoje para uma determinada model.
60
     * .
61
     * @param  string  $model_type Tipo da model
62
     * @param  int    $duration Serve para facilitar na hora de buscar horários livres
63
     *                          que precisem ter uma certa duração.
64
     * @param \Carbon\Carbon|null $openingTime Serve como referencia para buscar horários livres.
65
     *                                         Se for nulo, ele busca a referencia da config.
66
     * @return array
67
     */
68
    public function availableToday($model_type, $duration, $openingTime = null)
69
    {
70
        return $this->availableOn($model_type, Carbon::now(), $duration, $openingTime);
71
    }
72
73
    /**
74
     * Retorna os horários disponiveis em um determinado dia para uma certa model.
75
     *
76
     * @param  string  $model_type Tipo da model
77
     * @param  \Carbon\Carbon $today Data para o qual ele irá fazer a busca.
78
     * @param  int    $durationMinutes Serve para facilitar na hora de buscar horários livres
79
     *                          que precisem ter uma certa duração.
80
     * @param \Carbon\Carbon|null $openingTime Serve como referencia para buscar horários livres.
81
     *                                         Se for nulo, ele busca a referencia da config.
82
     * @return array
83
     */
84
    public function availableOn($model_type, $today, $durationMinutes, $openingTime = null)
85
    {
86
        $openingTime = $openingTime ?? Carbon::parse(Config::get('scheduler.opening_time'))->setDateFrom($today);
87
        $closingTime = Carbon::parse(Config::get('scheduler.closing_time'))->setDateFrom($today);
88
89
        $livres = [];
90
        $today = Carbon::parse($today->toDateString());
91
        while($openingTime <= $closingTime)
92
        {
93
            $add = true;
94
95
            $opening = Carbon::parse($openingTime->toDateTimeString());
96
            $closing = Carbon::parse($openingTime->toDateTimeString())->addMinutes($durationMinutes);
97
98
            foreach (Schedule::orderBy('start_at', 'DESC')->cursor() as $schedule) {
99
            	if($schedule->model_type != $model_type)
100
            		continue;
101
102
                $start = Carbon::parse($schedule->start_at);
103
                $begin = Carbon::parse($start->toDateString());
104
105
                if($begin->greaterThan($today))
106
                    break;
107
108
                if($begin->notEqualTo($today))
109
                    continue;
110
111
                $end = Carbon::parse($schedule->end_at);
112
113
                if($this->isShouldntAdd($opening, $closing, $start, $end))
114
                    $add = false;
115
            }
116
117
            if($add && $closing->lessThanOrEqualTo($closingTime))
118
                $livres[] = [
119
                    'start_at' => $opening,
120
                    'end_at' => $closing
121
                ];
122
123
            $openingTime->addMinutes($durationMinutes);
124
        }
125
126
        return $livres;
127
    }
128
129
    /**
130
     * Verifica se ele não deve ser adicionado ao array de horários livres.
131
     *
132
     * @param  \Carbon\Carbon  $opening
133
     * @param  \Carbon\Carbon  $closing
134
     * @param  \Carbon\Carbon  $start
135
     * @param  \Carbon\Carbon  $end
136
     * @return boolean
137
     */
138
    private function isShouldntAdd($opening, $closing, $start, $end)
139
    {
140
        return $start <= $opening && $end >= $closing;
141
    }
142
}