ctucx.git: trainsearch

web based trip-planner, fork of https://cyberchaos.dev/yuka/trainsearch

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
65 
66 
67 
68 
69 
70 
71 
72 
73 
74 
75 
76 
77 
78 
79 
80 
81 
82 
83 
84 
85 
86 
87 
88 
89 
90 
91 
92 
93 
94 
95 
96 
97 
98 
99 
100 
101 
102 
103 
104 
105 
106 
107 
108 
109 
//  This code is mostly from marudor's great bahn.expert project.
//  See here: https://github.com/marudor/bahn.expert/tree/main/src/server/coachSequence
//  Since the source is MIT licensed, to following code is it too.
//

import { getBaureiheByCoaches, getBaureiheByUIC } from './baureihe.js';
import { getSeatsForCoach } from './specialSeats.js';
import TrainNames from './TrainNames.js';

const hasNonLokCoach = group => group.coaches.some(c => c.category !== 'LOK' && c.category !== 'TRIEBKOPF');

export function enrichCoachSequence(coachSequence) {
  let prevGroup;

  for (const group of coachSequence.sequence.groups) {
    enrichCoachSequenceGroup(group, coachSequence.product);

    if (!hasNonLokCoach(group)) {
      continue;
    }

    if (prevGroup && prevGroup.destinationName !== group.destinationName) {
      coachSequence.multipleDestinations = true;
    }

    if (prevGroup && prevGroup.number !== group.number) {
      coachSequence.multipleTrainNumbers = true;
    }

    prevGroup = group;
  }
}
const allowedBR = ['IC', 'EC', 'ICE', 'ECE'];
const tznRegex = /(\d+)/;

function enrichCoachSequenceGroup(group, product) {
  // https://inside.bahn.de/entstehung-zugnummern/?dbkanal_006=L01_S01_D088_KTL0006_INSIDE-BAHN-2019_Zugnummern_LZ01
  const trainNumberAsNumber = Number.parseInt(group.number, 10);

  if (trainNumberAsNumber >= 9550 && trainNumberAsNumber <= 9599) {
    group.coaches.forEach(c => {
      if (c.features.comfort) {
        c.features.comfort = false;
      }
    });
  }

  if (allowedBR.includes(product.type)) {
    let tzn;

    if (group.name.startsWith('IC')) {
      tzn = tznRegex.exec(group.name)?.[0];
      group.trainName = TrainNames(tzn);
    }

    group.baureihe = calculateBR(group.coaches, tzn);


    if (group.baureihe) {
      if (
        group.baureihe.identifier === '401.LDV' ||
        group.baureihe.identifier === '401.9'
      ) {
        // Schwerbehindertenplätze/Vorrangplätze sind in Wagen 11, nicht 12
        for (const coach of group.coaches) {
          if (coach.identificationNumber === '11') {
            coach.features.disabled = true;
          }
          if (coach.identificationNumber === '12') {
            coach.features.disabled = false;
          }
        }
      }
      if (
        group.baureihe.identifier === '4010' ||
        group.baureihe.identifier === '4110'
      ) {
        for (const c of group.coaches) {
          switch (c.identificationNumber) {
            case '6': {
              c.features.disabled = true;
              break;
            }
            case '5': {
              c.features.disabled = true;
              break;
            }
            case '4': {
              c.features.disabled = false;
            }
          }
        }
      }
      for (const c of group.coaches) {
        //c.seats = getSeatsForCoach(c, group.baureihe.identifier);
      }
    }
  }
}

function calculateBR(coaches, tzn) {
  for (const c of coaches) {
    if (!c.uic) continue;
    const br = getBaureiheByUIC(c.uic, coaches, tzn);
    if (br) return br;
  }

  return getBaureiheByCoaches(coaches);
}