signature; // Log command start logNotificationStart($commandName); $this->info('Checking daily repair rate...'); $notificationCode = 'notification_daily_repair_rate_high'; try { // Skip if checked recently (within 5 minutes) if (!shouldCheckNotification($notificationCode)) { $this->info('Skipping: Last notification sent less than 5 minutes ago.'); logNotificationSkip($commandName, 'Last notification sent less than 5 minutes ago'); return 0; } $today = Carbon::today()->toDateString(); $lastCheck = getLastCheckTimestamp($notificationCode); // If not first run, check if new repairs/welds since last check if ($lastCheck !== null) { $newRepairs = DB::table('repair_logs') ->whereDate('repair_date', $today) ->where('created_at', '>', $lastCheck) ->count(); $newWelds = DB::table('weld_logs') ->whereDate('welding_date', $today) ->where('created_at', '>', $lastCheck) ->count(); if ($newRepairs == 0 && $newWelds == 0) { $this->info('No new repairs or welds since last check. Skipping.'); $duration = microtime(true) - $startTime; logNotificationSkip($commandName, 'No new repairs or welds since last check'); return 0; } } // Count today's repairs $repairCount = DB::table('repair_logs') ->whereDate('repair_date', $today) ->count(); // Count today's welds $weldCount = DB::table('weld_logs') ->whereDate('welding_date', $today) ->count(); if ($weldCount == 0) { $this->info("No welding records for today. Skipping repair rate check."); $duration = microtime(true) - $startTime; logNotificationSkip($commandName, 'No welding records for today'); return 0; } $repairRate = ($repairCount / $weldCount) * 100; $threshold = 12; $this->info("Today's stats: {$repairCount} repairs / {$weldCount} welds = " . number_format($repairRate, 2) . "%"); if ($repairRate > $threshold) { // Check for duplicate (same day already notified) if ($lastCheck !== null && $lastCheck->isToday()) { $this->info('Skipping: Already notified for today.'); $duration = microtime(true) - $startTime; logNotificationSkip($commandName, 'Already notified for today'); return 0; } $title = 'Daily Repair Rate Exceeds 12%'; $message = sprintf( 'Daily repair rate is %.2f%% (%d repairs out of %d welds), which exceeds the %d%% threshold. QC team attention required.', $repairRate, $repairCount, $weldCount, $threshold ); $filterParams = [ 'table' => 'repair_logs', 'conditions' => [ 'repair_date' => $today ] ]; $sentCount = sendNotification($notificationCode, $message, null, $title, $filterParams); $duration = microtime(true) - $startTime; logNotificationComplete($commandName, $sentCount, 1, 1, $duration); $this->warn("⚠️ HIGH REPAIR RATE: Notification sent to QC teams."); // Check overall (project-wide) repair rate $this->checkOverallRepairRate(); return 0; } $this->info("✓ Daily repair rate is within acceptable limits."); // Check overall (project-wide) repair rate $this->checkOverallRepairRate(); $duration = microtime(true) - $startTime; logNotificationComplete($commandName, 0, 0, 0, $duration); return 0; } catch (\Exception $e) { $duration = microtime(true) - $startTime; logNotificationError($commandName, $e->getMessage(), [ 'file' => $e->getFile(), 'line' => $e->getLine(), 'duration' => $duration, ]); $this->error("Error: " . $e->getMessage()); return 1; } } /** * Check overall repair rate for entire project */ private function checkOverallRepairRate() { $this->info('Checking overall project repair rate...'); $notificationCode = 'notification_overall_repair_rate_high'; // Skip if checked recently (within 5 minutes) if (!shouldCheckNotification($notificationCode)) { $this->info('Skipping overall rate: Last notification sent less than 5 minutes ago.'); return; } $lastCheck = getLastCheckTimestamp($notificationCode); // If not first run, check if new repairs/welds since last check if ($lastCheck !== null) { $newRepairs = DB::table('repair_logs') ->where('created_at', '>', $lastCheck) ->count(); $newWelds = DB::table('weld_logs') ->whereNotNull('welding_date') ->where('welding_date', '!=', '') ->where('welding_date', '!=', '0000-00-00') ->where('created_at', '>', $lastCheck) ->count(); if ($newRepairs == 0 && $newWelds == 0) { $this->info('No new repairs or welds since last check. Skipping overall rate.'); return; } } // Count total repairs (all time) $totalRepairs = DB::table('repair_logs')->count(); // Count total welds (all time) $totalWelds = DB::table('weld_logs') ->whereNotNull('welding_date') ->where('welding_date', '!=', '') ->where('welding_date', '!=', '0000-00-00') ->count(); if ($totalWelds == 0) { $this->info("No welding records found. Skipping overall repair rate check."); return; } $overallRepairRate = ($totalRepairs / $totalWelds) * 100; $threshold = 5; $this->info("Overall stats: {$totalRepairs} repairs / {$totalWelds} welds = " . number_format($overallRepairRate, 2) . "%"); if ($overallRepairRate > $threshold) { // Check for duplicate if ($lastCheck !== null && isNotificationDuplicate($notificationCode, ['table' => 'repair_logs', 'conditions' => []])) { $this->info('Skipping: Already notified for overall rate.'); return; } $title = 'Overall Repair Rate Exceeds 5%'; $message = sprintf( 'Overall project repair rate is %.2f%% (%d repairs out of %d welds), which exceeds the %d%% threshold. Quality improvement measures recommended.', $overallRepairRate, $totalRepairs, $totalWelds, $threshold ); $filterParams = [ 'table' => 'repair_logs', 'conditions' => [] ]; sendNotification($notificationCode, $message, null, $title, $filterParams); $this->warn("⚠️ HIGH OVERALL REPAIR RATE: Notification sent."); } else { $this->info("✓ Overall repair rate is within acceptable limits."); } } }