SIPDAM/samooapk/app/Models/ProgresKerja.php

254 lines
7.5 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Carbon\Carbon;
class ProgresKerja extends Model
{
use HasFactory;
protected $table = 'progres_kerjas'; // Ubah dari 'progres_kerja' ke 'progres_kerjas'
protected $primaryKey = 'id_progres';
protected $fillable = [
'id_penugasan',
'id_teknisi',
'tugas',
'deskripsi_progres',
'status_progres',
'persentase_pekerjaan',
'foto_progress',
'tanggal_update'
];
protected $casts = [
'tanggal_update' => 'datetime',
'persentase_pekerjaan' => 'integer',
];
// Status progres options
public static $statusProgres = [
'belum_mulai' => 'Belum Mulai',
'dalam_progres' => 'Dalam Progres',
'terhenti' => 'Terhenti',
'selesai' => 'Selesai',
'ditunda' => 'Ditunda'
];
// Boot method untuk auto update tanggal_update
protected static function boot()
{
parent::boot();
static::creating(function ($model) {
$model->tanggal_update = now();
});
static::updating(function ($model) {
$model->tanggal_update = now();
});
}
// Relationships
public function teknisi()
{
return $this->belongsTo(Teknisi::class, 'id_teknisi', 'id_teknisi');
}
public function penugasan()
{
return $this->belongsTo(Penugasan::class, 'id_penugasan', 'id_penugasan');
}
// Scopes
public function scopeByStatus($query, $status)
{
return $query->where('status_progres', $status);
}
public function scopeByTeknisi($query, $teknisiId)
{
return $query->where('id_teknisi', $teknisiId);
}
public function scopeByDateRange($query, $startDate = null, $endDate = null)
{
if ($startDate) {
$query->whereDate('tanggal_update', '>=', $startDate);
}
if ($endDate) {
$query->whereDate('tanggal_update', '<=', $endDate);
}
return $query;
}
// Accessors
public function getStatusFormattedAttribute()
{
return self::$statusProgres[$this->status_progres] ?? 'Unknown';
}
public function getStatusBadgeClassAttribute()
{
$badgeClasses = [
'belum_mulai' => 'badge-secondary',
'dalam_progres' => 'badge-primary',
'terhenti' => 'badge-danger',
'selesai' => 'badge-success',
'ditunda' => 'badge-warning'
];
return $badgeClasses[$this->status_progres] ?? 'badge-secondary';
}
public function getTanggalUpdateFormattedAttribute()
{
return $this->tanggal_update ? $this->tanggal_update->format('d/m/Y H:i') : '-';
}
public function getHasFotoAttribute()
{
return !empty($this->foto_progress);
}
public function getFotoProgressUrlAttribute()
{
if ($this->foto_progress) {
return asset('storage/progress_photos/' . $this->foto_progress);
}
return null;
}
public function getDaysSinceUpdateAttribute()
{
if ($this->tanggal_update) {
return $this->tanggal_update->diffInDays(now());
}
return 0;
}
// Methods
public function autoUpdateStatus()
{
$percentage = $this->persentase_pekerjaan;
if ($percentage == 0) {
$newStatus = 'belum_mulai';
} elseif ($percentage > 0 && $percentage < 100) {
$newStatus = 'dalam_progres';
} elseif ($percentage == 100) {
$newStatus = 'selesai';
} else {
return; // No change needed
}
// Only update if status is different
if ($this->status_progres !== $newStatus) {
$this->update(['status_progres' => $newStatus]);
}
}
public function canTransitionTo($newStatus)
{
$allowedTransitions = [
'belum_mulai' => ['dalam_progres', 'ditunda'],
'dalam_progres' => ['terhenti', 'selesai', 'ditunda'],
'terhenti' => ['dalam_progres', 'ditunda'],
'selesai' => [], // Cannot transition from completed
'ditunda' => ['belum_mulai', 'dalam_progres']
];
$currentStatus = $this->status_progres;
return in_array($newStatus, $allowedTransitions[$currentStatus] ?? []);
}
// Static methods
public static function getByTeknisi($teknisiId)
{
return self::with(['teknisi', 'penugasan'])
->where('id_teknisi', $teknisiId)
->orderBy('tanggal_update', 'desc')
->get();
}
public static function getRecentUpdates($limit = 10)
{
return self::with(['teknisi', 'penugasan'])
->orderBy('tanggal_update', 'desc')
->limit($limit)
->get();
}
public static function getStatistics()
{
$total = self::count();
$byStatus = self::selectRaw('status_progres, COUNT(*) as count')
->groupBy('status_progres')
->pluck('count', 'status_progres')
->toArray();
$statistics = [
'total' => $total,
'belum_mulai' => $byStatus['belum_mulai'] ?? 0,
'dalam_progres' => $byStatus['dalam_progres'] ?? 0,
'terhenti' => $byStatus['terhenti'] ?? 0,
'selesai' => $byStatus['selesai'] ?? 0,
'ditunda' => $byStatus['ditunda'] ?? 0,
];
// Add percentages
if ($total > 0) {
$statistics['completion_rate'] = round(($statistics['selesai'] / $total) * 100, 1);
$statistics['in_progress_rate'] = round(($statistics['dalam_progres'] / $total) * 100, 1);
} else {
$statistics['completion_rate'] = 0;
$statistics['in_progress_rate'] = 0;
}
return $statistics;
}
public static function getOverdueProgress($days = 7)
{
return self::with(['teknisi', 'penugasan'])
->whereIn('status_progres', ['dalam_progres', 'terhenti'])
->where('tanggal_update', '<', now()->subDays($days))
->orderBy('tanggal_update', 'asc')
->get();
}
public static function getProgressSummaryByTeknisi()
{
return self::with('teknisi')
->selectRaw('id_teknisi, status_progres, COUNT(*) as count')
->groupBy('id_teknisi', 'status_progres')
->get()
->groupBy('id_teknisi')
->map(function ($items) {
$teknisi = $items->first()->teknisi;
$summary = [
'teknisi_id' => $teknisi->id_teknisi,
'teknisi_nama' => $teknisi->nama,
'total' => $items->sum('count'),
'belum_mulai' => 0,
'dalam_progres' => 0,
'terhenti' => 0,
'selesai' => 0,
'ditunda' => 0,
];
foreach ($items as $item) {
$summary[$item->status_progres] = $item->count;
}
return $summary;
})
->values();
}
}