Repository: digitalservicebund/a2j-rechtsantragstelle
Pull request #1801: ZOV: Empty last column for denied boarding
Author: login: pgurusinga
Created: 2025-02-28T15:18:06Z | Merged: 2025-03-03T14:44:19Z

https://app.asana.com/0/1207022303033556/1209431932880757


Diff:
diff --git a/app/domains/fluggastrechte/services/pdf/sections/reason/factsOfCases/table/__test__/getConnectionDetails.test.ts b/app/domains/fluggastrechte/services/pdf/sections/reason/factsOfCases/table/__test__/getConnectionDetails.test.ts
index d90534435c..2354f2a7f9 100644
--- a/app/domains/fluggastrechte/services/pdf/sections/reason/factsOfCases/table/__test__/getConnectionDetails.test.ts
+++ b/app/domains/fluggastrechte/services/pdf/sections/reason/factsOfCases/table/__test__/getConnectionDetails.test.ts
@@ -436,4 +436,60 @@ describe("getConnectionDetails", () => {
       });
     });
   });
+
+  describe("nichtbefoerderung", () => {
+    it("should return flight replacement details when 'ersatzverbindungArt' is 'flug'", () => {
+      const userData: FluggastrechtContext = {
+        bereich: "nichtbefoerderung",
+        ersatzverbindungArt: "flug",
+        direktAnkunftsDatum: "10.11.2024",
+        direktAnkunftsZeit: "12:00",
+        ersatzFlugAnkunftsDatum: "10.11.2024",
+        ersatzFlugAnkunftsZeit: "15:30",
+        ersatzFlugnummer: "AB123",
+      };
+      const result = getConnectionDetails(userData);
+      expect(result).toEqual({
+        info: "--",
+        timeTable: ["AB123", "--", "10.11.2024, 15:30"],
+      });
+    });
+
+    it("should return alternative transportation details when 'ersatzverbindungArt' is 'etwasAnderes'", () => {
+      const userData: FluggastrechtContext = {
+        bereich: "nichtbefoerderung",
+        ersatzverbindungArt: "etwasAnderes",
+        direktAnkunftsDatum: "10.11.2024",
+        direktAnkunftsZeit: "12:00",
+        andereErsatzverbindungAnkunftsDatum: "10.11.2024",
+        andereErsatzverbindungAnkunftsZeit: "14:30",
+      };
+      const result = getConnectionDetails(userData);
+      expect(result).toEqual({
+        info: "--",
+        timeTable: ["--", "--", "10.11.2024, 14:30"],
+      });
+    });
+
+    it("should return not measure and did not arrive text for 'keineAnkunft' ersatzverbindungArt", () => {
+      const userData: FluggastrechtContext = {
+        ersatzverbindungArt: "keineAnkunft",
+        bereich: "nichtbefoerderung",
+      };
+      const result = getConnectionDetails(userData);
+      expect(result).toEqual({
+        info: NOT_MEASURE_DID_NOT_ARRIVE_TEXT,
+        timeTable: ["--", "--", "--"],
+      });
+    });
+
+    it("should return error if no valid ersatzverbindungArt or tatsaechlicherFlug is provided", () => {
+      const userData: FluggastrechtContext = { bereich: "nichtbefoerderung" };
+      const result = getConnectionDetails(userData);
+      expect(result).toEqual({
+        info: "error",
+        timeTable: ["error", "error", "error"],
+      });
+    });
+  });
 });
diff --git a/app/domains/fluggastrechte/services/pdf/sections/reason/factsOfCases/table/getConnectionDetails.ts b/app/domains/fluggastrechte/services/pdf/sections/reason/factsOfCases/table/getConnectionDetails.ts
index 15b8579c66..033ec87752 100644
--- a/app/domains/fluggastrechte/services/pdf/sections/reason/factsOfCases/table/getConnectionDetails.ts
+++ b/app/domains/fluggastrechte/services/pdf/sections/reason/factsOfCases/table/getConnectionDetails.ts
@@ -124,10 +124,27 @@ const getConnectionDetailsCancel = (
   };
 };
 
