From 4e0adc72f5e5a0c311d5cb77bbd6d890d5920f44 Mon Sep 17 00:00:00 2001
From: "florian.azizian" <florian.azizian@maarch.org>
Date: Tue, 11 Feb 2020 17:09:34 +0100
Subject: [PATCH] FEAT #12595 TIME 2:30 Back Message Exchange in V2

---
 modules/export_seda/RequestSeda.php           |  44 --
 .../MessageExchangeReviewController.php       |  68 ---
 .../SendMessageExchangeController.php         | 556 ------------------
 rest/index.php                                |   7 +-
 .../MessageExchangeReviewController.php       |  54 +-
 .../ReceiveMessageExchangeController.php      |  36 +-
 .../SendMessageExchangeController.php         | 493 ++++++++++++++++
 .../models/MessageExchangeModelAbstract.php   |  50 ++
 8 files changed, 609 insertions(+), 699 deletions(-)
 delete mode 100755 modules/sendmail/Controllers/MessageExchangeReviewController.php
 delete mode 100755 modules/sendmail/Controllers/SendMessageExchangeController.php
 rename {modules/sendmail/Controllers => src/app/external/messageExchange/controllers}/ReceiveMessageExchangeController.php (92%)
 mode change 100755 => 100644

diff --git a/modules/export_seda/RequestSeda.php b/modules/export_seda/RequestSeda.php
index 32ef1020989..5f371a41365 100755
--- a/modules/export_seda/RequestSeda.php
+++ b/modules/export_seda/RequestSeda.php
@@ -891,17 +891,6 @@ class RequestSeda
         return $this->db->query($query, $queryParams);
     }
 
-    public function getMessagesByReferenceByDate($id)
-    {
-        $queryParams = [];
-
-        $queryParams[] = $id;
-
-        $query = "SELECT * FROM message_exchange WHERE reference = ? ORDER BY date asc";
-
-        return $this->db->query($query, $queryParams);
-    }
-
     public function getMessageByIdentifierAndResId($aArgs = [])
     {
         $queryParams = [];
@@ -933,37 +922,4 @@ class RequestSeda
 
         return $entities;
     }
-    public function updateOperationDateMessage($aArgs = [])
-    {
-        $queryParams = [];
-        $queryParams[] = $aArgs['operation_date'];
-        $queryParams[] = $aArgs['message_id'];
-
-        try {
-            $query = "UPDATE message_exchange SET operation_date = ? WHERE message_id = ?";
-
-            $smtp = $this->db->query($query, $queryParams);
-        } catch (Exception $e) {
-            return false;
-        }
-
-        return true;
-    }
-
-    public function updateReceptionDateMessage($aArgs = [])
-    {
-        $queryParams = [];
-        $queryParams[] = $aArgs['reception_date'];
-        $queryParams[] = $aArgs['message_id'];
-
-        try {
-            $query = "UPDATE message_exchange SET reception_date = ? WHERE message_id = ?";
-
-            $smtp = $this->db->query($query, $queryParams);
-        } catch (Exception $e) {
-            return false;
-        }
-
-        return true;
-    }
 }
