00001 #include "taskstates.h"
00002
00003 #include "task.h"
00004 #include "schedule.h"
00005 #include "resource.h"
00006 #include "duration.h"
00007 #include "reservation.h"
00008 #include "clock.h"
00009 #include "statechangedata.h"
00010
00011 #include <tools/invaliddataexception.h>
00012 #include <domain/businessrule2exception.h>
00013
00014 #include <QString>
00015 #include <QMap>
00016 #include <QDateTime>
00017 #include <QDebug>
00018
00019 using namespace domain;
00020
00021
00022
00023 QList<TaskState::SettableState> TaskState::allStates()
00024 {
00025 static QList<SettableState> ret;
00026
00027 if (ret.isEmpty())
00028 {
00029 ret << Successful
00030 << Unfinished
00031 << Failed;
00032 }
00033
00034 return ret;
00035 }
00036
00037 TaskState* TaskState::stateForEnum(SettableState state)
00038 {
00039 switch (state)
00040 {
00041 case Successful:
00042 return TaskSuccessful::instance();
00043 case Failed:
00044 return TaskFailed::instance();
00045 case Unfinished:
00046 return TaskUnfinished::instance();
00047 }
00048
00049 qFatal("How embarrassing!");
00050 return 0;
00051 }
00052
00053 QString TaskState::nameForEnum(SettableState state)
00054 {
00055 return stateForEnum(state)->name();
00056 }
00057
00058 TaskState::TaskState()
00059 {
00060 }
00061
00062 void TaskState::setTaskState(Task* task, TaskState* state)
00063 {
00064 task->setState(state);
00065 }
00066
00067 void TaskState::setTaskField(Task* task, const QString& id, const QVariant& value)
00068 {
00069 task->_setField(id, value);
00070 }
00071
00072 void TaskState::addTaskReservation(Task* task, Reservation* reservation)
00073 {
00074 task->_addReservation(reservation);
00075 }
00076
00077 void TaskState::setTaskProject(Task* task, Project* project)
00078 {
00079 task->_setProject(project);
00080 }
00081
00082 void TaskState::addTaskSubTask(Task* task, Task* subTask)
00083 {
00084 task->_addSubTask(subTask);
00085 }
00086
00087 void TaskState::updateTask(Task* task)
00088 {
00089 setTaskState(task, this);
00090 }
00091
00092 void TaskState::setField(Task*, const QString&, const QVariant&)
00093 {
00094 throw tools::StringException(QString("Cannot set a field of a task with "
00095 "state %1.").arg(name()));
00096 }
00097
00098 void TaskState::addReservation(Task*, Reservation*)
00099 {
00100 throw tools::StringException(QString("Cannot add a reservation to a task "
00101 "with state %1.").arg(name()));
00102 }
00103
00104 void TaskState::setProject(Task*, Project*)
00105 {
00106 throw tools::StringException(QString("Cannot set the project of a task with "
00107 "state %1.").arg(name()));
00108 }
00109
00110 void TaskState::addSubTask(Task*, Task*)
00111 {
00112 throw tools::StringException(QString("Cannot add a sub task to a task "
00113 "with state %1.").arg(name()));
00114 }
00115
00116
00117
00118 TaskSuccessful::TaskSuccessful()
00119 {
00120 }
00121
00122 TaskState::SettableState TaskSuccessful::settableState() const
00123 {
00124 return Successful;
00125 }
00126
00127 void TaskSuccessful::updateTask(Task* task)
00128 {
00129 if (!task->canBeSuccessful())
00130 {
00131 try
00132 {
00133 task->setState(Unfinished);
00134 }
00135 catch (...)
00136 {
00137 task->setState(Failed);
00138 }
00139 }
00140 else
00141 setTaskState(task, this);
00142 }
00143
00144 TaskState* TaskSuccessful::instance()
00145 {
00146 static TaskSuccessful state;
00147 return &state;
00148 }
00149
00150 QString TaskSuccessful::name() const
00151 {
00152 return "Successful";
00153 }
00154
00155 void TaskSuccessful::setProject(Task* task, Project* project)
00156 {
00157 setTaskProject(task, project);
00158 }
00159
00160 void TaskSuccessful::setField(Task* task, const QString& id, const QVariant& value)
00161 {
00162 setTaskField(task, id, value);
00163 }
00164
00165 void TaskSuccessful::addReservation(Task* task, Reservation* reservation)
00166 {
00167 addTaskReservation(task, reservation);
00168 }
00169
00170
00171
00172 TaskFailed::TaskFailed()
00173 {
00174 }
00175
00176 TaskState::SettableState TaskFailed::settableState() const
00177 {
00178 return Failed;
00179 }
00180
00181 TaskState* TaskFailed::instance()
00182 {
00183 static TaskFailed state;
00184 return &state;
00185 }
00186
00187 QString TaskFailed::name() const
00188 {
00189 return "Failed";
00190 }
00191
00192 void TaskFailed::setProject(Task* task, Project* project)
00193 {
00194 setTaskProject(task, project);
00195 }
00196
00197 void TaskFailed::setField(Task* task, const QString& id, const QVariant& value)
00198 {
00199 setTaskField(task, id, value);
00200 }
00201
00202 void TaskFailed::addReservation(Task* task, Reservation* reservation)
00203 {
00204 addTaskReservation(task, reservation);
00205 }
00206
00207
00208
00209 TaskUnfinished::TaskUnfinished()
00210 {
00211 }
00212
00213 TaskState::SettableState TaskUnfinished::settableState() const
00214 {
00215 return Unfinished;
00216 }
00217
00218 TaskState* TaskUnfinished::instance()
00219 {
00220 static TaskUnfinished state;
00221 return &state;
00222 }
00223
00224 QString TaskUnfinished::name() const
00225 {
00226 return "Unfinished";
00227 }
00228
00229 void TaskUnfinished::updateTask(Task* task)
00230 {
00231 if (shouldBeFailed(task))
00232 setTaskState(task, TaskFailed::instance());
00233 else if (isAvailable(task))
00234 setTaskState(task, TaskAvailable::instance());
00235 else
00236 setTaskState(task, TaskUnavailable::instance());
00237 }
00238
00239 bool TaskUnfinished::shouldBeFailed(Task* task)
00240 {
00241 Q_FOREACH (const Task* subTask, task->subTasks())
00242 {
00243 if (subTask->state() == Failed)
00244 return true;
00245 }
00246
00247 return Clock::currentTime() >= task->schedule().dueDate();
00248 }
00249
00250 bool TaskUnfinished::isAvailable(const Task* task)
00251 {
00252 QDateTime current = Clock::currentTime();
00253
00254 if (task->schedule().startDate() > current ||
00255 task->schedule().dueDate() <= current)
00256 {
00257 return false;
00258 }
00259
00260 Q_FOREACH (const Task* subTask, task->subTasks())
00261 {
00262 if (subTask->state() != Successful)
00263 return false;
00264 }
00265
00266 return task->requirementsAreFulfilled();
00267 }
00268
00269 void TaskUnfinished::setField(Task* task, const QString& id, const QVariant& value)
00270 {
00271 setTaskField(task, id, value);
00272 }
00273
00274 void TaskUnfinished::addReservation(Task* task, Reservation* reservation)
00275 {
00276 addTaskReservation(task, reservation);
00277 }
00278
00279 void TaskUnfinished::setProject(Task* task, Project* project)
00280 {
00281 setTaskProject(task, project);
00282 }
00283
00284 void TaskUnfinished::addSubTask(Task* task, Task* subTask)
00285 {
00286 addTaskSubTask(task, subTask);
00287 }
00288
00289
00290
00291 TaskAvailable::TaskAvailable()
00292 {
00293
00294 }
00295
00296 TaskState* TaskAvailable::instance()
00297 {
00298 static TaskAvailable state;
00299 return &state;
00300 }
00301
00302 QString TaskAvailable::name() const
00303 {
00304 return TaskUnfinished::name() + " (available)";
00305 }
00306
00307
00308
00309 TaskUnavailable::TaskUnavailable()
00310 {
00311
00312 }
00313
00314 TaskState* TaskUnavailable::instance()
00315 {
00316 static TaskUnavailable state;
00317 return &state;
00318 }
00319
00320 QString TaskUnavailable::name() const
00321 {
00322 return TaskUnfinished::name() + " (unavailable)";
00323 }
00324
00325
00326
00327
00328 TaskDeleting::TaskDeleting()
00329 {
00330 }
00331
00332 TaskState* TaskDeleting::instance()
00333 {
00334 static TaskDeleting state;
00335 return &state;
00336 }
00337
00338 void TaskDeleting::addReservation(Task* task, Reservation* reservation)
00339 {
00340 addTaskReservation(task, reservation);
00341 }
00342
00343 void TaskDeleting::addSubTask(Task* task, Task* subTask)
00344 {
00345 addTaskSubTask(task, subTask);
00346 }
00347
00348 QString TaskDeleting::name() const
00349 {
00350 return "Deleting";
00351 }
00352
00353 void TaskDeleting::setProject(Task* task, Project* project)
00354 {
00355 setTaskProject(task, project);
00356 }
00357
00358 void TaskDeleting::setField(Task* task, const QString& id, const QVariant& value)
00359 {
00360 setTaskField(task, id, value);
00361 }
00362
00363 TaskState::SettableState TaskDeleting::settableState() const
00364 {
00365 qFatal("This is embarrassing...");
00366 return (SettableState) 0;
00367 }
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383