expectServiceIds(7);
FixtureState::$serviceCalls[] = [[101, 201, 42, 7, self::DATE, 4, 3], $customer];
if ($standard !== null) {
FixtureState::$serviceCalls[] = [[101, 201, 0, 7, self::DATE, 4, 3], $standard];
}
self::assertSame($expected, getServicePrices('Transport', 'PKW', 42, 7, self::DATE, 0, 0, 0, false, 3));
}
public static function prices(): array
{
$standard = [100, 70, 5, 9, '2026-01-01'];
return [
'customer tariff' => [[80, 60, 10, 3, '2026-10-01'], null, [80, 0, 10, 0, 60, 0, true, '2026-10-01']],
'standard fallback' => [[0, 0, 0, 0, ''], $standard, [100, 0, 5, 0, 70, 0, false, '2026-01-01']],
'negative customer price is correction' => [[-15, 0, 0, 0, ''], $standard, [100, -15, 5, 0, 70, 0, true, '2026-01-01']],
'negative discount is correction' => [[0, 0, -3, 0, ''], $standard, [100, 0, 5, -3, 70, 0, true, '2026-01-01']],
'discount only keeps customer discount' => [[0, 0, 12, 0, ''], $standard, [100, 0, 12, 0, 70, 0, true, '2026-01-01']],
'one cent denotes free tariff' => [[0.01, 0.01, 0, 0, '2026-10-01'], null, [0, 0, 0, 0, 0, 0, true, '2026-10-01']],
'two cents remains charged' => [[0.02, 0.02, 0, 0, '2026-10-01'], null, [0.02, 0, 0, 0, 0.02, 0, true, '2026-10-01']],
];
}
public function testMissingHeadquartersTypeSwitchesBothLookupsToGlobalScope(): void
{
$GLOBALS['db']->expect('getOne', "SELECT srvt_id FROM servicetype WHERE srvt_name = 'PKW' AND srvt_mode = 0 AND hq_id = '7'", '');
$this->expectServiceIds(0);
FixtureState::$serviceCalls[] = [[101, 201, 42, 0, self::DATE, 4, 3], [80, 60, 0, 0, '2026-01-01']];
self::assertSame([80, 0, 0, 0, 60, 0, true, '2026-01-01'],
getServicePrices('Transport', 'PKW', 42, 7, self::DATE, 0, 0, 0, false, 3));
}
public function testExplicitDiscountAndCorrectionsArePreserved(): void
{
$this->expectServiceIds(7);
FixtureState::$serviceCalls[] = [[101, 201, 42, 7, self::DATE, 4, 3], [80, 60, 10, 0, '2026-01-01']];
self::assertSame([80, -2, 15, -1, 60, 0, true, '2026-01-01'],
getServicePrices('Transport', 'PKW', 42, 7, self::DATE, -2, 15, -1, false, 3));
}
private function expectServiceIds(int $hq): void
{
$GLOBALS['db']->expect('getOne', "SELECT srvt_id FROM servicetype WHERE srvt_name = 'PKW' AND srvt_mode = 0 AND hq_id = '$hq'", 201);
$GLOBALS['db']->expect('getOne', "SELECT srv_id FROM service WHERE srv_name = 'Transport' AND srv_mode = 0 AND hq_id = '$hq'", 101);
}
#[DataProvider('courierPrices')]
public function testGlobalCourierDeduction(mixed $price, mixed $rate, float $expected): void
{
$this->expectCourierIds('Globaler
Frachtverg.-Abschlag [%]');
FixtureState::$serviceCalls[] = [[301, 201, 42, 7, self::DATE, 4], [0, $rate, 0, 0, '2026-01-01']];
self::assertSame([$expected, is_numeric($rate) ? $rate : 0],
getCr_price_global($price, 7, 42, self::DATE, 'PKW', 0));
}
public static function courierPrices(): array
{
return ['percentage' => [100, 20, 80.0], 'cent rounding' => [10.01, 15, 8.51],
'negative credit' => [-100, 20, -80.0], 'full deduction' => [100, 100, 0.0],
'invalid base' => ['invalid', 20, 0.0], 'invalid deduction' => [100, 'invalid', 100.0]];
}
public function testZeroCustomerDeductionFallsBackToStandard(): void
{
$this->expectCourierIds('Globaler
Frachtverg.-Abschlag [%]');
FixtureState::$serviceCalls = [
[[301, 201, 42, 7, self::DATE, 4], [0, 0, 0, 0, '']],
[[301, 201, 0, 7, self::DATE, 4], [0, 25, 0, 0, '2026-01-01']],
];
self::assertSame([75.0, 25], getCr_price_global(100, 7, 42, self::DATE, 'PKW', 0));
}
public function testVehicleIdOverridesVehicleNameAndEmptyCustomerIsZero(): void
{
$GLOBALS['db']->expect('getOne', "SELECT mt_value FROM metatype WHERE mt_sort = '3' AND mt_type = 'vehicletype'", 'PKW');
$this->expectCourierIds('Globaler
Frachtverg.-Abschlag [%]');
FixtureState::$serviceCalls[] = [[301, 201, 0, 7, self::DATE, 4], [0, 20, 0, 0, '2026-01-01']];
self::assertSame([80.0, 20], getCr_price_global(100, 7, '', self::DATE, 'ignored', 3));
}
public function testCourierRateUsesSeparateTariffAndStandardFallback(): void
{
$this->expectCourierIds('Globaler
Fuhrlohnabschlag [%]');
FixtureState::$serviceCalls = [
[[301, 201, 42, 7, self::DATE, 4], [0, 0, 0, 0, '']],
[[301, 201, 0, 7, self::DATE, 4], [0, 17, 0, 0, '2026-01-01']],
];
self::assertSame(17, get_cr_price_rate(7, 42, self::DATE, 'PKW', 0));
}
private function expectCourierIds(string $service): void
{
$GLOBALS['db']->expect('getOne', "SELECT srvt_id FROM servicetype WHERE srvt_name = 'PKW' AND srvt_mode = 0 AND hq_id = '7'", 201);
$GLOBALS['db']->expect('getOne', "SELECT srv_id FROM service WHERE srv_name = '$service' AND srv_mode = 0 AND hq_id = '7'", 301);
}
}