diff --git a/modules/sendmail/Controllers/MessageExchangeReviewController.php b/modules/sendmail/Controllers/MessageExchangeReviewController.php
deleted file mode 100755
index 9009704f8c6..00000000000
--- a/modules/sendmail/Controllers/MessageExchangeReviewController.php
+++ /dev/null
@@ -1,68 +0,0 @@
-<?php
-
-/**
- * Copyright Maarch since 2008 under licence GPLv3.
- * See LICENCE.txt file at the root folder for more details.
- * This file is part of Maarch software.
- */
-
-/**
- * @brief Message Exchange Review Controller
- *
- * @author dev@maarch.org
- * @ingroup core
- */
-
-namespace Sendmail\Controllers;
-
-use Slim\Http\Request;
-use Slim\Http\Response;
-use SrcCore\models\CoreConfigModel;
-
-require_once __DIR__.'/../../export_seda/Controllers/ReceiveMessage.php';
-require_once 'modules/export_seda/RequestSeda.php';
-require_once 'modules/export_seda/Controllers/SendMessage.php';
-require_once 'modules/sendmail/Controllers/SendMessageExchangeController.php';
-
-class MessageExchangeReviewController
-{
-    public function saveMessageExchangeReview(Request $request, Response $response)
-    {
-        if (empty($GLOBALS['userId'])) {
-            return $response->withStatus(401)->withJson(['errors' => 'User Not Connected']);
-        }
-
-        $data = $request->getParams();
-
-        if (!ReceiveMessageExchangeController::checkNeededParameters(['data' => $data, 'needed' => ['type']])) {
-            return $response->withStatus(400)->withJson(['errors' => 'Bad Request']);
-        }
-
-        $tmpName = ReceiveMessageExchangeController::createFile(['base64' => $data['base64'], 'extension' => $data['extension'], 'size' => $data['size']]);
-        if (!empty($tmpName['errors'])) {
-            return $response->withStatus(400)->withJson($tmpName);
-        }
-
-        $receiveMessage = new \ReceiveMessage();
-        $tmpPath = CoreConfigModel::getTmpPath();
-        $res = $receiveMessage->receive($tmpPath, $tmpName, $data['type']);
-
-        $sDataObject = $res['content'];
-        $dataObject = json_decode($sDataObject);
-        $RequestSeda = new \RequestSeda();
-
-        $dataObject->TransferringAgency = $dataObject->OriginatingAgency;
-
-        $messageExchange = $RequestSeda->getMessageByReference($dataObject->UnitIdentifier->value);
-
-        if (empty($messageExchange->operation_date)) {
-            $RequestSeda->updateOperationDateMessage(['operation_date' => $dataObject->Date, 'message_id' => $messageExchange->message_id]);
-        }
-
-        $messageExchangeSaved = \SendMessageExchangeController::saveMessageExchange(['dataObject' => $dataObject, 'res_id_master' => $messageExchange->res_id_master, 'type' => 'ArchiveModificationNotification']);
-
-        return $response->withJson([
-            'messageId' => $messageExchangeSaved['messageId'],
-        ]);
-    }
-}
diff --git a/modules/sendmail/Controllers/SendMessageExchangeController.php b/modules/sendmail/Controllers/SendMessageExchangeController.php
deleted file mode 100755
index 1952ea1abf6..00000000000
--- a/modules/sendmail/Controllers/SendMessageExchangeController.php
+++ /dev/null
@@ -1,556 +0,0 @@
-<?php
-
-/**
-* Copyright Maarch since 2008 under licence GPLv3.
-* See LICENCE.txt file at the root folder for more details.
-* This file is part of Maarch software.
-*
-*/
-
-/**
-* @brief Send Message Exchange Controller
-* @author dev@maarch.org
-* @ingroup core
-*/
-
-require_once 'modules/sendmail/Controllers/ReceiveMessageExchangeController.php';
-require_once 'modules/export_seda/RequestSeda.php';
-require_once 'modules/export_seda/Controllers/SendMessage.php';
-
-class SendMessageExchangeController
-{
-    public static function createMessageExchange($aArgs = [])
-    {
-        $errors = self::control($aArgs);
-
-        if (!empty($errors)) {
-            return ['errors' => $errors];
-        }
-        $mlbCollExt = Resource\models\ResModel::getById(['resId' => $aArgs['identifier']]);
-        if (empty($mlbCollExt)) {
-            return ['errors' => "wrong identifier"];
-        }
-
-        // if (empty($mlbCollExt['exp_contact_id']) && empty($mlbCollExt['dest_contact_id'])) {
-        //     return ['errors' => "no contact"];
-        // }
-
-        /***************** GET MAIL INFOS *****************/
-        $AllUserEntities = \Entity\models\EntityModel::getWithUserEntities(['where' => ['user_id = ?', 'business_id != \'\''], 'data' => [$_SESSION['user']['UserId']]]);
-
-        foreach ($AllUserEntities as $value) {
-            if ($value['entity_id'] == $aArgs['sender_email']) {
-                $TransferringAgencyInformations = $value;
-            }
-        }
-
-        if (empty($TransferringAgencyInformations)) {
-            return ['errors' => "no sender"];
-        }
-
-        $AllInfoMainMail = Resource\models\ResModel::getById(['resId' => $aArgs['identifier']]);
-
-        $tmpMainExchangeDoc = explode("__", $aArgs['main_exchange_doc']);
-        $MainExchangeDoc    = ['tablename' => $tmpMainExchangeDoc[0], 'res_id' => $tmpMainExchangeDoc[1]];
-
-        $fileInfo = [];
-        if (!empty($aArgs['join_file']) || $MainExchangeDoc['tablename'] == 'res_letterbox') {
-            $AllInfoMainMail['Title']                                  = $AllInfoMainMail['subject'];
-            $AllInfoMainMail['OriginatingAgencyArchiveUnitIdentifier'] = $AllInfoMainMail['alt_identifier'];
-            $AllInfoMainMail['DocumentType']                           = $AllInfoMainMail['type_label'];
-            $AllInfoMainMail['tablenameExchangeMessage']               = 'res_letterbox';
-            $fileInfo = [$AllInfoMainMail];
-        }
-
-        if ($MainExchangeDoc['tablename'] == 'res_attachments') {
-            $aArgs['join_attachment'][] = $MainExchangeDoc['res_id'];
-        }
-
-        /**************** GET ATTACHMENTS INFOS ***************/
-        $AttachmentsInfo = [];
-        if (!empty($aArgs['join_attachment'])) {
-            $AttachmentsInfo = \Attachment\models\AttachmentModel::get(['select' => ['*'], 'where' => ['res_id in (?)'], 'data' => [$aArgs['join_attachment']]]);
-            foreach ($AttachmentsInfo as $key => $value) {
-                $AttachmentsInfo[$key]['Title']                                  = $value['title'];
-                $AttachmentsInfo[$key]['OriginatingAgencyArchiveUnitIdentifier'] = $value['identifier'];
-                $AttachmentsInfo[$key]['DocumentType']                           = $_SESSION['attachment_types'][$value['attachment_type']];
-                $AttachmentsInfo[$key]['tablenameExchangeMessage']               = 'res_attachments';
-            }
-        }
-        $aAllAttachment = $AttachmentsInfo;
-
-        /******************* GET NOTE INFOS **********************/
-        $aComments = self::generateComments([
-            'resId' => $aArgs['identifier'],
-            'notes' => $aArgs['notes'],
-            'body'  => $aArgs['body_from_raw'],
-            'TransferringAgencyInformations' => $TransferringAgencyInformations]);
-
-        /*********** ORDER ATTACHMENTS IN MAIL ***************/
-        if ($MainExchangeDoc['tablename'] == 'res_letterbox') {
-            $mainDocument     = $fileInfo;
-            $aMergeAttachment = array_merge($fileInfo, $aAllAttachment);
-        } else {
-            foreach ($aAllAttachment as $key => $value) {
-                if ($value['res_id'] == $MainExchangeDoc['res_id'] && $MainExchangeDoc['tablename'] == $value['tablenameExchangeMessage']) {
-                    if ($AllInfoMainMail['category_id'] == 'outgoing') {
-                        $aOutgoingMailInfo                                           = $AllInfoMainMail;
-                        $aOutgoingMailInfo['Title']                                  = $AllInfoMainMail['subject'];
-                        $aOutgoingMailInfo['OriginatingAgencyArchiveUnitIdentifier'] = $AllInfoMainMail['alt_identifier'];
-                        $aOutgoingMailInfo['DocumentType']                           = $AllInfoMainMail['type_label'];
-                        $aOutgoingMailInfo['tablenameExchangeMessage']               = $AllInfoMainMail['tablenameExchangeMessage'];
-                        $mainDocument = [$aOutgoingMailInfo];
-                    } else {
-                        $mainDocument = [$aAllAttachment[$key]];
-                    }
-                    $firstAttachment = [$aAllAttachment[$key]];
-                    unset($aAllAttachment[$key]);
-                }
-            }
-            $aMergeAttachment = array_merge($firstAttachment, $fileInfo, $aAllAttachment);
-        }
-
-        $mainDocument[0]['Title'] = '[CAPTUREM2M]'.$aArgs['object'];
-
-        $sendMessage = new SendMessage();
-
-        foreach ($_SESSION['adresses']['to'] as $key => $value) {
-            /******** GET ARCHIVAl INFORMATIONs **************/
-//            $contactInfo                       = \Contact\models\ContactModel::getFullAddressById(['addressId' => $key]); //TODO
-            $ArchivalAgencyCommunicationType   = \Contact\models\ContactModel::getContactCommunication(['contactId' => $contactInfo[0]['contact_id']]);
-//            $ArchivalAgencyContactInformations = \Contact\models\ContactModel::getFullAddressById(['addressId' => $key]); //TODO
-
-            /******** GENERATE MESSAGE EXCHANGE OBJECT *********/
-            $dataObject = self::generateMessageObject([
-                'Comment' => $aComments,
-                'ArchivalAgency' => [
-                    'CommunicationType'   => $ArchivalAgencyCommunicationType,
-                    'ContactInformations' => $ArchivalAgencyContactInformations[0]
-                ],
-                'TransferringAgency' => [
-                    'EntitiesInformations' => $TransferringAgencyInformations
-                ],
-                'attachment'            => $aMergeAttachment,
-                'res'                   => $mainDocument,
-                'mainExchangeDocument'  => $MainExchangeDoc
-            ]);
-            /******** GENERATION DU BORDEREAU */
-            $filePath = $sendMessage->generateMessageFile($dataObject, "ArchiveTransfer", $_SESSION['config']['tmppath']);
-
-            /******** SAVE MESSAGE *********/
-            $messageExchangeReturn = self::saveMessageExchange(['dataObject' => $dataObject, 'res_id_master' => $aArgs['identifier'], 'file_path' => $filePath, 'type' => 'ArchiveTransfer']);
-            if (!empty($messageExchangeReturn['error'])) {
-                return ['errors' => $messageExchangeReturn['error']];
-            } else {
-                $messageId = $messageExchangeReturn['messageId'];
-            }
-            self::saveUnitIdentifier(['attachment' => $aMergeAttachment, 'notes' => $aArgs['notes'], 'messageId' => $messageId]);
-
-            \History\controllers\HistoryController::add([
-                'tableName' => 'res_letterbox',
-                'recordId'  => $aArgs['identifier'],
-                'eventType' => 'UP',
-                'eventId'   => 'resup',
-                'info'       => _NUMERIC_PACKAGE_ADDED . _ON_DOC_NUM
-                    . $aArgs['identifier'] . ' ('.$messageId.') : "' . \SrcCore\models\TextFormatModel::cutString(['string' => $mainDocument[0]['Title'], 'max' => 254]),
-                'userId' => $_SESSION['user']['UserId']
-            ]);
-
-            \History\controllers\HistoryController::add([
-                'tableName' => 'message_exchange',
-                'recordId'  => $messageId,
-                'eventType' => 'ADD',
-                'eventId'   => 'messageexchangeadd',
-                'info'       => _NUMERIC_PACKAGE_ADDED . ' (' . $messageId . ')',
-                'userId' => $_SESSION['user']['UserId']
-            ]);
-
-            /******** ENVOI *******/
-            $res = $sendMessage->send($dataObject, $messageId, 'ArchiveTransfer');
-
-            if ($res['status'] == 1) {
-                $errors = [];
-                array_push($errors, _SENDS_FAIL);
-                array_push($errors, $res['content']);
-                return ['errors' => $errors];
-            }
-        }
-
-        return true;
-    }
-
-    protected static function control($aArgs = [])
-    {
-        $errors = [];
-
-        if (empty($aArgs['identifier']) || !is_numeric($aArgs['identifier'])) {
-            array_push($errors, 'wrong format for identifier');
-        }
-
-        if (empty($aArgs['main_exchange_doc'])) {
-            array_push($errors, 'wrong format for main_exchange_doc');
-        }
-
-        if (empty($aArgs['object'])) {
-            array_push($errors, _EMAIL_OBJECT . ' ' . _IS_EMPTY);
-        }
-
-        if (empty($aArgs['join_file']) && empty($aArgs['join_attachment']) && empty($aArgs['main_exchange_doc'])) {
-            array_push($errors, 'no attachment');
-        }
-
-        if (empty($_SESSION['adresses']['to'])) {
-            array_push($errors, _NO_RECIPIENT);
-        }
-
-        if (empty($aArgs['sender_email'])) {
-            array_push($errors, _NO_SENDER);
-        }
-
-        return $errors;
-    }
-
-    protected static function generateComments($aArgs = [])
-    {
-        $aReturn    = [];
-
-        $entityRoot = \Entity\models\EntityModel::getEntityRootById(['entityId' => $aArgs['TransferringAgencyInformations']['entity_id']]);
-        $headerNote = $_SESSION['user']['FirstName'] . ' ' . $_SESSION['user']['LastName'] . ' (' . $entityRoot['entity_label'] . ' - ' . $aArgs['TransferringAgencyInformations']['entity_label'] . ' - ' .$_SESSION['user']['Mail'].') : ';
-        $oBody        = new stdClass();
-        $oBody->value = $headerNote . ' ' . $aArgs['body'];
-        array_push($aReturn, $oBody);
-
-        if (!empty($aArgs['notes'])) {
-            $notes     = \Note\models\NoteModel::getByResId([
-                'select' => ['notes.id', 'notes.user_id', 'notes.creation_date', 'notes.note_text', 'users.firstname', 'users.lastname', 'users_entities.entity_id'],
-                'resId' => $aArgs['resId']
-            ]);
-
-            if (!empty($notes)) {
-                foreach ($notes as $value) {
-                    if (!in_array($value['id'], $aArgs['notes'])) {
-                        continue;
-                    }
-
-                    $oComment        = new stdClass();
-                    $date            = new DateTime($value['creation_date']);
-                    $additionalUserInfos = '';
-                    if (!empty($value['entity_id'])) {
-                        $entityRoot      = \Entity\models\EntityModel::getEntityRootById(['entityId' => $value['entity_id']]);
-                        $userEntity      = \Entity\models\entitymodel::getByEntityId(['entityId' => $value['entity_id']]);
-                        $additionalUserInfos = ' ('.$entityRoot['entity_label'].' - '.$userEntity['entity_label'].')';
-                    }
-                    $oComment->value = $value['firstname'].' '.$value['lastname'].' - '.$date->format('d-m-Y H:i:s'). $additionalUserInfos . ' : '.$value['note_text'];
-                    array_push($aReturn, $oComment);
-                }
-            }
-        }
-        return $aReturn;
-    }
-
-    public static function generateMessageObject($aArgs = [])
-    {
-        $date = new DateTime;
-
-        $messageObject          = new stdClass();
-        $messageObject->Comment = $aArgs['Comment'];
-        $messageObject->Date    = $date->format(DateTime::ATOM);
-
-        $messageObject->MessageIdentifier = new stdClass();
-        $messageObject->MessageIdentifier->value = 'ArchiveTransfer_'.date("Ymd_His").'_'.$_SESSION['user']['UserId'];
-
-        /********* BINARY DATA OBJECT PACKAGE *********/
-        $messageObject->DataObjectPackage                   = new stdClass();
-        $messageObject->DataObjectPackage->BinaryDataObject = self::getBinaryDataObject($aArgs['attachment']);
-
-        /********* DESCRIPTIVE META DATA *********/
-        $messageObject->DataObjectPackage->DescriptiveMetadata = self::getDescriptiveMetaDataObject($aArgs);
-
-        /********* ARCHIVAL AGENCY *********/
-        $messageObject->ArchivalAgency = self::getArchivalAgencyObject(['ArchivalAgency' => $aArgs['ArchivalAgency']]);
-
-        /********* TRANSFERRING AGENCY *********/
-        $channelType = $messageObject->ArchivalAgency->OrganizationDescriptiveMetadata->Communication[0]->Channel;
-        $messageObject->TransferringAgency = self::getTransferringAgencyObject(['TransferringAgency' => $aArgs['TransferringAgency'], 'ChannelType' => $channelType]);
-
-        return $messageObject;
-    }
-
-    public static function getBinaryDataObject($aArgs = [])
-    {
-        $aReturn     = [];
-        $RequestSeda = new RequestSeda();
-
-        foreach ($aArgs as $key => $value) {
-            if (!empty($value['tablenameExchangeMessage'])) {
-                $binaryDataObjectId = $value['tablenameExchangeMessage'] . "_" . $key . "_" . $value['res_id'];
-            } else {
-                $binaryDataObjectId = $value['res_id'];
-            }
-
-            $binaryDataObject                           = new stdClass();
-            $binaryDataObject->id                       = $binaryDataObjectId;
-
-            $binaryDataObject->MessageDigest            = new stdClass();
-            $binaryDataObject->MessageDigest->value     = $value['fingerprint'];
-            $binaryDataObject->MessageDigest->algorithm = "sha256";
-
-            $binaryDataObject->Size                     = $value['filesize'];
-
-            $uri = str_replace("##", DIRECTORY_SEPARATOR, $value['path']);
-            $uri = str_replace("#", DIRECTORY_SEPARATOR, $uri);
-            
-            $docServers = $RequestSeda->getDocServer($value['docserver_id']);
-            $binaryDataObject->Attachment           = new stdClass();
-            $binaryDataObject->Attachment->uri      = '';
-            $binaryDataObject->Attachment->filename = basename($value['filename']);
-            $binaryDataObject->Attachment->value    = base64_encode(file_get_contents($docServers->path_template . $uri . '/'. $value['filename']));
-
-            $binaryDataObject->FormatIdentification           = new stdClass();
-            $binaryDataObject->FormatIdentification->MimeType = mime_content_type($docServers->path_template . $uri . $value['filename']);
-
-            array_push($aReturn, $binaryDataObject);
-        }
-
-        return $aReturn;
-    }
-
-    public static function getDescriptiveMetaDataObject($aArgs = [])
-    {
-        $DescriptiveMetadataObject              = new stdClass();
-        $DescriptiveMetadataObject->ArchiveUnit = [];
-
-        $documentArchiveUnit                    = new stdClass();
-        $documentArchiveUnit->id                = 'mail_1';
-
-        $documentArchiveUnit->Content = self::getContent([
-            'DescriptionLevel'                       => 'File',
-            'Title'                                  => $aArgs['res'][0]['Title'],
-            'OriginatingSystemId'                    => $aArgs['res'][0]['res_id'],
-            'OriginatingAgencyArchiveUnitIdentifier' => $aArgs['res'][0]['OriginatingAgencyArchiveUnitIdentifier'],
-            'DocumentType'                           => $aArgs['res'][0]['DocumentType'],
-            'Status'                                 => $aArgs['res'][0]['status'],
-            'Writer'                                 => $aArgs['res'][0]['typist'],
-            'CreatedDate'                            => $aArgs['res'][0]['creation_date'],
-        ]);
-
-        $documentArchiveUnit->ArchiveUnit = [];
-        foreach ($aArgs['attachment'] as $key => $value) {
-            $attachmentArchiveUnit     = new stdClass();
-            $attachmentArchiveUnit->id = 'archiveUnit_'.$value['tablenameExchangeMessage'] . "_" . $key . "_" . $value['res_id'];
-            $attachmentArchiveUnit->Content = self::getContent([
-                'DescriptionLevel'                       => 'Item',
-                'Title'                                  => $value['Title'],
-                'OriginatingSystemId'                    => $value['res_id'],
-                'OriginatingAgencyArchiveUnitIdentifier' => $value['OriginatingAgencyArchiveUnitIdentifier'],
-                'DocumentType'                           => $value['DocumentType'],
-                'Status'                                 => $value['status'],
-                'Writer'                                 => $value['typist'],
-                'CreatedDate'                            => $value['creation_date'],
-            ]);
-            $dataObjectReference                        = new stdClass();
-            $dataObjectReference->DataObjectReferenceId = $value['tablenameExchangeMessage'].'_'.$key.'_'.$value['res_id'];
-            $attachmentArchiveUnit->DataObjectReference = [$dataObjectReference];
-
-            array_push($documentArchiveUnit->ArchiveUnit, $attachmentArchiveUnit);
-        }
-        array_push($DescriptiveMetadataObject->ArchiveUnit, $documentArchiveUnit);
-
-        return $DescriptiveMetadataObject;
-    }
-
-    public static function getContent($aArgs = [])
-    {
-        $contentObject                                         = new stdClass();
-        $contentObject->DescriptionLevel                       = $aArgs['DescriptionLevel'];
-        $contentObject->Title                                  = [$aArgs['Title']];
-        $contentObject->OriginatingSystemId                    = $aArgs['OriginatingSystemId'];
-        $contentObject->OriginatingAgencyArchiveUnitIdentifier = $aArgs['OriginatingAgencyArchiveUnitIdentifier'];
-        $contentObject->DocumentType                           = $aArgs['DocumentType'];
-        $contentObject->Status                                 = \Status\models\StatusModel::getById(['id' => $aArgs['Status']])['label_status'];
-
-        $userInfos = \User\models\UserModel::getByLogin(['login' => $aArgs['Writer']]);
-        $writer                = new stdClass();
-        $writer->FirstName     = $userInfos['firstname'];
-        $writer->BirthName     = $userInfos['lastname'];
-        $contentObject->Writer = [$writer];
-
-        $contentObject->CreatedDate = date("Y-m-d", strtotime($aArgs['CreatedDate']));
-
-        return $contentObject;
-    }
-
-    public static function getArchivalAgencyObject($aArgs = [])
-    {
-        $archivalAgencyObject                    = new stdClass();
-        $archivalAgencyObject->Identifier        = new stdClass();
-        $externalId = (array)json_decode($aArgs['ArchivalAgency']['ContactInformations']['external_id']);
-        $archivalAgencyObject->Identifier->value = $externalId['m2m'];
-
-        $archivalAgencyObject->OrganizationDescriptiveMetadata       = new stdClass();
-        $archivalAgencyObject->OrganizationDescriptiveMetadata->Name = trim($aArgs['ArchivalAgency']['ContactInformations']['society'] . ' ' . $aArgs['ArchivalAgency']['ContactInformations']['contact_lastname'] . ' ' . $aArgs['ArchivalAgency']['ContactInformations']['contact_firstname']);
-
-        if (isset($aArgs['ArchivalAgency']['CommunicationType']['type'])) {
-            $arcCommunicationObject          = new stdClass();
-            $arcCommunicationObject->Channel = $aArgs['ArchivalAgency']['CommunicationType']['type'];
-            if ($aArgs['ArchivalAgency']['CommunicationType']['type'] == 'url') {
-                $postUrl = '/rest/saveNumericPackage';
-            }
-            $arcCommunicationObject->value   = $aArgs['ArchivalAgency']['CommunicationType']['value'].$postUrl;
-
-            $archivalAgencyObject->OrganizationDescriptiveMetadata->Communication = [$arcCommunicationObject];
-        }
-
-        $contactObject = new stdClass();
-        $contactObject->DepartmentName = $aArgs['ArchivalAgency']['ContactInformations']['department'];
-        $contactObject->PersonName     = $aArgs['ArchivalAgency']['ContactInformations']['lastname'] . " " . $aArgs['ArchivalAgency']['ContactInformations']['firstname'];
-
-        $addressObject = new stdClass();
-        $addressObject->CityName      = $aArgs['ArchivalAgency']['ContactInformations']['address_town'];
-        $addressObject->Country       = $aArgs['ArchivalAgency']['ContactInformations']['address_country'];
-        $addressObject->Postcode      = $aArgs['ArchivalAgency']['ContactInformations']['address_postal_code'];
-        $addressObject->PostOfficeBox = $aArgs['ArchivalAgency']['ContactInformations']['address_num'];
-        $addressObject->StreetName    = $aArgs['ArchivalAgency']['ContactInformations']['address_street'];
-
-        $contactObject->Address = [$addressObject];
-
-        $communicationContactPhoneObject          = new stdClass();
-        $communicationContactPhoneObject->Channel = 'phone';
-        $communicationContactPhoneObject->value   = $aArgs['ArchivalAgency']['ContactInformations']['phone'];
-
-        $communicationContactEmailObject          = new stdClass();
-        $communicationContactEmailObject->Channel = 'email';
-        $communicationContactEmailObject->value   = $aArgs['ArchivalAgency']['ContactInformations']['email'];
-
-        $contactObject->Communication = [$communicationContactPhoneObject, $communicationContactEmailObject];
-
-        $archivalAgencyObject->OrganizationDescriptiveMetadata->Contact = [$contactObject];
-
-        return $archivalAgencyObject;
-    }
-
-    public static function getTransferringAgencyObject($aArgs = [])
-    {
-        $TransferringAgencyObject                    = new stdClass();
-        $TransferringAgencyObject->Identifier        = new stdClass();
-        $TransferringAgencyObject->Identifier->value = $aArgs['TransferringAgency']['EntitiesInformations']['business_id'];
-
-        $TransferringAgencyObject->OrganizationDescriptiveMetadata                      = new stdClass();
-
-        $entityRoot = \Entity\models\EntityModel::getEntityRootById(['entityId' => $aArgs['TransferringAgency']['EntitiesInformations']['entity_id']]);
-        $TransferringAgencyObject->OrganizationDescriptiveMetadata->LegalClassification = $entityRoot['entity_label'];
-        $TransferringAgencyObject->OrganizationDescriptiveMetadata->Name                = $aArgs['TransferringAgency']['EntitiesInformations']['entity_label'];
-        $TransferringAgencyObject->OrganizationDescriptiveMetadata->UserIdentifier      = $_SESSION['user']['UserId'];
-
-        $traCommunicationObject          = new stdClass();
-
-        $aDefaultConfig = \Sendmail\Controllers\ReceiveMessageExchangeController::readXmlConfig();
-
-        $traCommunicationObject->Channel = $aArgs['ChannelType'];
-        $traCommunicationObject->value   = rtrim($aDefaultConfig['m2m_communication_type'][$aArgs['ChannelType']], "/");
-
-        $TransferringAgencyObject->OrganizationDescriptiveMetadata->Communication = [$traCommunicationObject];
-
-        $contactUserObject                 = new stdClass();
-        $contactUserObject->DepartmentName = $aArgs['TransferringAgency']['EntitiesInformations']['entity_label'];
-        $contactUserObject->PersonName     = $_SESSION['user']['FirstName'] . " " . $_SESSION['user']['LastName'];
-
-        $communicationUserPhoneObject          = new stdClass();
-        $communicationUserPhoneObject->Channel = 'phone';
-        $communicationUserPhoneObject->value   = $_SESSION['user']['Phone'];
-
-        $communicationUserEmailObject          = new stdClass();
-        $communicationUserEmailObject->Channel = 'email';
-        $communicationUserEmailObject->value   = $_SESSION['user']['Mail'];
-
-        $contactUserObject->Communication = [$communicationUserPhoneObject, $communicationUserEmailObject];
-
-        $TransferringAgencyObject->OrganizationDescriptiveMetadata->Contact = [$contactUserObject];
-
-        return $TransferringAgencyObject;
-    }
-
-    public static function saveMessageExchange($aArgs = [])
-    {
-        $RequestSeda = new RequestSeda();
-
-        $dataObject = $aArgs['dataObject'];
-        $oData                                        = new stdClass();
-        $oData->messageId                             = $RequestSeda->generateUniqueId();
-        $oData->date                                  = $dataObject->Date;
-
-        $oData->MessageIdentifier                     = new stdClass();
-        $oData->MessageIdentifier->value              = $dataObject->MessageIdentifier->value;
-        
-        $oData->TransferringAgency                    = new stdClass();
-        $oData->TransferringAgency->Identifier        = new stdClass();
-        $oData->TransferringAgency->Identifier->value = $dataObject->TransferringAgency->Identifier->value;
-        
-        $oData->ArchivalAgency                        = new stdClass();
-        $oData->ArchivalAgency->Identifier            = new stdClass();
-        $oData->ArchivalAgency->Identifier->value     = $dataObject->ArchivalAgency->Identifier->value;
-        
-        $oData->archivalAgreement                     = new stdClass();
-        $oData->archivalAgreement->value              = ""; // TODO : ???
-        
-        $replyCode = "";
-        if (!empty($dataObject->ReplyCode)) {
-            $replyCode = $dataObject->ReplyCode;
-        }
-
-        $oData->replyCode                             = new stdClass();
-        $oData->replyCode                             = $replyCode;
-
-        $dataObject = self::cleanBase64Value(['dataObject' => $dataObject]);
-
-        $aDataExtension = [
-            'status'            => 'W',
-            'fullMessageObject' => $dataObject,
-            'resIdMaster'       => $aArgs['res_id_master'],
-            'SenderOrgNAme'     => $dataObject->TransferringAgency->OrganizationDescriptiveMetadata->Contact[0]->DepartmentName,
-            'RecipientOrgNAme'  => $dataObject->ArchivalAgency->OrganizationDescriptiveMetadata->Name,
-            'filePath'          => $aArgs['file_path'],
-        ];
-
-        $messageId = $RequestSeda->insertMessage($oData, $aArgs['type'], $aDataExtension);
-
-        return $messageId;
-    }
-
-    public static function saveUnitIdentifier($aArgs = [])
-    {
-        $messageId   = $aArgs['messageId'];
-        $RequestSeda = new RequestSeda();
-
-        foreach ($aArgs['attachment'] as $key => $value) {
-            $disposition = "attachment";
-            if ($key == 0) {
-                $disposition = "body";
-            }
-
-            $RequestSeda->insertUnitIdentifier($messageId, $value['tablenameExchangeMessage'], $value['res_id'], $disposition);
-        }
-
-        if (!empty($aArgs['notes'])) {
-            foreach ($aArgs['notes'] as $value) {
-                $RequestSeda->insertUnitIdentifier($messageId, "notes", $value, "note");
-            }
-        }
-
-        return true;
-    }
-
-    protected static function cleanBase64Value($aArgs = [])
-    {
-        $dataObject = $aArgs['dataObject'];
-        $aCleanDataObject = [];
-        if (!empty($dataObject->DataObjectPackage->BinaryDataObject)) {
-            foreach ($dataObject->DataObjectPackage->BinaryDataObject as $key => $value) {
-                $value->Attachment->value = "";
-                $aCleanDataObject[$key] = $value;
-            }
-            $dataObject->DataObjectPackage->BinaryDataObject = $aCleanDataObject;
-        }
-        return $dataObject;
-    }
-}
diff --git a/rest/index.php b/rest/index.php
index 5dc72097502..bc822df4fe7 100755
--- a/rest/index.php
+++ b/rest/index.php
@@ -530,9 +530,10 @@ $app->get('/administration/notifications/new', \Notification\controllers\Notific
 $app->get('/notifications/{id}', \Notification\controllers\NotificationController::class . ':getBySid');
 $app->post('/scriptNotification', \Notification\controllers\NotificationScheduleController::class . ':createScriptNotification');
 
-$app->post('/saveNumericPackage', \Sendmail\Controllers\ReceiveMessageExchangeController::class . ':saveMessageExchange');
-$app->post('/saveMessageExchangeReturn', \Sendmail\Controllers\ReceiveMessageExchangeController::class . ':saveMessageExchangeReturn');
-$app->post('/saveMessageExchangeReview', \Sendmail\Controllers\MessageExchangeReviewController::class . ':saveMessageExchangeReview');
+$app->post('/saveNumericPackage', \MessageExchange\Controllers\ReceiveMessageExchangeController::class . ':saveMessageExchange');
+$app->post('/saveMessageExchangeReturn', \MessageExchange\Controllers\ReceiveMessageExchangeController::class . ':saveMessageExchangeReturn');
+$app->post('/saveMessageExchangeReview', \MessageExchange\Controllers\MessageExchangeReviewController::class . ':saveMessageExchangeReview');
+$app->post('/resources/{resId}/messageExchange', \MessageExchange\Controllers\SendMessageExchangeController::class . ':createMessageExchangeReview');
 
 //ExternalSignatoryBooks
 $app->get('/maarchParapheur/user/{id}/picture', \ExternalSignatoryBook\controllers\MaarchParapheurController::class . ':getUserPicture');
diff --git a/src/app/external/messageExchange/controllers/MessageExchangeReviewController.php b/src/app/external/messageExchange/controllers/MessageExchangeReviewController.php
index 9e5fcfe2174..35d1e7b7372 100755
--- a/src/app/external/messageExchange/controllers/MessageExchangeReviewController.php
+++ b/src/app/external/messageExchange/controllers/MessageExchangeReviewController.php
@@ -14,12 +14,16 @@
 
 namespace MessageExchange\controllers;
 
-use DateTime;
-use User\models\UserModel;
-use Resource\models\ResModel;
 use Action\models\ActionModel;
-use MessageExchange\models\MessageExchangeModel;
 use ExportSeda\controllers\SendMessageController;
+use MessageExchange\Controllers\ReceiveMessageExchangeController;
+use MessageExchange\controllers\SendMessageExchangeController;
+use MessageExchange\models\MessageExchangeModel;
+use Resource\models\ResModel;
+use SrcCore\models\CoreConfigModel;
+use User\models\UserModel;
+
+require_once 'modules/export_seda/Controllers/ReceiveMessage.php';
 
 class MessageExchangeReviewController
 {
@@ -58,8 +62,8 @@ class MessageExchangeReviewController
             $primaryEntity = UserModel::getPrimaryEntityByUserId(['userId' => $aArgs['userId']]);
             $reviewObject->Comment[0]->value = '['.date('d/m/Y H:i:s').'] "'.$actionInfo['label_action'].'" '._M2M_ACTION_DONE.' '.$primaryEntity['entity_label'].'. '._M2M_ENTITY_DESTINATION.' : '.$messageExchangeData['entity_label'];
 
-            $date = new DateTime();
-            $reviewObject->Date = $date->format(DateTime::ATOM);
+            $date = new \DateTime();
+            $reviewObject->Date = $date->format(\DateTime::ATOM);
 
             $reviewObject->MessageIdentifier = new \stdClass();
             $reviewObject->MessageIdentifier->value = $messageExchangeData['external_id']['m2m'].'_NotificationSent';
@@ -104,4 +108,42 @@ class MessageExchangeReviewController
             SendMessageController::send($reviewObject, $messageExchangeSaved['messageId'], 'ArchiveModificationNotification');
         }
     }
