TKK_E32231477/app/Models/DoorReading.php

197 lines
4.8 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Carbon\Carbon;
class DoorReading extends Model
{
protected $fillable = [
'device_id',
'door_open',
'is_authorized_access',
'is_forced_entry',
'access_type',
'door_location',
'open_duration_seconds',
'proper_closure',
'access_card_data',
'metadata',
'door_opened_at',
'door_closed_at',
'recorded_at'
];
protected $casts = [
'door_open' => 'boolean',
'is_authorized_access' => 'boolean',
'is_forced_entry' => 'boolean',
'proper_closure' => 'boolean',
'access_card_data' => 'array',
'metadata' => 'array',
'door_opened_at' => 'datetime',
'door_closed_at' => 'datetime',
'recorded_at' => 'datetime',
'open_duration_seconds' => 'integer'
];
public function device(): BelongsTo
{
return $this->belongsTo(Device::class);
}
/**
* Cek apakah akses dalam jam kerja yang sah
*/
public function checkAuthorizedAccess(Carbon $timestamp = null): bool
{
$time = $timestamp ?? $this->recorded_at ?? now();
// Jam kerja: Senin-Jumat 07:00-18:00 (lebih fleksibel untuk maintenance)
$workStart = 7; // 07:00
$workEnd = 18; // 18:00
$hour = $time->hour;
$isWeekday = $time->isWeekday();
return $isWeekday && $hour >= $workStart && $hour < $workEnd;
}
/**
* Tentukan apakah pembukaan paksa berdasarkan durasi dan kondisi
*/
public function detectForcedEntry(): bool
{
// Indikator pembukaan paksa:
// 1. Dibuka di luar jam kerja tanpa kartu akses
// 2. Durasi terbuka sangat singkat (<5 detik) - kemungkinan dipaksa
// 3. Tidak ditutup dengan benar
// 4. Tidak ada data kartu akses di luar jam kerja
if (!$this->is_authorized_access && !$this->access_card_data) {
return true;
}
if ($this->open_duration_seconds > 0 && $this->open_duration_seconds < 5) {
return true;
}
if (!$this->proper_closure && !$this->is_authorized_access) {
return true;
}
return false;
}
/**
* Tentukan tipe akses berdasarkan kondisi
*/
public function determineAccessType(): string
{
if ($this->is_forced_entry) {
return 'forced';
}
if (!$this->is_authorized_access) {
return 'unauthorized';
}
// Cek apakah maintenance berdasarkan durasi dan waktu
if ($this->open_duration_seconds > 300 && $this->is_authorized_access) {
return 'maintenance';
}
return 'normal';
}
/**
* Hitung durasi terbuka jika ada door_opened_at dan door_closed_at
*/
public function calculateOpenDuration(): int
{
if ($this->door_opened_at && $this->door_closed_at) {
return $this->door_opened_at->diffInSeconds($this->door_closed_at);
}
return $this->open_duration_seconds;
}
/**
* Cek apakah pintu masih terbuka (belum ditutup)
*/
public function isCurrentlyOpen(): bool
{
return $this->door_open && !$this->door_closed_at;
}
/**
* Get security risk level
*/
public function getSecurityRiskLevel(): string
{
if ($this->is_forced_entry) {
return 'critical';
}
if (!$this->is_authorized_access) {
return 'high';
}
if ($this->open_duration_seconds > 600) { // Terbuka > 10 menit
return 'medium';
}
return 'low';
}
/**
* Scope untuk pintu terbuka
*/
public function scopeOpen($query)
{
return $query->where('door_open', true);
}
/**
* Scope untuk akses tidak sah
*/
public function scopeUnauthorized($query)
{
return $query->where('is_authorized_access', false);
}
/**
* Scope untuk pembukaan paksa
*/
public function scopeForcedEntry($query)
{
return $query->where('is_forced_entry', true);
}
/**
* Scope untuk tipe akses tertentu
*/
public function scopeAccessType($query, $type)
{
return $query->where('access_type', $type);
}
/**
* Scope untuk lokasi pintu tertentu
*/
public function scopeDoorLocation($query, $location)
{
return $query->where('door_location', $location);
}
/**
* Scope untuk pintu yang masih terbuka
*/
public function scopeCurrentlyOpen($query)
{
return $query->where('door_open', true)->whereNull('door_closed_at');
}
}