268 lines
8.9 KiB
PHP
268 lines
8.9 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use Illuminate\Console\Command;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Schema;
|
|
use Carbon\Carbon;
|
|
|
|
class CheckNDTReminders extends Command
|
|
{
|
|
/**
|
|
* The name and signature of the console command.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $signature = 'notifications:check-ndt';
|
|
|
|
/**
|
|
* The console command description.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $description = 'Check NDT tests and send reminder notifications for overdue or pending tests';
|
|
|
|
/**
|
|
* Execute the console command.
|
|
* Performance: Optimized with chunking and bulk operations
|
|
*
|
|
* @return int
|
|
*/
|
|
public function handle()
|
|
{
|
|
$this->info('Starting NDT reminder checks...');
|
|
|
|
$totalNotifications = 0;
|
|
|
|
// Check overdue NDT tests
|
|
$totalNotifications += $this->checkOverdueTests();
|
|
|
|
// Check missing test reports
|
|
$totalNotifications += $this->checkMissingReports();
|
|
|
|
// Check deadline approaching tests (within 3 days)
|
|
$totalNotifications += $this->checkDeadlineApproaching();
|
|
|
|
// Check pending results
|
|
$totalNotifications += $this->checkPendingResults();
|
|
|
|
$this->info("NDT reminder check completed. Sent {$totalNotifications} notifications.");
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Check for overdue NDT tests
|
|
* Performance: Single query with multiple conditions
|
|
*/
|
|
private function checkOverdueTests()
|
|
{
|
|
$overdueThreshold = Carbon::now()->subDays(7); // 7 days overdue
|
|
$nullableColumns = $this->availableColumns('weld_logs', [
|
|
'rt_testing_date',
|
|
'ut_testing_date',
|
|
'pt_testing_date',
|
|
'mt_testing_date'
|
|
]);
|
|
|
|
if (empty($nullableColumns)) {
|
|
$this->info('Skipping overdue check: weld_logs table lacks test date columns.');
|
|
return 0;
|
|
}
|
|
|
|
$ids = DB::table('weld_logs')
|
|
->where('welding_date', '<=', $overdueThreshold)
|
|
->where(function($query) use ($nullableColumns) {
|
|
foreach ($nullableColumns as $column) {
|
|
$query->orWhereNull($column);
|
|
}
|
|
})
|
|
->pluck('id')
|
|
->toArray();
|
|
|
|
return $this->sendWeldLogBatch(
|
|
'notification_ndt_test_overdue',
|
|
'NDT Test Overdue',
|
|
'%d weld log(s) have welding dates older than 7 days without NDT testing.',
|
|
$ids
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Check for missing test reports
|
|
* Performance: Checks only records with test dates but no results
|
|
*/
|
|
private function checkMissingReports()
|
|
{
|
|
$checkDate = Carbon::now()->subDays(3); // 3 days after test date
|
|
|
|
$rtIds = [];
|
|
if ($this->columnsAvailable('weld_logs', ['rt_testing_date', 'rt_result'])) {
|
|
$rtIds = DB::table('weld_logs')
|
|
->whereNotNull('rt_testing_date')
|
|
->where('rt_testing_date', '<=', $checkDate)
|
|
->where(function($query) {
|
|
$query->whereNull('rt_result')
|
|
->orWhere('rt_result', '');
|
|
})
|
|
->pluck('id')
|
|
->toArray();
|
|
}
|
|
|
|
$utIds = [];
|
|
if ($this->columnsAvailable('weld_logs', ['ut_testing_date', 'ut_result'])) {
|
|
$utIds = DB::table('weld_logs')
|
|
->whereNotNull('ut_testing_date')
|
|
->where('ut_testing_date', '<=', $checkDate)
|
|
->where(function($query) {
|
|
$query->whereNull('ut_result')
|
|
->orWhere('ut_result', '');
|
|
})
|
|
->pluck('id')
|
|
->toArray();
|
|
}
|
|
|
|
$notifications = 0;
|
|
|
|
$notifications += $this->sendWeldLogBatch(
|
|
'notification_ndt_report_missing',
|
|
'RT Report Missing',
|
|
'%d RT test(s) have results pending more than 3 days.',
|
|
$rtIds
|
|
);
|
|
|
|
$notifications += $this->sendWeldLogBatch(
|
|
'notification_ndt_report_missing',
|
|
'UT Report Missing',
|
|
'%d UT test(s) have results pending more than 3 days.',
|
|
$utIds
|
|
);
|
|
|
|
return $notifications;
|
|
}
|
|
|
|
/**
|
|
* Check for tests with approaching deadlines
|
|
* Performance: Single query with date calculation
|
|
*/
|
|
private function checkDeadlineApproaching()
|
|
{
|
|
$warnDate = Carbon::now()->subDays(4); // Welded 4 days ago, should be tested within 7 days
|
|
$graceDate = Carbon::now()->subDays(7);
|
|
|
|
$dateColumns = array_filter($this->availableColumns('weld_logs', ['rt_testing_date', 'ut_testing_date']));
|
|
if (empty($dateColumns)) {
|
|
$this->info('Skipping deadline approaching check: weld_logs table lacks RT/UT testing date columns.');
|
|
return 0;
|
|
}
|
|
|
|
$ids = DB::table('weld_logs')
|
|
->whereBetween('welding_date', [$graceDate, $warnDate]) // Fixed: older date first, newer date second
|
|
->where(function($query) use ($dateColumns) {
|
|
foreach ($dateColumns as $column) {
|
|
$query->orWhereNull($column);
|
|
}
|
|
})
|
|
->pluck('id')
|
|
->toArray();
|
|
|
|
return $this->sendWeldLogBatch(
|
|
'notification_test_deadline_approaching',
|
|
'Test Deadline Approaching',
|
|
'%d weld log(s) are approaching the 7-day NDT testing deadline.',
|
|
$ids
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Check for pending test results
|
|
* Performance: Optimized with specific conditions
|
|
*/
|
|
private function checkPendingResults()
|
|
{
|
|
$pendingThreshold = Carbon::now()->subDays(2);
|
|
|
|
$ids = [];
|
|
$rtColumnsAvailable = $this->columnsAvailable('weld_logs', ['rt_testing_date', 'rt_result']);
|
|
$utColumnsAvailable = $this->columnsAvailable('weld_logs', ['ut_testing_date', 'ut_result']);
|
|
|
|
if (!$rtColumnsAvailable && !$utColumnsAvailable) {
|
|
$this->info('Skipping pending results check: weld_logs table lacks RT/UT result columns.');
|
|
return 0;
|
|
}
|
|
|
|
$query = DB::table('weld_logs')
|
|
->where(function($query) use ($pendingThreshold) {
|
|
if ($this->columnsAvailable('weld_logs', ['rt_testing_date', 'rt_result'])) {
|
|
$query->orWhere(function($q) use ($pendingThreshold) {
|
|
$q->whereNotNull('rt_testing_date')
|
|
->where('rt_testing_date', '<=', $pendingThreshold)
|
|
->where(function($sq) {
|
|
$sq->whereNull('rt_result')
|
|
->orWhere('rt_result', '');
|
|
});
|
|
});
|
|
}
|
|
if ($this->columnsAvailable('weld_logs', ['ut_testing_date', 'ut_result'])) {
|
|
$query->orWhere(function($q) use ($pendingThreshold) {
|
|
$q->whereNotNull('ut_testing_date')
|
|
->where('ut_testing_date', '<=', $pendingThreshold)
|
|
->where(function($sq) {
|
|
$sq->whereNull('ut_result')
|
|
->orWhere('ut_result', '');
|
|
});
|
|
});
|
|
}
|
|
});
|
|
|
|
$ids = $query->pluck('id')->toArray();
|
|
|
|
return $this->sendWeldLogBatch(
|
|
'notification_ndt_result_pending',
|
|
'NDT Result Pending',
|
|
'%d weld log(s) have completed NDT tests but results are pending more than 2 days.',
|
|
$ids
|
|
);
|
|
}
|
|
|
|
private function sendWeldLogBatch(string $notificationCode, string $title, string $messageTemplate, array $ids): int
|
|
{
|
|
$ids = array_values(array_unique(array_filter($ids)));
|
|
if (empty($ids)) {
|
|
$this->info("No {$title} notifications to send.");
|
|
return 0;
|
|
}
|
|
|
|
$filterParams = [
|
|
'table' => 'weld_logs',
|
|
'conditions' => [
|
|
'id' => $ids
|
|
]
|
|
];
|
|
|
|
sendBatchNotificationWithFilter(
|
|
$notificationCode,
|
|
$title,
|
|
$messageTemplate,
|
|
$filterParams,
|
|
count($ids)
|
|
);
|
|
|
|
$this->info("Sent batch notification for {$title} (" . count($ids) . " joints).");
|
|
return 1;
|
|
}
|
|
|
|
private function availableColumns(string $table, array $columns): array
|
|
{
|
|
return array_values(array_filter($columns, function($column) use ($table) {
|
|
return Schema::hasColumn($table, $column);
|
|
}));
|
|
}
|
|
|
|
private function columnsAvailable(string $table, array $columns): bool
|
|
{
|
|
return count($this->availableColumns($table, $columns)) === count($columns);
|
|
}
|
|
}
|