+
+    public function saveMessageExchangeReview(Request $request, Response $response)
+    {
+        if (empty($GLOBALS['userId'])) {
+            return $response->withStatus(401)->withJson(['errors' => 'User Not Connected']);
+        }
+
+        $data = $request->getParams();
+
+        if (!ReceiveMessageExchangeController::checkNeededParameters(['data' => $data, 'needed' => ['type']])) {
+            return $response->withStatus(400)->withJson(['errors' => 'Bad Request']);
+        }
+
+        $tmpName = ReceiveMessageExchangeController::createFile(['base64' => $data['base64'], 'extension' => $data['extension'], 'size' => $data['size']]);
+        if (!empty($tmpName['errors'])) {
+            return $response->withStatus(400)->withJson($tmpName);
+        }
+
+        $receiveMessage = new \ReceiveMessage();
+        $tmpPath = CoreConfigModel::getTmpPath();
+        $res = $receiveMessage->receive($tmpPath, $tmpName, $data['type']);
+
+        $sDataObject = $res['content'];
+        $dataObject = json_decode($sDataObject);
+        $dataObject->TransferringAgency = $dataObject->OriginatingAgency;
+
+        $messageExchange = MessageExchangeModel::getMessageByReference(['select' => ['operation_date', 'message_id', 'res_id_master'], 'reference' => $dataObject->UnitIdentifier->value]);
+        if (empty($messageExchange['operation_date'])) {
+            MessageExchangeModel::updateOperationDateMessage(['operation_date' => $dataObject->Date, 'message_id' => $messageExchange['message_id']]);
+        }
+
+        $messageExchangeSaved = SendMessageExchangeController::saveMessageExchange(['dataObject' => $dataObject, 'res_id_master' => $messageExchange['res_id_master'], 'type' => 'ArchiveModificationNotification']);
+
+        return $response->withJson([
+            'messageId' => $messageExchangeSaved['messageId'],
+        ]);
+    }
+
 }
