Fix invoice period automatic flag cache misses
This commit is contained in:
@@ -525,16 +525,12 @@ class invoice_period_flag_service
|
||||
try {
|
||||
$flags = (new redis())->get_invoice_period_automatic_flags($dateFrom, $dateTo);
|
||||
} catch (Throwable) {
|
||||
return [];
|
||||
$flags = null;
|
||||
}
|
||||
|
||||
if (!is_array($flags)) {
|
||||
// Cache miss — enqueue for warming on the next cron run
|
||||
try {
|
||||
(new redis())->enqueue_invoice_period_warming($dateFrom, $dateTo);
|
||||
} catch (Throwable) {
|
||||
}
|
||||
return [];
|
||||
$flags = $this->buildAutomaticFlagsForPeriod($dateFrom, $dateTo);
|
||||
$this->cacheAutomaticFlagsForPeriod($dateFrom, $dateTo, $flags);
|
||||
}
|
||||
|
||||
if ($onlyCustomerNumbers === null) {
|
||||
@@ -548,18 +544,30 @@ class invoice_period_flag_service
|
||||
}
|
||||
|
||||
public function warmAutomaticFlagsForPeriod(string $dateFrom, string $dateTo): void
|
||||
{
|
||||
$this->cacheAutomaticFlagsForPeriod(
|
||||
$dateFrom,
|
||||
$dateTo,
|
||||
$this->buildAutomaticFlagsForPeriod($dateFrom, $dateTo)
|
||||
);
|
||||
}
|
||||
|
||||
private function buildAutomaticFlagsForPeriod(string $dateFrom, string $dateTo): array
|
||||
{
|
||||
$rows = $this->getPeriodOrderItemRows($dateFrom, $dateTo, null);
|
||||
$attributes = $this->getCustomerAttributes(null);
|
||||
|
||||
$flags = array_merge(
|
||||
return array_merge(
|
||||
$this->detectCustomerRuleViolations($rows, $attributes),
|
||||
$this->detectPriceMismatches($rows),
|
||||
$this->detectAbnormalQuantities($rows, $dateFrom, $dateTo),
|
||||
$this->detectVehicleTypeMismatches($rows, $dateFrom),
|
||||
$this->detectMissingXlVaskLinks($dateFrom, $dateTo, null)
|
||||
);
|
||||
}
|
||||
|
||||
private function cacheAutomaticFlagsForPeriod(string $dateFrom, string $dateTo, array $flags): void
|
||||
{
|
||||
try {
|
||||
(new redis())->cache_invoice_period_automatic_flags($dateFrom, $dateTo, $flags);
|
||||
} catch (Throwable) {
|
||||
@@ -606,11 +614,15 @@ class invoice_period_flag_service
|
||||
try {
|
||||
$rows = (new redis())->get_invoice_period_order_item_rows($dateFrom, $dateTo);
|
||||
} catch (Throwable) {
|
||||
return [];
|
||||
$rows = null;
|
||||
}
|
||||
|
||||
if (!is_array($rows)) {
|
||||
return [];
|
||||
$rows = $this->fetchOrderItemRowsFromDb($dateFrom, $dateTo);
|
||||
try {
|
||||
(new redis())->cache_invoice_period_order_item_rows($dateFrom, $dateTo, $rows);
|
||||
} catch (Throwable) {
|
||||
}
|
||||
}
|
||||
|
||||
$this->seedOrderItemsPreviewCacheFromRows($rows);
|
||||
@@ -1727,18 +1739,7 @@ class invoice_period_flag_service
|
||||
if ($currentVehicleType === '' || $expectedVehicleType === '') {
|
||||
return false;
|
||||
}
|
||||
if ($currentVehicleType === $expectedVehicleType) {
|
||||
return true;
|
||||
}
|
||||
// Allow a match if one normalized name's tokens are a subset of the other.
|
||||
// E.g. "Indvendig vask Kassevogn" → "kassevogn" is a subset of
|
||||
// "Kassevogn/varevogn" → "kassevogn varevogn", meaning the same vehicle type.
|
||||
$currentTokens = explode(' ', $currentVehicleType);
|
||||
$expectedTokens = explode(' ', $expectedVehicleType);
|
||||
if (count($currentTokens) <= count($expectedTokens)) {
|
||||
return array_diff($currentTokens, $expectedTokens) === [];
|
||||
}
|
||||
return array_diff($expectedTokens, $currentTokens) === [];
|
||||
return $currentVehicleType === $expectedVehicleType;
|
||||
}
|
||||
|
||||
private function normalizePrimaryVehicleProductName(string $productName): string
|
||||
|
||||
@@ -628,6 +628,25 @@ it('does not report a price mismatch when a product-specific discount makes the
|
||||
expect($flags)->toBe([]);
|
||||
});
|
||||
|
||||
it('does not treat subset primary vehicle product names as equivalent', function (): void {
|
||||
expect(invoice_period_flag_service_invoke('primaryVehicleProductsMatch', [5, 'Forvogn', 6, 'Forvogn med hænger']))
|
||||
->toBeFalse()
|
||||
->and(invoice_period_flag_service_invoke('primaryVehicleProductsMatch', [10, 'Indvendig vask Kassevogn', 11, 'Kassevogn']))
|
||||
->toBeTrue();
|
||||
});
|
||||
|
||||
it('rebuilds automatic invoice period data on cache misses instead of hiding warnings', function (): void {
|
||||
$content = file_get_contents(app_path('classes/invoice_period_flag_service.php'));
|
||||
|
||||
expect($content)->not->toBeFalse();
|
||||
$content = (string)$content;
|
||||
|
||||
expect($content)->toContain('$flags = $this->buildAutomaticFlagsForPeriod($dateFrom, $dateTo);');
|
||||
expect($content)->toContain('$rows = $this->fetchOrderItemRowsFromDb($dateFrom, $dateTo);');
|
||||
expect($content)->toContain('cache_invoice_period_order_item_rows($dateFrom, $dateTo, $rows)');
|
||||
expect($content)->not->toContain('enqueue_invoice_period_warming($dateFrom, $dateTo)');
|
||||
});
|
||||
|
||||
it('preloads and caches missing e-conomic discounts before price mismatch detection', function (): void {
|
||||
$content = file_get_contents(app_path('classes/invoice_period_flag_service.php'));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user