+function getAmountOfDelay(
+  startDate?: string,
+  startTime?: string,
+  endDate?: string,
+  endTime?: string,
+  bereich?: string,
+) {
+  const duration = calculateDuration({
+    startDate: startDate ?? "",
+    startTime: startTime ?? "",
+    endDate: endDate ?? "",
+    endTime: endTime ?? "",
+  });
+  return bereich === "nichtbefoerderung" ? "--" : duration;
+}
+
 function getConnectionDetailsDelayOrNoBoarding(
   userData: FluggastrechtContext,
 ): ConnectionDetailsType {
   const {
+    bereich,
     tatsaechlicherFlug,
     ersatzverbindungArt,
     direktAnkunftsDatum,
@@ -135,12 +152,14 @@ function getConnectionDetailsDelayOrNoBoarding(
   } = userData;
 
   if (tatsaechlicherFlug === "yes") {
-    const info = calculateDuration({
-      startDate: direktAnkunftsDatum ?? "",
-      startTime: direktAnkunftsZeit ?? "",
-      endDate: userData.tatsaechlicherAnkunftsDatum ?? "",
-      endTime: userData.tatsaechlicherAnkunftsZeit ?? "",
-    });
+    const info = getAmountOfDelay(
+      direktAnkunftsDatum,
+      direktAnkunftsZeit,
+      userData.tatsaechlicherAnkunftsDatum,
+      userData.tatsaechlicherAnkunftsZeit,
+      bereich,
+    );
+
     return {
       info,
       timeTable: [
@@ -151,44 +170,51 @@ function getConnectionDetailsDelayOrNoBoarding(
     };
   }
 
+  const timeTableMapping: Record<string, string[]> = {
+    flug: [
+      userData.ersatzFlugnummer ?? "--",
+      "--",
+      `${userData.ersatzFlugAnkunftsDatum}, ${userData.ersatzFlugAnkunftsZeit}`,
+    ],
+    etwasAnderes: [
+      "--",
+      "--",
+      `${userData.andereErsatzverbindungAnkunftsDatum}, ${userData.andereErsatzverbindungAnkunftsZeit}`,
+    ],
+    keineAnkunft: ["--", "--", "--"],
+  };
+
   switch (ersatzverbindungArt) {
-    case "flug": {
-      const info = calculateDuration({
-        startDate: direktAnkunftsDatum ?? "",
-        startTime: direktAnkunftsZeit ?? "",
-        endDate: userData.ersatzFlugAnkunftsDatum ?? "",
-        endTime: userData.ersatzFlugAnkunftsZeit ?? "",
-      });
+    case "flug":
       return {
-        info,
-        timeTable: [
-          userData.ersatzFlugnummer ?? "--",
-          "--",
-          `${userData.ersatzFlugAnkunftsDatum}, ${userData.ersatzFlugAnkunftsZeit}`,
-        ],
+        info: getAmountOfDelay(
+          direktAnkunftsDatum,
+          direktAnkunftsZeit,
+          userData.ersatzFlugAnkunftsDatum,
+          userData.ersatzFlugAnkunftsZeit,
+          bereich,
+        ),
+        timeTable: timeTableMapping.flug,
       };
-    }
-    case "etwasAnderes": {
-      const info = calculateDuration({
-        startDate: direktAnkunftsDatum ?? "",
-        startTime: direktAnkunftsZeit ?? "",
-        endDate: userData.andereErsatzverbindungAnkunftsDatum ?? "",
-        endTime: userData.andereErsatzverbindungAnkunftsZeit ?? "",
-      });
+
+    case "etwasAnderes":
       return {
-        info,
-        timeTable: [
-          "--",
-          "--",
-          `${userData.andereErsatzverbindungAnkunftsDatum}, ${userData.andereErsatzverbindungAnkunftsZeit}`,
-        ],
+        info: getAmountOfDelay(
+          direktAnkunftsDatum,
+          direktAnkunftsZeit,
+          userData.andereErsatzverbindungAnkunftsDatum,
+          userData.andereErsatzverbindungAnkunftsZeit,
+          bereich,
+        ),
+        timeTable: timeTableMapping.etwasAnderes,
       };
-    }
+
     case "keineAnkunft":
       return {
         info: NOT_MEASURE_DID_NOT_ARRIVE_TEXT,
-        timeTable: ["--", "--", "--"],
+        timeTable: timeTableMapping.keineAnkunft,
       };
+
     default:
       return { info: "error", timeTable: ["error", "error", "error"] };
   }


Reviews:
user: login: judithmh
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-03T09:50:02Z
user: login: pgurusinga
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-03T10:09:12Z
user: login: judithmh
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-03T13:37:14Z
user: login: pgurusinga
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-03T13:53:10Z
user: login: pgurusinga
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-03T13:53:52Z
user: login: pgurusinga
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-03T13:54:50Z
user: login: pgurusinga
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-03T13:56:39Z
user: login: judithmh
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-03T14:05:21Z
user: login: judithmh
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-03T14:06:12Z
user: login: judithmh
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-03T14:06:55Z

Review comments:
diff_hunk: @@ -436,4 +436,76 @@ describe("getConnectionDetails", () => {
       });
     });
   });