diff --git a/modules/sendmail/Controllers/ReceiveMessageExchangeController.php b/src/app/external/messageExchange/controllers/ReceiveMessageExchangeController.php
old mode 100755
new mode 100644
similarity index 92%
rename from modules/sendmail/Controllers/ReceiveMessageExchangeController.php
rename to src/app/external/messageExchange/controllers/ReceiveMessageExchangeController.php
index e0ed77125ee..e2a17b15a4f
--- a/modules/sendmail/Controllers/ReceiveMessageExchangeController.php
+++ b/src/app/external/messageExchange/controllers/ReceiveMessageExchangeController.php
@@ -13,7 +13,7 @@
 * @ingroup core
 */
 
-namespace Sendmail\Controllers;
+namespace MessageExchange\Controllers;
 
 use Basket\models\BasketModel;
 use Contact\models\ContactModel;
@@ -24,15 +24,13 @@ use Note\models\NoteModel;
 use Resource\controllers\StoreController;
 use Resource\models\ResModel;
 use Resource\models\ResourceContactModel;
+use ExportSeda\controllers\SendMessageController;
 use Slim\Http\Request;
 use Slim\Http\Response;
 use SrcCore\models\CoreConfigModel;
 use User\models\UserModel;
 
 require_once 'modules/export_seda/Controllers/ReceiveMessage.php';
