diff --git a/rest/index.php b/rest/index.php index 75c4cc81caad0ad96393755976bc3df6bd2a1175..8ce0c9050654cb1cafb15779538e0e9e8038a4ed 100755 --- a/rest/index.php +++ b/rest/index.php @@ -264,6 +264,7 @@ $app->get('/resources/{resId}/isAllowed', \Resource\controllers\ResController::c $app->get('/resourcesList/users/{userId}/groups/{groupId}/baskets/{basketId}', \Resource\controllers\ResourceListController::class . ':get'); $app->get('/resourcesList/users/{userId}/groups/{groupId}/baskets/{basketId}/actions', \Resource\controllers\ResourceListController::class . ':getActions'); $app->put('/resourcesList/users/{userId}/groups/{groupId}/baskets/{basketId}/lock', \Resource\controllers\ResourceListController::class . ':lock'); +$app->put('/resourcesList/users/{userId}/groups/{groupId}/baskets/{basketId}/unlock', \Resource\controllers\ResourceListController::class . ':unlock'); $app->get('/resourcesList/users/{userId}/groups/{groupId}/baskets/{basketId}/filters', \Resource\controllers\ResourceListController::class . ':getFilters'); $app->put('/resourcesList/users/{userId}/groups/{groupId}/baskets/{basketId}/exports', \Resource\controllers\ExportController::class . ':updateExport'); $app->post('/resourcesList/users/{userId}/groups/{groupId}/baskets/{basketId}/summarySheets', \Resource\controllers\SummarySheetController::class . ':createList'); diff --git a/sql/develop.sql b/sql/develop.sql index 0f521e13ac2d32ac29f25e669d449c79698eb140..52dccb984a8bf2b0e49d221d372f1cc98311d15a 100755 --- a/sql/develop.sql +++ b/sql/develop.sql @@ -12,9 +12,9 @@ DROP VIEW IF EXISTS res_view_letterbox; ALTER TABLE res_letterbox DROP COLUMN IF EXISTS external_signatory_book_id; ALTER TABLE res_letterbox ADD COLUMN external_signatory_book_id integer; +/* Acknowledgment receipt */ ALTER TABLE res_letterbox DROP COLUMN IF EXISTS acknowledgment_creation_date; ALTER TABLE res_letterbox ADD COLUMN acknowledgment_creation_date timestamp without time zone; - ALTER TABLE res_letterbox DROP COLUMN IF EXISTS acknowledgment_send_date; ALTER TABLE res_letterbox ADD COLUMN acknowledgment_send_date timestamp without time zone; diff --git a/src/app/resource/controllers/ResourceListController.php b/src/app/resource/controllers/ResourceListController.php index f93ec597f384cdcc7e5108aff97198fbc67c375d..82e95865f0993ccafec8b2ed21c7335b0d199acd 100644 --- a/src/app/resource/controllers/ResourceListController.php +++ b/src/app/resource/controllers/ResourceListController.php @@ -582,6 +582,14 @@ class ResourceListController return $response->withStatus(400)->withJson(['errors' => 'Action is not linked to this group basket']); } + $action = ActionModel::getById(['id' => $aArgs['actionId'], 'select' => ['component']]); + if (empty($action['component'])) { + return $response->withStatus(400)->withJson(['errors' => 'Action component does not exist']); + } + if (!array_key_exists($action['component'], ActionMethodController::COMPONENTS_ACTIONS)) { + return $response->withStatus(400)->withJson(['errors' => 'Action method does not exist']); + } + $user = UserModel::getById(['id' => $aArgs['userId'], 'select' => ['user_id']]); $whereClause = PreparedClauseController::getPreparedClause(['clause' => $basket['basket_clause'], 'login' => $user['user_id']]); $resources = ResModel::getOnView([ @@ -600,6 +608,7 @@ class ResourceListController } } + $resourcesForAction = []; foreach ($resources as $resource) { $lock = true; if (empty($resource['locker_user_id'] || empty($resource['locker_time']))) { @@ -609,28 +618,23 @@ class ResourceListController } elseif (strtotime($resource['locker_time']) < time()) { $lock = false; } - if ($lock) { - return $response->withStatus(403)->withJson(['errors' => 'One of resources is lock']); + if (!$lock) { + $resourcesForAction[] = $resource['res_id']; } } - $action = ActionModel::getById(['id' => $aArgs['actionId'], 'select' => ['component']]); - if (empty($action['component'])) { - return $response->withStatus(400)->withJson(['errors' => 'Action component does not exist']); - } - - if (!array_key_exists($action['component'], ActionMethodController::COMPONENTS_ACTIONS)) { - return $response->withStatus(400)->withJson(['errors' => 'Action method does not exist']); + if (empty($resourcesForAction)) { + return $response->withJson(['success' => 'No resource to process']); } - foreach ($body['resources'] as $resId) { + foreach ($resourcesForAction as $resId) { $method = ActionMethodController::COMPONENTS_ACTIONS[$action['component']]; if (!empty($method)) { ActionMethodController::$method(['id' => $aArgs['actionId'], 'resId' => $resId]); } } - ActionMethodController::terminateAction(['id' => $aArgs['actionId'], 'resources' => $body['resources'], 'basketName' => $basket['basket_name']]); + ActionMethodController::terminateAction(['id' => $aArgs['actionId'], 'resources' => $resourcesForAction, 'basketName' => $basket['basket_name']]); return $response->withStatus(204); } @@ -699,6 +703,58 @@ class ResourceListController return $response->withJson(['lockedResources' => $locked]); } + public function unlock(Request $request, Response $response, array $aArgs) + { + $body = $request->getParsedBody(); + if (!Validator::arrayType()->notEmpty()->validate($body['resources'])) { + return $response->withStatus(400)->withJson(['errors' => 'Data resources is empty or not an array']); + } + $body['resources'] = array_slice($body['resources'], 0, 500); + + $currentUser = UserModel::getByLogin(['login' => $GLOBALS['userId'], 'select' => ['id']]); + $errors = ResourceListController::listControl(['groupId' => $aArgs['groupId'], 'userId' => $aArgs['userId'], 'basketId' => $aArgs['basketId'], 'currentUserId' => $currentUser['id']]); + if (!empty($errors['errors'])) { + return $response->withStatus($errors['code'])->withJson(['errors' => $errors['errors']]); + } + + $basket = BasketModel::getById(['id' => $aArgs['basketId'], 'select' => ['basket_clause']]); + $user = UserModel::getById(['id' => $aArgs['userId'], 'select' => ['user_id']]); + + $whereClause = PreparedClauseController::getPreparedClause(['clause' => $basket['basket_clause'], 'login' => $user['user_id']]); + $resources = ResModel::getOnView([ + 'select' => ['res_id', 'locker_user_id', 'locker_time'], + 'where' => [$whereClause, 'res_view_letterbox.res_id in (?)'], + 'data' => [$body['resources']] + ]); + $resourcesInBasket = []; + foreach ($resources as $resource) { + $resourcesInBasket[] = $resource['res_id']; + } + + foreach ($body['resources'] as $resId) { + if (!in_array($resId, $resourcesInBasket)) { + return $response->withStatus(403)->withJson(['errors' => 'Resources out of perimeter']); + } + } + + $resourcesToUnlock = []; + foreach ($resources as $resource) { + if (!(!empty($resource['locker_user_id']) && $resource['locker_user_id'] != $currentUser['id'] && strtotime($resource['locker_time']) > time())) { + $resourcesToUnlock[] = $resource['res_id']; + } + } + + if (!empty($resourcesToUnlock)) { + ResModel::update([ + 'set' => ['locker_user_id' => null, 'locker_time' => null], + 'where' => ['res_id in (?)'], + 'data' => [$resourcesToUnlock] + ]); + } + + return $response->withStatus(204); + } + public static function listControl(array $aArgs) { ValidatorModel::notEmpty($aArgs, ['groupId', 'userId', 'basketId', 'currentUserId']); diff --git a/test/unitTests/app/resource/ResourceListControllerTest.php b/test/unitTests/app/resource/ResourceListControllerTest.php index 39adf5cb223ade341b64371177fed9791e4a0ed7..77585c3529777808788b5c5e957d5f72c9ac1e8b 100644 --- a/test/unitTests/app/resource/ResourceListControllerTest.php +++ b/test/unitTests/app/resource/ResourceListControllerTest.php @@ -174,4 +174,23 @@ class ResourceListControllerTest extends TestCase $GLOBALS['userId'] = 'superadmin'; } + + public function testGetActions() + { + $GLOBALS['userId'] = 'bbain'; + + $resListController = new \Resource\controllers\ResourceListController(); + + // GET + $environment = \Slim\Http\Environment::mock(['REQUEST_METHOD' => 'GET']); + $request = \Slim\Http\Request::createFromEnvironment($environment); + + $response = $resListController->getActions($request, new \Slim\Http\Response(), ['userId' => 19, 'groupId' => 2, 'basketId' => 10]); + $responseBody = json_decode((string)$response->getBody()); + + $this->assertInternalType('array', $responseBody->actions); + $this->assertNotNull($responseBody->actions); + + $GLOBALS['userId'] = 'superadmin'; + } }