+
+  describe("nichtbefoerderung", () => {
+    it("should return actual flight details when 'tatsaechlicherFlug' is 'yes'", () => {
path: app/domains/fluggastrechte/services/pdf/sections/reason/factsOfCases/table/__test__/getConnectionDetails.test.ts
user: login: judithmh
body: I think tatsaechlicherFlug is never yes/no here since it is never asked in the flow
created_at: 2025-03-03T09:50:02Z
author_association: CONTRIBUTOR
diff_hunk: @@ -436,4 +436,76 @@ describe("getConnectionDetails", () => {
       });
     });
   });
+
+  describe("nichtbefoerderung", () => {
+    it("should return actual flight details when 'tatsaechlicherFlug' is 'yes'", () => {
path: app/domains/fluggastrechte/services/pdf/sections/reason/factsOfCases/table/__test__/getConnectionDetails.test.ts
user: login: pgurusinga
body: thanks for checking!
created_at: 2025-03-03T10:09:12Z
author_association: MEMBER
diff_hunk: @@ -436,4 +436,60 @@ describe("getConnectionDetails", () => {
       });
     });
   });
+
+  describe("nichtbefoerderung", () => {
+    it("should return flight replacement details when 'ersatzverbindungArt' is 'flug'", () => {
+      const userData: FluggastrechtContext = {
+        bereich: "nichtbefoerderung",
+        ersatzverbindungArt: "flug",
+        direktAnkunftsDatum: "10.11.2024",
+        direktAnkunftsZeit: "12:00",
+        ersatzFlugAnkunftsDatum: "10.11.2024",
+        ersatzFlugAnkunftsZeit: "15:30",
+        ersatzFlugnummer: "AB123",
+      };
+      const result = getConnectionDetails(userData);
+      expect(result).toEqual({
+        info: "--",
+        timeTable: ["AB123", "--", "10.11.2024, 15:30"],
path: app/domains/fluggastrechte/services/pdf/sections/reason/factsOfCases/table/__test__/getConnectionDetails.test.ts
user: login: judithmh
body: why should it not show the start time and date of the Ersatzflug?
created_at: 2025-03-03T13:26:07Z
author_association: CONTRIBUTOR
diff_hunk: @@ -436,4 +436,60 @@ describe("getConnectionDetails", () => {
       });
     });
   });
+
+  describe("nichtbefoerderung", () => {
+    it("should return flight replacement details when 'ersatzverbindungArt' is 'flug'", () => {
+      const userData: FluggastrechtContext = {
+        bereich: "nichtbefoerderung",
+        ersatzverbindungArt: "flug",
+        direktAnkunftsDatum: "10.11.2024",
+        direktAnkunftsZeit: "12:00",
+        ersatzFlugAnkunftsDatum: "10.11.2024",
+        ersatzFlugAnkunftsZeit: "15:30",
+        ersatzFlugnummer: "AB123",
+      };
+      const result = getConnectionDetails(userData);
+      expect(result).toEqual({
+        info: "--",
+        timeTable: ["AB123", "--", "10.11.2024, 15:30"],
+      });
+    });
+
+    it("should return alternative transportation details when 'ersatzverbindungArt' is 'etwasAnderes'", () => {
+      const userData: FluggastrechtContext = {
+        bereich: "nichtbefoerderung",
+        ersatzverbindungArt: "etwasAnderes",
+        direktAnkunftsDatum: "10.11.2024",
+        direktAnkunftsZeit: "12:00",
+        andereErsatzverbindungAnkunftsDatum: "10.11.2024",
+        andereErsatzverbindungAnkunftsZeit: "14:30",
+      };
+      const result = getConnectionDetails(userData);
+      expect(result).toEqual({
+        info: "--",
+        timeTable: ["--", "--", "10.11.2024, 14:30"],
path: app/domains/fluggastrechte/services/pdf/sections/reason/factsOfCases/table/__test__/getConnectionDetails.test.ts
user: login: judithmh
body: same here: why should it not show the start time and date of the Ersatzverbidung?
created_at: 2025-03-03T13:27:02Z
author_association: CONTRIBUTOR
diff_hunk: @@ -124,23 +124,42 @@ const getConnectionDetailsCancel = (
   };
 };
 
+function getDurationAndInfo(
path: app/domains/fluggastrechte/services/pdf/sections/reason/factsOfCases/table/getConnectionDetails.ts
user: login: judithmh
body: maybe renaming in getAmountOfDelay since to my knowledge it does not give the duration of the travel but rather the difference between the original arrival time and the one of the ersatzverbindung
created_at: 2025-03-03T13:31:19Z
author_association: CONTRIBUTOR
diff_hunk: @@ -151,44 +170,51 @@ function getConnectionDetailsDelayOrNoBoarding(
     };
   }
 
+  const timeTableMapping: Record<string, string[]> = {
+    flug: [
+      userData.ersatzFlugnummer ?? "--",
+      "--",
path: app/domains/fluggastrechte/services/pdf/sections/reason/factsOfCases/table/getConnectionDetails.ts
user: login: judithmh
body: should it not be `${userData.ersatzFlugAbflugsDatum}, ${userData.ersatzFlugAbflugsZeit}`?
created_at: 2025-03-03T13:34:02Z
author_association: CONTRIBUTOR
diff_hunk: @@ -436,4 +436,60 @@ describe("getConnectionDetails", () => {
       });
     });
   });
+
+  describe("nichtbefoerderung", () => {
+    it("should return flight replacement details when 'ersatzverbindungArt' is 'flug'", () => {
+      const userData: FluggastrechtContext = {
+        bereich: "nichtbefoerderung",
+        ersatzverbindungArt: "flug",
+        direktAnkunftsDatum: "10.11.2024",
+        direktAnkunftsZeit: "12:00",
+        ersatzFlugAnkunftsDatum: "10.11.2024",
+        ersatzFlugAnkunftsZeit: "15:30",
+        ersatzFlugnummer: "AB123",
+      };
+      const result = getConnectionDetails(userData);
+      expect(result).toEqual({
+        info: "--",
+        timeTable: ["AB123", "--", "10.11.2024, 15:30"],
+      });
+    });
+
+    it("should return alternative transportation details when 'ersatzverbindungArt' is 'etwasAnderes'", () => {
+      const userData: FluggastrechtContext = {
+        bereich: "nichtbefoerderung",
+        ersatzverbindungArt: "etwasAnderes",
+        direktAnkunftsDatum: "10.11.2024",
+        direktAnkunftsZeit: "12:00",
+        andereErsatzverbindungAnkunftsDatum: "10.11.2024",
+        andereErsatzverbindungAnkunftsZeit: "14:30",
+      };
+      const result = getConnectionDetails(userData);
+      expect(result).toEqual({
+        info: "--",
+        timeTable: ["--", "--", "10.11.2024, 14:30"],
path: app/domains/fluggastrechte/services/pdf/sections/reason/factsOfCases/table/__test__/getConnectionDetails.test.ts
user: login: pgurusinga
body: here because we don't ask when the user starts flying
![image](https://github.com/user-attachments/assets/c2759b22-98f9-4f9e-b8c0-e1200ffc0bb2)

created_at: 2025-03-03T13:53:10Z
author_association: MEMBER
diff_hunk: @@ -436,4 +436,60 @@ describe("getConnectionDetails", () => {
       });
     });
   });
+
+  describe("nichtbefoerderung", () => {
+    it("should return flight replacement details when 'ersatzverbindungArt' is 'flug'", () => {
+      const userData: FluggastrechtContext = {
+        bereich: "nichtbefoerderung",
+        ersatzverbindungArt: "flug",
+        direktAnkunftsDatum: "10.11.2024",
+        direktAnkunftsZeit: "12:00",
+        ersatzFlugAnkunftsDatum: "10.11.2024",
+        ersatzFlugAnkunftsZeit: "15:30",
+        ersatzFlugnummer: "AB123",
+      };
+      const result = getConnectionDetails(userData);
+      expect(result).toEqual({
+        info: "--",
+        timeTable: ["AB123", "--", "10.11.2024, 15:30"],
path: app/domains/fluggastrechte/services/pdf/sections/reason/factsOfCases/table/__test__/getConnectionDetails.test.ts
user: login: pgurusinga
body: same here as well, no question asked for start

![image](https://github.com/user-attachments/assets/0b20a7a2-4774-430b-a23e-876eb9620ea4)

created_at: 2025-03-03T13:53:52Z
author_association: MEMBER
diff_hunk: @@ -124,23 +124,42 @@ const getConnectionDetailsCancel = (
   };
 };
 
+function getDurationAndInfo(
path: app/domains/fluggastrechte/services/pdf/sections/reason/factsOfCases/table/getConnectionDetails.ts
user: login: pgurusinga
body: sure
created_at: 2025-03-03T13:54:50Z
author_association: MEMBER
diff_hunk: @@ -151,44 +170,51 @@ function getConnectionDetailsDelayOrNoBoarding(
     };
   }
 
+  const timeTableMapping: Record<string, string[]> = {
+    flug: [
+      userData.ersatzFlugnummer ?? "--",
+      "--",
path: app/domains/fluggastrechte/services/pdf/sections/reason/factsOfCases/table/getConnectionDetails.ts
user: login: pgurusinga
body: since when do we have `ersatzFlugAbflugsDatum` and `ersatzFlugAbflugsZeit` ?
created_at: 2025-03-03T13:56:39Z
author_association: MEMBER
diff_hunk: @@ -436,4 +436,60 @@ describe("getConnectionDetails", () => {
       });
     });
   });
+
+  describe("nichtbefoerderung", () => {
+    it("should return flight replacement details when 'ersatzverbindungArt' is 'flug'", () => {
+      const userData: FluggastrechtContext = {
+        bereich: "nichtbefoerderung",
+        ersatzverbindungArt: "flug",
+        direktAnkunftsDatum: "10.11.2024",
+        direktAnkunftsZeit: "12:00",
+        ersatzFlugAnkunftsDatum: "10.11.2024",
+        ersatzFlugAnkunftsZeit: "15:30",
+        ersatzFlugnummer: "AB123",
+      };
+      const result = getConnectionDetails(userData);
+      expect(result).toEqual({
+        info: "--",
+        timeTable: ["AB123", "--", "10.11.2024, 15:30"],
path: app/domains/fluggastrechte/services/pdf/sections/reason/factsOfCases/table/__test__/getConnectionDetails.test.ts
user: login: judithmh
body: you are right -sorry 😅 
created_at: 2025-03-03T14:05:21Z
author_association: CONTRIBUTOR
diff_hunk: @@ -151,44 +170,51 @@ function getConnectionDetailsDelayOrNoBoarding(
     };
   }
 
+  const timeTableMapping: Record<string, string[]> = {
+    flug: [
+      userData.ersatzFlugnummer ?? "--",
+      "--",
path: app/domains/fluggastrechte/services/pdf/sections/reason/factsOfCases/table/getConnectionDetails.ts
user: login: judithmh
body: you are right sorry we don't have it - must have been a fever dream 😅 
created_at: 2025-03-03T14:06:12Z
author_association: CONTRIBUTOR

PR comments:
user: login: sonarqubecloud[bot]
created_at: 2025-03-03T14:39:22Z
body: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=digitalservicebund_a2j-rechtsantragstelle&pullRequest=1801) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=digitalservicebund_a2j-rechtsantragstelle&pullRequest=1801&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=digitalservicebund_a2j-rechtsantragstelle&pullRequest=1801&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=digitalservicebund_a2j-rechtsantragstelle&pullRequest=1801&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [84.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=digitalservicebund_a2j-rechtsantragstelle&pullRequest=1801&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=digitalservicebund_a2j-rechtsantragstelle&pullRequest=1801&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=digitalservicebund_a2j-rechtsantragstelle&pullRequest=1801)


author_association: NONE