diff --git a/rest/index.php b/rest/index.php index ef6c41bf282440455328b5de6523245bbeb33cef..a5314193ccb6e2cd36bf4dd6d2eda38e6b851da2 100755 --- a/rest/index.php +++ b/rest/index.php @@ -473,6 +473,7 @@ $app->post('/resourcesList/users/{userId}/groups/{groupId}/baskets/{basketId}/ac $app->post('/resourcesList/users/{userId}/groups/{groupId}/baskets/{basketId}/actions/{actionId}/checkPrintDepositList', \Action\controllers\PreProcessActionController::class . ':checkPrintDepositList'); $app->post('/resourcesList/users/{userId}/groups/{groupId}/baskets/{basketId}/checkAcknowledgementRecordManagement', \Action\controllers\PreProcessActionController::class . ':checkAcknowledgementRecordManagement'); $app->post('/resourcesList/users/{userId}/groups/{groupId}/baskets/{basketId}/checkReplyRecordManagement', \Action\controllers\PreProcessActionController::class . ':checkReplyRecordManagement'); +$app->post('/resourcesList/users/{userId}/groups/{groupId}/baskets/{basketId}/actions/{actionId}/checkSendToRecordManagement', \Action\controllers\PreProcessActionController::class . ':checkSendToRecordManagement'); //Search $app->post('/search', \Search\controllers\SearchController::class . ':get'); @@ -643,7 +644,6 @@ $app->delete('/collaboraOnline/file', \ContentManagement\controllers\CollaboraOn $app->post('/collaboraOnline/encodedFile', \ContentManagement\controllers\CollaboraOnlineController::class . ':saveTmpEncodedDocument'); // Archival -$app->post('/resourcesList/users/{userId}/groups/{groupId}/baskets/{basketId}/actions/{actionId}/checkSendToRecordManagement', \ExportSeda\controllers\SedaController::class . ':checkSendToRecordManagement'); $app->get('/archival/retentionRules', \ExportSeda\controllers\SedaController::class . ':getRetentionRules'); $app->put('/archival/binding', \ExportSeda\controllers\SedaController::class . ':setBindingDocument'); $app->put('/archival/freezeRetentionRule', \ExportSeda\controllers\SedaController::class . ':freezeRetentionRule'); diff --git a/src/app/external/exportSeda/controllers/PreProcessActionSEDATrait.php b/src/app/external/exportSeda/controllers/PreProcessActionSEDATrait.php index 85191a07dcfac05386fe8f4a685f9434d450fb1c..d5722326f24507905f0af11df4a9d3fce68a6d0b 100644 --- a/src/app/external/exportSeda/controllers/PreProcessActionSEDATrait.php +++ b/src/app/external/exportSeda/controllers/PreProcessActionSEDATrait.php @@ -12,21 +12,187 @@ namespace ExportSeda\controllers; -use Respect\Validation\Validator; use Action\controllers\PreProcessActionController; use Attachment\models\AttachmentModel; use Docserver\models\DocserverModel; use Docserver\models\DocserverTypeModel; +use Doctype\models\DoctypeModel; +use Entity\models\EntityModel; use MessageExchange\models\MessageExchangeModel; +use Parameter\models\ParameterModel; use Resource\controllers\ResController; use Resource\controllers\ResourceListController; use Resource\controllers\StoreController; use Resource\models\ResModel; +use Respect\Validation\Validator; use Slim\Http\Request; use Slim\Http\Response; +use SrcCore\models\CoreConfigModel; trait PreProcessActionSEDATrait { + public function checkSendToRecordManagement(Request $request, Response $response, array $aArgs) + { + $body = $request->getParsedBody(); + + if (!Validator::arrayType()->notEmpty()->validate($body['resources'])) { + return $response->withStatus(400)->withJson(['errors' => 'Body resources is empty or not an array']); + } + + $errors = ResourceListController::listControl(['groupId' => $aArgs['groupId'], 'userId' => $aArgs['userId'], 'basketId' => $aArgs['basketId'], 'currentUserId' => $GLOBALS['id']]); + if (!empty($errors['errors'])) { + return $response->withStatus($errors['code'])->withJson(['errors' => $errors['errors']]); + } + + $body['resources'] = array_slice($body['resources'], 0, 500); + if (!ResController::hasRightByResId(['resId' => $body['resources'], 'userId' => $GLOBALS['id']])) { + return $response->withStatus(403)->withJson(['errors' => 'Document out of perimeter']); + } + + $resourcesInformations = ['success' => [], 'errors' => []]; + $body['resources'] = PreProcessActionController::getNonLockedResources(['resources' => $body['resources'], 'userId' => $GLOBALS['id']]); + + // Common Data + $resources = ResModel::get([ + 'select' => ['res_id', 'destination', 'type_id', 'subject', 'linked_resources', 'retention_frozen', 'binding', 'creation_date', 'alt_identifier'], + 'where' => ['res_id in (?)'], + 'data' => [$body['resources']] + ]); + $resources = array_column($resources, null, 'res_id'); + $doctypesId = array_column($resources, 'type_id'); + $destinationsId = array_column($resources, 'destination'); + + $doctypes = DoctypeModel::get([ + 'select' => ['type_id', 'description', 'duration_current_use', 'retention_rule', 'action_current_use', 'retention_final_disposition'], + 'where' => ['type_id in (?)'], + 'data' => [$doctypesId] + ]); + $doctypesData = array_column($doctypes, null, 'type_id'); + + $attachments = AttachmentModel::get([ + 'select' => ['res_id_master', 'res_id'], + 'where' => ['res_id_master in (?)', 'attachment_type in (?)', 'status = ?'], + 'data' => [$body['resources'], ['acknowledgement_record_management', 'reply_record_management'], 'TRA'] + ]); + $resourcesAcknowledgement = array_column($attachments, 'res_id', 'res_id_master'); + + $entities = EntityModel::get([ + 'select' => ['producer_service', 'entity_label', 'entity_id'], + 'where' => ['entity_id in (?)'], + 'data' => [$destinationsId] + ]); + $destinationsData = array_column($entities, null, 'entity_id'); + + $bindingDocument = ParameterModel::getById(['select' => ['param_value_string'], 'id' => 'bindingDocumentFinalAction']); + $nonBindingDocument = ParameterModel::getById(['select' => ['param_value_string'], 'id' => 'nonBindingDocumentFinalAction']); + + $config = CoreConfigModel::getJsonLoaded(['path' => 'apps/maarch_entreprise/xml/config.json']); + if (empty($config['exportSeda']['senderOrgRegNumber'])) { + return $response->withStatus(400)->withJson(['errors' => 'No senderOrgRegNumber found in config.json', 'lang' => 'noSenderOrgRegNumber']); + } + if (empty($config['exportSeda']['accessRuleCode'])) { + return $response->withStatus(400)->withJson(['errors' => 'No accessRuleCode found in config.json', 'lang' => 'noAccessRuleCode']); + } + + $producerService = ''; + foreach ($destinationsData as $value) { + if (!empty($value['producer_service'])) { + if (!empty($producerService) && $producerService != $value['producer_service']) { + return $response->withStatus(400)->withJson(['errors' => 'All producer services are not the same', 'lang' => 'differentProducerServices']); + } + $producerService = $value['producer_service']; + } + } + if (empty($producerService)) { + return $response->withStatus(400)->withJson(['errors' => 'No accessRuleCode found in config.json', 'lang' => 'noProducerService']); + } + + $archivalAgreements = SedaController::getArchivalAgreements([ + 'config' => $config, + 'senderArchiveEntity' => $config['exportSeda']['senderOrgRegNumber'], + 'producerService' => $producerService + ]); + if (!empty($archivalAgreements['errors'])) { + return $response->withStatus(400)->withJson($archivalAgreements); + } + $recipientArchiveEntities = SedaController::getRecipientArchiveEntities(['config' => $config, 'archivalAgreements' => $archivalAgreements['archivalAgreements']]); + if (!empty($recipientArchiveEntities['errors'])) { + return $response->withStatus(400)->withJson($recipientArchiveEntities); + } + + $resourcesInformations['archivalAgreements'] = $archivalAgreements['archivalAgreements']; + $resourcesInformations['recipientArchiveEntities'] = $recipientArchiveEntities['archiveEntities']; + $resourcesInformations['senderArchiveEntity'] = $config['exportSeda']['senderOrgRegNumber']; + // End of Common Data + + foreach ($body['resources'] as $resId) { + if (empty($resources[$resId]['destination'])) { + $resourcesInformations['errors'][] = ['alt_identifier' => $resources[$resId]['alt_identifier'], 'res_id' => $resId, 'reason' => 'noDestination']; + continue; + } elseif ($resources[$resId]['retention_frozen'] === true) { + $resourcesInformations['errors'][] = ['alt_identifier' => $resources[$resId]['alt_identifier'], 'res_id' => $resId, 'reason' => 'retentionRuleFrozen']; + continue; + } + + if (!empty($resourcesAcknowledgement[$resId])) { + $resourcesInformations['errors'][] = ['alt_identifier' => $resources[$resId]['alt_identifier'], 'res_id' => $resId, 'reason' => 'recordManagement_alreadySent']; + continue; + } + + $typeId = $resources[$resId]['type_id']; + if (empty($doctypesData[$typeId]['retention_rule']) || empty($doctypesData[$typeId]['retention_final_disposition']) || empty($doctypesData[$typeId]['duration_current_use'])) { + $resourcesInformations['errors'][] = ['alt_identifier' => $resources[$resId]['alt_identifier'], 'res_id' => $resId, 'reason' => 'noRetentionInfo']; + continue; + } else { + if ($resources[$resId]['binding'] === null && !in_array($doctypesData[$typeId]['action_current_use'], ['transfer', 'copy'])) { + $resourcesInformations['errors'][] = ['alt_identifier' => $resources[$resId]['alt_identifier'], 'res_id' => $resId, 'reason' => 'noTransferCopyRecordManagement']; + continue; + } elseif ($resources[$resId]['binding'] === true && !in_array($bindingDocument['param_value_string'], ['transfer', 'copy'])) { + $resourcesInformations['errors'][] = ['alt_identifier' => $resources[$resId]['alt_identifier'], 'res_id' => $resId, 'reason' => 'noTransferCopyBindingRecordManagement']; + continue; + } elseif ($resources[$resId]['binding'] === false && !in_array($nonBindingDocument['param_value_string'], ['transfer', 'copy'])) { + $resourcesInformations['errors'][] = ['alt_identifier' => $resources[$resId]['alt_identifier'], 'res_id' => $resId, 'reason' => 'noTransferCopyNoBindingRecordManagement']; + continue; + } + $date = new \DateTime($resources[$resId]['creation_date']); + $date->add(new \DateInterval("P{$doctypesData[$typeId]['duration_current_use']}D")); + if (strtotime($date->format('Y-m-d')) >= time()) { + $resourcesInformations['errors'][] = ['alt_identifier' => $resources[$resId]['alt_identifier'], 'res_id' => $resId, 'reason' => 'durationCurrentUseNotExceeded']; + continue; + } + } + + $destinationId = $resources[$resId]['destination']; + if (empty($destinationsData[$destinationId]['producer_service'])) { + $resourcesInformations['errors'][] = ['alt_identifier' => $resources[$resId]['alt_identifier'], 'res_id' => $resId, 'reason' => 'noProducerService']; + continue; + } + + $archivalData = SedaController::initArchivalData([ + 'resource' => $resources[$resId], + 'senderOrgRegNumber' => $config['exportSeda']['senderOrgRegNumber'], + 'entity' => $destinationsData[$destinationId], + 'doctype' => $doctypesData[$typeId] + ]); + + if (!empty($return['errors'])) { + $resourcesInformations['errors'][] = ['alt_identifier' => $resources[$resId]['alt_identifier'], 'res_id' => $resId, 'reason' => $return['errors']]; + continue; + } else { + $resourcesInformations['success'][$resId] = $archivalData['archivalData']; + } + + $unitIdentifier = MessageExchangeModel::getUnitIdentifierByResId(['select' => ['message_id'], 'resId' => (string)$resId]); + if (!empty($unitIdentifier[0]['message_id'])) { + MessageExchangeModel::delete(['where' => ['message_id = ?'], 'data' => [$unitIdentifier[0]['message_id']]]); + } + MessageExchangeModel::deleteUnitIdentifier(['where' => ['res_id = ?'], 'data' => [$resId]]); + } + + + return $response->withJson($resourcesInformations); + } + public function checkAcknowledgementRecordManagement(Request $request, Response $response, array $args) { $body = $request->getParsedBody(); diff --git a/src/app/external/exportSeda/controllers/SedaController.php b/src/app/external/exportSeda/controllers/SedaController.php index 4222b27550f0c57ca31bed6103fb8ba65c7c33a4..899acb3ac6ef8ddf65e158784027f24603680409 100755 --- a/src/app/external/exportSeda/controllers/SedaController.php +++ b/src/app/external/exportSeda/controllers/SedaController.php @@ -18,18 +18,13 @@ use Attachment\models\AttachmentModel; use Convert\models\AdrModel; use Docserver\models\DocserverModel; use Docserver\models\DocserverTypeModel; -use Doctype\models\DoctypeModel; use Email\models\EmailModel; -use Entity\models\EntityModel; use ExportSeda\controllers\ExportSEDATrait; use Folder\models\FolderModel; use Group\controllers\PrivilegeController; use History\controllers\HistoryController; -use MessageExchange\models\MessageExchangeModel; use Note\models\NoteModel; -use Parameter\models\ParameterModel; use Resource\controllers\ResController; -use Resource\controllers\ResourceListController; use Resource\controllers\StoreController; use Resource\models\ResModel; use Respect\Validation\Validator; @@ -41,114 +36,6 @@ use User\models\UserModel; class SedaController { - public function checkSendToRecordManagement(Request $request, Response $response, array $aArgs) - { - $body = $request->getParsedBody(); - - if (!Validator::arrayType()->notEmpty()->validate($body['resources'])) { - return $response->withStatus(400)->withJson(['errors' => 'Body resources is empty or not an array']); - } - - $errors = ResourceListController::listControl(['groupId' => $aArgs['groupId'], 'userId' => $aArgs['userId'], 'basketId' => $aArgs['basketId'], 'currentUserId' => $GLOBALS['id']]); - if (!empty($errors['errors'])) { - return $response->withStatus($errors['code'])->withJson(['errors' => $errors['errors']]); - } - - $body['resources'] = array_slice($body['resources'], 0, 500); - if (!ResController::hasRightByResId(['resId' => $body['resources'], 'userId' => $GLOBALS['id']])) { - return $response->withStatus(403)->withJson(['errors' => 'Document out of perimeter']); - } - - $firstResource = $body['resources'][0]; - - $resource = ResModel::getById(['resId' => $firstResource, 'select' => ['res_id', 'destination', 'type_id', 'subject', 'linked_resources', 'retention_frozen', 'binding', 'creation_date']]); - if (empty($resource)) { - return $response->withStatus(400)->withJson(['errors' => 'resource does not exists']); - } elseif (empty($resource['destination'])) { - return $response->withStatus(400)->withJson(['errors' => 'resource has no destination', 'lang' => 'noDestination']); - } elseif ($resource['retention_frozen'] === true) { - return $response->withStatus(400)->withJson(['errors' => 'retention rule is frozen', 'lang' => 'retentionRuleFrozen']); - } - - $attachments = AttachmentModel::get([ - 'select' => ['res_id'], - 'where' => ['res_id_master = ?', 'attachment_type in (?)', 'status = ?'], - 'data' => [$firstResource, ['acknowledgement_record_management', 'reply_record_management'], 'TRA'] - ]); - if (!empty($attachments)) { - return $response->withStatus(400)->withJson(['errors' => 'acknowledgement or reply already exists', 'lang' => 'recordManagement_alreadySent']); - } - - $doctype = DoctypeModel::getById(['id' => $resource['type_id'], 'select' => ['description', 'duration_current_use', 'retention_rule', 'action_current_use', 'retention_final_disposition']]); - if (empty($doctype['retention_rule']) || empty($doctype['retention_final_disposition']) || empty($doctype['duration_current_use'])) { - return $response->withStatus(400)->withJson(['errors' => 'retention_rule, retention_final_disposition or duration_current_use is empty for doctype', 'lang' => 'noRetentionInfo']); - } else { - $bindingDocument = ParameterModel::getById(['select' => ['param_value_string'], 'id' => 'bindingDocumentFinalAction']); - $nonBindingDocument = ParameterModel::getById(['select' => ['param_value_string'], 'id' => 'nonBindingDocumentFinalAction']); - if ($resource['binding'] === null && !in_array($doctype['action_current_use'], ['transfer', 'copy'])) { - return $response->withStatus(400)->withJson(['errors' => 'action_current_use is not transfer or copy', 'lang' => 'noTransferCopyRecordManagement']); - } elseif ($resource['binding'] === true && !in_array($bindingDocument['param_value_string'], ['transfer', 'copy'])) { - return $response->withStatus(400)->withJson(['errors' => 'binding document is not transfer or copy', 'lang' => 'noTransferCopyBindingRecordManagement']); - } elseif ($resource['binding'] === false && !in_array($nonBindingDocument['param_value_string'], ['transfer', 'copy'])) { - return $response->withStatus(400)->withJson(['errors' => 'no binding document is not transfer or copy', 'lang' => 'noTransferCopyNoBindingRecordManagement']); - } - $date = new \DateTime($resource['creation_date']); - $date->add(new \DateInterval("P{$doctype['duration_current_use']}D")); - if (strtotime($date->format('Y-m-d')) >= time()) { - return $response->withStatus(400)->withJson(['errors' => 'duration current use is not exceeded', 'lang' => 'durationCurrentUseNotExceeded']); - } - } - $entity = EntityModel::getByEntityId(['entityId' => $resource['destination'], 'select' => ['producer_service', 'entity_label']]); - if (empty($entity['producer_service'])) { - return $response->withStatus(400)->withJson(['errors' => 'producer_service is empty for this entity', 'lang' => 'noProducerService']); - } - - $config = CoreConfigModel::getJsonLoaded(['path' => 'apps/maarch_entreprise/xml/config.json']); - if (empty($config['exportSeda']['senderOrgRegNumber'])) { - return $response->withStatus(400)->withJson(['errors' => 'No senderOrgRegNumber found in config.json', 'lang' => 'noSenderOrgRegNumber']); - } - if (empty($config['exportSeda']['accessRuleCode'])) { - return $response->withStatus(400)->withJson(['errors' => 'No accessRuleCode found in config.json', 'lang' => 'noAccessRuleCode']); - } - - $return = SedaController::initArchivalData([ - 'resource' => $resource, - 'senderOrgRegNumber' => $config['exportSeda']['senderOrgRegNumber'], - 'entity' => $entity, - 'doctype' => $doctype - ]); - - if (!empty($return['errors'])) { - return $response->withStatus(400)->withJson(['errors' => $return['errors']]); - } else { - $return = $return['archivalData']; - } - - $archivalAgreements = SedaController::getArchivalAgreements([ - 'config' => $config, - 'senderArchiveEntity' => $config['exportSeda']['senderOrgRegNumber'], - 'producerService' => $entity['producer_service'] - ]); - if (!empty($archivalAgreements['errors'])) { - return $response->withStatus(400)->withJson($archivalAgreements); - } - $recipientArchiveEntities = SedaController::getRecipientArchiveEntities(['config' => $config, 'archivalAgreements' => $archivalAgreements['archivalAgreements']]); - if (!empty($recipientArchiveEntities['errors'])) { - return $response->withStatus(400)->withJson($recipientArchiveEntities); - } - - $return['archivalAgreements'] = $archivalAgreements['archivalAgreements']; - $return['recipientArchiveEntities'] = $recipientArchiveEntities['archiveEntities']; - - $unitIdentifier = MessageExchangeModel::getUnitIdentifierByResId(['select' => ['message_id'], 'resId' => (string)$firstResource]); - if (!empty($unitIdentifier[0]['message_id'])) { - MessageExchangeModel::delete(['where' => ['message_id = ?'], 'data' => [$unitIdentifier[0]['message_id']]]); - } - MessageExchangeModel::deleteUnitIdentifier(['where' => ['res_id = ?'], 'data' => [$firstResource]]); - - return $response->withJson($return); - } - public static function initArchivalData($args = []) { $date = new \DateTime(); diff --git a/src/lang/lang-fr.json b/src/lang/lang-fr.json index aca62787a3badefec31a946900093fd44d51481e..c3058c87b6679a78a46278f49559d60f02e03a8b 100644 --- a/src/lang/lang-fr.json +++ b/src/lang/lang-fr.json @@ -2099,6 +2099,7 @@ "noTransferCopyNoBindingRecordManagement": "Les documents non engageants ne doivent pas être envoyés au SAE", "durationCurrentUseNotExceeded": "La durée de conservation n'est pas dépassée", "noProducerService": "L'entité traitante n'a pas d'identifiant de service producteur", + "differentProducerServices": "Tous les courriers n'ont pas le même service producteur", "noSenderOrgRegNumber": "Aucun service versant défini (senderOrgRegNumber dans config.json)", "producerServiceDoesNotExists": "Le service producteur n'existe pas dans MaarchRM", "nextPage": "Page suivante",