61 lines
1.9 KiB
PHP
61 lines
1.9 KiB
PHP
<?php
|
|
|
|
namespace Modules\Maintenance\Services;
|
|
|
|
use App\Business;
|
|
use Illuminate\Support\Facades\Schema;
|
|
use Modules\Maintenance\Models\Equipment;
|
|
use Modules\Maintenance\Models\FailureReport;
|
|
use Modules\Maintenance\Models\InspectionVisit;
|
|
|
|
class EquipmentHealthScoreService
|
|
{
|
|
public function recalculate(Business $business, Equipment $equipment): float
|
|
{
|
|
$score = (float) ($equipment->health_percentage ?? 100);
|
|
|
|
if (Schema::hasTable('maintenance_inspection_visits')) {
|
|
$lastVisit = InspectionVisit::where('business_id', $business->id)
|
|
->where('equipment_id', $equipment->id)
|
|
->whereNotNull('health_percentage')
|
|
->orderByDesc('visit_date')
|
|
->value('health_percentage');
|
|
|
|
if ($lastVisit !== null) {
|
|
$score = ((float) $lastVisit * 0.6) + ($score * 0.4);
|
|
}
|
|
}
|
|
|
|
if (Schema::hasTable('maintenance_failure_reports')) {
|
|
$recentFailures = FailureReport::where('business_id', $business->id)
|
|
->where('equipment_id', $equipment->id)
|
|
->where('created_at', '>=', now()->subMonths(6))
|
|
->count();
|
|
|
|
$score -= min(30, $recentFailures * 5);
|
|
}
|
|
|
|
if ($equipment->warranty_expires_at && $equipment->warranty_expires_at->isPast()) {
|
|
$score -= 5;
|
|
}
|
|
|
|
$score = max(0, min(100, round($score, 2)));
|
|
$equipment->update(['health_percentage' => $score]);
|
|
|
|
return $score;
|
|
}
|
|
|
|
public function recalculateAll(Business $business): int
|
|
{
|
|
$count = 0;
|
|
Equipment::where('business_id', $business->id)->chunkById(50, function ($items) use ($business, &$count) {
|
|
foreach ($items as $equipment) {
|
|
$this->recalculate($business, $equipment);
|
|
$count++;
|
|
}
|
|
});
|
|
|
|
return $count;
|
|
}
|
|
}
|