diff --git a/core/xml/actions_pages.xml b/core/xml/actions_pages.xml index 2412c120e67dff9e86460c67ed5478e94cb90096..9b75658ed2e82105f5661a9d1e02dd3cb7a3d8a8 100755 --- a/core/xml/actions_pages.xml +++ b/core/xml/actions_pages.xml @@ -296,7 +296,7 @@ An action page is described in a ACTIONPAGE tag : <LABEL>_SEND_DOCS_TO_RECOMMENDATION</LABEL> <NAME>send_docs_to_recommendation</NAME> <DESC>_SEND_DOCS_TO_RECOMMENDATION_DESC</DESC> - <component>v1Action</component> + <component>sendToParallelOpinion</component> <ORIGIN>module</ORIGIN> <MODULE>avis</MODULE> <FLAG_CREATE>false</FLAG_CREATE> diff --git a/migration/20.03/2003.sql b/migration/20.03/2003.sql index 2fd777c0f56f86a208142117ab8ac1d7d2c23812..7ad82c81f35e9cf7318607ff59df1deb1711e4fc 100644 --- a/migration/20.03/2003.sql +++ b/migration/20.03/2003.sql @@ -98,6 +98,7 @@ UPDATE actions SET component = 'closeMailWithAttachmentsOrNotesAction' WHERE act UPDATE actions SET component = 'sendToOpinionCircuitAction' WHERE action_page = 'send_to_avis'; UPDATE actions SET component = 'continueOpinionCircuitAction' WHERE action_page = 'avis_workflow'; UPDATE actions SET component = 'giveOpinionParallelAction' WHERE action_page = 'avis_workflow_simple'; +UPDATE actions SET component = 'sendToParallelOpinion' WHERE action_page = 'send_docs_to_recommendation'; DELETE FROM actions_groupbaskets WHERE id_action IN (SELECT id FROM actions WHERE action_page = 'put_in_copy'); DELETE FROM actions_categories WHERE action_id IN (SELECT id FROM actions WHERE action_page = 'put_in_copy'); diff --git a/rest/index.php b/rest/index.php index 1c4869f35a5f156c515ad99fa3d2550839d7f916..ead633a08ea5e055ce050d58a4d607ce34dc961c 100755 --- a/rest/index.php +++ b/rest/index.php @@ -352,6 +352,7 @@ $app->get('/resources/{resId}/templates', \Template\controllers\TemplateControll $app->get('/resources/{resId}/listInstance', \Entity\controllers\ListInstanceController::class . ':getByResId'); $app->get('/resources/{resId}/visaCircuit', \Entity\controllers\ListInstanceController::class . ':getVisaCircuitByResId'); $app->get('/resources/{resId}/opinionCircuit', \Entity\controllers\ListInstanceController::class . ':getOpinionCircuitByResId'); +$app->get('/resources/{resId}/parallelOpinion', \Entity\controllers\ListInstanceController::class . ':getParallelOpinionByResId'); $app->get('/resources/{resId}/defaultCircuit', \Entity\controllers\ListTemplateController::class . ':getDefaultCircuitByResId'); $app->delete('/resources/{resId}/circuits/{type}', \Entity\controllers\ListInstanceController::class . ':deleteCircuit'); $app->get('/resources/{resId}/linkedResources', \Resource\controllers\LinkController::class . ':getLinkedResources'); diff --git a/sql/data_fr.sql b/sql/data_fr.sql index 5dd63a1af3842556a9e494f248bd399d5832d74f..32a89d5c980e8172afd759e4b6139d801cedd80c 100755 --- a/sql/data_fr.sql +++ b/sql/data_fr.sql @@ -984,7 +984,7 @@ INSERT INTO actions (id, label_action, id_status, is_system, history, component) INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (22, '', 'Attribuer au service', 'NEW', 'N', 'confirm_status', 'Y', 'confirmAction'); INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (23, 'indexing', 'Attribuer au(x) service(s)', 'NEW', 'N', 'confirm_status', 'Y', 'confirmAction'); INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (24, 'indexing', 'Remettre en validation', 'VAL', 'N', 'confirm_status', 'Y', 'confirmAction'); -INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (36, '', 'Envoyer pour avis', 'EAVIS', 'N', 'send_docs_to_recommendation', 'Y', 'v1Action'); +INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (36, '', 'Envoyer pour avis', 'EAVIS', 'N', 'send_docs_to_recommendation', 'Y', 'sendToParallelOpinion'); INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (37, '', 'Donner un avis', '_NOSTATUS_', 'N', 'avis_workflow_simple', 'Y', 'giveOpinionParallelAction'); -- INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (100, '', 'Voir le document', '', 'N', 'view', 'N', 'viewDoc'); --INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (101, '', 'Envoyer pour visa', 'VIS', 'N', 'confirm_status', 'Y', 'confirmAction'); @@ -997,8 +997,8 @@ INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_pag INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (407, '', 'Renvoyer pour traitement', 'COU', 'N', 'confirm_status', 'Y', 'confirmAction'); INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (408, '', 'Refuser le visa et remonter le circuit', '_NOSTATUS_', 'N', 'rejection_visa_previous', 'N', 'rejectVisaBackToPreviousAction'); INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (410, '', 'Transmettre la réponse signée', 'EENV', 'N', 'interrupt_visa', 'Y', 'interruptVisaAction'); -INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (414, '', 'Envoyer au parapheur', '_NOSTATUS_', 'N', 'send_to_visa', 'Y', 'v1Action'); -INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (416, '', 'Valider et poursuivre le circuit', '_NOSTATUS_', 'N', 'visa_workflow', 'Y', 'v1Action'); +INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (414, '', 'Envoyer au parapheur', '_NOSTATUS_', 'N', 'send_to_visa', 'Y', 'sendSignatureBookAction'); +INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (416, '', 'Valider et poursuivre le circuit', '_NOSTATUS_', 'N', 'visa_workflow', 'Y', 'continueVisaCircuitAction'); --INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (417, '', 'Envoyer l''AR', 'SVX', 'N', 'send_to_contact_with_mandatory_attachment', 'Y', 'v1Action'); INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (420, '', 'Classer sans suite', 'SSUITE', 'N', 'confirm_status', 'Y', 'confirmAction'); INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (421, '', 'Retourner au Service Courrier', 'RET', 'N', 'confirm_status', 'Y', 'confirmAction'); diff --git a/src/app/action/controllers/ActionMethodController.php b/src/app/action/controllers/ActionMethodController.php index cedace191a68938a3a16e90614b820ffcb219fba..ce3260aa942e44c6021429f9967e4ae127bab47b 100644 --- a/src/app/action/controllers/ActionMethodController.php +++ b/src/app/action/controllers/ActionMethodController.php @@ -25,9 +25,11 @@ use ExternalSignatoryBook\controllers\MaarchParapheurController; use History\controllers\HistoryController; use MessageExchange\controllers\MessageExchangeReviewController; use Note\models\NoteModel; +use Resource\controllers\ResController; use Resource\models\ResModel; use SrcCore\models\CoreConfigModel; use SrcCore\models\CurlModel; +use SrcCore\models\DatabaseModel; use SrcCore\models\ValidatorModel; use User\models\UserModel; @@ -59,6 +61,7 @@ class ActionMethodController 'rejectVisaBackToPreviousAction' => 'rejectVisaBackToPrevious', 'resetVisaAction' => 'resetVisa', 'interruptVisaAction' => 'interruptVisa', + 'sendToParallelOpinion' => 'sendToParallelOpinion', 'sendToOpinionCircuitAction' => 'sendToOpinionCircuit', 'continueOpinionCircuitAction' => 'continueOpinionCircuit', 'giveOpinionParallelAction' => 'giveOpinionParallel', @@ -555,10 +558,116 @@ class ActionMethodController return ["errors" => ["Opinion limit date is missing"]]; } + $opinionLimitDate = new \DateTime($args['data']['opinionLimitDate']); + $today = new \DateTime('today'); + if ($opinionLimitDate < $today) { + return ['errors' => "Opinion limit date is not a valid date"]; + } + ResModel::update([ 'set' => ['opinion_limit_date' => $args['data']['opinionLimitDate']], - 'where' => ['res_id = ?', 'difflist_type = ?'], - 'data' => [$args['resId'], 'AVIS_CIRCUIT'] + 'where' => ['res_id = ?'], + 'data' => [$args['resId']] + ]); + + return true; + } + + public static function sendToParallelOpinion(array $args) + { + + $currentUser = UserModel::getById(['select' => ['user_id'], 'id' => $args['userId']]); + + DatabaseModel::beginTransaction(); + + foreach ($args['data'] as $ListInstanceByRes) { + if (empty($ListInstanceByRes['resId'])) { + DatabaseModel::rollbackTransaction(); + return ['errors' => ['resId is empty']]; + } + + if (!Validator::intVal()->validate($ListInstanceByRes['resId']) || !ResController::hasRightByResId(['resId' => [$ListInstanceByRes['resId']], 'userId' => $GLOBALS['id']])) { + DatabaseModel::rollbackTransaction(); + return ['errors' => ['Document out of perimeter']]; + } + + if (empty($ListInstanceByRes['listInstances'])) { + return ['errors' => ['listInstances is empty']]; + } + + $listInstances = ListInstanceModel::get([ + 'select' => ['*'], + 'where' => ['res_id = ?', 'difflist_type = ?', 'item_mode in (?)'], + 'data' => [$ListInstanceByRes['resId'], 'entity_id', ['avis', 'avis_copy', 'avis_info']] + ]); + ListInstanceModel::delete([ + 'where' => ['res_id = ?', 'difflist_type = ?', 'item_mode in (?)'], + 'data' => [$ListInstanceByRes['resId'], 'entity_id', ['avis', 'avis_copy', 'avis_info']] + ]); + + foreach ($ListInstanceByRes['listInstances'] as $instance) { + if (!in_array($instance['item_mode'], ['avis', 'avis_copy', 'avis_info']) { + return ['errors' => ['item_mode is different from avis, avis_copy or avis_info']]; + } + } + + foreach ($ListInstanceByRes['listInstances'] as $key => $instance) { + $listControl = ['item_id', 'item_type', 'item_mode']; + foreach ($listControl as $itemControl) { + if (empty($instance[$itemControl])) { + return ['errors' => ["ListInstance {$itemControl} is not set or empty"]]; + } + } + + if (in_array($instance['item_type'], ['user_id', 'user'])) { + if ($instance['item_type'] == 'user_id') { + $user = UserModel::getByLogin(['login' => $instance['item_id'], 'select' => ['id']]); + } else { + $user = UserModel::getById(['id' => $instance['item_id'], 'select' => ['id', 'user_id']]); + $instance['item_id'] = $user['user_id'] ?? null; + $instance['item_type'] = 'user_id'; + } + if (empty($user)) { + DatabaseModel::rollbackTransaction(); + return ['errors' => ['User not found']]; + } + } else { + DatabaseModel::rollbackTransaction(); + return ['errors' => ['item_type does not exist']]; + } + + ListInstanceModel::create([ + 'res_id' => $ListInstanceByRes['resId'], + 'sequence' => $key, + 'item_id' => $instance['item_id'], + 'item_type' => $instance['item_type'], + 'item_mode' => $instance['item_mode'], + 'added_by_user' => $currentUser['user_id'], + 'difflist_type' => 'entity_id', + 'process_date' => null, + 'process_comment' => null, + 'requested_signature' => false, + 'viewed' => empty($instance['viewed']) ? 0 : $instance['viewed'] + ]); + } + } + + DatabaseModel::commitTransaction(); + + if (empty($args['data']['opinionLimitDate'])) { + return ["errors" => ["Opinion limit date is missing"]]; + } + + $opinionLimitDate = new \DateTime($args['data']['opinionLimitDate']); + $today = new \DateTime('today'); + if ($opinionLimitDate < $today) { + return ['errors' => "Opinion limit date is not a valid date"]; + } + + ResModel::update([ + 'set' => ['opinion_limit_date' => $args['data']['opinionLimitDate']], + 'where' => ['res_id = ?'], + 'data' => [$args['resId']] ]); return true; diff --git a/src/app/entity/controllers/ListInstanceController.php b/src/app/entity/controllers/ListInstanceController.php index 35616ce0fae722c8f65ad9e63719cd38ef2f050e..c9a2918220f6d6cde921b7c8683884dc218e049d 100755 --- a/src/app/entity/controllers/ListInstanceController.php +++ b/src/app/entity/controllers/ListInstanceController.php @@ -95,6 +95,22 @@ class ListInstanceController return $response->withJson($listInstances); } + public function getParallelOpinionByResId(Request $request, Response $response, array $aArgs) + { + if (!Validator::intVal()->validate($aArgs['resId']) || !ResController::hasRightByResId(['resId' => [$aArgs['resId']], 'userId' => $GLOBALS['id']])) { + return $response->withStatus(403)->withJson(['errors' => 'Document out of perimeter']); + } + + $listInstances = ListInstanceModel::getParallelOpinionByResId(['select' => ['listinstance_id', 'sequence', 'item_id', 'item_type', 'users.id', 'firstname as item_firstname', 'lastname as item_lastname', 'entity_label as item_entity', 'viewed', 'process_date', 'process_comment'], 'id' => $aArgs['resId']]); + foreach ($listInstances as $key => $value) { + $listInstances[$key]['item_id'] = $listInstances[$key]['id']; + $listInstances[$key]['item_type'] = 'user'; + $listInstances[$key]['labelToDisplay'] = $listInstances[$key]['item_firstname'].' '.$listInstances[$key]['item_lastname']; + } + + return $response->withJson($listInstances); + } + public function update(Request $request, Response $response) { $body = $request->getParsedBody(); diff --git a/src/app/entity/models/ListInstanceModelAbstract.php b/src/app/entity/models/ListInstanceModelAbstract.php index 83c205b50e70dc14f6d6619fce21e28417d54e15..3cb3d5ea4cba868050992e76a042bb7a78d5248f 100755 --- a/src/app/entity/models/ListInstanceModelAbstract.php +++ b/src/app/entity/models/ListInstanceModelAbstract.php @@ -150,6 +150,24 @@ abstract class ListInstanceModelAbstract return $aListinstance; } + public static function getParallelOpinionByResId(array $aArgs) + { + ValidatorModel::notEmpty($aArgs, ['id']); + ValidatorModel::intVal($aArgs, ['id']); + ValidatorModel::arrayType($aArgs, ['select']); + + $aListinstance = DatabaseModel::select([ + 'select' => empty($aArgs['select']) ? ['*'] : $aArgs['select'], + 'table' => ['listinstance', 'users', 'users_entities', 'entities'], + 'left_join' => ['listinstance.item_id = users.user_id', 'users_entities.user_id = users.user_id', 'entities.entity_id = users_entities.entity_id'], + 'where' => ['res_id = ?', 'item_type = ?', 'difflist_type = ?', 'primary_entity = ?', 'item_mode in (?)'], + 'data' => [$aArgs['id'], 'user_id', 'entity_id', 'Y', ['avis', 'avis_copy', 'avis_info']], + 'order_by' => ['listinstance_id ASC'], + ]); + + return $aListinstance; + } + public static function getCurrentStepByResId(array $aArgs) { ValidatorModel::notEmpty($aArgs, ['resId']);