-require_once 'modules/export_seda/Controllers/SendMessage.php';
-require_once 'modules/export_seda/RequestSeda.php';
-require_once 'modules/sendmail/Controllers/SendMessageExchangeController.php';
 
 class ReceiveMessageExchangeController
 {
@@ -190,10 +188,10 @@ class ReceiveMessageExchangeController
         } else {
             $path = 'apps/maarch_entreprise/xml/m2m_config.xml';
         }
+        $loadedXml = CoreConfigModel::getXmlLoaded(['path' => 'apps/maarch_entreprise/xml/m2m_config.xml']);
 
         $aDefaultConfig = [];
-        if (file_exists($path)) {
-            $loadedXml = simplexml_load_file($path);
+        if (!empty($loadedXml)) {
             foreach ($loadedXml as $key => $value) {
                 $aDefaultConfig[$key] = (array)$value;
             }
@@ -433,11 +431,9 @@ class ReceiveMessageExchangeController
             $acknowledgementObject->Receiver->OrganizationDescriptiveMetadata->Communication[0]->value .= '/rest/saveMessageExchangeReturn';
         }
 
-        $sendMessage = new \SendMessage();
-
         $acknowledgementObject->MessageIdentifier->value          = $dataObject->MessageIdentifier->value . '_Ack';
         $tmpPath = CoreConfigModel::getTmpPath();
-        $filePath = $sendMessage->generateMessageFile($acknowledgementObject, 'Acknowledgement', $tmpPath);
+        $filePath = SendMessageController::generateMessageFile($acknowledgementObject, 'Acknowledgement', $tmpPath);
 
         $acknowledgementObject->ArchivalAgency = $acknowledgementObject->Receiver;
         $acknowledgementObject->TransferringAgency = $acknowledgementObject->Sender;
@@ -445,7 +441,7 @@ class ReceiveMessageExchangeController
         $acknowledgementObject->TransferringAgency->OrganizationDescriptiveMetadata->UserIdentifier = $GLOBALS['userId'];
 
         $acknowledgementObject->MessageIdentifier->value          = $dataObject->MessageIdentifier->value . '_AckSent';
-        $messageExchangeSaved = \SendMessageExchangeController::saveMessageExchange(['dataObject' => $acknowledgementObject, 'res_id_master' => 0, 'type' => 'Acknowledgement', 'file_path' => $filePath]);
+        $messageExchangeSaved = SendMessageExchangeController::saveMessageExchange(['dataObject' => $acknowledgementObject, 'res_id_master' => 0, 'type' => 'Acknowledgement', 'file_path' => $filePath]);
 
         $acknowledgementObject->DataObjectPackage = new \stdClass();
         $acknowledgementObject->DataObjectPackage->DescriptiveMetadata = new \stdClass();
@@ -454,7 +450,7 @@ class ReceiveMessageExchangeController
         $acknowledgementObject->DataObjectPackage->DescriptiveMetadata->ArchiveUnit[0]->Content = new \stdClass();
         $acknowledgementObject->DataObjectPackage->DescriptiveMetadata->ArchiveUnit[0]->Content->Title[0] = '[CAPTUREM2M_ACK]'.date("Ymd_his");
 
-        $sendMessage->send($acknowledgementObject, $messageExchangeSaved['messageId'], 'Acknowledgement');
+        SendMessageController::send($acknowledgementObject, $messageExchangeSaved['messageId'], 'Acknowledgement');
 
         return $messageExchangeSaved;
     }
@@ -480,14 +476,12 @@ class ReceiveMessageExchangeController
         $replyObject->TransferringAgency->OrganizationDescriptiveMetadata->UserIdentifier = $GLOBALS['userId'];
         $replyObject->ArchivalAgency                    = $dataObject->TransferringAgency;
 
-        $sendMessage = new \SendMessage();
-
         $replyObject->MessageIdentifier->value          = $dataObject->MessageIdentifier->value . '_Reply';
         $tmpPath = CoreConfigModel::getTmpPath();
-        $filePath = $sendMessage->generateMessageFile($replyObject, "ArchiveTransferReply", $tmpPath);
+        $filePath = SendMessageController::generateMessageFile($replyObject, "ArchiveTransferReply", $tmpPath);
 
         $replyObject->MessageIdentifier->value          = $dataObject->MessageIdentifier->value . '_ReplySent';
-        $messageExchangeSaved = \SendMessageExchangeController::saveMessageExchange(['dataObject' => $replyObject, 'res_id_master' => $aArgs['res_id_master'], 'type' => 'ArchiveTransferReply', 'file_path' => $filePath]);
+        $messageExchangeSaved = SendMessageExchangeController::saveMessageExchange(['dataObject' => $replyObject, 'res_id_master' => $aArgs['res_id_master'], 'type' => 'ArchiveTransferReply', 'file_path' => $filePath]);
 
         $replyObject->MessageIdentifier->value          = $dataObject->MessageIdentifier->value . '_Reply';
 
@@ -500,7 +494,7 @@ class ReceiveMessageExchangeController
 
         $replyObject->DataObjectPackage->DescriptiveMetadata->ArchiveUnit[0]->Content->Title[0] = '[CAPTUREM2M_REPLY]'.date("Ymd_his");
 
-        $sendMessage->send($replyObject, $messageExchangeSaved['messageId'], 'ArchiveTransferReply');
+        SendMessageController::send($replyObject, $messageExchangeSaved['messageId'], 'ArchiveTransferReply');
     }
 
     public function saveMessageExchangeReturn(Request $request, Response $response)
@@ -524,18 +518,16 @@ class ReceiveMessageExchangeController
         $sDataObject = $res['content'];
         $dataObject = json_decode($sDataObject);
 
-        $RequestSeda = new \RequestSeda();
-
         if ($dataObject->type == 'Acknowledgement') {
-            $messageExchange                = $RequestSeda->getMessageByReference($dataObject->MessageReceivedIdentifier->value);
+            $messageExchange = MessageExchangeModel::getMessageByReference(['select' => ['message_id', 'res_id_master'], 'reference' => $dataObject->MessageReceivedIdentifier->value]);
             $dataObject->TransferringAgency = $dataObject->Sender;
             $dataObject->ArchivalAgency     = $dataObject->Receiver;
-            $RequestSeda->updateReceptionDateMessage(['reception_date' => $dataObject->Date, 'message_id' => $messageExchange->message_id]);
+            MessageExchangeModel::updateReceptionDateMessage(['reception_date' => $dataObject->Date, 'message_id' => $messageExchange['message_id']]);
         } elseif ($dataObject->type == 'ArchiveTransferReply') {
-            $messageExchange = $RequestSeda->getMessageByReference($dataObject->MessageRequestIdentifier->value);
+            $messageExchange = MessageExchangeModel::getMessageByReference(['select' => ['message_id', 'res_id_master'], 'reference' => $dataObject->MessageRequestIdentifier->value]);
         }
 
