148 lines
5.1 KiB
PHP
148 lines
5.1 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use Illuminate\Console\Command;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class NotificationCheckCalibrationDue extends Command
|
|
{
|
|
/**
|
|
* The name and signature of the console command.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $signature = 'notifications:check-calibration-due';
|
|
|
|
/**
|
|
* The console command description.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $description = 'Check calibration logs for equipment with calibration due within 20 days or overdue and send notifications.';
|
|
|
|
/**
|
|
* Execute the console command.
|
|
*
|
|
* @return int
|
|
*/
|
|
public function handle()
|
|
{
|
|
$startTime = microtime(true);
|
|
$commandName = $this->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;
|
|
}
|
|
}
|
|
}
|
|
|
|
|