Commit 6a9c80d7 authored by Volker Krause's avatar Volker Krause
Browse files

Handle return trip stations in the UIC parser

Same pattern as for the outbound side, also adding support for ERA FCB
content.
parent c2f1a9f3
Pipeline #261847 passed with stage
in 11 minutes and 17 seconds
......@@ -85,6 +85,50 @@
},
"pnr": "9E8DXL",
"rawData": "<binary: 442 bytes>",
"returnArrivalStation": {
"address": {
"addressCountry": "",
"addressLocality": "",
"addressRegion": "",
"className": "PostalAddress",
"isEmpty": true,
"postalCode": "",
"streetAddress": ""
},
"className": "TrainStation",
"geo": {
"className": "GeoCoordinates",
"isValid": false,
"latitude": null,
"longitude": null
},
"geoUri": "",
"identifier": "",
"name": "Köln",
"telephone": ""
},
"returnDepartureStation": {
"address": {
"addressCountry": "",
"addressLocality": "",
"addressRegion": "",
"className": "PostalAddress",
"isEmpty": true,
"postalCode": "",
"streetAddress": ""
},
"className": "TrainStation",
"geo": {
"className": "GeoCoordinates",
"isValid": false,
"latitude": null,
"longitude": null
},
"geoUri": "",
"identifier": "",
"name": "Frankfurt(Main)+City",
"telephone": ""
},
"seatingType": "2",
"validFrom": "Invalid Date",
"validUntil": "Invalid Date"
......@@ -178,6 +222,50 @@
},
"pnr": "9E8DXL",
"rawData": "<binary: 442 bytes>",
"returnArrivalStation": {
"address": {
"addressCountry": "",
"addressLocality": "",
"addressRegion": "",
"className": "PostalAddress",
"isEmpty": true,
"postalCode": "",
"streetAddress": ""
},
"className": "TrainStation",
"geo": {
"className": "GeoCoordinates",
"isValid": false,
"latitude": null,
"longitude": null
},
"geoUri": "",
"identifier": "",
"name": "Köln",
"telephone": ""
},
"returnDepartureStation": {
"address": {
"addressCountry": "",
"addressLocality": "",
"addressRegion": "",
"className": "PostalAddress",
"isEmpty": true,
"postalCode": "",
"streetAddress": ""
},
"className": "TrainStation",
"geo": {
"className": "GeoCoordinates",
"isValid": false,
"latitude": null,
"longitude": null
},
"geoUri": "",
"identifier": "",
"name": "Frankfurt(Main)+City",
"telephone": ""
},
"seatingType": "2",
"validFrom": "Invalid Date",
"validUntil": "Invalid Date"
......
......@@ -22,6 +22,14 @@
"givenName": "kíck_-_:.,stû R"
},
"pnr": "9E8DXL",
"returnArrivalStation": {
"@type": "TrainStation",
"name": "Köln"
},
"returnDepartureStation": {
"@type": "TrainStation",
"name": "Frankfurt(Main)+City"
},
"seatingType": "2"
}
]
......@@ -21,32 +21,36 @@ public:
* in the format needed for output with our JSON-LD format.
*/
template <typename T>
static QString fromStationIdentifier(const T &doc)
static QString fromStationIdentifier(Fcb::CodeTableType stationCodeTable, const T &doc)
{
switch (doc.stationCodeTable) {
switch (stationCodeTable) {
case Fcb::stationUIC:
case Fcb::stationUICReservation:
return stringifyUicStationIdentifier(doc.fromStationNum, doc.fromStationIA5);
default:
qCWarning(Log) << "Unhandled station code table:" << doc.stationCodeTable;
qCWarning(Log) << "Unhandled station code table:" << stationCodeTable;
}
return stringifyStationIdentifier(doc.fromStationNumIsSet(), doc.fromStationNum, doc.fromStationIA5);
}
template <typename T>
static QString fromStationIdentifier(const T &doc) { return fromStationIdentifier(doc.stationCodeTable, doc); }
/** Arrival station identifier for a travel document,
* in the format needed for output with our JSON-LD format.
*/
template <typename T>
static QString toStationIdentifier(const T &doc)
static QString toStationIdentifier(Fcb::CodeTableType stationCodeTable, const T &doc)
{
switch (doc.stationCodeTable) {
switch (stationCodeTable) {
case Fcb::stationUIC:
case Fcb::stationUICReservation:
return stringifyUicStationIdentifier(doc.toStationNum, doc.toStationIA5);
default:
qCWarning(Log) << "Unhandled station code table:" << doc.stationCodeTable;
qCWarning(Log) << "Unhandled station code table:" << stationCodeTable;
}
return stringifyStationIdentifier(doc.toStationNumIsSet(), doc.toStationNum, doc.toStationIA5);
}
template <typename T>
static QString toStationIdentifier(const T &doc) { return toStationIdentifier(doc.stationCodeTable, doc); }
private:
static QString stringifyUicStationIdentifier(int num, const QByteArray &ia5);
......
......@@ -59,18 +59,6 @@ void Uic9183DocumentProcessor::expandNode(ExtractorDocumentNode &node, [[maybe_u
}
}
static QJsonValue makeStation(const QString &name)
{
if (name.isEmpty()) {
return {};
}
QJsonObject station;
station.insert(QStringLiteral("@type"), QLatin1String("TrainStation"));
station.insert(QStringLiteral("name"), name);
return station;
}
static bool isValidTrip(const QJsonObject &trip)
{
if (trip.size() <= 1) {
......@@ -125,9 +113,9 @@ void Uic9183DocumentProcessor::preExtract(ExtractorDocumentNode &node, [[maybe_u
trip.insert(QStringLiteral("arrivalTime"), JsonLdDocument::toJsonValue(rct2.outboundArrivalTime()));
}
if (rct2.type() == Rct2Ticket::Transport && !rct2.returnDepartureStation().isEmpty()) {
returnTrip.insert(QStringLiteral("departureStation"), makeStation(rct2.returnDepartureStation()));
returnTrip.insert(QStringLiteral("arrivalStation"), makeStation(rct2.returnArrivalStation()));
if (rct2.type() == Rct2Ticket::Transport && !p.returnDepartureStation().name().isEmpty()) {
returnTrip.insert(QStringLiteral("departureStation"), JsonLdDocument::toJson(p.returnDepartureStation()));
returnTrip.insert(QStringLiteral("arrivalStation"), JsonLdDocument::toJson(p.returnArrivalStation()));
if (rct2.returnDepartureTime().isValid()) {
returnTrip.insert(QStringLiteral("departureDay"), JsonLdDocument::toJsonValue(rct2.returnDepartureTime().date()));
......
......@@ -306,11 +306,8 @@ function parseUic9183(code, node) {
ret.reservedTicket = node.result[0];
applyUic9183ToReservation(ret, code);
ret.reservationFor.departureDay = JsonLd.toDateTime(bl.findSubBlock('032').content, 'dd.mm.yyyy', 'de');
ret.reservationFor.departureStation.name = bl.findSubBlock('017').content;
ret.reservationFor.departureStation.identifier = ret.reservationFor.departureStation.name === res.reservationFor.arrivalStation.name ? code.outboundArrivalStation.identifier : undefined;
ret.reservationFor.arrivalStation.name = bl.findSubBlock('018').content;
ret.reservationFor.arrivalStation.identifier = ret.reservationFor.arrivalStation.name === res.reservationFor.departureStation.name ? code.outboundDepartureStation.identifier : undefined;
ret.reservationFor.departureStation = JsonLd.toJson(code.returnDepartureStation);
ret.reservationFor.arrivalStation = JsonLd.toJson(code.returnArrivalStation);
return [res, ret];
}
......
......@@ -477,6 +477,84 @@ TrainStation Uic9183Parser::outboundArrivalStation() const
return station;
}
TrainStation Uic9183Parser::returnDepartureStation() const
{
TrainStation station;
// RTC2 ticket layout
if (const auto rtc2 = rct2Ticket(); rtc2.isValid()) {
station.setName(rtc2.returnDepartureStation());
}
const auto outboundArrival = outboundArrivalStation();
// DB vendor block
if (const auto b = findBlock<Vendor0080BLBlock>(); b.isValid()) {
if (const auto sblock = b.findSubBlock("017"); !sblock.isNull()) {
station.setName(sblock.toString());
}
if (outboundArrival.name() == station.name()) {
station.setIdentifier(outboundArrival.identifier());
}
}
// ERA FCB
if (const auto fcb = findBlock<Fcb::UicRailTicketData>(); fcb.isValid() && !fcb.transportDocument.isEmpty()) {
const auto doc = fcb.transportDocument.at(0);
if (doc.ticket.userType() == qMetaTypeId<Fcb::OpenTicketData>()) {
const auto nrt = doc.ticket.value<Fcb::OpenTicketData>();
if (nrt.returnIncluded && nrt.returnDescriptionIsSet()) {
station.setName(nrt.returnDescription.fromStationNameUTF8);
station.setIdentifier(FcbUtil::fromStationIdentifier(nrt.stationCodeTable, nrt.returnDescription));
} else if (nrt.returnIncluded) {
if (outboundArrival.name() == station.name()) {
station.setIdentifier(outboundArrival.identifier());
}
}
}
}
return station;
}
TrainStation Uic9183Parser::returnArrivalStation() const
{
TrainStation station;
// RTC2 ticket layout
if (const auto rtc2 = rct2Ticket(); rtc2.isValid()) {
station.setName(rtc2.returnArrivalStation());
}
const auto outboundDeparture = outboundDepartureStation();
// DB vendor block
if (const auto b = findBlock<Vendor0080BLBlock>(); b.isValid()) {
if (const auto sblock = b.findSubBlock("018"); !sblock.isNull()) {
station.setName(sblock.toString());
}
if (outboundDeparture.name() == station.name()) {
station.setIdentifier(outboundDeparture.identifier());
}
}
// ERA FCB
if (const auto fcb = findBlock<Fcb::UicRailTicketData>(); fcb.isValid() && !fcb.transportDocument.isEmpty()) {
const auto doc = fcb.transportDocument.at(0);
if (doc.ticket.userType() == qMetaTypeId<Fcb::OpenTicketData>()) {
const auto nrt = doc.ticket.value<Fcb::OpenTicketData>();
if (nrt.returnIncluded && nrt.returnDescriptionIsSet()) {
station.setName(nrt.returnDescription.toStationNameUTF8);
station.setIdentifier(FcbUtil::toStationIdentifier(nrt.stationCodeTable, nrt.returnDescription));
} else if (nrt.returnIncluded) {
if (outboundDeparture.name() == station.name()) {
station.setIdentifier(outboundDeparture.identifier());
}
}
}
}
return station;
}
static QString fcbClassCodeToString(Fcb::TravelClassType classCode)
{
switch (classCode) {
......
......@@ -46,6 +46,8 @@ class KITINERARY_EXPORT Uic9183Parser
Q_PROPERTY(KItinerary::Person person READ person)
Q_PROPERTY(KItinerary::TrainStation outboundDepartureStation READ outboundDepartureStation)
Q_PROPERTY(KItinerary::TrainStation outboundArrivalStation READ outboundArrivalStation)
Q_PROPERTY(KItinerary::TrainStation returnDepartureStation READ returnDepartureStation)
Q_PROPERTY(KItinerary::TrainStation returnArrivalStation READ returnArrivalStation)
Q_PROPERTY(QString seatingType READ seatingType)
/** U_TLAY ticket layout block, if present, @c null otherwise. */
Q_PROPERTY(QVariant ticketLayout READ ticketLayoutVariant)
......@@ -87,6 +89,10 @@ public:
TrainStation outboundDepartureStation() const;
/** Station object for the arrival station of the outbound trip. */
TrainStation outboundArrivalStation() const;
/** Station object for the departure station of the return trip. */
TrainStation returnDepartureStation() const;
/** Station object for the arrival station of the return trip. */
TrainStation returnArrivalStation() const;
/** @see Ticket::seatingType */
QString seatingType() const;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment