Completed
Push — master ( a07cb6...d9a68a )
by Ariel
14:19 queued 05:51
created

Appointment   B

Complexity

Total Complexity 43

Size/Duplication

Total Lines 475
Duplicated Lines 3.37 %

Coupling/Cohesion

Components 2
Dependencies 2

Test Coverage

Coverage 85.19%

Importance

Changes 11
Bugs 2 Features 0
Metric Value
wmc 43
c 11
b 2
f 0
lcom 2
cbo 2
dl 16
loc 475
ccs 92
cts 108
cp 0.8519
rs 8.3157

31 Methods

Rating   Name   Duplication   Size   Complexity  
A save() 0 6 1
A issuer() 0 4 1
A contact() 0 4 1
A business() 0 4 1
A service() 0 4 1
A vacancy() 0 4 1
A user() 0 4 1
A duplicates() 0 4 1
A getHashAttribute() 0 6 2
A getFinishAtAttribute() 0 12 3
A getPresenterClass() 0 4 1
A getDateAttribute() 0 6 1
A doHash() 0 9 1
A setStartAtAttribute() 0 4 1
A setFinishAtAttribute() 0 4 1
A setCommentsAttribute() 0 4 2
A isReserved() 0 4 1
A isPending() 0 4 2
A scopeUnServed() 0 4 1
A scopeActive() 0 4 1
B scopeAffectingInterval() 16 24 1
A isServeable() 0 4 2
A isConfirmable() 0 4 2
A isAnnulable() 0 4 1
A doReserve() 0 8 2
A doConfirm() 0 10 2
A doAnnulate() 0 10 2
A doServe() 0 10 2
A isActive() 0 6 2
A isFuture() 0 4 1
A isDue() 0 4 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Appointment often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Appointment, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Timegridio\Concierge\Models;
4
5
use Carbon\Carbon;
6
use Illuminate\Database\Eloquent\Model as EloquentModel;
7
use McCool\LaravelAutoPresenter\HasPresenter;
8
use Timegridio\Concierge\Presenters\AppointmentPresenter;
9
10
/**
11
 * An Appointment can be understood as a reservation of a given Service,
12
 * provided by a given Business, targeted to a Contact, which will take place
13
 * on a determined Date and Time, and might have a duration and or comments.
14
 *
15
 * The Appointment can be issued by the Contact's User or by the Business owner.
16
 */
