signature; logNotificationStart($commandName); $this->info('Checking Calibration Log for upcoming/overdue calibrations...'); $notificationCode = 'notification_calibration_due_soon'; try { // Run at most every 5 minutes if (!shouldCheckNotification($notificationCode)) { $this->info('Skipping: last calibration notification was sent recently.'); return 0; } $lastCheck = getLastCheckTimestamp($notificationCode); $today = now()->startOfDay(); $limitDate = $today->copy()->addDays(20); $query = DB::table('calibration_logs') ->whereNotNull('calibration_due_date') ->whereDate('calibration_due_date', '<=', $limitDate->toDateString()); // Optional: skip records explicitly marked as completed $query->where(function ($q) { $q->whereNull('status') ->orWhereNotIn('status', ['Completed']); }); if ($lastCheck !== null) { $query->where(function ($q) use ($lastCheck) { $q->where('created_at', '>', $lastCheck) ->orWhere('updated_at', '>', $lastCheck); }); $alreadyNotifiedIds = getAlreadyNotifiedIds($notificationCode); if (!empty($alreadyNotifiedIds)) { $query->whereNotIn('id', $alreadyNotifiedIds); } } $ids = $query->pluck('id')->toArray(); if (empty($ids)) { $this->info('No new calibration records found for notification.'); logNotificationComplete($commandName, 0, 0, 0, microtime(true) - $startTime); return 0; } $filterParams = [ 'table' => 'calibration_logs', 'conditions' => [], ]; 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: no new calibration records since last notification.'); logNotificationComplete($commandName, 0, count($allIds), 0, microtime(true) - $startTime); return 0; } $filterParams['conditions']['id'] = $allIds; } else { $filterParams['conditions']['id'] = $ids; } } else { $filterParams['conditions']['id'] = $ids; } if ($lastCheck !== null && isNotificationDuplicate($notificationCode, $filterParams)) { $this->info('Skipping: duplicate calibration notification with same filter params.'); logNotificationComplete($commandName, 0, count($filterParams['conditions']['id']), 0, microtime(true) - $startTime); return 0; } $recordCount = count($filterParams['conditions']['id']); $newCount = $lastCheck !== null ? count(array_diff($ids, getAlreadyNotifiedIds($notificationCode))) : $recordCount; $messageTemplate = '%d equipment item(s) have calibration due within 20 days or are already overdue. Please review the Calibration Log module.'; $sent = sendBatchNotificationWithFilter( $notificationCode, 'Calibration Due Soon', $messageTemplate, $filterParams, $recordCount ); $duration = microtime(true) - $startTime; logNotificationComplete($commandName, $sent, $recordCount, $newCount, $duration); $this->info("Calibration notifications sent: {$sent} (records: {$recordCount}, new: {$newCount})."); return 0; } catch (\Throwable $e) { $duration = microtime(true) - $startTime; logNotificationError($commandName, $e->getMessage(), [ 'file' => $e->getFile(), 'line' => $e->getLine(), 'duration' => $duration, ]); $this->error('Error: ' . $e->getMessage()); return 1; } } }