KItinerary

iatabcbpparser.cpp
1/*
2 SPDX-FileCopyrightText: 2018 Volker Krause <vkrause@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "iatabcbpparser.h"
8#include "logging.h"
9#include "iata/iatabcbp.h"
10
11#include <KItinerary/Flight>
12#include <KItinerary/Organization>
13#include <KItinerary/Person>
14#include <KItinerary/Place>
15#include <KItinerary/Reservation>
16#include <KItinerary/Ticket>
17
18#include <QVariant>
19
20using namespace KItinerary;
21
22static QString stripLeadingZeros(const QString &s)
23{
24 const auto it = std::find_if(s.begin(), s.end(), [](const QChar &c) { return c != QLatin1Char('0'); });
25 const auto d = std::distance(s.begin(), it);
26 return s.mid(d);
27}
28
30 const QDateTime &externalIssueDate) {
31 IataBcbp bcbp(message);
32 if (!bcbp.isValid()) {
33 return {};
34 }
35 return parse(bcbp, externalIssueDate.isValid() ? externalIssueDate : QDateTime({1970, 1, 1}, {}));
36}
37
38[[nodiscard]] static QString ticketNumber(QStringView airlineNumericCode, QStringView documentNumber)
39{
40 if (airlineNumericCode.size() != 3 || documentNumber.size() != 10) {
41 return {};
42 }
43
44 if (std::any_of(airlineNumericCode.begin(), airlineNumericCode.end(), [](QChar c) { return !c.isDigit(); })
45 || std::any_of(documentNumber.begin(), documentNumber.end(), [](QChar c) { return !c.isDigit(); })) {
46 return {};
47 }
48
49 if (std::all_of(documentNumber.begin(), documentNumber.end(), [](QChar c) { return c == QLatin1Char('0'); })) {
50 return {};
51 }
52
53 return airlineNumericCode + QLatin1Char(' ') + documentNumber;
54}
55
57 const QDateTime &contextDate) {
58 const auto count = bcbp.uniqueMandatorySection().numberOfLegs();
59 const auto issueDate = bcbp.uniqueConditionalSection().dateOfIssue(contextDate);
60
61 QList<QVariant> result;
62 result.reserve(count);
63
64 Person person;
65 {
66 const auto fullName = bcbp.uniqueMandatorySection().passengerName();
67 const auto idx = fullName.indexOf(QLatin1Char('/'));
68 if (idx > 0 && idx < fullName.size() - 1) {
69 person.setFamilyName(fullName.left(idx));
70 person.setGivenName(fullName.mid(idx + 1));
71 } else {
72 person.setName(fullName);
73 }
74 }
75
76
77 for (auto i = 0; i < count; ++i) {
78 Flight flight;
79
80 const auto rms = bcbp.repeatedMandatorySection(i);
81 flight.setDepartureDay(rms.dateOfFlight(issueDate.isValid() ? QDateTime(issueDate, {}) : contextDate));
82
83 Airport dep;
84 dep.setIataCode(rms.fromCityAirportCode());
85 flight.setDepartureAirport(dep);
86 Airport arr;
87 arr.setIataCode(rms.toCityAirportCode());
88 flight.setArrivalAirport(arr);
89 Airline airline;
90 airline.setIataCode(rms.operatingCarrierDesignator());
91 flight.setAirline(airline);
92 flight.setFlightNumber(stripLeadingZeros(rms.flightNumber()));
93
95 res.setReservationFor(flight);
96 res.setPassengerSequenceNumber(stripLeadingZeros(rms.checkinSequenceNumber()));
97 res.setAirplaneSeat(stripLeadingZeros(rms.seatNumber()));
98 res.setReservationNumber(rms.operatingCarrierPNRCode());
99 res.setUnderName(person);
100
101 Ticket ticket;
102 ticket.setTicketToken(QStringLiteral("aztecCode:") + bcbp.rawData());
103 const auto rcs = bcbp.repeatedConditionalSection(i);
104 ticket.setTicketNumber(ticketNumber(rcs.airlineNumericCode(), rcs.documentNumber()));
105 res.setReservedTicket(ticket);
106
107 if (!rcs.frequenFlyerNumber().isEmpty()) {
108 ProgramMembership program;
109 program.setMembershipNumber(rcs.frequenFlyerNumber());
110 program.setProgramName(rcs.frequentFlyerAirlineDesignator());
111 program.setMember(person);
112 res.setProgramMembershipUsed(program);
113 }
114
115 result.push_back(std::move(res));
116 }
117
118 return result;
119}
A flight reservation.
Definition reservation.h:90
A flight.
Definition flight.h:25
A IATA BarCoded Boarding Pass (BCBP)
Definition iatabcbp.h:21
Q_INVOKABLE KItinerary::IataBcbpRepeatedConditionalSection repeatedConditionalSection(int leg) const
Conditional (optional) section of leg.
Definition iatabcbp.cpp:91
Q_INVOKABLE KItinerary::IataBcbpRepeatedMandatorySection repeatedMandatorySection(int leg) const
Mandatory section of leg.
Definition iatabcbp.cpp:82
A person.
Definition person.h:20
A frequent traveler, bonus points or discount scheme program membership.
A booked ticket.
Definition ticket.h:41
QString fullName(const PartType &type)
QList< QVariant > parse(const QString &message, const QDateTime &externalIssueDateTime=QDateTime())
Parses the bar coded boarding pass message message into a list of FlightReservation instances.
Classes for reservation/travel data models, data extraction and data augmentation.
Definition berelement.h:17
bool isValid() const const
void push_back(const T &value)
void reserve(int alloc)
QString::iterator begin()
QString::iterator end()
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const const
QString left(int n) const const
QString mid(int position, int n) const const
int size() const const
QStringView::const_iterator begin() const const
QStringView::const_iterator end() const const
qsizetype size() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sun Feb 25 2024 18:40:32 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.