db-vendo-client/p/dbnav/journeys-req.js
Marius Angelmann 86f2302ad4
Add BMIS number support for business customer rates (#30)
* Add BMIS number support for business customer rates

Introduces a new `bmisNumber` option to journey requests, allowing bahn.business customers to access corporate rates by providing their 7-digit BMIS number. Adds documentation and a `createBusinessClient` helper for convenience. The request payload now includes a `firmenZugehoerigkeit` object when a BMIS number is set.

* Update cspell.config.json

Update cspell.config.json to fix spell check issues in PR #30
2025-07-14 19:48:41 +02:00

103 lines
2.8 KiB
JavaScript

import {getHeaders} from './header.js';
const formatBaseJourneysReq = (ctx) => {
// TODO opt.accessibility
// TODO routingMode
const travellers = ctx.profile.formatTravellers(ctx);
const baseReq = {
autonomeReservierung: false,
einstiegsTypList: [
'STANDARD',
],
fahrverguenstigungen: {
deutschlandTicketVorhanden: ctx.opt.deutschlandTicketDiscount,
nurDeutschlandTicketVerbindungen: ctx.opt.deutschlandTicketConnectionsOnly,
},
klasse: travellers.klasse,
reisendenProfil: {
reisende: travellers.reisende.map(t => {
return {
ermaessigungen: [
t.ermaessigungen[0].art + ' ' + t.ermaessigungen[0].klasse,
],
reisendenTyp: t.typ,
alter: t.alter.length && parseInt(t.alter[0]) || undefined,
};
}),
},
reservierungsKontingenteVorhanden: false,
};
// Add business customer affiliation if BMIS number is provided
if (ctx.opt.bmisNumber) {
baseReq.firmenZugehoerigkeit = {
bmisNr: ctx.opt.bmisNumber,
identifikationsart: 'BMIS',
};
}
return baseReq;
};
const formatJourneysReq = (ctx, from, to, when, outFrwd, journeysRef) => {
const {profile, opt} = ctx;
from = profile.formatLocation(profile, from, 'from');
to = profile.formatLocation(profile, to, 'to');
const filters = profile.formatProductsFilter({profile}, opt.products || {}, 'dbnav');
const transfers = profile.formatTransfers(opt.transfers) ?? undefined; // `dbnav` does not allow `null` here
// TODO opt.accessibility
// TODO routingMode
let query = formatBaseJourneysReq(ctx);
query.reiseHin = {
wunsch: {
abgangsLocationId: from.lid,
verkehrsmittel: filters,
zeitWunsch: {
reiseDatum: profile.formatTime(profile, when, true),
zeitPunktArt: outFrwd ? 'ABFAHRT' : 'ANKUNFT',
},
viaLocations: opt.via
? [{locationId: profile.formatLocation(profile, opt.via, 'opt.via').lid}]
: undefined,
zielLocationId: to.lid,
maxUmstiege: transfers,
minUmstiegsdauer: opt.transferTime || undefined,
fahrradmitnahme: opt.bike,
},
};
if (journeysRef) {
query.reiseHin.wunsch.context = journeysRef;
}
if (opt.notOnlyFastRoutes) {
query.reiseHin.wunsch.economic = true;
}
return {
endpoint: opt.bestprice ? profile.bestpriceEndpoint : profile.journeysEndpoint,
body: query,
headers: getHeaders('application/x.db.vendo.mob.verbindungssuche.v8+json'),
method: 'post',
};
};
const formatRefreshJourneyReq = (ctx, refreshToken) => {
const {profile, opt} = ctx;
let query = {
reconCtx: refreshToken,
};
if (opt.tickets) {
query = formatBaseJourneysReq(ctx);
query.verbindungHin = {kontext: refreshToken};
}
return {
endpoint: opt.tickets ? profile.refreshJourneysEndpointTickets : profile.refreshJourneysEndpointPolyline,
body: query,
headers: getHeaders('application/x.db.vendo.mob.verbindungssuche.v8+json'),
method: 'post',
};
};
export {
formatJourneysReq,
formatRefreshJourneyReq,
};