sackey e839d40a99
Some checks are pending
linter / quality (push) Waiting to run
tests / ci (push) Waiting to run
Initial commit
2025-07-30 17:15:50 +00:00

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
]);
}
}