Files
CKB/app/Models/KpiAchievement.php

168 lines
4.1 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Carbon\Carbon;
class KpiAchievement extends Model
{
use HasFactory;
protected $fillable = [
'user_id',
'kpi_target_id',
'target_value',
'actual_value',
'achievement_percentage',
'year',
'month',
'notes'
];
protected $casts = [
'achievement_percentage' => 'decimal:2',
'year' => 'integer',
'month' => 'integer'
];
protected $attributes = [
'actual_value' => 0,
'achievement_percentage' => 0
];
/**
* Get the user that owns the achievement
*/
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
/**
* Get the KPI target for this achievement
*/
public function kpiTarget(): BelongsTo
{
return $this->belongsTo(KpiTarget::class);
}
/**
* Scope to get achievements for specific year and month
*/
public function scopeForPeriod($query, $year, $month)
{
return $query->where('year', $year)->where('month', $month);
}
/**
* Scope to get achievements for current month
*/
public function scopeCurrentMonth($query)
{
return $query->where('year', now()->year)->where('month', now()->month);
}
/**
* Scope to get achievements within year range
*/
public function scopeWithinYearRange($query, $startYear, $endYear)
{
return $query->whereBetween('year', [$startYear, $endYear]);
}
/**
* Scope to get achievements for specific user
*/
public function scopeForUser($query, $userId)
{
return $query->where('user_id', $userId);
}
/**
* Get achievement status
*/
public function getStatusAttribute(): string
{
if ($this->achievement_percentage >= 100) {
return 'exceeded';
} elseif ($this->achievement_percentage >= 80) {
return 'good';
} elseif ($this->achievement_percentage >= 60) {
return 'fair';
} else {
return 'poor';
}
}
/**
* Get status color for display
*/
public function getStatusColorAttribute(): string
{
return match($this->status) {
'exceeded' => 'success',
'good' => 'info',
'fair' => 'warning',
'poor' => 'danger',
default => 'secondary'
};
}
/**
* Get period display name (e.g., "Januari 2024")
*/
public function getPeriodDisplayName(): string
{
$monthNames = [
1 => 'Januari', 2 => 'Februari', 3 => 'Maret', 4 => 'April',
5 => 'Mei', 6 => 'Juni', 7 => 'Juli', 8 => 'Agustus',
9 => 'September', 10 => 'Oktober', 11 => 'November', 12 => 'Desember'
];
return $monthNames[$this->month] . ' ' . $this->year;
}
/**
* Get period start date
*/
public function getPeriodStartDate(): Carbon
{
return Carbon::createFromDate($this->year, $this->month, 1);
}
/**
* Get period end date
*/
public function getPeriodEndDate(): Carbon
{
return Carbon::createFromDate($this->year, $this->month, 1)->endOfMonth();
}
/**
* Get target value (from stored value or from relation)
*/
public function getTargetValueAttribute(): int
{
// Return stored target value if available, otherwise get from relation
return $this->target_value ?? $this->kpiTarget?->target_value ?? 0;
}
/**
* Get current target value from relation (for comparison)
*/
public function getCurrentTargetValueAttribute(): int
{
return $this->kpiTarget?->target_value ?? 0;
}
/**
* Check if stored target value differs from current target value
*/
public function hasTargetValueChanged(): bool
{
return $this->target_value !== $this->current_target_value;
}
}