diff --git a/model/dao/ProjectDAO/PostgreSQLProjectDAO.php b/model/dao/ProjectDAO/PostgreSQLProjectDAO.php index f763498e1..ba82c54fa 100644 --- a/model/dao/ProjectDAO/PostgreSQLProjectDAO.php +++ b/model/dao/ProjectDAO/PostgreSQLProjectDAO.php @@ -482,70 +482,137 @@ public function getByDescription(string $desc): ?int * * @param ProjectVO $projectVO the {@link ProjectVO} with the data we want to update on database. * @param array $update an array with flags for updating or not the different fields. - * @return int the number of rows that have been affected (it should be 1). - * @throws {@link SQLQueryErrorException} + * @return OperationResult the result {@link OperationResult} with information about operation status */ public function partialUpdate(ProjectVO $projectVO, $update) { - $affectedRows = 0; + $result = new OperationResult(false); - if($projectVO->getId() != "") { - $currProjectVO = $this->getById($projectVO->getId()); + $sql = "UPDATE project SET "; + + if ($update['activation']) + $sql .= "activation=:activation, "; + + if ($update['init']) + $sql .= "init=:init, "; + + if ($update['end']) + $sql .= "_end=:end, "; + + if ($update['invoice']) + $sql .= "invoice=:invoice, "; + + if ($update['estHours']) + $sql .= "est_hours=:est_hours, "; + + if ($update['areaId']) + $sql .= "areaid=:areaid, "; + + if ($update['customerId']) + $sql .= "customerid=:customerid, "; + + if ($update['description']) + $sql .= "description=:description, "; + + if ($update['type']) + $sql .= "type=:type, "; + + if ($update['movHours']) + $sql .= "moved_hours=:moved_hours, "; + + if ($update['schedType']) + $sql .= "sched_type=:sched_type, "; + + if (strlen($sql) == strlen("UPDATE project SET ")) { + $result->setIsSuccessful(true); + $result->setMessage('No changes.'); + $result->setResponseCode(200); + + return $result; } - // If the query returned a row then update - if (!is_null($currProjectVO)) { + // remove the last comma + $sql = substr($sql, 0, -2); + + $sql .= " WHERE id=:id"; - $sql = "UPDATE project SET "; + $initDateFormatted = (is_null($projectVO->getInit())) ? null : DBPostgres::formatDate($projectVO->getInit()); + $endDateFormatted = (is_null($projectVO->getEnd())) ? null : DBPostgres::formatDate($projectVO->getEnd()); + + try { + $statement = $this->pdo->prepare($sql); + $statement->bindValue(":id", $projectVO->getId(), PDO::PARAM_INT); if ($update['activation']) - $sql .= "activation=" . DBPostgres::boolToString($projectVO->getActivation()) . ", "; + $statement->bindValue(":activation", $projectVO->getActivation(), PDO::PARAM_BOOL); if ($update['init']) - $sql .= "init=" . DBPostgres::formatDate($projectVO->getInit()) . ", "; + $statement->bindValue(":init", $initDateFormatted, PDO::PARAM_STR); if ($update['end']) - $sql .= "_end=" . DBPostgres::formatDate($projectVO->getEnd()) . ", "; + $statement->bindValue(":end", $endDateFormatted, PDO::PARAM_STR); if ($update['invoice']) - $sql .= "invoice=" . DBPostgres::checkNull($projectVO->getInvoice()) . ", "; + $statement->bindValue(":invoice", $projectVO->getInvoice(), PDO::PARAM_STR); if ($update['estHours']) - $sql .= "est_hours=" . DBPostgres::checkNull($projectVO->getEstHours()) . ", "; + $statement->bindValue(":est_hours", $projectVO->getEstHours(), PDO::PARAM_STR); if ($update['areaId']) - $sql .= "areaid=" . DBPostgres::checkNull($projectVO->getAreaId()) . ", "; + $statement->bindValue(":areaid", $projectVO->getAreaId(), PDO::PARAM_INT); if ($update['customerId']) - $sql .= "customerid=" . DBPostgres::checkNull($projectVO->getCustomerId()) . ", "; + $statement->bindValue(":customerid", $projectVO->getCustomerId(), PDO::PARAM_INT); if ($update['description']) - $sql .= "description=" . DBPostgres::checkStringNull($projectVO->getDescription()) . ", "; + $statement->bindValue(":description", $projectVO->getDescription(), PDO::PARAM_STR); if ($update['type']) - $sql .= "type=" . DBPostgres::checkStringNull($projectVO->getType()) . ", "; + $statement->bindValue(":type", $projectVO->getType(), PDO::PARAM_STR); if ($update['movHours']) - $sql .= "moved_hours=" . DBPostgres::checkNull($projectVO->getMovedHours()) . ", "; + $statement->bindValue(":moved_hours", $projectVO->getMovedHours(), PDO::PARAM_STR); if ($update['schedType']) - $sql .= "sched_type=" . DBPostgres::checkStringNull($projectVO->getSchedType()); - - if (strlen($sql) == strlen("UPDATE project SET ")) - return NULL; + $statement->bindValue(":sched_type", $projectVO->getSchedType(), PDO::PARAM_STR); - $last = strrpos($sql, ","); + $statement->execute(); - if ($last == (strlen($sql) - 2)) - $sql = substr($sql, 0, -2); + $result->setIsSuccessful(true); + $result->setMessage('Project created successfully.'); + $result->setResponseCode(200); + } + catch (PDOException $ex) { + //make sure to log the error as a failure, but return the OperationResult object + //successfully so that front end can see error and fail gracefully + $errorMessage = $ex->getMessage(); + error_log('Project update failed: ' . $errorMessage); + $result->setErrorNumber($ex->getCode()); + $resultMessage = "Project update failed: \n"; - $sql .= " WHERE id=".$projectVO->getId(); + if (strpos($errorMessage, "Foreign key violation")){ + if (strpos($errorMessage, "customerid")) { + $resultMessage .= "Assigned customer does not exist."; + } + else if (strpos($errorMessage,"areaid")) { + $resultMessage .= "Assigned area does not exist."; + } + } + else if (strpos($errorMessage, "Not null violation")) { + if (strpos($errorMessage,"areaid")) { + $resultMessage .= "Area is null. Please choose area."; + } + } + else { + //if not a predictable error like FK/null violation, just return the native error code and message + $resultMessage .= $errorMessage; + } - $res = pg_query($this->connect, $sql); - if ($res == NULL) throw new SQLQueryErrorException(pg_last_error()); - $affectedRows = pg_affected_rows($res); + $result->setMessage($resultMessage); + $result->setIsSuccessful(false); + $result->setResponseCode(500); } - return $affectedRows; + return $result; } /** Project updater for PostgreSQL. diff --git a/model/facade/ProjectsFacade.php b/model/facade/ProjectsFacade.php index e0ad76810..019ae0ef1 100644 --- a/model/facade/ProjectsFacade.php +++ b/model/facade/ProjectsFacade.php @@ -284,15 +284,11 @@ static function UpdateProject(ProjectVO $project) { * * @param ProjectVO $task the Project value object we want to update. * @param array $update the updating flags of the Project VO. - * @return int it just indicates if there was any error (-1) or not (0). - * @throws {@link SQLQueryErrorException} + * @return OperationResult the result {@link OperationResult} with information about operation status */ static function PartialUpdateProject(ProjectVO $project, $update) { - - $action = new PartialUpdateProjectAction($project, $update); - - return $action->execute(); - + $action = new PartialUpdateProjectAction($project, $update); + return $action->execute(); } /** Partial Update Projects Function @@ -302,17 +298,13 @@ static function PartialUpdateProject(ProjectVO $project, $update) { * * @param array $projects the Project value objects we want to update. * @param array $updates the updating flag arrays of the Project VOs. - * @return int it just indicates if there was any error (-1) or not (0). - * @throws {@link SQLQueryErrorException} + * @return array OperationResult the array of results {@link OperationResult} with information about operation status. */ static function PartialUpdateProjects($projects, $updates) { - - foreach((array)$projects as $i=>$project) - if ((ProjectsFacade::PartialUpdateProject($project, $updates[$i])) == -1) - return -1; - - return 0; - + $operationResults = []; + foreach ((array) $projects as $i=>$project) + $operationResults[] = ProjectsFacade::PartialUpdateProject($project, $updates[$i]); + return $operationResults; } /** GetProjectsByCustomerUserLogin Function diff --git a/model/facade/action/PartialUpdateProjectAction.php b/model/facade/action/PartialUpdateProjectAction.php index cd319606e..e27695acb 100644 --- a/model/facade/action/PartialUpdateProjectAction.php +++ b/model/facade/action/PartialUpdateProjectAction.php @@ -32,6 +32,7 @@ include_once(PHPREPORT_ROOT . '/model/facade/action/Action.php'); include_once(PHPREPORT_ROOT . '/model/dao/DAOFactory.php'); include_once(PHPREPORT_ROOT . '/model/vo/ProjectVO.php'); +include_once(PHPREPORT_ROOT . '/model/OperationResult.php'); /** Partial Update Project Action * @@ -77,17 +78,11 @@ public function __construct(ProjectVO $project, $update) { * * This is the function that contains the code that updates the Project on persistent storing. * - * @return int it just indicates if there was any error (-1) or not (0). + * @return OperationResult the result {@link OperationResult} with information about operation status */ protected function doExecute() { - $dao = DAOFactory::getProjectDAO(); - - if ($dao->partialUpdate($this->project, $this->update)!=1) { - return -1; - } - - return 0; + return $dao->partialUpdate($this->project, $this->update); } } diff --git a/web/services/updateProjectsService.php b/web/services/updateProjectsService.php index bbe25e665..32a8ffd09 100644 --- a/web/services/updateProjectsService.php +++ b/web/services/updateProjectsService.php @@ -66,7 +66,19 @@ $projectVO = new ProjectVO(); - $update = array(); + $update = array( + "activation" => false, + "init" => false, + "end" => false, + "invoice" => false, + "estHours" => false, + "description" => false, + "areaId" => false, + "customerId" => false, + "type" => false, + "movedHours" => false, + "schedType" => false + ); $parser->read(); @@ -226,11 +238,19 @@ } - - if (count($updateProjects) >= 1) - if (ProjectsFacade::PartialUpdateProjects($updateProjects, $updates) == -1) - $string = "There was some error while updating the projects"; - + $operationResults = ProjectsFacade::PartialUpdateProjects($updateProjects, $updates); + $errors = array_filter($operationResults, function ($item) { + return (!$item->getIsSuccessful()); + }); + if ($errors) { + //if multiple failures, let's just return a 500 + http_response_code(500); + $string = ""; + foreach ($errors as $result) { + $string .= "" . $result->getMessage() . ""; + } + $string .= ""; + } if (!isset($string)) $string = "Operation Success!";