17
class Appointment extends EloquentModel implements HasPresenter
18
{
19
    /**
20
     * The attributes that are mass assignable.
21
     *
22
     * @var array
23
     */
24
    protected $fillable = ['issuer_id', 'contact_id', 'business_id',
25
        'service_id', 'start_at', 'finish_at', 'duration', 'comments', ];
26
27
    /**
28
     * The attributes that aren't mass assignable.
29
     *
30
     * @var array
31
     */
32
    protected $guarded = ['id', 'hash', 'status', 'vacancy_id'];
33
34
    /**
35
     * The attributes that should be mutated to dates.
36
     *
37
     * @var array
38
     */
39
    protected $dates = ['start_at', 'finish_at'];
40
41
    /**
42
     * Appointment Hard Status Constants.
43
     */
44
    const STATUS_RESERVED = 'R';
45
    const STATUS_CONFIRMED = 'C';
46
    const STATUS_ANNULATED = 'A';
47
    const STATUS_SERVED = 'S';
48
49
    ///////////////
50
    // PRESENTER //
51
    ///////////////
52
53
    /**
54
     * Get Presenter Class.
55
     *
56
     * @return App\Presenters\AppointmentPresenter
57
     */
58 1
    public function getPresenterClass()
59
    {
60 1
        return AppointmentPresenter::class;
61
    }
62
63
    /**
64
     * Generate hash and save the model to the database.
65
     *
66
     * @param array $options
67
     *
68
     * @return bool
69
     */
70 24
    public function save(array $options = [])
71
    {
72 24
        $this->doHash();
73
74 24
        return parent::save($options);
75
    }
76
77
    ///////////////////
78
    // Relationships //
79
    ///////////////////
80
81
    /**
82
     * Get the issuer (the User that generated the Appointment).
83
     *
84
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
85
     */
86 4
    public function issuer()
87
    {
88 4
        return $this->belongsTo(config('auth.providers.users.model'));
89
    }
90
91
    /**
92
     * Get the target Contact (for whom is reserved the Appointment).
93
     *
94
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
95
     */
96 4
    public function contact()
97
    {
98 4
        return $this->belongsTo(Contact::class);
99
    }
100
101
    /**
102
     * Get the holding Business (that has taken the reservation).
103
     *
104
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
105
     */
106 8
    public function business()
107
    {
108 8
        return $this->belongsTo(Business::class);
109
    }
110
111
    /**
112
     * Get the reserved Service.
113
     *
114
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
115
     */
116 8
    public function service()
117
    {
118 8
        return $this->belongsTo(Service::class);
119
    }
120
121
    /**
122
     * Get the Vacancy (that justifies the availability of resources for the
123
     * Appointment generation).
124
     *
125
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
126
     */
127 5
    public function vacancy()
128
    {
129 5
        return $this->belongsTo(Vacancy::class);
130
    }
131
132
    ///////////
133
    // Other //
134
    ///////////
135
136
    /**
137
     * Get the User through Contact.
138
     *
139
     * @return User
140
     */
141 2
    public function user()
142
    {
143 2
        return $this->contact->user;
0 ignored issues
show
Documentation introduced by
The property contact does not exist on object<Timegridio\Concierge\Models\Appointment>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
144
    }
145
146
    /**
147
     * Determine if the new Appointment will hash-crash with another existing
148
     * Appointment.
149
     *
150
     * @return bool
151
     */
152 5
    public function duplicates()
153
    {
154 5
        return !self::where('hash', $this->hash)->get()->isEmpty();
0 ignored issues
show
Documentation introduced by
The property hash does not exist on object<Timegridio\Concierge\Models\Appointment>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
155
    }
156
157
    ///////////////
158
    // Accessors //
159
    ///////////////
160
161
    /**
162
     * Get Hash.
163
     *
164
     * @return string
165
     */
166 5
    public function getHashAttribute()
167
    {
168 5
        return isset($this->attributes['hash'])
169 5
            ? $this->attributes['hash']
170 5
            : $this->doHash();
171
    }
172
173
    /**
174
     * Get Finish At:
175
     * Calculates the start_at time plus duration in minutes.
176
     *
177
     * @return Carbon
178
     */
179 1
    public function getFinishAtAttribute()
180
    {
181 1
        if (array_get($this->attributes, 'finish_at') !== null) {
182
            return Carbon::parse($this->attributes['finish_at']);
183
        }
184
185 1
        if (is_numeric($this->duration)) {
0 ignored issues
show
Documentation introduced by
The property duration does not exist on object<Timegridio\Concierge\Models\Appointment>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
186 1
            return $this->start_at->addMinutes($this->duration);
0 ignored issues
show
Documentation introduced by
The property start_at does not exist on object<Timegridio\Concierge\Models\Appointment>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
Documentation introduced by
The property duration does not exist on object<Timegridio\Concierge\Models\Appointment>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
187
        }
188
189
        return $this->start_at;
0 ignored issues
show
Documentation introduced by
The property start_at does not exist on object<Timegridio\Concierge\Models\Appointment>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
190
    }
191
192
    /**
193
     * Get the date of the Appointment.
194
     *
195
     * @return string
196
     */
197 3
    public function getDateAttribute()
198
    {
199 3
        return $this->start_at
0 ignored issues
show
Documentation introduced by
The property start_at does not exist on object<Timegridio\Concierge\Models\Appointment>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
200 3
                    ->timezone($this->business->timezone)
0 ignored issues
show
Documentation introduced by
The property business does not exist on object<Timegridio\Concierge\Models\Appointment>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
201 3
                    ->toDateString();
202
    }
203
204
    //////////////
205
    // Mutators //
206
    //////////////
207
208
    /**
209
     * Generate Appointment hash.
210
     *
211
     * @return string
212
     */
213 24
    public function doHash()
214
    {
215 24
        return $this->attributes['hash'] = md5(
216 24
            $this->start_at.'/'.
0 ignored issues
show
Documentation introduced by
The property start_at does not exist on object<Timegridio\Concierge\Models\Appointment>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
217 24
            $this->contact_id.'/'.
0 ignored issues
show
Documentation introduced by
The property contact_id does not exist on object<Timegridio\Concierge\Models\Appointment>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
218 24
            $this->business_id.'/'.
0 ignored issues
show
Documentation introduced by
The property business_id does not exist on object<Timegridio\Concierge\Models\Appointment>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
219 24
            $this->service_id
0 ignored issues
show
Documentation introduced by
The property service_id does not exist on object<Timegridio\Concierge\Models\Appointment>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
220 24
        );
221
    }
222
223
    /**
224
     * Set start at.
225
     *
226
     * @param Carbon $datetime
227
     */
228 24
    public function setStartAtAttribute(Carbon $datetime)
229
    {
230 24
        $this->attributes['start_at'] = $datetime;
231 24
    }
232
233
    /**
234
     * Set finish_at attribute.
235
     *
236
     * @param Carbon $datetime
237
     */
238 8
    public function setFinishAtAttribute(Carbon $datetime)
239
    {
240 8
        $this->attributes['finish_at'] = $datetime;
241 8
    }
242
243
    /**
244
     * Set Comments.
245
     *
246
     * @param string $comments
247
     */
248 24
    public function setCommentsAttribute($comments)
249
    {
250 24
        $this->attributes['comments'] = trim($comments) ?: null;
251 24
    }
252
253
    /////////////////
254
    // HARD STATUS //
255
    /////////////////
256
257
    /**
258
     * Determine if is Reserved.
259
     *
260
     * @return bool
261
     */
262 1
    public function isReserved()
263
    {
264 1
        return $this->status == Self::STATUS_RESERVED;
0 ignored issues
show
Documentation introduced by
The property status does not exist on object<Timegridio\Concierge\Models\Appointment>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
265
    }
266
267
    ///////////////////////////
268
    // Calculated attributes //
269
    ///////////////////////////
270
271
    /**
272
     * Appointment Status Workflow.
273
     *
274
     * Hard Status: Those concrete values stored in DB
275
     * Soft Status: Those values calculated from stored values in DB
276
     *
277
     * Suggested transitions (Binding is not mandatory)
278
     *     Reserved -> Confirmed -> Served
279
     *     Reserved -> Served
280
     *     Reserved -> Annulated
281
     *     Reserved -> Confirmed -> Annulated
282
     *
283
     * Soft Status
284
     *     (Active)   [ Reserved  | Confirmed ]
285
     *     (InActive) [ Annulated | Served    ]
286
     */
287
288
    /**
289
     * Determine if is Active.
290
     *
291
     * @return bool
292
     */
293 3
    public function isActive()
294
    {
295
        return
296 3
            $this->status == Self::STATUS_CONFIRMED ||
0 ignored issues
show
Documentation introduced by
The property status does not exist on object<Timegridio\Concierge\Models\Appointment>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
297 3
            $this->status == Self::STATUS_RESERVED;
0 ignored issues
show
Documentation introduced by
The property status does not exist on object<Timegridio\Concierge\Models\Appointment>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
298
    }
299
300
    /**
301
     * Determine if is Pending.
302
     *
303
     * @return bool
304
     */
305 3
    public function isPending()
306
    {
307 3
        return $this->isActive() && $this->isFuture();
308
    }
309
310
    /**
311
     * Determine if is Future.
312
     *
313
     * @return bool
314
     */
315 3
    public function isFuture()
316
    {
317 3
        return !$this->isDue();
318
    }
319
320
    /**
321
     * Determine if is due.
322
     *
323
     * @return bool
324
     */
325 3
    public function isDue()
326
    {
327 3
        return $this->start_at->isPast();
0 ignored issues
show
Documentation introduced by
The property start_at does not exist on object<Timegridio\Concierge\Models\Appointment>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
328
    }
329
330
    ////////////
331
    // Scopes //
332
    ////////////
333
334
    /////////////////////////
335
    // Soft Status Scoping //
336
    /////////////////////////
337
338
    /**
339
     * Scope to not Served Appointments.
340
     *
341
     * @param Illuminate\Database\Query $query
342
     *
343
     * @return Illuminate\Database\Query
344
     */
345
    public function scopeUnServed($query)
346
    {
347
        return $query->where('status', '<>', Self::STATUS_SERVED);
348
    }
349
350
    /**
351
     * Scope to Active Appointments.
352
     *
353
     * @param Illuminate\Database\Query $query
354
     *
355
     * @return Illuminate\Database\Query
356
     */
357 12
    public function scopeActive($query)
358
    {
359 12
        return $query->whereIn('status', [Self::STATUS_RESERVED, Self::STATUS_CONFIRMED]);
360
    }
361
362
    /**
363
     * Between Dates.
364
     *
365
     * @param Illuminate\Database\Query $query
366
     * @param Carbon                    $startAt
367
     * @param Carbon                    $finishAt
368
     *
369
     * @return Illuminate\Database\Query
370
     */
371 8
    public function scopeAffectingInterval($query, Carbon $startAt, Carbon $finishAt)
372
    {
373
        return $query
374
            ->where(function ($query) use ($startAt, $finishAt) {
375
376 View Code Duplication
                $query->where(function ($query) use ($startAt, $finishAt) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
377 8
                    $query->where('finish_at', '>=', $finishAt->timezone('UTC'))
378 8
                            ->where('start_at', '<=', $startAt->timezone('UTC'));
379 8
                })
380 View Code Duplication
                ->orWhere(function ($query) use ($startAt, $finishAt) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
381 8
                    $query->where('finish_at', '<', $finishAt->timezone('UTC'))
382 8
                            ->where('finish_at', '>', $startAt->timezone('UTC'));
383 8
                })
384 View Code Duplication
                ->orWhere(function ($query) use ($startAt, $finishAt) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
385 8
                    $query->where('start_at', '>', $startAt->timezone('UTC'))
386 8
                            ->where('start_at', '<', $finishAt->timezone('UTC'));
387 8
                })
388 8 View Code Duplication
                ->orWhere(function ($query) use ($startAt, $finishAt) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
389 8
                    $query->where('start_at', '>', $startAt->timezone('UTC'))
390 8
                            ->where('finish_at', '<', $finishAt->timezone('UTC'));
391 8
                });
