File indexing completed on 2024-11-24 04:45:11
0001 /* 0002 SPDX-FileCopyrightText: 2018 Volker Krause <vkrause@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "iatabcbpparser.h" 0008 #include "logging.h" 0009 #include "iata/iatabcbp.h" 0010 0011 #include <KItinerary/Flight> 0012 #include <KItinerary/Organization> 0013 #include <KItinerary/Person> 0014 #include <KItinerary/Place> 0015 #include <KItinerary/Reservation> 0016 #include <KItinerary/Ticket> 0017 0018 #include <QVariant> 0019 0020 using namespace KItinerary; 0021 0022 static QString stripLeadingZeros(const QString &s) 0023 { 0024 const auto it = std::find_if(s.begin(), s.end(), [](const QChar &c) { return c != QLatin1Char('0'); }); 0025 const auto d = std::distance(s.begin(), it); 0026 return s.mid(d); 0027 } 0028 0029 QList<QVariant> IataBcbpParser::parse(const QString &message, 0030 const QDateTime &externalIssueDate) { 0031 IataBcbp bcbp(message); 0032 if (!bcbp.isValid()) { 0033 return {}; 0034 } 0035 return parse(bcbp, externalIssueDate.isValid() ? externalIssueDate : QDateTime({1970, 1, 1}, {})); 0036 } 0037 0038 QList<QVariant> IataBcbpParser::parse(const IataBcbp &bcbp, 0039 const QDateTime &contextDate) { 0040 const auto count = bcbp.uniqueMandatorySection().numberOfLegs(); 0041 const auto issueDate = bcbp.uniqueConditionalSection().dateOfIssue(contextDate); 0042 0043 QList<QVariant> result; 0044 result.reserve(count); 0045 0046 Person person; 0047 { 0048 const auto fullName = bcbp.uniqueMandatorySection().passengerName(); 0049 const auto idx = fullName.indexOf(QLatin1Char('/')); 0050 if (idx > 0 && idx < fullName.size() - 1) { 0051 person.setFamilyName(fullName.left(idx)); 0052 person.setGivenName(fullName.mid(idx + 1)); 0053 } else { 0054 person.setName(fullName); 0055 } 0056 } 0057 0058 Ticket ticket; 0059 ticket.setTicketToken(QStringLiteral("aztecCode:") + bcbp.rawData()); 0060 0061 for (auto i = 0; i < count; ++i) { 0062 Flight flight; 0063 0064 const auto rms = bcbp.repeatedMandatorySection(i); 0065 flight.setDepartureDay(rms.dateOfFlight(issueDate.isValid() ? QDateTime(issueDate, {}) : contextDate)); 0066 0067 Airport dep; 0068 dep.setIataCode(rms.fromCityAirportCode()); 0069 flight.setDepartureAirport(dep); 0070 Airport arr; 0071 arr.setIataCode(rms.toCityAirportCode()); 0072 flight.setArrivalAirport(arr); 0073 Airline airline; 0074 airline.setIataCode(rms.operatingCarrierDesignator()); 0075 flight.setAirline(airline); 0076 flight.setFlightNumber(stripLeadingZeros(rms.flightNumber())); 0077 0078 FlightReservation res; 0079 res.setReservationFor(flight); 0080 res.setPassengerSequenceNumber(stripLeadingZeros(rms.checkinSequenceNumber())); 0081 res.setAirplaneSeat(stripLeadingZeros(rms.seatNumber())); 0082 res.setReservationNumber(rms.operatingCarrierPNRCode()); 0083 res.setUnderName(person); 0084 res.setReservedTicket(ticket); 0085 0086 const auto rcs = bcbp.repeatedConditionalSection(i); 0087 if (!rcs.frequenFlyerNumber().isEmpty()) { 0088 ProgramMembership program; 0089 program.setMembershipNumber(rcs.frequenFlyerNumber()); 0090 program.setProgramName(rcs.frequentFlyerAirlineDesignator()); 0091 program.setMember(person); 0092 res.setProgramMembershipUsed(program); 0093 } 0094 0095 result.push_back(std::move(res)); 0096 } 0097 0098 return result; 0099 }