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

View File

@ -0,0 +1,8 @@
-- AlterEnum
ALTER TYPE "CostTypeVariant" ADD VALUE 'GRUNDPREIS_ZEIT';
-- AlterTable
ALTER TABLE "_AvicennaTenantToTariffGroup" ADD CONSTRAINT "_AvicennaTenantToTariffGroup_AB_pkey" PRIMARY KEY ("A", "B");
-- DropIndex
DROP INDEX "_AvicennaTenantToTariffGroup_AB_unique";

View File

@ -0,0 +1,2 @@
-- AlterEnum
ALTER TYPE "CostTypeVariant" ADD VALUE 'PRIVATVERSICHERUNG';

View File

@ -1,3 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (i.e. Git)
provider = "postgresql"
# It should be added in your version-control system (e.g., Git)
provider = "postgresql"

View File

@ -526,6 +526,8 @@ enum CostTypeVariant {
FAHRZEUGZUSCHLAG
TSWDIFFERENZIERUNG
GRUNDPREIS
GRUNDPREIS_ZEIT
PRIVATVERSICHERUNG
}
model AvicennaTenant {

View File

@ -192,19 +192,19 @@ export const BTW_AOK_TARIFFS = [
costTypes: [
{
description: 'Grundpauschale je Fahrt',
variant: CostTypeVariant.NACHTZUSCHLAG,
variant: CostTypeVariant.GRUNDPREIS_ZEIT,
costAmount: 4250,
timeRange: '00:00-14:29',
},
{
description: 'Grundpauschale je Fahrt',
variant: CostTypeVariant.NACHTZUSCHLAG,
variant: CostTypeVariant.GRUNDPREIS_ZEIT,
costAmount: 4250,
timeRange: '18:01-23:59',
},
{
description: 'Grundpauschale je Fahrt (14:30-18:00)',
variant: CostTypeVariant.NACHTZUSCHLAG,
variant: CostTypeVariant.GRUNDPREIS_ZEIT,
costAmount: 5000,
timeRange: '14:30-18:00',
},
@ -239,19 +239,19 @@ export const BTW_AOK_TARIFFS = [
costTypes: [
{
description: 'Grundpauschale je Fahrt',
variant: CostTypeVariant.NACHTZUSCHLAG,
variant: CostTypeVariant.GRUNDPREIS_ZEIT,
costAmount: 4500,
timeRange: '00:00-14:29',
},
{
description: 'Grundpauschale je Fahrt',
variant: CostTypeVariant.NACHTZUSCHLAG,
variant: CostTypeVariant.GRUNDPREIS_ZEIT,
costAmount: 4500,
timeRange: '18:01-23:59',
},
{
description: 'Grundpauschale je Fahrt (14:30-18:00)',
variant: CostTypeVariant.NACHTZUSCHLAG,
variant: CostTypeVariant.GRUNDPREIS_ZEIT,
costAmount: 5000,
timeRange: '14:30-18:00',
},

View File

@ -358,7 +358,7 @@ export const KTW_AOK_TARIFFS = [
costAmount: 940,
},
{
description: 'Desinfektionszuschlag pauschal',
description: 'Desinfektionpauschale',
variant: CostTypeVariant.GRUNDPREIS,
costAmount: 2610,
},
@ -369,10 +369,10 @@ export const KTW_AOK_TARIFFS = [
kmInclusive: 18,
},
{
description: 'Nachtzuschlag 19:00-07:00',
description: 'Nachtzuschlag 18:30-06:30',
variant: CostTypeVariant.NACHTZUSCHLAG,
costAmount: 8875,
timeRange: '19:00-07:00',
timeRange: '18:30-06:30',
},
{
description: 'Wochenendzuschlag',

View File

@ -77,13 +77,13 @@ export const KTW_PRIVAT_TARIFFS = [
},
{
description: 'QMS Zuschlag',
variant: CostTypeVariant.GRUNDPREIS,
variant: CostTypeVariant.PRIVATVERSICHERUNG,
costAmount: 3300,
},
{
description: 'Hygienemaßnahmen',
variant: CostTypeVariant.GRUNDPREIS,
costAmount: 1500,
variant: CostTypeVariant.PRIVATVERSICHERUNG,
costAmount: 2000,
},
{
description: 'ab dem 16. km',

View File

@ -185,19 +185,19 @@ export const TSW_AOK_TARIFFS = [
costTypes: [
{
description: 'Grundpauschale je Fahrt',
variant: CostTypeVariant.NACHTZUSCHLAG,
variant: CostTypeVariant.GRUNDPREIS_ZEIT,
costAmount: 6250,
timeRange: '00:00-14:29',
},
{
description: 'Grundpauschale je Fahrt',
variant: CostTypeVariant.NACHTZUSCHLAG,
variant: CostTypeVariant.GRUNDPREIS_ZEIT,
costAmount: 6250,
timeRange: '18:01-23:59',
},
{
description: 'Nachmittagspauschale 14:30-18:00',
variant: CostTypeVariant.NACHTZUSCHLAG,
variant: CostTypeVariant.GRUNDPREIS_ZEIT,
costAmount: 7500,
timeRange: '14:30-18:00',
},
@ -232,13 +232,19 @@ export const TSW_AOK_TARIFFS = [
costTypes: [
{
description: 'Grundpauschale je Fahrt',
variant: CostTypeVariant.NACHTZUSCHLAG,
variant: CostTypeVariant.GRUNDPREIS_ZEIT,
costAmount: 6500,
timeRange: '00:00-14:29',
},
{
description: 'Nachmittagspauschale 14:30-18:00',
variant: CostTypeVariant.GRUNDPREIS_ZEIT,
costAmount: 7500,
timeRange: '14:30-18:00',
},
{
description: 'Grundpauschale je Fahrt',
variant: CostTypeVariant.NACHTZUSCHLAG,
variant: CostTypeVariant.GRUNDPREIS_ZEIT,
costAmount: 6500,
timeRange: '18:01-23:59',
},
@ -248,12 +254,6 @@ export const TSW_AOK_TARIFFS = [
costAmount: 200,
kmInclusive: 20,
},
{
description: 'Nachmittagszuschlag 14:30-18:00',
variant: CostTypeVariant.NACHTZUSCHLAG,
costAmount: 7500,
timeRange: '14:30-18:00',
},
{
description: 'Nachtzuschlag 18:00-07:30',
variant: CostTypeVariant.NACHTZUSCHLAG,

View File

@ -77,13 +77,14 @@ export const TSW_DAK_VDEK_TARIFFS = [
},
{
description: 'Fallmanagementzuschlag',
variant: CostTypeVariant.GRUNDPREIS,
variant: CostTypeVariant.NACHTZUSCHLAG,
costAmount: 750,
timeRange: '14:30-18:00',
},
{
description: 'Morgenzuschlag 05:00-07:00',
variant: CostTypeVariant.NACHTZUSCHLAG,
costAmount: 450,
costAmount: 445,
timeRange: '05:00-07:00',
},
{

View File

@ -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 = {

View File

@ -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)];
}

View File

@ -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,