392
393 8
            });
394
    }
395
396
    /**
397
     * Determine if the Serve action can be performed.
398
     *
399
     * @return bool
400
     */
401
    public function isServeable()
402
    {
403
        return $this->isActive() && $this->isDue();
404
    }
405
406
    /**
407
     * Determine if the Confirm action can be performed.
408
     *
409
     * @return bool
410
     */
411
    public function isConfirmable()
412
    {
413
        return $this->status == self::STATUS_RESERVED && $this->isFuture();
0 ignored issues
show
Documentation introduced by
The property status does not exist on object<Timegridio\Concierge\Models\Appointment>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
414
    }
415
416
    /**
417
     * Determine if the Annulate action can be performed.
418
     *
419
     * @return bool
420
     */
421
    public function isAnnulable()
422
    {
423
        return $this->isActive();
424
    }
425
426
    /////////////////////////
427
    // Hard Status Actions //
428
    /////////////////////////
429
430
    /**
431
     * Check and perform Confirm action.
432
     *
433
     * @return $this
434
     */
435 5
    public function doReserve()
436
    {
437 5
        if ($this->status === null) {
0 ignored issues
show
Documentation introduced by
The property status does not exist on object<Timegridio\Concierge\Models\Appointment>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
438 5
            $this->status = self::STATUS_RESERVED;
0 ignored issues
show
Documentation introduced by
The property status does not exist on object<Timegridio\Concierge\Models\Appointment>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
439 5
        }
440
441 5
        return $this;
442
    }