-        $messageExchangeSaved = \SendMessageExchangeController::saveMessageExchange(['dataObject' => $dataObject, 'res_id_master' => $messageExchange->res_id_master, 'type' => $data['type']]);
+        $messageExchangeSaved = SendMessageExchangeController::saveMessageExchange(['dataObject' => $dataObject, 'res_id_master' => $messageExchange['res_id_master'], 'type' => $data['type']]);
         if (!empty($messageExchangeSaved['error'])) {
             return $response->withStatus(400)->withJson(['errors' => $messageExchangeSaved['error']]);
         }
diff --git a/src/app/external/messageExchange/controllers/SendMessageExchangeController.php b/src/app/external/messageExchange/controllers/SendMessageExchangeController.php
index 9bd067bb022..45aa45d03ef 100755
--- a/src/app/external/messageExchange/controllers/SendMessageExchangeController.php
+++ b/src/app/external/messageExchange/controllers/SendMessageExchangeController.php
@@ -14,7 +14,20 @@
 
 namespace MessageExchange\controllers;
 
+use Attachment\models\AttachmentModel;
+use Contact\models\ContactModel;
+use Docserver\models\DocserverModel;
+use Doctype\models\DoctypeModel;
+use Entity\models\EntityModel;
+use ExportSeda\controllers\SendMessageController;
+use History\controllers\HistoryController;
+use MessageExchange\Controllers\ReceiveMessageExchangeController;
 use MessageExchange\models\MessageExchangeModel;
+use Note\models\NoteModel;
+use Resource\models\ResModel;
+use SrcCore\models\TextFormatModel;
+use Status\models\StatusModel;
+use User\models\UserModel;
 
 class SendMessageExchangeController
 {
@@ -81,4 +94,484 @@ class SendMessageExchangeController
         }
         return $dataObject;
     }
