athenahr/app/Absence.php
miguel456 e567094f40 feat: add loa requests
This commit adds a feature that allows users to request periods of inactivity from their managers. This is effectively known as a leave of absence.

The commit also introduces new permissions and migrations, therefore, you'll need to adapt your database according to these changes.
2022-02-24 00:56:46 +00:00

126 lines
2.9 KiB
PHP
Executable File

<?php
namespace App;
use App\Exceptions\AbsenceNotActionableException;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Absence extends Model
{
use HasFactory;
protected $fillable = [
'requesterID',
'start',
'predicted_end',
'available_assist',
'reason',
'status',
'reviewer',
'reviewed_date'
];
public function requester(): BelongsTo
{
return $this->belongsTo('App\User', 'requesterID', 'id');
}
/**
* Determines whether this model can be setApproved(), setDeclined() or setCancelled()
*
* @param bool $toCancel Switch the check to cancellability check
* @return bool
*/
public function isActionable(bool $toCancel = false): bool
{
if ($toCancel)
{
return in_array($this->getRawOriginal('status'), ['PENDING', 'APPROVED']);
}
return $this->getRawOriginal('status') == 'PENDING';
}
/**
* Sets the Absence's status as approved
*
* @return Absence
* @throws AbsenceNotActionableException
*/
public function setApproved(): Absence
{
if ($this->isActionable())
{
return tap($this)->update([
'status' => 'APPROVED'
]);
}
throw new AbsenceNotActionableException('This absence is not actionable!');
}
/**
* Sets the absence's status as declined
*
* @return Absence
* @throws AbsenceNotActionableException
*/
public function setDeclined(): Absence
{
if ($this->isActionable()) {
return tap($this)->update([
'status' => 'DECLINED'
]);
}
throw new AbsenceNotActionableException('This absence is not actionable!');
}
/**
* Sets the absence's status as cancelled
*
* @return Absence
* @throws AbsenceNotActionableException Thrown when the switch to this status would be invalid
*/
public function setCancelled(): Absence
{
if ($this->isActionable(true)) {
return tap($this)->update([
'status' => 'CANCELLED'
]);
}
throw new AbsenceNotActionableException('This absence is not actionable!');
}
/**
* Sets the absence's status as ended
*
* @return Absence
*/
public function setEnded(): Absence
{
return tap($this)->update([
'status' => 'ENDED'
]);
}
// Look out when retrieving this value;
//If you need the unaltered version of it, either adapt to its formatting or call getRawOriginal()
protected function status(): Attribute {
return Attribute::make(
get: fn($value) => ucfirst(strtolower($value))
);
}
}