Commit d45dd7da authored by Volker Krause's avatar Volker Krause

Allow to update existing events for a booking

So far we just blindly created new events, now we can merge the initial
reservation and e.g. a boarding pass into one event for the corresponding
flight.
parent 1c54711c
......@@ -5,7 +5,7 @@ CALSCALE:GREGORIAN
BEGIN:VEVENT
DTSTAMP:20171227T111649Z
CREATED:20171227T111649Z
UID:1b22236a-21ff-4885-8c99-b3b2bbca062c
UID:XXX007-1b22236a-21ff-4885-8c99-b3b2bbca062c
LAST-MODIFIED:20171227T111649Z
DESCRIPTION:Boarding time: 2:25 PM\nDeparture gate: 16\nBoarding group: C\nSeat: 16E\nBooking reference: XXX007
SUMMARY:Flight AB 8075 from HEL to TXL
......
......@@ -5,7 +5,7 @@ CALSCALE:GREGORIAN
BEGIN:VEVENT
DTSTAMP:20171227T111649Z
CREATED:20171227T111649Z
UID:1b22236a-21ff-4885-8c99-b3b2bbca062c
UID:1234567890-1b22236a-21ff-4885-8c99-b3b2bbca062c
LAST-MODIFIED:20171227T111649Z
DESCRIPTION:Check-in: 3:00 PM\nCheck-out: 12:00 PM\nBooking reference: 1234567890
SUMMARY:Hotel reservation: Glo Hotel Sello
......
......@@ -5,7 +5,7 @@ CALSCALE:GREGORIAN
BEGIN:VEVENT
DTSTAMP:20171227T111649Z
CREATED:20171227T111649Z
UID:1b22236a-21ff-4885-8c99-b3b2bbca062c
UID:XXX007-1b22236a-21ff-4885-8c99-b3b2bbca062c
LAST-MODIFIED:20171227T111649Z
DESCRIPTION:Coach: 17\nSeat: 62\nBooking reference: XXX007
SUMMARY:Train 5186 from Nîmes Gare to Lyon Part-Dieu
......
......@@ -104,6 +104,47 @@ private Q_SLOTS:
QVERIFY(*newEvent == *refEvent);
}
}
void testFindEvent_data()
{
QTest::addColumn<QString>("jsonFile");
QTest::addColumn<QString>("icalFile");
QDir dir(QStringLiteral(SOURCE_DIR "/calendarhandlerdata"));
const auto lst = dir.entryList(QStringList(QStringLiteral("*.json")), QDir::Files | QDir::Readable | QDir::NoSymLinks);
for (const auto &file : lst) {
const auto refFile = dir.path() + QLatin1Char('/') + file.left(file.size() - 4) + QStringLiteral("ics");
if (!QFile::exists(refFile)) {
qDebug() << "reference file" << refFile << "does not exist, skipping test file" << file;
continue;
}
QTest::newRow(file.toLatin1()) << QString(dir.path() + QLatin1Char('/') + file) << refFile;
}
}
void testFindEvent()
{
QFETCH(QString, jsonFile);
QFETCH(QString, icalFile);
QFile f(jsonFile);
QVERIFY(f.open(QFile::ReadOnly));
const auto inArray = QJsonDocument::fromJson(f.readAll()).array();
QVERIFY(!inArray.isEmpty());
const auto preData = JsonLdDocument::fromJson(inArray);
QCOMPARE(inArray.size(), preData.size());
ExtractorPostprocessor postproc;
postproc.process(preData);
QCOMPARE(inArray.size(), postproc.result().size());
MemoryCalendar::Ptr refCal(new MemoryCalendar(QTimeZone{}));
ICalFormat format;
format.load(refCal, icalFile);
const auto event = CalendarHandler::findEvent(refCal, postproc.result().at(0));
QVERIFY(event);
}
};
QTEST_APPLESS_MAIN(CalendarHandlerTest)
......
......@@ -28,15 +28,52 @@
using namespace KCalCore;
QDateTime CalendarHandler::startDateTime(const QVariant &reservation)
{
if (reservation.userType() == qMetaTypeId<FlightReservation>() || reservation.userType() == qMetaTypeId<TrainReservation>()) {
const auto trip = JsonLdDocument::readProperty(reservation, "reservationFor");
return JsonLdDocument::readProperty(trip, "departureTime").toDateTime();
} else if (reservation.userType() == qMetaTypeId<LodgingReservation>()) {
return JsonLdDocument::readProperty(reservation, "checkinDate").toDateTime();
}
return {};
}
Event::Ptr CalendarHandler::findEvent(const Calendar::Ptr &calendar, const QVariant &reservation)
{
const auto bookingRef = JsonLdDocument::readProperty(reservation, "reservationNumber").toString();
if (bookingRef.isEmpty()) {
return {};
}
auto dt = startDateTime(reservation);
if (reservation.userType() == qMetaTypeId<LodgingReservation>()) {
dt = QDateTime(dt.date(), QTime());
}
const auto events = calendar->events(dt);
for (const auto &event : events) {
if (event->dtStart() == dt && event->uid().startsWith(bookingRef)) {
return event;
}
}
return {};
}
void CalendarHandler::fillEvent(const QVariant &reservation, const KCalCore::Event::Ptr &event)
{
const int typeId = reservation.userType();
if (typeId == qMetaTypeId<FlightReservation>()) {
return fillFlightReservation(reservation, event);
fillFlightReservation(reservation, event);
} else if (typeId == qMetaTypeId<LodgingReservation>()) {
return fillLodgingReservation(reservation, event);
fillLodgingReservation(reservation, event);
} else if (typeId == qMetaTypeId<TrainReservation>()) {
return fillTrainReservation(reservation, event);
fillTrainReservation(reservation, event);
}
const auto bookingRef = JsonLdDocument::readProperty(reservation, "reservationNumber").toString();
if (!event->uid().startsWith(bookingRef)) {
event->setUid(bookingRef + QLatin1Char('-') + event->uid());
}
}
......
......@@ -20,6 +20,7 @@
#ifndef CALENDARHANDLER_H
#define CALENDARHANDLER_H
#include <KCalCore/Calendar>
#include <KCalCore/Event>
class QVariant;
......@@ -28,6 +29,15 @@ class QVariant;
class CalendarHandler
{
public:
/** Returns the start time associated with the given reservation. */
static QDateTime startDateTime(const QVariant &reservation);
/** Attempts to find an event in @p calendar for @p reservation. */
static KCalCore::Event::Ptr findEvent(const KCalCore::Calendar::Ptr &calendar, const QVariant &reservation);
/** Fills @p event with details of @p reservation.
* Can be used on new events or to update existing ones.
*/
static void fillEvent(const QVariant &reservation, const KCalCore::Event::Ptr &event);
private:
......
......@@ -242,13 +242,19 @@ void SemanticUrlHandler::addToCalendar(SemanticMemento *memento) const
{
using namespace KCalCore;
auto calendar = CalendarSupport::calendarSingleton(true);
const auto calendar = CalendarSupport::calendarSingleton(true);
for (const auto &r : memento->data()) {
Event::Ptr event(new Event);
CalendarHandler::fillEvent(r, event);
if (!event->dtStart().isValid() || !event->dtEnd().isValid() || event->summary().isEmpty()) {
continue;
auto event = CalendarHandler::findEvent(calendar, r);
if (!event) {
event.reset(new Event);
CalendarHandler::fillEvent(r, event);
if (!event->dtStart().isValid() || !event->dtEnd().isValid() || event->summary().isEmpty()) {
continue;
}
calendar->addEvent(event);
} else {
CalendarHandler::fillEvent(r, event);
calendar->modifyIncidence(event);
}
calendar->addEvent(event);
}
}
Markdown is supported
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