+
+
+    public static function createMessageExchange(Request $request, Response $response, array $args)
+    {
+        if (!PrivilegeController::hasPrivilege(['privilegeId' => 'manage_numeric_package', 'userId' => $GLOBALS['id']])) {
+            return $response->withStatus(403)->withJson(['errors' => 'Service forbidden']);
+        }
+
+        if (!Validator::intVal()->validate($args['resId']) || !ResController::hasRightByResId(['resId' => [$args['resId']], 'userId' => $GLOBALS['id']])) {
+            return $response->withStatus(403)->withJson(['errors' => 'Document out of perimeter']);
+        }
+
+        $body = $request->getParsedBody();
+        $errors = self::control($body);
+
+        if (!empty($errors)) {
+            return ['errors' => $errors];
+        }
+
+        /***************** GET MAIL INFOS *****************/
+        $AllUserEntities = EntityModel::getWithUserEntities(['where' => ['user_id = ?', 'business_id != \'\''], 'data' => [$GLOBALS['userId']]]);
+
+        foreach ($AllUserEntities as $value) {
+            if ($value['entity_id'] == $body['senderEmail']) {
+                $TransferringAgencyInformations = $value;
+                break;
+            }
+        }
+
+        if (empty($TransferringAgencyInformations)) {
+            return ['errors' => "no sender"];
+        }
+
+        $AllInfoMainMail = ResModel::getById(['resId' => $args['resId']]);
+        $doctype = DoctypeModel::getById(['select' => ['description'], 'id' => $AllInfoMainMail['doctype']]);
+
+        $tmpMainExchangeDoc = explode("__", $body['mainExchangeDoc']);
+        $MainExchangeDoc    = ['tablename' => $tmpMainExchangeDoc[0], 'res_id' => $tmpMainExchangeDoc[1]];
+
+        $fileInfo = [];
+        if (!empty($body['joinFile']) || $MainExchangeDoc['tablename'] == 'res_letterbox') {
+            $AllInfoMainMail['Title']                                  = $AllInfoMainMail['subject'];
+            $AllInfoMainMail['OriginatingAgencyArchiveUnitIdentifier'] = $AllInfoMainMail['alt_identifier'];
+            $AllInfoMainMail['DocumentType']                           = $doctype['description'];
+            $AllInfoMainMail['tablenameExchangeMessage']               = 'res_letterbox';
+            $fileInfo = [$AllInfoMainMail];
+        }
+
+        if ($MainExchangeDoc['tablename'] == 'res_attachments') {
+            $body['join_attachment'][] = $MainExchangeDoc['res_id'];
+        }
+
+        /**************** GET ATTACHMENTS INFOS ***************/
+        $AttachmentsInfo = [];
+        if (!empty($body['joinAttachment'])) {
+            $AttachmentsInfo = AttachmentModel::get(['select' => ['*'], 'where' => ['res_id in (?)'], 'data' => [$body['joinAttachment']]]);
+            foreach ($AttachmentsInfo as $key => $value) {
+                $AttachmentsInfo[$key]['Title']                                  = $value['title'];
+                $AttachmentsInfo[$key]['OriginatingAgencyArchiveUnitIdentifier'] = $value['identifier'];
+                $AttachmentsInfo[$key]['DocumentType']                           = $_SESSION['attachment_types'][$value['attachment_type']];
+                $AttachmentsInfo[$key]['tablenameExchangeMessage']               = 'res_attachments';
+            }
+        }
+        $aAllAttachment = $AttachmentsInfo;
+
+        /******************* GET NOTE INFOS **********************/
+        $aComments = self::generateComments([
+            'resId' => $args['resId'],
+            'notes' => $body['notes'],
+            'body'  => $body['content'],
+            'TransferringAgencyInformations' => $TransferringAgencyInformations]);
+
+        /*********** ORDER ATTACHMENTS IN MAIL ***************/
+        if ($MainExchangeDoc['tablename'] == 'res_letterbox') {
+            $mainDocument     = $fileInfo;
+            $aMergeAttachment = array_merge($fileInfo, $aAllAttachment);
+        } else {
+            foreach ($aAllAttachment as $key => $value) {
+                if ($value['res_id'] == $MainExchangeDoc['res_id'] && $MainExchangeDoc['tablename'] == $value['tablenameExchangeMessage']) {
+                    if ($AllInfoMainMail['category_id'] == 'outgoing') {
+                        $aOutgoingMailInfo                                           = $AllInfoMainMail;
+                        $aOutgoingMailInfo['Title']                                  = $AllInfoMainMail['subject'];
+                        $aOutgoingMailInfo['OriginatingAgencyArchiveUnitIdentifier'] = $AllInfoMainMail['alt_identifier'];
+                        $aOutgoingMailInfo['DocumentType']                           = $AllInfoMainMail['type_label'];
+                        $aOutgoingMailInfo['tablenameExchangeMessage']               = $AllInfoMainMail['tablenameExchangeMessage'];
+                        $mainDocument = [$aOutgoingMailInfo];
+                    } else {
+                        $mainDocument = [$aAllAttachment[$key]];
+                    }
+                    $firstAttachment = [$aAllAttachment[$key]];
+                    unset($aAllAttachment[$key]);
+                }
+            }
+            $aMergeAttachment = array_merge($firstAttachment, $fileInfo, $aAllAttachment);
+        }
+
+        $mainDocument[0]['Title'] = '[CAPTUREM2M]'.$body['object'];
+
+        foreach ($body['contacts'] as $contactId) {
+            /******** GET ARCHIVAl INFORMATIONs **************/
+            $ArchivalAgencyCommunicationType   = ContactModel::getContactCommunication(['contactId' => $contactId]);
+            $ArchivalAgencyContactInformations = ContactModel::getById(['id' => $contactId]);
+
+            /******** GENERATE MESSAGE EXCHANGE OBJECT *********/
+            $dataObject = self::generateMessageObject([
+                'Comment' => $aComments,
+                'ArchivalAgency' => [
+                    'CommunicationType'   => $ArchivalAgencyCommunicationType,
+                    'ContactInformations' => $ArchivalAgencyContactInformations[0]
+                ],
+                'TransferringAgency' => [
+                    'EntitiesInformations' => $TransferringAgencyInformations
+                ],
+                'attachment'            => $aMergeAttachment,
+                'res'                   => $mainDocument,
+                'mainExchangeDocument'  => $MainExchangeDoc
+            ]);
+            /******** GENERATION DU BORDEREAU */
+            $filePath = SendMessageController::generateMessageFile($dataObject, "ArchiveTransfer", $_SESSION['config']['tmppath']);
+
+            /******** SAVE MESSAGE *********/
+            $messageExchangeReturn = self::saveMessageExchange(['dataObject' => $dataObject, 'res_id_master' => $args['resId'], 'file_path' => $filePath, 'type' => 'ArchiveTransfer']);
+            if (!empty($messageExchangeReturn['error'])) {
+                return ['errors' => $messageExchangeReturn['error']];
+            } else {
+                $messageId = $messageExchangeReturn['messageId'];
+            }
+            self::saveUnitIdentifier(['attachment' => $aMergeAttachment, 'notes' => $body['notes'], 'messageId' => $messageId]);
+
+            HistoryController::add([
+                'tableName' => 'res_letterbox',
+                'recordId'  => $args['resId'],
+                'eventType' => 'UP',
+                'eventId'   => 'resup',
+                'info'       => _NUMERIC_PACKAGE_ADDED . _ON_DOC_NUM
+                    . $args['resId'] . ' ('.$messageId.') : "' . TextFormatModel::cutString(['string' => $mainDocument[0]['Title'], 'max' => 254]),
+                'userId' => $GLOBALS['userId']
+            ]);
+
+            HistoryController::add([
+                'tableName' => 'message_exchange',
+                'recordId'  => $messageId,
+                'eventType' => 'ADD',
+                'eventId'   => 'messageexchangeadd',
+                'info'       => _NUMERIC_PACKAGE_ADDED . ' (' . $messageId . ')',
+                'userId' => $GLOBALS['userId']
+            ]);
+
+            /******** ENVOI *******/
+            $res = SendMessageController::send($dataObject, $messageId, 'ArchiveTransfer');
+
+            if ($res['status'] == 1) {
+                $errors = [];
+                array_push($errors, _SENDS_FAIL);
+                array_push($errors, $res['content']);
+                return ['errors' => $errors];
+            }
+        }
+
+        return true;
+    }
+
+    protected static function control($aArgs = [])
+    {
+        $errors = [];
+
+        if (empty($aArgs['mainExchangeDoc'])) {
+            array_push($errors, 'wrong format for mainExchangeDoc');
+        }
+
+        if (empty($aArgs['object'])) {
+            array_push($errors, _EMAIL_OBJECT . ' ' . _IS_EMPTY);
+        }
+
+        if (empty($aArgs['joinFile']) && empty($aArgs['joinAttachment']) && empty($aArgs['mainExchangeDoc'])) {
+            array_push($errors, 'no attachment');
+        }
+
+        if (empty($aArgs['contacts'])) {
+            array_push($errors, _NO_RECIPIENT);
+        }
+
+        if (empty($aArgs['senderEmail'])) {
+            array_push($errors, _NO_SENDER);
+        }
+
+        return $errors;
+    }
+
+    protected static function generateComments($aArgs = [])
+    {
+        $aReturn    = [];
+
+        $entityRoot = EntityModel::getEntityRootById(['entityId' => $aArgs['TransferringAgencyInformations']['entity_id']]);
+        $userInfo = UserModel::getById(['id' => $GLOBALS['id'], 'select' => ['firstname', 'lastname', 'mail']]);
+        $headerNote = $userInfo['firstname'] . ' ' . $userInfo['lastname'] . ' (' . $entityRoot['entity_label'] . ' - ' . $aArgs['TransferringAgencyInformations']['entity_label'] . ' - ' .$userInfo['mail'].') : ';
+        $oBody        = new \stdClass();
+        $oBody->value = $headerNote . ' ' . $aArgs['body'];
+        array_push($aReturn, $oBody);
+
+        if (!empty($aArgs['notes'])) {
+            $notes     = NoteModel::getByResId([
+                'select' => ['notes.id', 'notes.user_id', 'notes.creation_date', 'notes.note_text', 'users.firstname', 'users.lastname', 'users_entities.entity_id'],
+                'resId' => $aArgs['resId']
+            ]);
+
+            if (!empty($notes)) {
+                foreach ($notes as $value) {
+                    if (!in_array($value['id'], $aArgs['notes'])) {
+                        continue;
+                    }
+
+                    $oComment        = new \stdClass();
+                    $date            = new \DateTime($value['creation_date']);
+                    $additionalUserInfos = '';
+                    if (!empty($value['entity_id'])) {
+                        $entityRoot      = EntityModel::getEntityRootById(['entityId' => $value['entity_id']]);
+                        $userEntity      = Entitymodel::getByEntityId(['entityId' => $value['entity_id']]);
+                        $additionalUserInfos = ' ('.$entityRoot['entity_label'].' - '.$userEntity['entity_label'].')';
+                    }
+                    $oComment->value = $value['firstname'].' '.$value['lastname'].' - '.$date->format('d-m-Y H:i:s'). $additionalUserInfos . ' : '.$value['note_text'];
+                    array_push($aReturn, $oComment);
+                }
+            }
+        }
+        return $aReturn;
+    }
+
+    public static function generateMessageObject($aArgs = [])
+    {
+        $date = new \DateTime;
+
+        $messageObject          = new \stdClass();
+        $messageObject->Comment = $aArgs['Comment'];
+        $messageObject->Date    = $date->format(\DateTime::ATOM);
+
+        $messageObject->MessageIdentifier = new \stdClass();
+        $messageObject->MessageIdentifier->value = 'ArchiveTransfer_'.date("Ymd_His").'_'.$GLOBALS['userId'];
+
+        /********* BINARY DATA OBJECT PACKAGE *********/
+        $messageObject->DataObjectPackage                   = new \stdClass();
+        $messageObject->DataObjectPackage->BinaryDataObject = self::getBinaryDataObject($aArgs['attachment']);
+
+        /********* DESCRIPTIVE META DATA *********/
+        $messageObject->DataObjectPackage->DescriptiveMetadata = self::getDescriptiveMetaDataObject($aArgs);
+
+        /********* ARCHIVAL AGENCY *********/
+        $messageObject->ArchivalAgency = self::getArchivalAgencyObject(['ArchivalAgency' => $aArgs['ArchivalAgency']]);
+
+        /********* TRANSFERRING AGENCY *********/
+        $channelType = $messageObject->ArchivalAgency->OrganizationDescriptiveMetadata->Communication[0]->Channel;
+        $messageObject->TransferringAgency = self::getTransferringAgencyObject(['TransferringAgency' => $aArgs['TransferringAgency'], 'ChannelType' => $channelType]);
+
+        return $messageObject;
+    }
+
+    public static function getBinaryDataObject($aArgs = [])
+    {
+        $aReturn     = [];
+
+        foreach ($aArgs as $key => $value) {
+            if (!empty($value['tablenameExchangeMessage'])) {
+                $binaryDataObjectId = $value['tablenameExchangeMessage'] . "_" . $key . "_" . $value['res_id'];
+            } else {
+                $binaryDataObjectId = $value['res_id'];
+            }
+
+            $binaryDataObject                           = new \stdClass();
+            $binaryDataObject->id                       = $binaryDataObjectId;
+
+            $binaryDataObject->MessageDigest            = new \stdClass();
+            $binaryDataObject->MessageDigest->value     = $value['fingerprint'];
+            $binaryDataObject->MessageDigest->algorithm = "sha256";
+
+            $binaryDataObject->Size                     = $value['filesize'];
+
+            $uri = str_replace("##", DIRECTORY_SEPARATOR, $value['path']);
+            $uri = str_replace("#", DIRECTORY_SEPARATOR, $uri);
+            
+            $docServers = DocserverModel::getByDocserverId(['docserverId' => $value['docserver_id']]);
+            $binaryDataObject->Attachment           = new \stdClass();
+            $binaryDataObject->Attachment->uri      = '';
+            $binaryDataObject->Attachment->filename = basename($value['filename']);
+            $binaryDataObject->Attachment->value    = base64_encode(file_get_contents($docServers['path_template'] . $uri . '/'. $value['filename']));
+
+            $binaryDataObject->FormatIdentification           = new \stdClass();
+            $binaryDataObject->FormatIdentification->MimeType = mime_content_type($docServers['path_template'] . $uri . $value['filename']);
+
+            array_push($aReturn, $binaryDataObject);
+        }
+
+        return $aReturn;
+    }
+
+    public static function getDescriptiveMetaDataObject($aArgs = [])
+    {
+        $DescriptiveMetadataObject              = new \stdClass();
+        $DescriptiveMetadataObject->ArchiveUnit = [];
+
+        $documentArchiveUnit                    = new \stdClass();
+        $documentArchiveUnit->id                = 'mail_1';
+
+        $documentArchiveUnit->Content = self::getContent([
+            'DescriptionLevel'                       => 'File',
+            'Title'                                  => $aArgs['res'][0]['Title'],
+            'OriginatingSystemId'                    => $aArgs['res'][0]['res_id'],
+            'OriginatingAgencyArchiveUnitIdentifier' => $aArgs['res'][0]['OriginatingAgencyArchiveUnitIdentifier'],
+            'DocumentType'                           => $aArgs['res'][0]['DocumentType'],
+            'Status'                                 => $aArgs['res'][0]['status'],
+            'Writer'                                 => $aArgs['res'][0]['typist'],
+            'CreatedDate'                            => $aArgs['res'][0]['creation_date'],
+        ]);
+
+        $documentArchiveUnit->ArchiveUnit = [];
+        foreach ($aArgs['attachment'] as $key => $value) {
+            $attachmentArchiveUnit     = new \stdClass();
+            $attachmentArchiveUnit->id = 'archiveUnit_'.$value['tablenameExchangeMessage'] . "_" . $key . "_" . $value['res_id'];
+            $attachmentArchiveUnit->Content = self::getContent([
+                'DescriptionLevel'                       => 'Item',
+                'Title'                                  => $value['Title'],
+                'OriginatingSystemId'                    => $value['res_id'],
+                'OriginatingAgencyArchiveUnitIdentifier' => $value['OriginatingAgencyArchiveUnitIdentifier'],
+                'DocumentType'                           => $value['DocumentType'],
+                'Status'                                 => $value['status'],
+                'Writer'                                 => $value['typist'],
+                'CreatedDate'                            => $value['creation_date'],
+            ]);
+            $dataObjectReference                        = new \stdClass();
+            $dataObjectReference->DataObjectReferenceId = $value['tablenameExchangeMessage'].'_'.$key.'_'.$value['res_id'];
+            $attachmentArchiveUnit->DataObjectReference = [$dataObjectReference];
+
+            array_push($documentArchiveUnit->ArchiveUnit, $attachmentArchiveUnit);
+        }
+        array_push($DescriptiveMetadataObject->ArchiveUnit, $documentArchiveUnit);
+
+        return $DescriptiveMetadataObject;
+    }
+
+    public static function getContent($aArgs = [])
+    {
+        $contentObject                                         = new \stdClass();
+        $contentObject->DescriptionLevel                       = $aArgs['DescriptionLevel'];
+        $contentObject->Title                                  = [$aArgs['Title']];
+        $contentObject->OriginatingSystemId                    = $aArgs['OriginatingSystemId'];
+        $contentObject->OriginatingAgencyArchiveUnitIdentifier = $aArgs['OriginatingAgencyArchiveUnitIdentifier'];
+        $contentObject->DocumentType                           = $aArgs['DocumentType'];
+        $contentObject->Status                                 = StatusModel::getById(['id' => $aArgs['Status']])['label_status'];
+
+        $userInfos = UserModel::getByLogin(['login' => $aArgs['Writer']]);
+        $writer                = new \stdClass();
+        $writer->FirstName     = $userInfos['firstname'];
+        $writer->BirthName     = $userInfos['lastname'];
+        $contentObject->Writer = [$writer];
+
+        $contentObject->CreatedDate = date("Y-m-d", strtotime($aArgs['CreatedDate']));
+
+        return $contentObject;
+    }
+
+    public static function getArchivalAgencyObject($aArgs = [])
+    {
+        $archivalAgencyObject                    = new \stdClass();
+        $archivalAgencyObject->Identifier        = new \stdClass();
+        $externalId = (array)json_decode($aArgs['ArchivalAgency']['ContactInformations']['external_id']);
+        $archivalAgencyObject->Identifier->value = $externalId['m2m'];
+
+        $archivalAgencyObject->OrganizationDescriptiveMetadata       = new \stdClass();
+        $archivalAgencyObject->OrganizationDescriptiveMetadata->Name = trim($aArgs['ArchivalAgency']['ContactInformations']['company'] . ' ' . $aArgs['ArchivalAgency']['ContactInformations']['lastname'] . ' ' . $aArgs['ArchivalAgency']['ContactInformations']['firstname']);
+
+        if (isset($aArgs['ArchivalAgency']['CommunicationType']['type'])) {
+            $arcCommunicationObject          = new \stdClass();
+            $arcCommunicationObject->Channel = $aArgs['ArchivalAgency']['CommunicationType']['type'];
+            if ($aArgs['ArchivalAgency']['CommunicationType']['type'] == 'url') {
+                $postUrl = '/rest/saveNumericPackage';
+            }
+            $arcCommunicationObject->value   = $aArgs['ArchivalAgency']['CommunicationType']['value'].$postUrl;
+
+            $archivalAgencyObject->OrganizationDescriptiveMetadata->Communication = [$arcCommunicationObject];
+        }
+
+        $contactObject = new \stdClass();
+        $contactObject->DepartmentName = $aArgs['ArchivalAgency']['ContactInformations']['department'];
+        $contactObject->PersonName     = $aArgs['ArchivalAgency']['ContactInformations']['lastname'] . " " . $aArgs['ArchivalAgency']['ContactInformations']['firstname'];
+
+        $addressObject = new \stdClass();
+        $addressObject->CityName      = $aArgs['ArchivalAgency']['ContactInformations']['address_town'];
+        $addressObject->Country       = $aArgs['ArchivalAgency']['ContactInformations']['address_country'];
+        $addressObject->Postcode      = $aArgs['ArchivalAgency']['ContactInformations']['address_postcode'];
+        $addressObject->PostOfficeBox = $aArgs['ArchivalAgency']['ContactInformations']['address_number'];
+        $addressObject->StreetName    = $aArgs['ArchivalAgency']['ContactInformations']['address_street'];
+
+        $contactObject->Address = [$addressObject];
+
+        $communicationContactPhoneObject          = new \stdClass();
+        $communicationContactPhoneObject->Channel = 'phone';
+        $communicationContactPhoneObject->value   = $aArgs['ArchivalAgency']['ContactInformations']['phone'];
+
+        $communicationContactEmailObject          = new \stdClass();
+        $communicationContactEmailObject->Channel = 'email';
+        $communicationContactEmailObject->value   = $aArgs['ArchivalAgency']['ContactInformations']['email'];
+
+        $contactObject->Communication = [$communicationContactPhoneObject, $communicationContactEmailObject];
+
+        $archivalAgencyObject->OrganizationDescriptiveMetadata->Contact = [$contactObject];
+
+        return $archivalAgencyObject;
+    }
+
+    public static function getTransferringAgencyObject($aArgs = [])
+    {
+        $TransferringAgencyObject                    = new \stdClass();
+        $TransferringAgencyObject->Identifier        = new \stdClass();
+        $TransferringAgencyObject->Identifier->value = $aArgs['TransferringAgency']['EntitiesInformations']['business_id'];
+
+        $TransferringAgencyObject->OrganizationDescriptiveMetadata                      = new \stdClass();
+
+        $entityRoot = EntityModel::getEntityRootById(['entityId' => $aArgs['TransferringAgency']['EntitiesInformations']['entity_id']]);
+        $TransferringAgencyObject->OrganizationDescriptiveMetadata->LegalClassification = $entityRoot['entity_label'];
+        $TransferringAgencyObject->OrganizationDescriptiveMetadata->Name                = $aArgs['TransferringAgency']['EntitiesInformations']['entity_label'];
+        $TransferringAgencyObject->OrganizationDescriptiveMetadata->UserIdentifier      = $GLOBALS['userId'];
+
+        $traCommunicationObject          = new \stdClass();
+
+        $aDefaultConfig = ReceiveMessageExchangeController::readXmlConfig();
+
+        $traCommunicationObject->Channel = $aArgs['ChannelType'];
+        $traCommunicationObject->value   = rtrim($aDefaultConfig['m2m_communication_type'][$aArgs['ChannelType']], "/");
+
+        $TransferringAgencyObject->OrganizationDescriptiveMetadata->Communication = [$traCommunicationObject];
+
+        $userInfo = UserModel::getById(['id' => $GLOBALS['id'], 'select' => ['firstname', 'lastname', 'mail', 'phone']]);
+
+        $contactUserObject                 = new \stdClass();
+        $contactUserObject->DepartmentName = $aArgs['TransferringAgency']['EntitiesInformations']['entity_label'];
+        $contactUserObject->PersonName     = $userInfo['firstname'] . " " . $userInfo['lastname'];
+
+        $communicationUserPhoneObject          = new \stdClass();
+        $communicationUserPhoneObject->Channel = 'phone';
+        $communicationUserPhoneObject->value   = $userInfo['phone'];
+
+        $communicationUserEmailObject          = new \stdClass();
+        $communicationUserEmailObject->Channel = 'email';
+        $communicationUserEmailObject->value   = $userInfo['mail'];
+
+        $contactUserObject->Communication = [$communicationUserPhoneObject, $communicationUserEmailObject];
+
+        $TransferringAgencyObject->OrganizationDescriptiveMetadata->Contact = [$contactUserObject];
+
+        return $TransferringAgencyObject;
+    }
+
+    public static function saveUnitIdentifier($aArgs = [])
+    {
+        foreach ($aArgs['attachment'] as $key => $value) {
+            $disposition = "attachment";
+            if ($key == 0) {
+                $disposition = "body";
+            }
+
+            MessageExchangeModel::insertUnitIdentifier([
+                'messageId'   => $aArgs['messageId'], 
+                'tableName'   => $value['tablenameExchangeMessage'], 
+                'resId'       => $value['res_id'], 
+                'disposition' => $disposition
+            ]);
+        }
+
+        if (!empty($aArgs['notes'])) {
+            foreach ($aArgs['notes'] as $value) {
+                MessageExchangeModel::insertUnitIdentifier([
+                    'messageId'   => $aArgs['messageId'], 
+                    'tableName'   => "notes", 
+                    'resId'       => $value, 
+                    'disposition' => "note"
+                ]);
+            }
+        }
+
+        return true;
+    }
 }
