commit 2a40e887cc9a2b77b162555b08d1394cb34a2d8e
Author: SebastianDiel <sebastian.diel@web.de>
Date:   Tue Jan 3 13:45:02 2017 +0100

    Reproducing error 629

diff --git a/samples/simple/group.cpp b/samples/simple/group.cpp
index d8b01a2..3cdb68b 100644
--- a/samples/simple/group.cpp
+++ b/samples/simple/group.cpp
@@ -34,8 +34,8 @@ QList<QSharedPointer<Person> > Group::getPersons() const {
     return persons;
 }
 
-void Group::addPerson(Person *person) {
-    this->persons.append(QSharedPointer<Person>(person));
+void Group::addPerson(QSharedPointer<Person> person) {
+    this->persons.append(person);
 }
 
 void Group::setPersons(const QList<QSharedPointer<Person> > &value) {
diff --git a/samples/simple/group.h b/samples/simple/group.h
index d24dd51..89f7b4d 100644
--- a/samples/simple/group.h
+++ b/samples/simple/group.h
@@ -29,7 +29,7 @@ class Group: public CuteEntityManager::Entity {
     void setMainTeacher(const QSharedPointer<Person> &value);
 
     QList<QSharedPointer<Person> > getPersons() const;
-    void addPerson(Person *person);
+    void addPerson(QSharedPointer<Person> person);
     void setPersons(const QList<QSharedPointer<Person> > &value);
 
   protected:
diff --git a/samples/simple/incident.cpp b/samples/simple/incident.cpp
index ff68cb3..506392e 100644
--- a/samples/simple/incident.cpp
+++ b/samples/simple/incident.cpp
@@ -1,6 +1,5 @@
 #include "incident.h"
-//#include "src/model/appdata/appdata.h"
-//#include "src/trivia/errorhandling.h"
+#include <QDebug>
 
 Incident::Incident() :
     Entity()
@@ -18,7 +17,7 @@ void Incident::initIncident(const QSharedPointer<Pupil> pupil,
 //    this->setAppData(appData);
     this->setBookedFor(dateTime);
     this->setBookedAt(dateTime);
-    this->setCancelledAt(QDateTime());
+    m_cancelledAt = QDateTime();
     this->setLocked(false);
     this->setPredecessor(QSharedPointer<Incident>());
 }
@@ -53,11 +52,12 @@ void Incident::setCancelledAt(const QDateTime &cancelledAt, bool forceOverwrite)
     if (m_cancelledAt.isValid() && !forceOverwrite) {
         // sometimes an EntityManager metacall reaches this, too. Immediately after setting it manually. (<= 1ms?)
         // reproduce: change attendanceIncident, ok, change again
-        qint64 diff = qAbs(m_cancelledAt.secsTo(cancelledAt));
-        if (diff > 10) { // giving some delay headroom for a possible double call
-            Q_ASSERT(!m_cancelledAt.isValid());
-//            THROW_MODERATE_ERROR_CIT("Das Canceln eines Ereignisses ist fehlgeschlagen, das Ereignis war bereits vorher gecancelt!");
-        }
+        // qint64 diff = qAbs(m_cancelledAt.secsTo(cancelledAt));
+        // if (diff > 10) { // giving some delay headroom for a possible double call
+        qDebug()<< "\n\n-------------------------------\n-------------------------------\n-------------------------------\nWHY DOES THIS HAPPEN? \nEach incident's cancelledAt has been invalidated in the ctor!\n------------------------\n-------------------------------\n-------------------------------\n-------------------------------";
+        // Q_ASSERT(!m_cancelledAt.isValid());
+        // THROW_MODERATE_ERROR_CIT("Das Canceln eines Ereignisses ist fehlgeschlagen, das Ereignis war bereits vorher gecancelt!");
+        // }
     }
     m_cancelledAt = cancelledAt;
 }
@@ -72,16 +72,6 @@ void Incident::setPupil(const QSharedPointer<Pupil> &pupil)
     m_pupil = pupil;
 }
 
-//QSharedPointer<AppData> Incident::appData() const
-//{
-//    return m_appData;
-//}
-
-//void Incident::setAppData(const QSharedPointer<AppData> &appData)
-//{
-//    m_appData = appData;
-//}
-
 QSharedPointer<Group> Incident::group() const
 {
     return m_group;
@@ -110,16 +100,6 @@ void Incident::setLocked(bool locked)
     m_locked = locked;
 }
 
-//QSharedPointer<Room> Incident::room() const
-//{
-//    return m_room;
-//}
-
-//void Incident::setRoom(const QSharedPointer<Room> &room)
-//{
-//    m_room = room;
-//}
-
 QString Incident::additionalInfo() const
 {
     return m_additionalInfo;
@@ -136,28 +116,12 @@ const QHash<QString, Relation> Incident::getRelations() const
 
     hash.insert("pupil",CuteEntityManager::Relation(
                     "pupil",CuteEntityManager::RelationType::MANY_TO_ONE));
-//    hash.insert("appData",CuteEntityManager::Relation(
-//                    "appData",CuteEntityManager::RelationType::MANY_TO_ONE));
     hash.insert("group",CuteEntityManager::Relation(
                     "group",CuteEntityManager::RelationType::MANY_TO_ONE));
-//    hash.insert("room",CuteEntityManager::Relation(
-//                    "room",CuteEntityManager::RelationType::MANY_TO_ONE));
-//    hash.insert("seatingPlan", CuteEntityManager::Relation(
-//                    "seatingPlan",CuteEntityManager::RelationType::MANY_TO_ONE));
     hash.insert("predecessor", CuteEntityManager::Relation("predecessor", true, CuteEntityManager::RelationType::ONE_TO_ONE));
     return hash;
 }
 
-//QSharedPointer<SeatingPlan> Incident::seatingPlan() const
-//{
-//    return m_seatingPlan;
-//}
-
-//void Incident::setSeatingPlan(const QSharedPointer<SeatingPlan> &seatingPlan)
-//{
-//    m_seatingPlan = seatingPlan;
-//}
-
 QSharedPointer<Incident> Incident::predecessor() const
 {
     return m_predecessor;
diff --git a/samples/simple/main.cpp b/samples/simple/main.cpp
index 9562545..1955196 100644
--- a/samples/simple/main.cpp
+++ b/samples/simple/main.cpp
@@ -16,6 +16,7 @@
 #include "datacreation.h"
 #include "incident.h"
 
+#include "stuff.h"
 
 using namespace CuteEntityManager;
 int main(int argc, char *argv[]) {
@@ -43,25 +44,80 @@ int main(int argc, char *argv[]) {
         auto entities = DataCreation::createRatingEntities();
         e->save(entities);
 
-        QSharedPointer<Pupil> pupil = QSharedPointer<Pupil>(new Pupil("Vorname","Nachname","","","Keks"));
-        pupil->setLegalGuardianNote("note");
+        QSharedPointer<Pupil> pupil1 = QSharedPointer<Pupil>(new Pupil("Vorname1","Nachname1","","","Keks1"));
+        QSharedPointer<Pupil> pupil2 = QSharedPointer<Pupil>(new Pupil("Vorname2","Nachname2","","","Keks2"));
+        QSharedPointer<Group> firstGroup = QSharedPointer<Group>(new Group());
+        firstGroup->setName("05c");
+        firstGroup->addPerson(pupil1);
+        firstGroup->addPerson(pupil2);
 
-        e->save(QList<QSharedPointer<Entity>>()<<pupil);
 
-        QSharedPointer<Occasion> occasion = QSharedPointer<Occasion>(new Occasion("IrgendeinAnlass"));
-        QSharedPointer<RatingMarkIncident> inc = QSharedPointer<RatingMarkIncident>(new RatingMarkIncident());
-        inc->setAdditionalInfo("addInf");
+
+        e->save(QList<QSharedPointer<Entity>>()<<pupil1<<pupil2<<firstGroup);
+
+        QSharedPointer<Occasion> occasion = QSharedPointer<Occasion>(new Occasion(""));
+        QSharedPointer<RatingMarkIncident> firstInc = QSharedPointer<RatingMarkIncident>(new RatingMarkIncident());
+        firstInc->setAdditionalInfo("addInf");
+        firstInc->setBookedAt(QDateTime::currentDateTime());
+        firstInc->setBookedFor(QDateTime::currentDateTime());
+        firstInc->setOccasion(occasion);
+        firstInc->setPupil(pupil1);
+        firstInc->setRateable(true);
+        auto system = e->findAll<RatingMarkSystem>().first();
+        firstInc->setRatingMarkSystem(system);
+        firstInc->setSymbol("NB");
+        firstInc->setValue(0.0);
+        firstInc->setPercentValue(0.0);
+        firstInc->setWeight(1.0);
+        firstInc->setGroup(firstGroup);
+        firstInc->setSignatureNeeded(false);
+        firstInc->setLocked(false);
+
+        e->save(firstInc);
+
+
+// ----------------------------------------------------------------------------------------------------------------------
+        auto oldInc = e->findById<RatingMarkIncident>(1);
+        e->refresh(oldInc, true);
+        e->refresh(oldInc->group());
+        e->refresh(oldInc->pupil());
+        QSharedPointer<RatingMarkIncident> inc = Stuff::makeTwin(oldInc, QDateTime::currentDateTime());
+        if (oldInc) {
+            oldInc->setCancelledAt(QDateTime::currentDateTime());
+        }
+        inc->setCancelledAt(QDateTime());
+        QSharedPointer<Pupil> pupil = e->findById<Pupil>(1);
+        inc->setLocked(false);
         inc->setBookedAt(QDateTime::currentDateTime());
         inc->setBookedFor(QDateTime::currentDateTime());
-        inc->setOccasion(occasion);
         inc->setPupil(pupil);
+
+        auto group = e->findById<Group>(1);
+        e->refresh(group,false);
+        inc->setGroup(group);
+        inc->setSymbol("NB");
+        inc->setPercentValue(0.0);
+        inc->setValue(0.0);
+        inc->setWeight(1.0);
         inc->setRateable(true);
-        auto system = e->findAll<RatingMarkSystem>().first();
-        inc->setRatingMarkSystem(system);
-        inc->setSymbol("z");
-        inc->setValue(23);
+        inc->setSignatureNeeded(false);
+        inc->setOccasion(e->findById<Occasion>(1));
+        auto rateSys = e->findById<RatingMarkSystem>(1);
+        e->refresh(rateSys);
+        inc->setRatingMarkSystem(rateSys);
+
+
+        // ---------------------------------------------------------------------
+
+
+        bool success;
+        success = oldInc.isNull() || e->save(oldInc);
+        // only save new version if old version could is successfully cancelled
+        if (success) {
+            success &= e->save(inc);
+            success &= inc->getId() >= 0; // check
+        }
 
-        e->save(inc);
 
     } catch(QString s) {
         qDebug()<<s;
diff --git a/samples/simple/simple.pro b/samples/simple/simple.pro
index 4414fdc..94af4cf 100644
--- a/samples/simple/simple.pro
+++ b/samples/simple/simple.pro
@@ -26,7 +26,8 @@ HEADERS += \
     contact.h \
     group.h \
     person.h \
-    pupil.h
+    pupil.h \
+    stuff.h
 
 SOURCES += \
     main.cpp \
diff --git a/samples/simple/stuff.h b/samples/simple/stuff.h
new file mode 100644
index 0000000..34d0989
--- /dev/null
+++ b/samples/simple/stuff.h
@@ -0,0 +1,31 @@
+#ifndef STUFF_H
+#define STUFF_H
+
+#include "entity.h"
+
+class Stuff {
+public:
+    Stuff(){}
+    template <class T> static QSharedPointer<T> makeTwin(
+            QSharedPointer<T> source,
+            QDateTime bookedAt,
+            bool setPredecessor = true)
+    {
+        QSharedPointer<T> twin;
+        if (source.isNull()) {
+            twin = QSharedPointer<T>(new T());
+        } else {
+            QSharedPointer<Entity> twinEntity = QSharedPointer<Entity>(source->copy());
+            twin = twinEntity.objectCast<T>();
+        }
+        if (twin) {
+            twin->setBookedAt(bookedAt);
+            if (setPredecessor) {
+                twin->setPredecessor(source);
+            }
+        }
+        return twin;
+    }
+};
+
+#endif // STUFF_H