443
444
    /**
445
     * Check and perform Confirm action.
446
     *
447
     * @return $this
448
     */
449 1
    public function doConfirm()
450
    {
451 1
        if ($this->isConfirmable()) {
452 1
            $this->status = self::STATUS_CONFIRMED;
0 ignored issues
show
Documentation introduced by
The property status does not exist on object<Timegridio\Concierge\Models\Appointment>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
453
454 1
            $this->save();
455 1
        }
456
457 1
        return $this;
458
    }
459
460
    /**
461
     * Check and perform Annulate action.
462
     *
463
     * @return $this
464
     */
465 1
    public function doAnnulate()
466
    {
467 1
        if ($this->isAnnulable()) {
468
            $this->status = self::STATUS_ANNULATED;
0 ignored issues
show
Documentation introduced by
The property status does not exist on object<Timegridio\Concierge\Models\Appointment>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
469
470
            $this->save();
471
        }
472
473 1
        return $this;
474
    }
475
476
    /**
477
     * Check and perform Serve action.
478
     *
479
     * @return $this
480
     */
481 2
    public function doServe()
482
    {
483 2
        if ($this->isServeable()) {
484
            $this->status = self::STATUS_SERVED;
0 ignored issues
show
Documentation introduced by
The property status does not exist on object<Timegridio\Concierge\Models\Appointment>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
485
486
            $this->save();
487
        }
488
489 2
        return $this;
490
    }
491
}
492