58726ee0e9
API CI/CD / Validate (composer + pint) (push) Successful in 3m6s
API CI/CD / Test (PHPUnit) (push) Failing after 5m48s
API CI/CD / Build frontend assets (push) Successful in 1m2s
API CI/CD / Security audit (push) Failing after 1m33s
API CI/CD / Deploy to shared hosting (PHP) (push) Has been skipped
173 lines
4.9 KiB
PHP
173 lines
4.9 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
|
|
class Staff extends BaseModel
|
|
{
|
|
protected $table = 'staff';
|
|
|
|
/**
|
|
* legacy: timestamps managed manually (created_at/updated_at set by caller/controller)
|
|
*/
|
|
public $timestamps = false;
|
|
|
|
protected $fillable = [
|
|
'user_id',
|
|
'firstname',
|
|
'lastname',
|
|
'email',
|
|
'phone',
|
|
'role_name',
|
|
'active_role',
|
|
'status',
|
|
'school_year',
|
|
'created_at',
|
|
'updated_at',
|
|
];
|
|
|
|
protected $casts = [
|
|
'user_id' => 'integer',
|
|
'created_at' => 'datetime',
|
|
'updated_at' => 'datetime',
|
|
];
|
|
|
|
/* ============================================================
|
|
* Relationships (optional)
|
|
* ============================================================
|
|
*/
|
|
|
|
public function user(): BelongsTo
|
|
{
|
|
return $this->belongsTo(User::class, 'user_id');
|
|
}
|
|
|
|
/* ============================================================
|
|
* Scopes (nice for queries)
|
|
* ============================================================
|
|
*/
|
|
|
|
public function scopeActive(Builder $q): Builder
|
|
{
|
|
return $q->where('active_role', '!=', 'inactive');
|
|
}
|
|
|
|
public function scopeInactive(Builder $q): Builder
|
|
{
|
|
return $q->where('active_role', '=', 'inactive');
|
|
}
|
|
|
|
public function scopeForSchoolYear(Builder $q, string $schoolYear): Builder
|
|
{
|
|
return $q;
|
|
}
|
|
|
|
/* ============================================================
|
|
* legacy-compatible methods
|
|
* ============================================================
|
|
*/
|
|
|
|
public static function getActiveStaff(): array
|
|
{
|
|
return static::query()
|
|
->active()
|
|
->orderByDesc('created_at')
|
|
->get()
|
|
->all();
|
|
}
|
|
|
|
public static function getInactiveStaff(): array
|
|
{
|
|
return static::query()
|
|
->inactive()
|
|
->orderByDesc('updated_at')
|
|
->get()
|
|
->all();
|
|
}
|
|
|
|
/**
|
|
* Insert or update a staff row keyed by user_id.
|
|
* - created_at is preserved on update (unless explicitly provided).
|
|
* - updated_at can be provided by caller; otherwise we set it.
|
|
*
|
|
* Returns the saved model or null if invalid.
|
|
*/
|
|
public static function upsertStaff(array $data): ?self
|
|
{
|
|
if (empty($data['user_id'])) {
|
|
return null;
|
|
}
|
|
|
|
$userId = (int) $data['user_id'];
|
|
|
|
$existing = static::query()
|
|
->where('user_id', $userId)
|
|
->orderByDesc('id')
|
|
->first();
|
|
|
|
$now = now(); // use UTC if app.timezone=UTC (recommended)
|
|
|
|
// Only allow fillable keys
|
|
$payload = array_intersect_key($data, array_flip((new static)->getFillable()));
|
|
|
|
if ($existing) {
|
|
// Preserve original created_at unless explicitly provided
|
|
if (! array_key_exists('created_at', $payload) && $existing->created_at) {
|
|
$payload['created_at'] = $existing->created_at;
|
|
}
|
|
// Ensure updated_at exists
|
|
if (! array_key_exists('updated_at', $payload)) {
|
|
$payload['updated_at'] = $now;
|
|
}
|
|
|
|
$existing->fill($payload);
|
|
$existing->save();
|
|
|
|
return $existing;
|
|
}
|
|
|
|
// Insert new row — set created_at/updated_at if not provided
|
|
if (! array_key_exists('created_at', $payload)) {
|
|
$payload['created_at'] = $now;
|
|
}
|
|
if (! array_key_exists('updated_at', $payload)) {
|
|
$payload['updated_at'] = $now;
|
|
}
|
|
|
|
return static::query()->create($payload);
|
|
}
|
|
|
|
/**
|
|
* legacy-compatible boolean wrapper if you want the same signature.
|
|
*/
|
|
public static function upsertBool(array $data): bool
|
|
{
|
|
return (bool) static::upsertStaff($data);
|
|
}
|
|
|
|
/* ============================================================
|
|
* Optional validation helper (FormRequest/controller)
|
|
* ============================================================
|
|
*/
|
|
|
|
public static function rules(bool $updating = false): array
|
|
{
|
|
$req = $updating ? 'sometimes' : 'required';
|
|
|
|
return [
|
|
'user_id' => [$req, 'integer', 'min:1', 'exists:users,id'],
|
|
'firstname' => ['nullable', 'string', 'max:120'],
|
|
'lastname' => ['nullable', 'string', 'max:120'],
|
|
'email' => ['nullable', 'email', 'max:255'],
|
|
'phone' => ['nullable', 'string', 'max:40'],
|
|
'role_name' => ['nullable', 'string', 'max:80'],
|
|
'active_role' => ['nullable', 'string', 'max:80'], // includes 'inactive'
|
|
'status' => ['nullable', 'string', 'max:40'],
|
|
'created_at' => ['nullable', 'date'],
|
|
'updated_at' => ['nullable', 'date'],
|
|
];
|
|
}
|
|
}
|