151 lines
5.1 KiB
PHP
151 lines
5.1 KiB
PHP
<?php
|
|
|
|
use App\Models\Notification;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Carbon\Carbon;
|
|
|
|
/**
|
|
* Get last notification time for a notification code
|
|
* Returns null if never sent (first time)
|
|
*/
|
|
function getLastNotificationTime(string $notificationCode): ?Carbon
|
|
{
|
|
$lastNotification = Notification::where('notification_code', $notificationCode)
|
|
->orderBy('created_at', 'DESC')
|
|
->first();
|
|
|
|
return $lastNotification ? $lastNotification->created_at : null;
|
|
}
|
|
|
|
/**
|
|
* Check if we should run the check
|
|
* Returns true if last notification was more than 5 minutes ago (or never sent)
|
|
*/
|
|
function shouldCheckNotification(string $notificationCode, int $minMinutes = 5): bool
|
|
{
|
|
$lastNotification = getLastNotificationTime($notificationCode);
|
|
|
|
// If never sent, should check
|
|
if (!$lastNotification) {
|
|
return true;
|
|
}
|
|
|
|
// If last notification was more than 5 minutes ago, should check
|
|
return $lastNotification->diffInMinutes(now()) >= $minMinutes;
|
|
}
|
|
|
|
/**
|
|
* Get records created/updated after last notification
|
|
* Returns null if first run (should check all records)
|
|
*/
|
|
function getLastCheckTimestamp(string $notificationCode): ?Carbon
|
|
{
|
|
$lastNotification = getLastNotificationTime($notificationCode);
|
|
|
|
// If never sent, return null (will check all records on first run)
|
|
if (!$lastNotification) {
|
|
return null;
|
|
}
|
|
|
|
// Check records after last notification
|
|
return $lastNotification;
|
|
}
|
|
|
|
/**
|
|
* Check if notification already sent for same issue (duplicate prevention)
|
|
* Compares filter_params to detect same issue
|
|
*
|
|
* @param string $notificationCode
|
|
* @param array|null $filterParams
|
|
* @return bool True if duplicate exists
|
|
*/
|
|
function isNotificationDuplicate(string $notificationCode, ?array $filterParams = null): bool
|
|
{
|
|
// If no filter params, can't check for duplicates
|
|
if (empty($filterParams)) {
|
|
return false;
|
|
}
|
|
|
|
// Get last notification with same code and filter params
|
|
$lastNotification = Notification::where('notification_code', $notificationCode)
|
|
->whereNotNull('filter_params')
|
|
->orderBy('created_at', 'DESC')
|
|
->first();
|
|
|
|
if (!$lastNotification || !$lastNotification->filter_params) {
|
|
return false; // No previous notification
|
|
}
|
|
|
|
// Compare filter_params (normalize arrays for comparison)
|
|
$lastParams = is_array($lastNotification->filter_params)
|
|
? $lastNotification->filter_params
|
|
: json_decode($lastNotification->filter_params, true);
|
|
|
|
// Check if same table and same conditions
|
|
if (isset($lastParams['table']) && isset($filterParams['table'])) {
|
|
if ($lastParams['table'] !== $filterParams['table']) {
|
|
return false; // Different tables, not duplicate
|
|
}
|
|
}
|
|
|
|
// Compare conditions (simplified - check if same IDs or same conditions)
|
|
if (isset($lastParams['conditions']) && isset($filterParams['conditions'])) {
|
|
// If both have 'id' conditions, check if they overlap
|
|
if (isset($lastParams['conditions']['id']) && isset($filterParams['conditions']['id'])) {
|
|
$lastIds = is_array($lastParams['conditions']['id'])
|
|
? $lastParams['conditions']['id']
|
|
: [$lastParams['conditions']['id']];
|
|
$newIds = is_array($filterParams['conditions']['id'])
|
|
? $filterParams['conditions']['id']
|
|
: [$filterParams['conditions']['id']];
|
|
|
|
// If all new IDs are already in last notification, it's duplicate
|
|
$newUniqueIds = array_diff($newIds, $lastIds);
|
|
if (empty($newUniqueIds)) {
|
|
return true; // All IDs already notified
|
|
}
|
|
}
|
|
|
|
// For other conditions, do simple comparison
|
|
// If conditions are exactly same, it's duplicate
|
|
$lastConditions = json_encode($lastParams['conditions'], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
|
$newConditions = json_encode($filterParams['conditions'], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
|
|
|
if ($lastConditions === $newConditions) {
|
|
return true; // Exact same conditions
|
|
}
|
|
}
|
|
|
|
return false; // Not duplicate
|
|
}
|
|
|
|
/**
|
|
* Get already notified IDs from last notification
|
|
* Used to filter out already notified records
|
|
*
|
|
* @param string $notificationCode
|
|
* @return array Array of already notified IDs
|
|
*/
|
|
function getAlreadyNotifiedIds(string $notificationCode): array
|
|
{
|
|
$lastNotification = Notification::where('notification_code', $notificationCode)
|
|
->whereNotNull('filter_params')
|
|
->orderBy('created_at', 'DESC')
|
|
->first();
|
|
|
|
if (!$lastNotification || !$lastNotification->filter_params) {
|
|
return []; // No previous notification
|
|
}
|
|
|
|
$filterParams = is_array($lastNotification->filter_params)
|
|
? $lastNotification->filter_params
|
|
: json_decode($lastNotification->filter_params, true);
|
|
|
|
if (isset($filterParams['conditions']['id'])) {
|
|
$ids = $filterParams['conditions']['id'];
|
|
return is_array($ids) ? $ids : [$ids];
|
|
}
|
|
|
|
return [];
|
|
}
|