feat: implement new costTypes

Grundpreis auf Zeit, sowie Privat Versicherung
This commit is contained in:
Marcel Arndt
2025-06-12 17:14:51 +02:00
parent 068fa9519c
commit 0fa97c53b1
12 changed files with 69 additions and 41 deletions
@@ -37,7 +37,9 @@ export const CostTypeVariant = {
KILOMETERZUSCHLAG: "KILOMETERZUSCHLAG",
FAHRZEUGZUSCHLAG: "FAHRZEUGZUSCHLAG",
TSWDIFFERENZIERUNG: "TSWDIFFERENZIERUNG",
GRUNDPREIS: "GRUNDPREIS"
GRUNDPREIS: "GRUNDPREIS",
GRUNDPREIS_ZEIT: "GRUNDPREIS_ZEIT",
PRIVATVERSICHERUNG: "PRIVATVERSICHERUNG"
} as const;
export type CostTypeVariant = (typeof CostTypeVariant)[keyof typeof CostTypeVariant];
export type Anomaly = {
@@ -17,6 +17,7 @@ import {
calculateFeiertagszuschlag,
calculateKilometerzuschlag,
calculateNachtzuschlag,
calculatePrivatVersicherung,
calculateTSW,
calculateWochenendzuschlag,
} from './cost-type-calculations';
@@ -51,7 +52,7 @@ export class CalculationService {
);
if (!tariff) {
this.logger.warn(
`No tariff found for tour ${tour.operationId} (${tour.healthInsurance})`,
`No tariff found for tour ${tour.operationId} (${healthInsurance}, ${ordinanceType})`,
);
return 0;
}
@@ -78,7 +79,7 @@ export class CalculationService {
);
if (!tariff) {
this.logger.warn(
`No tariff found for tour ${tour.operationId} (${healthInsurance}, ${ordinanceType}, ${startDate})`,
`No tariff found for tour ${tour.operationId} (${healthInsurance}, ${ordinanceType})`,
);
return { tariff: undefined, servicePositions: [] };
}
@@ -206,20 +207,17 @@ export class CalculationService {
): [CostType, number][] {
const highestZuschlag = this.getHighestZuschlag(tour, tariff);
// if TariffGroup is VDEK KTW, sum up costTypes
const isVdek = tariff.tariffGroup?.description?.indexOf('VDEK KTW') > -1;
const sumZuschlaege =
tariff.tariffGroup?.description?.indexOf('VDEK KTW') > -1 ||
tariff.tariffGroup?.description?.indexOf('Privat') > -1;
return tariff.costTypes
.map((costType) => {
switch (costType.variant) {
case CostTypeVariant.GRUNDPREIS:
// TODO: decide if you need a CostTypeVariant for QMS Zuschlag and exclude the category there
if (
costType.description.indexOf('QMS') > -1 &&
tour.category === 'Privatfahrt Rechnung'
) {
return [costType, 0];
}
return [costType, costType.costAmount];
case CostTypeVariant.PRIVATVERSICHERUNG:
return [costType, calculatePrivatVersicherung(tour, costType)];
case CostTypeVariant.TSWDIFFERENZIERUNG:
return [costType, calculateTSW(tour, costType)];
case CostTypeVariant.DESINFEKTIONSZUSCHLAG:
@@ -228,15 +226,20 @@ export class CalculationService {
return [costType, calculateKilometerzuschlag(tour, costType)];
case CostTypeVariant.FAHRZEUGZUSCHLAG:
return [costType, calculateFahrzeugzuschlag(tour, costType)];
case CostTypeVariant.GRUNDPREIS_ZEIT:
case CostTypeVariant.NACHTZUSCHLAG:
if (highestZuschlag === CostTypeVariant.NACHTZUSCHLAG || isVdek) {
if (
sumZuschlaege ||
highestZuschlag === CostTypeVariant.NACHTZUSCHLAG ||
costType.variant !== CostTypeVariant.NACHTZUSCHLAG
) {
return [costType, calculateNachtzuschlag(tour, costType)];
}
return [costType, 0];
case CostTypeVariant.WOCHENENDZUSCHLAG:
if (
highestZuschlag === CostTypeVariant.WOCHENENDZUSCHLAG ||
isVdek
sumZuschlaege
) {
return [costType, calculateWochenendzuschlag(tour, costType)];
}
@@ -244,7 +247,7 @@ export class CalculationService {
case CostTypeVariant.FEIERTAGSZUSCHLAG:
if (
highestZuschlag === CostTypeVariant.FEIERTAGSZUSCHLAG ||
isVdek
sumZuschlaege
) {
return [costType, calculateFeiertagszuschlag(tour, costType)];
}
@@ -5,6 +5,16 @@ import { generateIntervalForTimeRange } from 'src/utils';
import { INFECTION_TYPES } from './infection-types';
import { PUBLIC_HOLIDAYS_HH } from './public-holidays';
export function calculatePrivatVersicherung(tour: Tour, costType: CostType): number {
if(tour.category?.indexOf('Privatfahrt Rechnung') === -1 && tour.category?.indexOf('Barzahlung') === -1) {
if(costType.description === 'Hygienemaßnahmen' && tour.hasInfection) {
return 0;
}
return costType.costAmount;
}
return 0;
}
export function calculateDesinfektionszuschlag(
tour: Tour,
costType: CostType,