wip: insurance booking phases 1 and 2

This commit is contained in:
Björn Fromme
2026-03-16 11:59:10 +01:00
parent 411166ffba
commit 241785b428
8 changed files with 1109 additions and 4 deletions
+135
View File
@@ -0,0 +1,135 @@
<?php
declare(strict_types=1);
namespace App\Service;
use App\BusProNet\Model\Insurance;
/**
* Resolves insurance types for both individual insurances and packages.
*
* This service provides consistent type resolution by mapping insurance subtypes
* to standardized type constants. For packages, it analyzes contained insurances
* to determine the dominant (non-deductible) type and applies family variants
* based on the familyInsurance flag.
*/
class InsuranceTypeResolver
{
public const TRAVEL_CANCELLATION = 'TRAVEL_CANCELLATION';
public const TRAVEL_CANCELLATION_FAMILY = 'TRAVEL_CANCELLATION_FAMILY';
public const TRAVEL_PROTECTION = 'TRAVEL_PROTECTION';
public const TRAVEL_PROTECTION_FAMILY = 'TRAVEL_PROTECTION_FAMILY';
public const DEDUCTIBLE = 'DEDUCTIBLE';
/**
* Resolves the standardized type for an insurance or package.
*
* @param Insurance $insurance The insurance to resolve the type for
*
* @return string|null The resolved type constant or null if unresolvable
*/
public function resolveType(Insurance $insurance): ?string
{
if (!$insurance->package) {
return $this->mapSubtypeToType($insurance->subType, $insurance->familyInsurance);
}
return $this->resolvePackageType($insurance);
}
/**
* Resolves the type for an insurance package by analyzing contained insurances.
*
* @param Insurance $package The package to analyze
*
* @return string|null The resolved type or null if no primary type found
*/
private function resolvePackageType(Insurance $package): ?string
{
// Get primary (non-deductible) insurance type from contained insurances
$primaryType = null;
foreach ($package->containedInsurances as $contained) {
$baseType = $this->mapSubtypeToBaseType($contained->subType);
if ($baseType && self::DEDUCTIBLE !== $baseType) {
$primaryType = $baseType;
break;
}
}
// Apply family suffix using package's familyInsurance flag
return $primaryType ? $primaryType.($package->familyInsurance ? '_FAMILY' : '') : null;
}
/**
* Maps a subtype to a full type including family variant.
*
* @param string|null $subtype The subtype to map
* @param bool $isFamily Whether this is a family insurance
*
* @return string|null The mapped type or null if unmappable
*/
private function mapSubtypeToType(?string $subtype, bool $isFamily): ?string
{
$baseType = $this->mapSubtypeToBaseType($subtype);
return $baseType ? $baseType.($isFamily ? '_FAMILY' : '') : null;
}
/**
* Maps a subtype to its base type constant.
*
* @param string|null $subtype The subtype to map
*
* @return string|null The base type constant or null if unmappable
*/
private function mapSubtypeToBaseType(?string $subtype): ?string
{
return match ($subtype) {
'RRV' => self::TRAVEL_CANCELLATION,
'PAK' => self::TRAVEL_PROTECTION,
'OHN' => self::DEDUCTIBLE,
default => null,
};
}
/**
* Gets all available insurance type constants.
*
* @return array<string> Array of all type constants
*/
public function getAllTypes(): array
{
return [
self::TRAVEL_CANCELLATION,
self::TRAVEL_CANCELLATION_FAMILY,
self::TRAVEL_PROTECTION,
self::TRAVEL_PROTECTION_FAMILY,
self::DEDUCTIBLE,
];
}
/**
* Checks if a type is a family variant.
*
* @param string $type The type to check
*
* @return bool True if the type is a family variant
*/
public function isFamilyType(string $type): bool
{
return str_ends_with($type, '_FAMILY');
}
/**
* Gets the base type from a family type.
*
* @param string $type The type to get the base for
*
* @return string The base type (without _FAMILY suffix)
*/
public function getBaseType(string $type): string
{
return str_replace('_FAMILY', '', $type);
}
}