diff --git a/src/akonadi/akonadiserializer.cpp b/src/akonadi/akonadiserializer.cpp --- a/src/akonadi/akonadiserializer.cpp +++ b/src/akonadi/akonadiserializer.cpp @@ -267,11 +267,6 @@ todo->setSummary(task->title()); todo->setDescription(task->text()); - if (task->isDone()) - todo->setCompleted(KDateTime(task->doneDate())); - else - todo->setCompleted(false); - todo->setDtStart(KDateTime(task->startDate(), KDateTime::UTC)); todo->setDtDue(KDateTime(task->dueDate(), KDateTime::UTC)); @@ -321,6 +316,13 @@ todo->removeCustomProperty("Zanshin", "Running"); } + // Needs to be done after all other dates are positioned + // since this applies the recurrence logic + if (task->isDone()) + todo->setCompleted(KDateTime(task->doneDate())); + else + todo->setCompleted(false); + Akonadi::Item item; if (task->property("itemId").isValid()) { item.setId(task->property("itemId").value()); diff --git a/tests/units/akonadi/akonadiserializertest.cpp b/tests/units/akonadi/akonadiserializertest.cpp --- a/tests/units/akonadi/akonadiserializertest.cpp +++ b/tests/units/akonadi/akonadiserializertest.cpp @@ -893,6 +893,49 @@ QCOMPARE(task->recurrence(), expectedRecurrence); } + void shouldNotBreakRecurrenceDuringSerialization() + { + // GIVEN + + // Data... + const QDateTime today(QDate::currentDate(), QTime(0, 0), Qt::UTC); + const QDateTime doneDate(QDate(2013, 11, 20), QTime(0, 0), Qt::UTC); + const QDateTime startDate(QDate(2013, 11, 10), QTime(0, 0), Qt::UTC); + + // ... stored in a todo... + KCalCore::Todo::Ptr todo(new KCalCore::Todo); + todo->setSummary(QStringLiteral("summary")); + todo->setDtStart(KDateTime(startDate, KDateTime::UTC)); + todo->recurrence()->setMonthly(1); + + // ... as payload of an item... + Akonadi::Item item; + item.setMimeType(QStringLiteral("application/x-vnd.akonadi.calendar.todo")); + item.setPayload(todo); + + // ... deserialized as a task + Akonadi::Serializer serializer; + auto task = serializer.createTaskFromItem(item); + + // WHEN + // Task is marked done... + task->setDoneDate(doneDate); + task->setDone(true); + + // and goes through serialization and back + const auto newItem = serializer.createItemFromTask(task); + serializer.updateTaskFromItem(task, newItem); + + // THEN + QCOMPARE(task->recurrence(), Domain::Task::RecursMonthly); + QVERIFY(!task->isDone()); + const QDateTime lastOccurrence(QDate(today.date().year(), today.date().month(), 10), QTime(0, 0), Qt::UTC); + if (today.date().day() >= 10) + QCOMPARE(task->startDate(), lastOccurrence.addMonths(1)); + else + QCOMPARE(task->startDate(), lastOccurrence); + } + void shouldNotUpdateTaskFromInvalidItem() { // GIVEN