signature; // Log command start logNotificationStart($commandName); $this->info('Checking for missing PDF documents...'); $totalNotifications = 0; $totalSent = 0; $totalRecords = 0; $totalNew = 0; try { $pdfNotificationCodes = [ 'notification_wps_pdf_missing', 'notification_naks_welder_cert_missing', 'notification_welding_equipment_pdf_missing', 'notification_wpq_followup_pdf_missing', ]; $result1 = $this->sendBatchNotification( 'w_p_s', 'download', 'notification_wps_pdf_missing', 'WPS PDF Document Missing', 'download', [ 'message' => '%d WPS document(s) have no PDF file uploaded. Please add the missing PDF files.' ], $totalSent, $totalRecords, $totalNew ); if ($result1 > 0) { $totalNotifications += 1; } $result2 = $this->sendBatchNotification( 'naks_welders', 'naks_certificate_no', 'notification_naks_welder_cert_missing', 'NAKS Welder Certificate Missing', 'naks_certificate_no', [ 'message' => '%d NAKS welder(s) have no certificate number assigned. Please update each welder record.' ], $totalSent, $totalRecords, $totalNew ); if ($result2 > 0) { $totalNotifications += 1; } $result3 = $this->sendBatchNotification( 'welding_equipment', 'download', 'notification_welding_equipment_pdf_missing', 'Welding Equipment PDF Missing', 'download', [ 'message' => '%d welding equipment record(s) have no PDF document uploaded. Please add the missing files.', ], $totalSent, $totalRecords, $totalNew ); if ($result3 > 0) { $totalNotifications += 1; } $result4 = $this->sendBatchNotification( 'welder_tests', 'download', 'notification_wpq_followup_pdf_missing', 'WPQR PDF Missing', 'download', [ 'message' => '%d WPQR record(s) have no PDF document uploaded. Please add the missing files.', ], $totalSent, $totalRecords, $totalNew ); if ($result4 > 0) { $totalNotifications += 1; } $duration = microtime(true) - $startTime; // Log completion logNotificationComplete($commandName, $totalSent, $totalRecords, $totalNew, $duration); $this->info("Total batch notifications sent: {$totalNotifications}"); 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; } } /** * Send a batch notification for a table/column combination */ private function sendBatchNotification( string $table, string $column, string $notificationCode, string $title, string $columnKeyForFilter, array $options = [], &$totalSent = null, &$totalRecords = null, &$totalNew = null ): int { $this->info("Checking {$title}..."); // Skip if checked recently (within 5 minutes) if (!shouldCheckNotification($notificationCode)) { $this->info("Skipping {$title}: Last notification sent less than 5 minutes ago."); return 0; } // Get last check time (null = first run, check all records) $lastCheck = getLastCheckTimestamp($notificationCode); $query = DB::table($table)->where(function($q) use ($column) { $q->whereNull($column) ->orWhere($column, ''); }); // If not first run, only check new/updated records if ($lastCheck !== null) { $query->where(function($q) use ($lastCheck) { $q->where('created_at', '>', $lastCheck) ->orWhere('updated_at', '>', $lastCheck); }); // Get already notified IDs $alreadyNotifiedIds = getAlreadyNotifiedIds($notificationCode); if (!empty($alreadyNotifiedIds)) { $query->whereNotIn('id', $alreadyNotifiedIds); } } $ids = $query->pluck('id')->toArray(); if (empty($ids)) { $this->info("No new missing records found for {$title}."); return 0; } // Prepare filter params $filterParams = [ 'table' => $table, 'conditions' => [ 'or' => [ [$columnKeyForFilter => null], [$columnKeyForFilter => ''] ] ] ]; // If not first run, merge with existing IDs if ($lastCheck !== null) { $existingIds = getAlreadyNotifiedIds($notificationCode); if (!empty($existingIds)) { $allIds = array_values(array_unique(array_merge($existingIds, $ids))); $newIds = array_diff($ids, $existingIds); if (empty($newIds)) { $this->info("Skipping {$title}: No new records since last notification."); return 0; } $filterParams['conditions']['id'] = $allIds; } else { $filterParams['conditions']['id'] = $ids; } } else { $filterParams['conditions']['id'] = $ids; } // Check for duplicate if ($lastCheck !== null && isNotificationDuplicate($notificationCode, $filterParams)) { $this->info("Skipping {$title}: Same issue already notified and no new records."); return 0; } $newCount = $lastCheck !== null ? count(array_diff($ids, getAlreadyNotifiedIds($notificationCode))) : count($ids); $totalRecords = count($filterParams['conditions']['id'] ?? $ids); $message = $options['message'] ?? '%d record(s) have missing data. Please review the filtered list.'; $message = sprintf($message, $totalRecords); $sentCount = sendNotification( $notificationCode, $message, null, $title, $filterParams, $totalRecords ); // Update totals if references provided if ($totalSent !== null) { $totalSent += $sentCount; $totalRecords += $totalRecords; $totalNew += $newCount; } $this->info("Sent batch notification for {$title} ({$totalRecords} records, {$newCount} new)."); return $sentCount; } }