diff --git a/src/app/external/messageExchange/models/MessageExchangeModelAbstract.php b/src/app/external/messageExchange/models/MessageExchangeModelAbstract.php
index 84046ddf7e1..19e5e97169c 100755
--- a/src/app/external/messageExchange/models/MessageExchangeModelAbstract.php
+++ b/src/app/external/messageExchange/models/MessageExchangeModelAbstract.php
@@ -97,6 +97,38 @@ abstract class MessageExchangeModelAbstract
         return true;
     }
 
+    public static function updateOperationDateMessage(array $aArgs)
+    {
+        ValidatorModel::notEmpty($aArgs, ['operation_date','message_id']);
+
+        DatabaseModel::update([
+            'table'     => 'message_exchange',
+            'set'       => [
+                'operation_date' => $aArgs['operation_date']
+            ],
+            'where'     => ['message_id = ?'],
+            'data'      => [$aArgs['message_id']]
+        ]);
+
+        return true;
+    }
+
+    public static function updateReceptionDateMessage(array $aArgs)
+    {
+        ValidatorModel::notEmpty($aArgs, ['reception_date','message_id']);
+
+        DatabaseModel::update([
+            'table'     => 'message_exchange',
+            'set'       => [
+                'reception_date' => $aArgs['reception_date']
+            ],
+            'where'     => ['message_id = ?'],
+            'data'      => [$aArgs['message_id']]
+        ]);
+
+        return true;
+    }
+
     /*** Generates a local unique identifier
     @return string The unique id*/
     public static function generateUniqueId()
@@ -228,4 +260,22 @@ abstract class MessageExchangeModelAbstract
 
         return $messages;
     }
+
+    public static function insertUnitIdentifier(array $args)
+    {
+        ValidatorModel::notEmpty($args, ['messageId', 'tableName', 'resId', 'disposition']);
+        ValidatorModel::stringType($args, ['messageId', 'tableName', 'resId', 'disposition']);
+
+        $messages = DatabaseModel::insert([
+            'table'         => 'unit_identifier',
+            'columnsValues' => [
+                'message_id'   => $args['messageId'],
+                'tablename'    => $args['tableName'],
+                'res_id'       => $args['resId'],
+                'disposition'  => $args['disposition']
+            ]
+        ]);
+
+        return $messages;
+    }
 }
-- 
GitLab