Files
citrus-cms/app/Console/Commands/NotificationCheckCalibrationDue.php
T
2026-04-28 21:14:25 +03:00

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;
}
}
}