00001 #include "taskmodifier.h"
00002
00003 #include <controldata.h>
00004 #include <models/taskmodel.h>
00005 #include <models/resourcemodel.h>
00006 #include <models/userrequirementsmodel.h>
00007 #include <models/resourcerequirementsmodel.h>
00008
00009 #include <domain/taskmanagerdata.h>
00010 #include <domain/schedule.h>
00011 #include <domain/user.h>
00012 #include <domain/taskstates.h>
00013
00014 #include <tools/functions.h>
00015 #include <tools/stringexception.h>
00016
00017 #include <QDebug>
00018
00019 using namespace control;
00020
00021 ControllerInterface::ActionType TaskModifier::actionType() const
00022 {
00023 return ModifyAction;
00024 }
00025
00026 ControllerInterface::DataType TaskModifier::dataType() const
00027 {
00028 return TaskData;
00029 }
00030
00031 QString TaskModifier::description() const
00032 {
00033 return "Modify task";
00034 }
00035
00036 QString TaskModifier::name() const
00037 {
00038 return "TaskModifier";
00039 }
00040
00041 bool TaskModifier::userIsValid() const
00042 {
00043 return userHasLoggedIn() && !userIsAdmin();
00044 }
00045
00046 void TaskModifier::execute()
00047 {
00048 QList<const domain::Task*> tasksList = tools::makeConstList(data->tasksForUser(user()));
00049
00050 if (tasksList.isEmpty())
00051 {
00052 ui->showWarning(QString("User %1 does not have any tasks").arg(user()->name()));
00053 return;
00054 }
00055
00056 TaskModel tasks(data, tasksList);
00057 data::SelectionData selection = ui->getSelection("Select a task", &tasks);
00058
00059 if (!selection.processData)
00060 return;
00061
00062 if (selection.selection.isEmpty())
00063 {
00064 ui->showWarning("No task selected.");
00065 return;
00066 }
00067
00068 Q_ASSERT(selection.selection.count() == 1);
00069
00070 bool tryAgain;
00071 do
00072 {
00073 tryAgain = false;
00074
00075 try
00076 {
00077 execute(tasks.taskForIndex(selection.selection.first()));
00078 }
00079 catch (tools::StringException& e)
00080 {
00081 tryAgain = ui->askQuestion(e.message(), 0,
00082 "Would you like to correct this?");
00083 }
00084 }
00085 while (tryAgain);
00086 }
00087
00088 void TaskModifier::execute(const domain::StorableData* data)
00089 {
00090 const domain::Task* originalTask = qobject_cast<const domain::Task*>(data);
00091
00092 if (originalTask == 0)
00093 throw tools::StringException("Given data is not a task.");
00094
00095 if (originalTask->state() == domain::TaskState::Successful ||
00096 originalTask->state() == domain::TaskState::Failed)
00097 {
00098 ui->showError("Cannot update task details because the state of the "
00099 "selected task is " +
00100 originalTask->stateString().toLower() + ".");
00101 return;
00102 }
00103
00104 QList<const domain::Task*> taskList =
00105 tools::makeConstList(this->data->tasksForUser(user()));
00106 taskList.removeAll(originalTask);
00107 TaskModel tasks(this->data, taskList);
00108 data::TaskDetails currentDetails(originalTask);
00109
00110 Q_FOREACH (const domain::Task* subTask, originalTask->subTasks())
00111 {
00112 currentDetails.selectedTasks.selection
00113 << tasks.indexForTask(this->data->task(subTask));
00114 }
00115
00116 data::TaskRepresentation rep;
00117 rep.subTasks = &tasks;
00118 rep.type = data::TaskTypeDetails(originalTask->taskType());
00119 rep.details = currentDetails;
00120 UserRequirementsModel userReqs(this->data->task(originalTask));
00121 rep.userReqs = &userReqs;
00122 ResourceRequirementsModel resourceReqs(this->data->task(originalTask));
00123 rep.resourceReqs = &resourceReqs;
00124 data::TaskDetails details = ui->getTaskDetails(rep);
00125
00126 if (!details.processData)
00127 return;
00128
00129 domain::Schedule schedule(details.duration, details.startTime,
00130 details.endTime);
00131 QList<domain::Task*> subTasks;
00132 Q_FOREACH (QModelIndex index, details.selectedTasks.selection)
00133 {
00134 subTasks << this->data->task(tasks.taskForIndex(index));
00135 }
00136 QList<domain::InvitationData> invitations;
00137
00138 Q_FOREACH(const domain::Invitation* invitation, originalTask->invitations())
00139 {
00140 domain::InvitationData invitationData;
00141 if (invitation->state() == domain::Invitation::Accepted)
00142 invitationData.state = domain::Invitation::Pending;
00143 else
00144 invitationData.state = invitation->state();
00145
00146 invitationData.user = this->data->user(invitation->user());
00147 invitations << invitationData;
00148 }
00149 QList<domain::ReservationData> reservations;
00150 Q_FOREACH(const domain::Reservation* reservation, originalTask->reservations())
00151 {
00152 domain::ReservationData reservationData;
00153 reservationData.duration = reservation->duration();
00154 reservationData.resource = this->data->resource(reservation->resource());
00155 reservationData.startDate = reservation->time();
00156 reservations << reservationData;
00157 this->data->removeData(reservation);
00158 }
00159
00160 domain::Task* newTask;
00161
00162 try
00163 {
00164 newTask = this->data->createTask(originalTask->taskType(),
00165 originalTask->user(), schedule,
00166 originalTask->state(), subTasks,
00167 invitations, reservations);
00168
00169 Q_FOREACH (QString field, details.fields.keys())
00170 newTask->setField(field, details.fields[field]);
00171
00172 Q_FOREACH (const domain::Task* superTask, originalTask->superTasks())
00173 this->data->task(superTask)->addSubTask(newTask);
00174
00175 newTask->setProject(this->data->project(originalTask->project()));
00176
00177 this->data->removeData(originalTask);
00178 }
00179 catch (tools::StringException e)
00180 {
00181 this->data->removeData(newTask);
00182 Q_FOREACH(domain::ReservationData reservation, reservations)
00183 {
00184 this->data->createReservation(originalTask, reservation.resource,
00185 reservation.startDate,
00186 reservation.duration);
00187 }
00188 throw e;
00189 }
00190 }
00191
00192 Q_EXPORT_PLUGIN2(controller_taskmodifier, TaskModifier)
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217