252 lines
7.6 KiB
PHP
252 lines
7.6 KiB
PHP
<?php
|
|
|
|
namespace App\Livewire\TechnicianManagement;
|
|
|
|
use Livewire\Component;
|
|
use App\Models\Technician;
|
|
use App\Models\TechnicianPerformance;
|
|
use Livewire\Attributes\On;
|
|
use Carbon\Carbon;
|
|
|
|
class PerformanceTracking extends Component
|
|
{
|
|
public $showModal = false;
|
|
public $technicianId = null;
|
|
public $technician = null;
|
|
public $performanceId = null;
|
|
public $editing = false;
|
|
|
|
// Date filters
|
|
public $startDate = '';
|
|
public $endDate = '';
|
|
public $periodFilter = 'current_month';
|
|
|
|
// Form fields
|
|
public $metric_type = '';
|
|
public $metric_value = '';
|
|
public $performance_date = '';
|
|
public $period_type = 'daily';
|
|
public $notes = '';
|
|
|
|
// Chart data
|
|
public $chartData = [];
|
|
public $selectedMetric = 'jobs_completed';
|
|
|
|
protected $rules = [
|
|
'metric_type' => 'required|string|max:255',
|
|
'metric_value' => 'required|numeric',
|
|
'performance_date' => 'required|date',
|
|
'period_type' => 'required|in:daily,weekly,monthly,quarterly,yearly',
|
|
'notes' => 'nullable|string|max:1000'
|
|
];
|
|
|
|
public function mount()
|
|
{
|
|
$this->startDate = now()->startOfMonth()->format('Y-m-d');
|
|
$this->endDate = now()->format('Y-m-d');
|
|
$this->performance_date = now()->format('Y-m-d');
|
|
}
|
|
|
|
#[On('track-performance')]
|
|
public function trackPerformance($technicianId)
|
|
{
|
|
$this->technicianId = $technicianId;
|
|
$this->technician = Technician::with('performances')->findOrFail($technicianId);
|
|
$this->showModal = true;
|
|
$this->resetForm();
|
|
$this->loadChartData();
|
|
}
|
|
|
|
public function updatedPeriodFilter()
|
|
{
|
|
$this->setDateRange();
|
|
$this->loadChartData();
|
|
}
|
|
|
|
public function updatedSelectedMetric()
|
|
{
|
|
$this->loadChartData();
|
|
}
|
|
|
|
public function updatedStartDate()
|
|
{
|
|
$this->loadChartData();
|
|
}
|
|
|
|
public function updatedEndDate()
|
|
{
|
|
$this->loadChartData();
|
|
}
|
|
|
|
public function setDateRange()
|
|
{
|
|
switch ($this->periodFilter) {
|
|
case 'current_week':
|
|
$this->startDate = now()->startOfWeek()->format('Y-m-d');
|
|
$this->endDate = now()->endOfWeek()->format('Y-m-d');
|
|
break;
|
|
case 'current_month':
|
|
$this->startDate = now()->startOfMonth()->format('Y-m-d');
|
|
$this->endDate = now()->endOfMonth()->format('Y-m-d');
|
|
break;
|
|
case 'current_quarter':
|
|
$this->startDate = now()->startOfQuarter()->format('Y-m-d');
|
|
$this->endDate = now()->endOfQuarter()->format('Y-m-d');
|
|
break;
|
|
case 'current_year':
|
|
$this->startDate = now()->startOfYear()->format('Y-m-d');
|
|
$this->endDate = now()->endOfYear()->format('Y-m-d');
|
|
break;
|
|
case 'last_30_days':
|
|
$this->startDate = now()->subDays(30)->format('Y-m-d');
|
|
$this->endDate = now()->format('Y-m-d');
|
|
break;
|
|
}
|
|
}
|
|
|
|
public function loadChartData()
|
|
{
|
|
if (!$this->technician) return;
|
|
|
|
$performances = $this->technician->performances()
|
|
->where('metric_type', $this->selectedMetric)
|
|
->whereBetween('performance_date', [$this->startDate, $this->endDate])
|
|
->orderBy('performance_date')
|
|
->get();
|
|
|
|
$this->chartData = $performances->map(function ($performance) {
|
|
return [
|
|
'date' => $performance->performance_date->format('Y-m-d'),
|
|
'value' => $performance->metric_value,
|
|
'formatted_value' => $performance->formatted_value
|
|
];
|
|
})->toArray();
|
|
}
|
|
|
|
public function addPerformanceRecord()
|
|
{
|
|
$this->resetForm();
|
|
$this->editing = false;
|
|
}
|
|
|
|
public function editPerformance($performanceId)
|
|
{
|
|
$performance = TechnicianPerformance::findOrFail($performanceId);
|
|
|
|
$this->performanceId = $performance->id;
|
|
$this->metric_type = $performance->metric_type;
|
|
$this->metric_value = $performance->metric_value;
|
|
$this->performance_date = $performance->performance_date->format('Y-m-d');
|
|
$this->period_type = $performance->period_type;
|
|
$this->notes = $performance->notes;
|
|
|
|
$this->editing = true;
|
|
}
|
|
|
|
public function savePerformance()
|
|
{
|
|
$this->validate();
|
|
|
|
$data = [
|
|
'technician_id' => $this->technicianId,
|
|
'metric_type' => $this->metric_type,
|
|
'metric_value' => $this->metric_value,
|
|
'performance_date' => $this->performance_date,
|
|
'period_type' => $this->period_type,
|
|
'notes' => $this->notes,
|
|
];
|
|
|
|
if ($this->editing) {
|
|
$performance = TechnicianPerformance::findOrFail($this->performanceId);
|
|
$performance->update($data);
|
|
session()->flash('message', 'Performance record updated successfully!');
|
|
} else {
|
|
TechnicianPerformance::create($data);
|
|
session()->flash('message', 'Performance record added successfully!');
|
|
}
|
|
|
|
$this->technician->refresh();
|
|
$this->loadChartData();
|
|
$this->resetForm();
|
|
}
|
|
|
|
public function deletePerformance($performanceId)
|
|
{
|
|
TechnicianPerformance::findOrFail($performanceId)->delete();
|
|
$this->technician->refresh();
|
|
$this->loadChartData();
|
|
session()->flash('message', 'Performance record deleted successfully!');
|
|
}
|
|
|
|
public function closeModal()
|
|
{
|
|
$this->showModal = false;
|
|
$this->resetForm();
|
|
}
|
|
|
|
public function resetForm()
|
|
{
|
|
$this->performanceId = null;
|
|
$this->metric_type = '';
|
|
$this->metric_value = '';
|
|
$this->performance_date = now()->format('Y-m-d');
|
|
$this->period_type = 'daily';
|
|
$this->notes = '';
|
|
$this->editing = false;
|
|
$this->resetErrorBag();
|
|
}
|
|
|
|
public function getMetricTypesProperty()
|
|
{
|
|
return TechnicianPerformance::getMetricTypes();
|
|
}
|
|
|
|
public function getPeriodTypesProperty()
|
|
{
|
|
return TechnicianPerformance::getPeriodTypes();
|
|
}
|
|
|
|
public function getFilteredPerformancesProperty()
|
|
{
|
|
if (!$this->technician) return collect();
|
|
|
|
return $this->technician->performances()
|
|
->whereBetween('performance_date', [$this->startDate, $this->endDate])
|
|
->orderBy('performance_date', 'desc')
|
|
->get();
|
|
}
|
|
|
|
public function getPerformanceStatsProperty()
|
|
{
|
|
if (!$this->technician) return [];
|
|
|
|
$performances = $this->filteredPerformances;
|
|
|
|
$stats = [];
|
|
foreach ($this->metricTypes as $type => $label) {
|
|
$typePerformances = $performances->where('metric_type', $type);
|
|
if ($typePerformances->count() > 0) {
|
|
$stats[$type] = [
|
|
'label' => $label,
|
|
'current' => $typePerformances->first()->metric_value ?? 0,
|
|
'average' => round($typePerformances->avg('metric_value'), 2),
|
|
'total' => round($typePerformances->sum('metric_value'), 2),
|
|
'count' => $typePerformances->count()
|
|
];
|
|
}
|
|
}
|
|
|
|
return $stats;
|
|
}
|
|
|
|
public function render()
|
|
{
|
|
return view('livewire.technician-management.performance-tracking', [
|
|
'metricTypes' => $this->metricTypes,
|
|
'periodTypes' => $this->periodTypes,
|
|
'filteredPerformances' => $this->filteredPerformances,
|
|
'performanceStats' => $this->performanceStats
|
|
]);
|
|
}
|
|
}
|