123 lines
4.1 KiB
PHP
123 lines
4.1 KiB
PHP
<?php
|
|
|
|
namespace Modules\Maintenance\Services;
|
|
|
|
use Illuminate\Support\Facades\Artisan;
|
|
use Illuminate\Support\Facades\Schema;
|
|
|
|
class MaintenanceHealthService
|
|
{
|
|
/** @var array<int, string> */
|
|
protected array $requiredTables = [
|
|
'maintenance_equipment',
|
|
'maintenance_equipment_categories',
|
|
'maintenance_equipment_parts',
|
|
'maintenance_work_orders',
|
|
'maintenance_preventive_schedules',
|
|
'maintenance_spare_parts',
|
|
'maintenance_work_order_parts',
|
|
'maintenance_spare_part_consumptions',
|
|
'maintenance_failure_reports',
|
|
'maintenance_activity_logs',
|
|
'maintenance_notifications',
|
|
'maintenance_inspection_visits',
|
|
'maintenance_service_records',
|
|
'maintenance_part_replacements',
|
|
'maintenance_history_entries',
|
|
'maintenance_asset_documents',
|
|
'maintenance_checklist_templates',
|
|
'maintenance_production_lines',
|
|
'maintenance_part_catalogs',
|
|
'maintenance_service_providers',
|
|
];
|
|
|
|
/** @var array<int, string> */
|
|
protected array $ensureMigrations = [
|
|
'2026_07_07_170000_ensure_missing_cmms_tables',
|
|
'2026_07_07_160000_ensure_maintenance_lifecycle_tables',
|
|
'2026_07_07_150000_ensure_maintenance_asset_documents_table',
|
|
'2026_07_07_180000_fix_spare_parts_and_service_contracts',
|
|
'2026_06_30_200005_fix_maintenance_morph_types',
|
|
'2026_06_30_200006_inspection_visit_project_scope',
|
|
'2026_06_30_200007_maintenance_client_and_scope',
|
|
'2026_07_07_190000_fix_equipment_scope_columns',
|
|
];
|
|
|
|
public function assess(): array
|
|
{
|
|
$missing = [];
|
|
$present = [];
|
|
|
|
foreach ($this->requiredTables as $table) {
|
|
if (Schema::hasTable($table)) {
|
|
$present[] = $table;
|
|
} else {
|
|
$missing[] = $table;
|
|
}
|
|
}
|
|
|
|
$score = count($this->requiredTables) > 0
|
|
? (int) round((count($present) / count($this->requiredTables)) * 100)
|
|
: 100;
|
|
|
|
return [
|
|
'healthy' => empty($missing),
|
|
'score' => $score,
|
|
'present_count' => count($present),
|
|
'required_count' => count($this->requiredTables),
|
|
'missing_tables' => $missing,
|
|
'present_tables' => $present,
|
|
'integrations' => $this->assessIntegrations(),
|
|
];
|
|
}
|
|
|
|
public function repair(): array
|
|
{
|
|
$before = $this->assess();
|
|
$ran = [];
|
|
$errors = [];
|
|
|
|
foreach ($this->ensureMigrations as $migration) {
|
|
$path = "Modules/Maintenance/Database/Migrations/{$migration}.php";
|
|
if (! file_exists(base_path($path))) {
|
|
continue;
|
|
}
|
|
|
|
try {
|
|
Artisan::call('migrate', [
|
|
'--path' => $path,
|
|
'--force' => true,
|
|
]);
|
|
$ran[] = $migration;
|
|
} catch (\Throwable $e) {
|
|
$errors[] = $migration.': '.$e->getMessage();
|
|
}
|
|
}
|
|
|
|
Artisan::call('optimize:clear');
|
|
|
|
$after = $this->assess();
|
|
|
|
return [
|
|
'before' => $before,
|
|
'after' => $after,
|
|
'migrations_ran' => $ran,
|
|
'errors' => $errors,
|
|
'repaired' => $after['healthy'] || $after['score'] > $before['score'],
|
|
];
|
|
}
|
|
|
|
protected function assessIntegrations(): array
|
|
{
|
|
return [
|
|
'industrial_engineering' => class_exists(\Modules\IndustrialEngineering\Models\LineTemplate::class),
|
|
'asset_management' => class_exists(\Modules\AssetManagement\Entities\Asset::class),
|
|
'accounting' => class_exists(\Modules\Accounting\Entities\AccountingAccTransMapping::class),
|
|
'manufacturing' => class_exists(\Modules\Manufacturing\Entities\MfgRecipe::class)
|
|
|| class_exists(\Modules\Manufacturing\Http\Controllers\ProductionController::class),
|
|
'project' => Schema::hasTable('pjt_projects'),
|
|
'erp_products' => Schema::hasTable('products'),
|
|
];
|
|
}
|
|
}
|