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