Add unit tests for various modules: attachments grouping, department weather caching behaviors, economic module order sanitization, enriched order batching, and user cashier name lookups. Update related route logic for enhanced data fetching and caching integrations.
This commit is contained in:
@@ -23,6 +23,7 @@ use objects\departments_o;
|
||||
use objects\bookings_o;
|
||||
use objects\logs_o;
|
||||
use objects\users_o;
|
||||
use routes\moduleWeatherAPIRoute;
|
||||
|
||||
if (!defined('WD')) {
|
||||
exit;
|
||||
@@ -105,6 +106,12 @@ $cron_tasks = [
|
||||
'next_run' => 0,
|
||||
'function' => 'PreRenderDynamicImagesCron',
|
||||
],
|
||||
'PreloadDepartmentWeatherResponsesCron' => [
|
||||
'interval' => 60, // 1 minute
|
||||
'last_run' => 0,
|
||||
'next_run' => 0,
|
||||
'function' => 'PreloadDepartmentWeatherResponsesCron',
|
||||
],
|
||||
'GoalsProgressAlertsCron' => [
|
||||
'interval' => 60, // check every minute
|
||||
'last_run' => 0,
|
||||
@@ -626,6 +633,165 @@ function mergeUniqueIntValues(array $base, array $append): array
|
||||
return array_values($result);
|
||||
}
|
||||
|
||||
function PreloadDepartmentWeatherResponsesCron(): void
|
||||
{
|
||||
$start = microtime(true);
|
||||
|
||||
if (!defined('redis')) {
|
||||
warn('PreloadDepartmentWeatherResponsesCron skipped: Redis is unavailable.');
|
||||
return;
|
||||
}
|
||||
|
||||
$maxDepartmentsRaw = getenv('DEPARTMENTS_WEATHER_PRELOAD_MAX_DEPARTMENTS');
|
||||
$maxDepartmentsPerRun = max(
|
||||
1,
|
||||
(int)(
|
||||
$maxDepartmentsRaw !== false && trim((string)$maxDepartmentsRaw) !== ''
|
||||
? $maxDepartmentsRaw
|
||||
: 25
|
||||
)
|
||||
);
|
||||
$hotLimitRaw = getenv('DEPARTMENTS_WEATHER_PRELOAD_HOT_LIMIT');
|
||||
$hotLimit = max(
|
||||
1,
|
||||
(int)(
|
||||
$hotLimitRaw !== false && trim((string)$hotLimitRaw) !== ''
|
||||
? $hotLimitRaw
|
||||
: 50
|
||||
)
|
||||
);
|
||||
$hotTtlRaw = getenv('DEPARTMENTS_WEATHER_PRELOAD_HOT_TTL');
|
||||
$hotTtl = max(
|
||||
1,
|
||||
(int)(
|
||||
$hotTtlRaw !== false && trim((string)$hotTtlRaw) !== ''
|
||||
? $hotTtlRaw
|
||||
: 900
|
||||
)
|
||||
);
|
||||
|
||||
try {
|
||||
$departmentRows = (new departments_o())->list(true);
|
||||
} catch (Throwable $e) {
|
||||
warn('PreloadDepartmentWeatherResponsesCron failed to list departments: ' . $e->getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_array($departmentRows) || $departmentRows === []) {
|
||||
echo "[" . date('Y-m-d H:i:s') . "][CRON] PreloadDepartmentWeatherResponsesCron: no departments found.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
usort($departmentRows, static function (array $left, array $right): int {
|
||||
$leftPriority = isset($left['order_priority']) ? (int)$left['order_priority'] : PHP_INT_MAX;
|
||||
$rightPriority = isset($right['order_priority']) ? (int)$right['order_priority'] : PHP_INT_MAX;
|
||||
if ($leftPriority !== $rightPriority) {
|
||||
return $leftPriority <=> $rightPriority;
|
||||
}
|
||||
|
||||
return ((int)($left['id'] ?? 0)) <=> ((int)($right['id'] ?? 0));
|
||||
});
|
||||
|
||||
$departmentIds = [];
|
||||
foreach ($departmentRows as $row) {
|
||||
$departmentId = (int)($row['id'] ?? 0);
|
||||
if ($departmentId < 1) {
|
||||
continue;
|
||||
}
|
||||
if (isset($row['visible']) && (int)$row['visible'] === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$departmentIds[$departmentId] = true;
|
||||
if (count($departmentIds) >= $maxDepartmentsPerRun) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: if visibility is unavailable or all are hidden, include all departments up to cap.
|
||||
if ($departmentIds === []) {
|
||||
foreach ($departmentRows as $row) {
|
||||
$departmentId = (int)($row['id'] ?? 0);
|
||||
if ($departmentId < 1) {
|
||||
continue;
|
||||
}
|
||||
$departmentIds[$departmentId] = true;
|
||||
if (count($departmentIds) >= $maxDepartmentsPerRun) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$departmentIds = array_map('intval', array_keys($departmentIds));
|
||||
sort($departmentIds, SORT_NUMERIC);
|
||||
|
||||
if ($departmentIds === []) {
|
||||
echo "[" . date('Y-m-d H:i:s') . "][CRON] PreloadDepartmentWeatherResponsesCron: no preloadable departments.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
$warmedSets = 0;
|
||||
$failedSets = 0;
|
||||
$totalEntries = 0;
|
||||
$hotTargetsRequested = 0;
|
||||
$hotTargetsWarmed = 0;
|
||||
|
||||
$hotTargets = moduleWeatherAPIRoute::getDepartmentWeatherHotPreloadTargets($hotLimit, $hotTtl);
|
||||
$hotTargetsRequested = count($hotTargets);
|
||||
foreach ($hotTargets as $target) {
|
||||
try {
|
||||
$result = moduleWeatherAPIRoute::preloadDepartmentWeatherTimelineCache(
|
||||
$target['department_ids'] ?? [],
|
||||
null,
|
||||
null,
|
||||
$target['timeline_range'] ?? null
|
||||
);
|
||||
if (($result['warmed'] ?? false) === true) {
|
||||
$warmedSets++;
|
||||
$hotTargetsWarmed++;
|
||||
$totalEntries += (int)($result['entries'] ?? 0);
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
$failedSets++;
|
||||
warn('PreloadDepartmentWeatherResponsesCron failed for hot target: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($departmentIds as $departmentId) {
|
||||
try {
|
||||
$result = moduleWeatherAPIRoute::preloadDepartmentWeatherTimelineCache([$departmentId]);
|
||||
if (($result['warmed'] ?? false) === true) {
|
||||
$warmedSets++;
|
||||
$totalEntries += (int)($result['entries'] ?? 0);
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
$failedSets++;
|
||||
warn('PreloadDepartmentWeatherResponsesCron failed for department #' . $departmentId . ': ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (count($departmentIds) > 1) {
|
||||
try {
|
||||
$result = moduleWeatherAPIRoute::preloadDepartmentWeatherTimelineCache($departmentIds);
|
||||
if (($result['warmed'] ?? false) === true) {
|
||||
$warmedSets++;
|
||||
$totalEntries += (int)($result['entries'] ?? 0);
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
$failedSets++;
|
||||
warn('PreloadDepartmentWeatherResponsesCron failed for aggregate department set: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
$duration = round(microtime(true) - $start, 2);
|
||||
echo "[" . date('Y-m-d H:i:s') . "][CRON] PreloadDepartmentWeatherResponsesCron completed. "
|
||||
. "departments=" . count($departmentIds)
|
||||
. " warmed_sets=$warmedSets failed_sets=$failedSets total_entries=$totalEntries "
|
||||
. "hot_targets_requested=$hotTargetsRequested hot_targets_warmed=$hotTargetsWarmed "
|
||||
. "max_departments_per_run=$maxDepartmentsPerRun hot_limit=$hotLimit hot_ttl=$hotTtl "
|
||||
. "duration={$duration}s\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* GoalsProgressAlertsCron
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user