From f182aed158f998b925ee991c0c451ad65daf39e5 Mon Sep 17 00:00:00 2001
From: Arnaud PAUGET <arnaud.pauget@maarch.org>
Date: Fri, 23 Oct 2020 14:38:50 +0200
Subject: [PATCH] feature() : add functions to generate SEDA 2.1 message before
 to send to maarch RM

---
 .../export_seda/resources/ArchiveTransfer.xml |    2 +-
 modules/export_seda/resources/ArchiveUnit.xml |   18 +
 .../exportSeda/class/AbstractMessage.php      |  184 +++
 .../exportSeda/class/Acknowledgement.php      |  137 ++
 .../exportSeda/class/ArchiveTransfer.php      |  876 ++++++++++++
 .../exportSeda/class/ArchiveTransferReply.php |  143 ++
 .../controllers/DOMTemplateProcessor.php      | 1236 +++++++++++++++++
 .../controllers/ExportSEDATrait.php           |   24 +-
 .../exportSeda/controllers/RequestSeda.php    |  895 ++++++++++++
 .../controllers/SendMessageController.php     |  423 +++++-
 .../exportSeda/models/AbstractMessage.php     |  182 +++
 .../exportSeda/models/Acknowledgement.php     |  137 ++
 .../exportSeda/models/ArchiveTransfer.php     |  876 ++++++++++++
 .../models/ArchiveTransferReply.php           |  143 ++
 14 files changed, 5254 insertions(+), 22 deletions(-)
 create mode 100644 src/app/external/exportSeda/class/AbstractMessage.php
 create mode 100644 src/app/external/exportSeda/class/Acknowledgement.php
 create mode 100644 src/app/external/exportSeda/class/ArchiveTransfer.php
 create mode 100644 src/app/external/exportSeda/class/ArchiveTransferReply.php
 create mode 100644 src/app/external/exportSeda/controllers/DOMTemplateProcessor.php
 create mode 100644 src/app/external/exportSeda/controllers/RequestSeda.php
 create mode 100644 src/app/external/exportSeda/models/AbstractMessage.php
 create mode 100644 src/app/external/exportSeda/models/Acknowledgement.php
 create mode 100644 src/app/external/exportSeda/models/ArchiveTransfer.php
 create mode 100644 src/app/external/exportSeda/models/ArchiveTransferReply.php

diff --git a/modules/export_seda/resources/ArchiveTransfer.xml b/modules/export_seda/resources/ArchiveTransfer.xml
index 051e049ba86..d6469dc141e 100755
--- a/modules/export_seda/resources/ArchiveTransfer.xml
+++ b/modules/export_seda/resources/ArchiveTransfer.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<ArchiveTransfer xmlns="fr:gouv:culture:archivesdefrance:seda:v2.0">
+<ArchiveTransfer xmlns="fr:gouv:culture:archivesdefrance:seda:v2.1">
     <?merge ArchiveTransfer.Comment ?><Comment><?merge .value ?></Comment>
     <Date><?merge ArchiveTransfer.Date ?></Date>
     <?merge ArchiveTransfer.MessageIdentifier $messageIdentifier ?><?xinclude /resources/MessageIdentifier.xml ?>
diff --git a/modules/export_seda/resources/ArchiveUnit.xml b/modules/export_seda/resources/ArchiveUnit.xml
index 7ddb9aa7b28..16779c8aaf9 100755
--- a/modules/export_seda/resources/ArchiveUnit.xml
+++ b/modules/export_seda/resources/ArchiveUnit.xml
@@ -169,6 +169,24 @@
             <Corpname><?merge .Corpname ?></Corpname>
             <Identifier><?merge .Identifier ?></Identifier>
         </Recipient>
+        <?merge .Content.Sender.array() ?>
+        <Sender>
+            <FirstName><?merge .FirstName ?></FirstName>
+            <BirthName><?merge .BirthName ?></BirthName>
+            <GivenName><?merge .GivenName ?></GivenName>
+            <Gender><?merge .Gender ?></Gender>
+            <BirthDate><?merge .BirthDate ?></BirthDate>
+            <BirthPlace><?merge .BirthPlace ?></BirthPlace>
+            <DeathDate><?merge .DeathDate ?></DeathDate>
+            <DeathPlace><?merge .DeathPlace ?></DeathPlace>
+            <Nationality><?merge .Nationality ?></Nationality>
+            <Function><?merge .Function ?></Function>
+            <Activity><?merge .Activity ?></Activity>
+            <Position><?merge .Position ?></Position>
+            <Role><?merge .Role ?></Role>
+            <Corpname><?merge .Corpname ?></Corpname>
+            <Identifier><?merge .Identifier ?></Identifier>
+        </Sender>
         <Source><?merge .Content.Source ?></Source>
         <?merge .Content.RelatedObjectReference.bool() ?>
         <RelatedObjectReference>
diff --git a/src/app/external/exportSeda/class/AbstractMessage.php b/src/app/external/exportSeda/class/AbstractMessage.php
new file mode 100644
index 00000000000..ba4ea1f3db3
--- /dev/null
+++ b/src/app/external/exportSeda/class/AbstractMessage.php
@@ -0,0 +1,184 @@
+<?php
+
+require_once __DIR__ .  DIRECTORY_SEPARATOR .'../RequestSeda.php';
+require_once __DIR__ . DIRECTORY_SEPARATOR .'../DOMTemplateProcessor.php';
+
+if ($_SESSION['config']['app_id']) {
+    require_once 'apps/maarch_entreprise/class/class_pdf.php';
+}
+
+class AbstractMessage{
+
+    private $db;
+    private $xml;
+    private $directoryMessage;
+    public function __construct()
+    {
+        $this->db = new RequestSeda();
+
+        $getXml = false;
+        $path = '';
+        if (file_exists(
+            $_SESSION['config']['corepath'] . 'custom' . DIRECTORY_SEPARATOR
+            . $_SESSION['custom_override_id'] . DIRECTORY_SEPARATOR . 'modules'
+            . DIRECTORY_SEPARATOR . 'export_seda'. DIRECTORY_SEPARATOR . 'xml'
+            . DIRECTORY_SEPARATOR . 'config.xml'
+        )) {
+            $path = $_SESSION['config']['corepath'] . 'custom' . DIRECTORY_SEPARATOR
+                . $_SESSION['custom_override_id'] . DIRECTORY_SEPARATOR . 'modules'
+                . DIRECTORY_SEPARATOR . 'export_seda'. DIRECTORY_SEPARATOR . 'xml'
+                . DIRECTORY_SEPARATOR . 'config.xml';
+            $getXml = true;
+        } elseif (file_exists(
+            $_SESSION['config']['corepath'] . 'modules'
+            . DIRECTORY_SEPARATOR . 'export_seda'.  DIRECTORY_SEPARATOR . 'xml'
+            . DIRECTORY_SEPARATOR . 'config.xml'
+        )) {
+            $path = $_SESSION['config']['corepath'] . 'modules' . DIRECTORY_SEPARATOR . 'export_seda'
+                . DIRECTORY_SEPARATOR . 'xml' . DIRECTORY_SEPARATOR . 'config.xml';
+            $getXml = true;
+        }
+
+        if ($getXml) {
+            $this->xml = simplexml_load_file($path);
+
+            $this->directoryMessage = (string) $this->xml->CONFIG->directoryMessage;
+        }
+    }
+
+    public function generatePackage($reference, $name)
+    {
+        $message = $this->db->getMessageByReference($reference);
+        $messageObject = json_decode($message->data);
+
+        if (!is_dir($this->directoryMessage)) {
+            umask(0);
+            mkdir($this->directoryMessage, 0777, true);
+        }
+
+        if (!is_dir($this->directoryMessage . DIRECTORY_SEPARATOR . $messageObject->MessageIdentifier->value)) {
+            umask(0);
+            mkdir($this->directoryMessage . DIRECTORY_SEPARATOR . $messageObject->MessageIdentifier->value, 0777, true);
+        }
+
+        $this->sendAttachment($messageObject);
+
+        $this->saveXml($messageObject, $name, ".xml");
+    }
+
+    public function saveXml($messageObject, $name, $extension)
+    {
+        if (isset($messageObject->DataObjectPackage)) {
+            if ($messageObject->DataObjectPackage->BinaryDataObject) {
+                foreach ($messageObject->DataObjectPackage->BinaryDataObject as $binaryDataObject) {
+                    unset($binaryDataObject->Attachment->value);
+                }
+            }
+        }
+
+        $DOMTemplate = new DOMDocument();
+        $DOMTemplate->preserveWhiteSpace = false;
+        $DOMTemplate->formatOutput = true;
+        $DOMTemplate->load(__DIR__ .DIRECTORY_SEPARATOR. '..'. DIRECTORY_SEPARATOR.'resources'.DIRECTORY_SEPARATOR.$name.'.xml');
+        $DOMTemplateProcessor = new DOMTemplateProcessor($DOMTemplate);
+        $DOMTemplateProcessor->setSource($name, $messageObject);
+        $DOMTemplateProcessor->merge();
+        $DOMTemplateProcessor->removeEmptyNodes();
+
+        try {
+            if (!is_dir($this->directoryMessage)) {
+                umask(0);
+                mkdir($this->directoryMessage, 0777, true);
+            }
+
+            if (!is_dir($this->directoryMessage . DIRECTORY_SEPARATOR . $messageObject->MessageIdentifier->value)) {
+                umask(0);
+                mkdir($this->directoryMessage . DIRECTORY_SEPARATOR . $messageObject->MessageIdentifier->value, 0777, true);
+            }
+
+            if (!file_exists($this->directoryMessage . DIRECTORY_SEPARATOR.$messageObject->MessageIdentifier->value.DIRECTORY_SEPARATOR. $messageObject->MessageIdentifier->value . $extension)) {
+                $DOMTemplate->save($this->directoryMessage . DIRECTORY_SEPARATOR.$messageObject->MessageIdentifier->value.DIRECTORY_SEPARATOR. $messageObject->MessageIdentifier->value . $extension);
+            }
+
+        } catch (Exception $e) {
+            return false;
+        }
+    }
+
+    public function addAttachment($reference, $resIdMaster, $fileName, $extension, $title, $type) {
+        $db = new RequestSeda();
+        $object = new stdClass();
+        $dir =  $this->directoryMessage . DIRECTORY_SEPARATOR . $reference . DIRECTORY_SEPARATOR;
+
+        $object->tmpDir = $dir;
+        $object->size = filesize($dir);
+        $object->format = $extension;
+        $object->tmpFileName = $fileName;
+        $object->title = $title;
+        $object->attachmentType = "simple_attachment";
+        $object->resIdMaster = $resIdMaster;
+
+        return $db->insertAttachment($object, $type);
+    }
+
+    private function sendAttachment($messageObject)
+    {
+        $messageId = $messageObject->MessageIdentifier->value;
+
+        foreach ($messageObject->DataObjectPackage->BinaryDataObject as $binaryDataObject) {
+            $dest = $this->directoryMessage . DIRECTORY_SEPARATOR . $messageId . DIRECTORY_SEPARATOR . $binaryDataObject->Attachment->filename;
+
+            if (!file_exists($dest)) {
+                copy($binaryDataObject->Uri, $dest);
+
+                unset($binaryDataObject->Uri);
+            }
+        }
+
+        $this->db->updateDataMessage($messageObject->MessageIdentifier->value, json_encode($messageObject));
+    }
+
+    public function addTitleToMessage($reference, $title = ' ')
+    {
+        $message = $this->db->getMessageByReference($reference);
+
+        $messageObject = json_decode($message->data);
+
+        $messageObject->DataObjectPackage->DescriptiveMetadata->ArchiveUnit[0]->Content->Title[0] = $title;
+
+        $this->db->updateDataMessage($reference, json_encode($messageObject));
+
+        return true;
+    }
+
+    public function changeStatus($reference, $status)
+    {
+        $message = $this->db->getMessageByReference($reference);
+        $listResId = $this->db->getUnitIdentifierByMessageId($message->message_id);
+
+        for ($i=0; $i < count($listResId); $i++) {
+            $this->db->updateStatusLetterbox($listResId[$i]->res_id, $status);
+        }
+
+        return true;
+    }
+
+    public function createPDF($name, $body)
+    {
+        $pdf = new PDF("p", "pt", "A4");
+        $pdf->SetAuthor("MAARCH");
+        $pdf->SetTitle($name);
+
+        $pdf->SetFont('times', '', 12);
+        $pdf->SetTextColor(50, 60, 100);
+
+        $pdf->AddPage('P');
+
+        $pdf->SetAlpha(1);
+
+        $pdf->MultiCell(0, 10, utf8_decode($body), 0, 'L');
+
+        $dir = $_SESSION['config']['tmppath'] . $name . '.pdf';
+        $pdf->Output($dir, "F");
+    }
+}
diff --git a/src/app/external/exportSeda/class/Acknowledgement.php b/src/app/external/exportSeda/class/Acknowledgement.php
new file mode 100644
index 00000000000..a4546c8bf9d
--- /dev/null
+++ b/src/app/external/exportSeda/class/Acknowledgement.php
@@ -0,0 +1,137 @@
+<?php
+
+/*
+*   Copyright 2008-2017 Maarch
+*
+*   This file is part of Maarch Framework.
+*
+*   Maarch Framework is free software: you can redistribute it and/or modify
+*   it under the terms of the GNU General Public License as published by
+*   the Free Software Foundation, either version 3 of the License, or
+*   (at your option) any later version.
+*
+*   Maarch Framework is distributed in the hope that it will be useful,
+*   but WITHOUT ANY WARRANTY; without even the implied warranty of
+*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*   GNU General Public License for more details.
+*
+*   You should have received a copy of the GNU General Public License
+*   along with Maarch Framework.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+require_once __DIR__ . DIRECTORY_SEPARATOR .'../DOMTemplateProcessor.php';
+require_once __DIR__ . '/AbstractMessage.php';
+
+class Acknowledgement {
+
+	public function __construct()
+	{
+	}
+
+	public function receive($data, $resIds)
+	{
+	    $messageObject = $this->getMessageObject($data);
+	    $abstractMessage = new AbstractMessage();
+        $abstractMessage->saveXml($messageObject,"Acknowledgement", ".xml");
+
+		foreach ($resIds as $resId) {
+            $abstractMessage->addAttachment($messageObject->MessageIdentifier->value, $resId, $messageObject->MessageIdentifier->value.".xml", "xml", "Accusé de réception",1);
+        }
+
+        return $messageObject;
+	}
+
+    private function getMessageObject($data)
+    {
+        $messageObject = new stdClass();
+
+        $messageObject->Comment = $data->comment;
+        $messageObject->Date = $data->date;
+        $messageObject->MessageIdentifier = $data->messageIdentifier;
+        $messageObject->MessageReceivedIdentifier = $data->messageReceivedIdentifier;
+
+        $messageObject->Receiver = $this->getOrganisation($data->receiver);
+        $messageObject->Sender = $this->getOrganisation($data->sender);
+
+        return $messageObject;
+    }
+
+    private function getOrganisation($data)
+    {
+        $organisationObject = new stdClass();
+        $organisationObject->Identifier = new stdClass();
+        $organisationObject->Identifier->value = $data->id;
+
+        $organisationObject->OrganizationDescriptiveMetadata = new stdClass();
+        $organisationObject->OrganizationDescriptiveMetadata->Name = $data->name;
+        $organisationObject->OrganizationDescriptiveMetadata->LegalClassification = $data->legalClassification;
+
+        if ($data->address) {
+            $organisationObject->OrganizationDescriptiveMetadata->Address = $this->getAddress($data->address);
+        }
+
+        if ($data->communication) {
+            $organisationObject->OrganizationDescriptiveMetadata->Communication = $this->getCommunication($data->communication);
+        }
+
+        if ($data->contact) {
+            $organisationObject->OrganizationDescriptiveMetadata->Contact = $this->getContact($data->contact);
+        }
+
+        return $organisationObject;
+    }
+
+    private function getContact($data)
+    {
+        $listContact = [];
+        foreach ($data as $contact) {
+            $tmpContact =  new stdClass();
+            $tmpContact->DepartmentName = $contact->departmentName;
+            $tmpContact->PersonName = $contact->personName;
+
+            if ($contact->address){
+                $tmpContact->Address = [];
+                $tmpContact->Address = $this->getAddress($contact->address);
+            }
+
+            if ($contact->communication) {
+                $tmpContact->Communication = [];
+                $tmpContact->Communication = $this->getCommunication($contact->communication);
+            }
+            $listContact[] = $tmpContact;
+        }
+        return $listContact;
+    }
+
+    private function getAddress($data)
+    {
+	    $listAddress = [];
+        foreach ($data as $address) {
+            $tmpAddress = new stdClass();
+            $tmpAddress->CityName = $address->cityName;
+            $tmpAddress->Country = $address->country;
+            $tmpAddress->PostCode = $address->postCode;
+            $tmpAddress->StreetName = $address->streetName;
+
+            $listAddress[] = $tmpAddress;
+        }
+        return $listAddress;
+    }
+
+    private function getCommunication($data)
+    {
+        $listCommunication = [];
+        foreach ($data as $communication) {
+            $tmpCommunication = new stdClass();
+            $tmpCommunication->Channel = $communication->channel;
+
+            if ($communication->completeNumber) {
+                $tmpCommunication->value = $communication->completeNumber;
+            } else {
+                $tmpCommunication->value = $communication->URIID;
+            }
+            $listCommunication[] = $tmpCommunication;
+        }
+        return $listCommunication;
+    }
+}
diff --git a/src/app/external/exportSeda/class/ArchiveTransfer.php b/src/app/external/exportSeda/class/ArchiveTransfer.php
new file mode 100644
index 00000000000..87de4f2a7a5
--- /dev/null
+++ b/src/app/external/exportSeda/class/ArchiveTransfer.php
@@ -0,0 +1,876 @@
+<?php
+
+/*
+*   Copyright 2008-2017 Maarch
+*
+*   This file is part of Maarch Framework.
+*
+*   Maarch Framework is free software: you can redistribute it and/or modify
+*   it under the terms of the GNU General Public License as published by
+*   the Free Software Foundation, either version 3 of the License, or
+*   (at your option) any later version.
+*
+*   Maarch Framework is distributed in the hope that it will be useful,
+*   but WITHOUT ANY WARRANTY; without even the implied warranty of
+*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*   GNU General Public License for more details.
+*
+*   You should have received a copy of the GNU General Public License
+*   along with Maarch Framework.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+require_once __DIR__ . DIRECTORY_SEPARATOR .'../RequestSeda.php';
+require_once __DIR__ . DIRECTORY_SEPARATOR .'../DOMTemplateProcessor.php';
+require_once __DIR__ . '/AbstractMessage.php';
+
+class ArchiveTransfer
+{
+    private $db;
+    private $abstractMessage;
+    private $externalLink;
+    private $xml;
+    protected $entities;
+
+    public function __construct()
+    {
+        $this->db = new RequestSeda();
+        $this->abstractMessage = new AbstractMessage();
+        $_SESSION['error'] = "";
+
+        $getXml = false;
+        $path = '';
+        if (file_exists(
+            $_SESSION['config']['corepath'] . 'custom' . DIRECTORY_SEPARATOR
+            . $_SESSION['custom_override_id'] . DIRECTORY_SEPARATOR . 'modules'
+            . DIRECTORY_SEPARATOR . 'export_seda'. DIRECTORY_SEPARATOR . 'xml'
+            . DIRECTORY_SEPARATOR . 'config.xml'
+        )) {
+            $path = $_SESSION['config']['corepath'] . 'custom' . DIRECTORY_SEPARATOR
+                . $_SESSION['custom_override_id'] . DIRECTORY_SEPARATOR . 'modules'
+                . DIRECTORY_SEPARATOR . 'export_seda'. DIRECTORY_SEPARATOR . 'xml'
+                . DIRECTORY_SEPARATOR . 'config.xml';
+            $getXml = true;
+        } elseif (file_exists(
+            $_SESSION['config']['corepath'] . 'modules'
+            . DIRECTORY_SEPARATOR . 'export_seda'.  DIRECTORY_SEPARATOR . 'xml'
+            . DIRECTORY_SEPARATOR . 'config.xml'
+        )) {
+            $path = $_SESSION['config']['corepath'] . 'modules' . DIRECTORY_SEPARATOR . 'export_seda'
+                . DIRECTORY_SEPARATOR . 'xml' . DIRECTORY_SEPARATOR . 'config.xml';
+            $getXml = true;
+        }
+
+        if ($getXml) {
+            $this->xml = simplexml_load_file($path);
+        }
+
+        $this->entities = [];
+    }
+
+    public function receive($listResId)
+    {
+        if (!$listResId) {
+            return false;
+        }
+
+        $messageObject = new stdClass();
+        $messageObject = $this->initMessage($messageObject);
+
+        if (!empty($_SESSION['error'])) {
+            return;
+        }
+
+        $messageObject->DataObjectPackage->DescriptiveMetadata->ArchiveUnit[] = $this->getArchiveUnit(
+            "RecordGrp",
+            null,
+            null,
+            'group_1',
+            null,
+            null
+        );
+
+        $result = $startDate = $endDate = '';
+        $i = 1;
+        foreach ($listResId as $resId) {
+            $this->externalLink = false;
+
+            if (!empty($result)) {
+                $result .= ',';
+            }
+            $result .= $resId;
+
+            $letterbox = $this->db->getLetter($resId);
+            $attachments = $this->db->getAttachments($letterbox->res_id);
+            $notes = $this->db->getNotes($letterbox->res_id);
+            $mails = $this->db->getMails($letterbox->res_id);
+            $links = $this->db->getLinks($letterbox->res_id);
+
+            $relatedObjectReference = [];
+            if (is_array($links)) {
+                foreach ($links as $link) {
+                    if (!array_search($link, $listResId)) {
+                        $relatedObjectReference[$link] = false;
+                    } else {
+                        $relatedObjectReference[$link] = true;
+                    }
+                }
+            } else {
+                if (!array_search($links, $listResId)) {
+                    $relatedObjectReference[$links] = false;
+                } else {
+                    $relatedObjectReference[$links] = true;
+                }
+            }
+
+            $archiveUnitId = 'letterbox_' . $resId;
+            if ($letterbox->filename) {
+                $docServers = $this->db->getDocServer($letterbox->docserver_id);
+                $uri = str_replace("##", DIRECTORY_SEPARATOR, $letterbox->path);
+                $uri = str_replace("#", DIRECTORY_SEPARATOR, $uri);
+                $uri .= $letterbox->filename;
+                $filePath = $docServers->path_template . $uri;
+
+                if (!file_exists($filePath)) {
+                    $_SESSION['error'] = _ERROR_FILE_NOT_EXIST;
+                    return;
+                }
+
+                $messageObject->DataObjectPackage->DescriptiveMetadata->ArchiveUnit[0]->ArchiveUnit[] = $this->getArchiveUnit(
+                    "File",
+                    $letterbox,
+                    $attachments,
+                    $archiveUnitId,
+                    $letterbox->res_id,
+                    $relatedObjectReference
+                );
+
+                $messageObject->DataObjectPackage->BinaryDataObject[] = $this->getBinaryDataObject(
+                    $filePath,
+                    $_SESSION['collections'][0]['table'] . '_' . $letterbox->res_id
+                );
+            } else {
+                $messageObject->DataObjectPackage->DescriptiveMetadata->ArchiveUnit[0]->ArchiveUnit[] = $this->getArchiveUnit(
+                    "File",
+                    $letterbox,
+                    null,
+                    null,
+                    null,
+                    $relatedObjectReference
+                );
+            }
+
+            if ($attachments) {
+                $j = 1;
+                foreach ($attachments as $attachment) {
+                    $docServers = $this->db->getDocServer($attachment->docserver_id);
+
+                    $uri = str_replace("##", DIRECTORY_SEPARATOR, $attachment->path);
+                    $uri = str_replace("#", DIRECTORY_SEPARATOR, $uri);
+                    $uri .= $attachment->filename;
+
+                    $filePath = $docServers->path_template . $uri;
+                    if ($attachment->attachment_type == "signed_response") {
+                        $messageObject->DataObjectPackage->DescriptiveMetadata->ArchiveUnit[0]->ArchiveUnit[] = $this->getArchiveUnit(
+                            "Response",
+                            $attachment,
+                            null,
+                            'attachment_'. $i. '_'. $j,
+                            "response_" . $attachment->res_id
+//                            $archiveUnitId
+                        );
+
+                        $messageObject->DataObjectPackage->BinaryDataObject[] = $this->getBinaryDataObject(
+                            $filePath,
+                            $_SESSION['collections'][1]['table'] . '_'.  $attachment->res_id
+                        );
+                        $j++;
+                    } else {
+                        $messageObject->DataObjectPackage->BinaryDataObject[] = $this->getBinaryDataObject(
+                            $filePath,
+                            $_SESSION['collections'][1]['table']. '_'.  $attachment->res_id
+                        );
+                    }
+                }
+            }
+
+            if ($notes) {
+                foreach ($notes as $note) {
+                    $id = 'note_'.$note->id;
+                    $filePath = $_SESSION['config']['tmppath']. DIRECTORY_SEPARATOR. $id. '.pdf';
+
+                    $this->abstractMessage->createPDF($id, $note->note_text);
+                    $messageObject->DataObjectPackage->BinaryDataObject[] = $this->getBinaryDataObject($filePath, $id);
+                }
+            }
+
+            if ($mails) {
+                foreach ($mails as $mail) {
+                    $id = 'email_'.$mail->email_id;
+                    $filePath = $_SESSION['config']['tmppath']. DIRECTORY_SEPARATOR. $id. '.pdf';
+                    $body = str_replace('###', ';', $mail->email_body);
+                    $data = 'email n°' . $mail->email_id . '
+' .'de ' . $mail->sender_email . '
+' . 'à ' . $mail->to_list . '
+' . 'objet : ' . $mail->email_object . '
+' . 'corps : ' . strip_tags(html_entity_decode($body));
+
+                    $this->abstractMessage->createPDF($id, $data);
+                    $messageObject->DataObjectPackage->BinaryDataObject[] = $this->getBinaryDataObject($filePath, $id);
+                }
+            }
+
+            $format = 'Y-m-d H:i:s.u';
+            $creationDate = DateTime::createFromFormat($format, $letterbox->creation_date);
+            if ($startDate == '') {
+                $startDate = $creationDate;
+            } elseif ( date_diff($startDate, $creationDate) > 0 ) {
+                $startDate = $creationDate;
+            }
+
+            $modificationDate = DateTime::createFromFormat($format, $letterbox->modification_date);
+            if ($endDate == '') {
+                $endDate = $modificationDate;
+            } elseif ( date_diff($endDate, $modificationDate) < 0) {
+                $endDate = $modificationDate;
+            }
+
+            $i++;
+        }
+
+        $originator = "";
+        foreach ($messageObject->DataObjectPackage->DescriptiveMetadata->ArchiveUnit[0]->ArchiveUnit as $archiveUnit) {
+            if (!empty($archiveUnit->Content->OriginatingAgency->Identifier->value)) {
+                $originator = $archiveUnit->Content->OriginatingAgency->Identifier->value;
+                break;
+            }
+        }
+
+        if (!empty($originator)) {
+            $messageObject->DataObjectPackage->DescriptiveMetadata->ArchiveUnit[0]->Content->OriginatingAgency = new stdClass();
+            $messageObject->DataObjectPackage->DescriptiveMetadata->ArchiveUnit[0]->Content->OriginatingAgency->Identifier = new stdClass();
+            $messageObject->DataObjectPackage->DescriptiveMetadata->ArchiveUnit[0]->Content->OriginatingAgency->Identifier->value = $messageObject->DataObjectPackage->DescriptiveMetadata->ArchiveUnit[0]->ArchiveUnit[0]->Content->OriginatingAgency->Identifier->value;
+        } else {
+            $_SESSION['error'] = _ERROR_ORIGINATOR_EMPTY;
+        }
+
+        $messageObject->DataObjectPackage->DescriptiveMetadata->ArchiveUnit[0]->Content->StartDate = $startDate->format('Y-m-d');
+        $messageObject->DataObjectPackage->DescriptiveMetadata->ArchiveUnit[0]->Content->EndDate = $endDate->format('Y-m-d');
+
+        $messageSaved = $this->saveMessage($messageObject);
+
+        foreach ($listResId as $resId) {
+            $this->db->insertUnitIdentifier($messageSaved['messageId'], "res_letterbox", $resId);
+        }
+
+        return $result;
+    }
+
+    public function deleteMessage($listResId)
+    {
+        if (!$listResId) {
+            return false;
+        }
+
+        $resIds = [];
+        if (!is_array($listResId)) {
+            $resIds[] = $listResId;
+        } else {
+            $resIds = $listResId;
+        }
+
+
+        foreach ($resIds as $resId) {
+            $unitIdentifier = $this->db->getUnitIdentifierByResId($resId);
+            $this->db->deleteMessage($unitIdentifier->message_id);
+            $this->db->deleteUnitIdentifier($resId);
+        }
+
+        return true;
+    }
+
+    private function saveMessage($messageObject)
+    {
+        $data = new stdClass();
+
+        $data->messageId                             = $messageObject->MessageIdentifier->value;
+        $data->date                                  = $messageObject->Date;
+
+        $data->MessageIdentifier                     = new stdClass();
+        $data->MessageIdentifier->value              = $messageObject->MessageIdentifier->value;
+
+        $data->TransferringAgency                    = new stdClass();
+        $data->TransferringAgency->Identifier        = new stdClass();
+        $data->TransferringAgency->Identifier->value = $messageObject->TransferringAgency->Identifier->value;
+
+        $data->ArchivalAgency                        = new stdClass();
+        $data->ArchivalAgency->Identifier            = new stdClass();
+        $data->ArchivalAgency->Identifier->value     = $messageObject->ArchivalAgency->Identifier->value;
+
+        $data->ArchivalAgreement                     = new stdClass();
+        $data->ArchivalAgreement->value              = $messageObject->ArchivalAgreement->value;
+
+        $data->ReplyCode                             = $messageObject->ReplyCode;
+
+        $aArgs                                       = [];
+        $aArgs['fullMessageObject']                  = $messageObject;
+        $aArgs['SenderOrgNAme']                      = "";
+        $aArgs['RecipientOrgNAme']                   = "";
+
+        $messageId = $this->db->insertMessage($data, "ArchiveTransfer", $aArgs);
+
+        return $messageId;
+    }
+
+    private function initMessage($messageObject)
+    {
+
+        $this->directoryMessage = (string) $this->xml->CONFIG->directoryMessage;
+
+        if (!$this->directoryMessage || !is_dir($this->directoryMessage)) {
+            $_SESSION['error'] .= _DIRECTORY_MESSAGE_REQUIRED;
+            return;
+        }
+
+        $date = new DateTime;
+        $messageObject->Date = $date->format(DateTime::ATOM);
+        $messageObject->MessageIdentifier = new stdClass();
+        $messageObject->MessageIdentifier->value = $_SESSION['user']['UserId'] . "-" . date('Ymd-His');
+
+        $messageObject->TransferringAgency = new stdClass();
+        $messageObject->TransferringAgency->Identifier = new stdClass();
+
+        $messageObject->ArchivalAgency = new stdClass();
+        $messageObject->ArchivalAgency->Identifier = new stdClass();
+
+        $messageObject->ArchivalAgreement = new stdClass();
+
+        foreach ($_SESSION['user']['entities'] as $entity) {
+            $res = array_key_exists($entity['ENTITY_ID'], $this->entities);
+            if ($res === false) {
+                $this->entities[$entity['ENTITY_ID']] = $entity = $this->db->getEntity($entity['ENTITY_ID']);
+            } else {
+                $entity = $this->entities[$entity['ENTITY_ID']];
+            }
+
+            if ($entity) {
+                if (!(string) $this->xml->CONFIG->senderOrgRegNumber) {
+                    $_SESSION['error'] .= _TRANSFERRING_AGENCY_SIREN_REQUIRED;
+                }
+
+                if (!$entity->archival_agency) {
+                    $_SESSION['error'] .= _ARCHIVAL_AGENCY_SIREN_REQUIRED;
+                }
+
+                if (!$entity->archival_agreement) {
+                    $_SESSION['error'] .= _ARCHIVAL_AGREEMENT_REQUIRED;
+                }
+
+                if (!empty($_SESSION['error'])) {
+                    return;
+                }
+
+                $messageObject->TransferringAgency->Identifier->value = (string) $this->xml->CONFIG->senderOrgRegNumber;
+                $messageObject->ArchivalAgency->Identifier->value = $entity->archival_agency;
+                $messageObject->ArchivalAgreement->value = $entity->archival_agreement;
+            } else {
+                $_SESSION['error'] .= _NO_ENTITIES;
+            }
+        }
+
+        $messageObject->DataObjectPackage = new stdClass();
+        $messageObject->DataObjectPackage->BinaryDataObject = [];
+        $messageObject->DataObjectPackage->DescriptiveMetadata = new stdClass();
+        $messageObject->DataObjectPackage->ManagementMetadata = new stdClass();
+
+        return $messageObject;
+    }
+
+    private function getArchiveUnit(
+        $type,
+        $object = null,
+        $attachments = null,
+        $archiveUnitId = null,
+        $dataObjectReferenceId = null,
+        $relatedObjectReference = null
+    ) {
+        $archiveUnit = new stdClass();
+
+        if ($archiveUnitId) {
+            $archiveUnit->id = $archiveUnitId;
+        } else {
+            $archiveUnit->id = uniqid();
+        }
+
+        if (isset($object)) {
+            if ($relatedObjectReference) {
+                $archiveUnit->Content = $this->getContent($type, $object, $relatedObjectReference);
+            } else {
+                $archiveUnit->Content = $this->getContent($type, $object);
+            }
+
+            $archiveUnit->Management = $this->getManagement($object);
+        } else {
+            $archiveUnit->Content = $this->getContent($type);
+            $archiveUnit->Management = $this->getManagement();
+        }
+
+
+        if ($dataObjectReferenceId) {
+            $archiveUnit->DataObjectReference = new stdClass();
+            if ($type == 'File') {
+                $archiveUnit->DataObjectReference->DataObjectReferenceId = $_SESSION['collections'][0]['table'] . '_' .$dataObjectReferenceId;
+            } elseif ($type == 'Note') {
+                $archiveUnit->DataObjectReference->DataObjectReferenceId = 'note_' .$dataObjectReferenceId;
+            } elseif ($type == 'Email') {
+                $archiveUnit->DataObjectReference->DataObjectReferenceId = 'email_' .$dataObjectReferenceId;
+            } else {
+                $archiveUnit->DataObjectReference->DataObjectReferenceId = $_SESSION['collections'][1]['table'] . '_' .$dataObjectReferenceId;
+            }
+
+        }
+
+        $archiveUnit->ArchiveUnit = [];
+        if ($attachments) {
+            $i = 1;
+            foreach ($attachments as $attachment) {
+                if ($attachment->res_id_master == $object->res_id) {
+                    if ($attachment->attachment_type != "signed_response") {
+                        $archiveUnit->ArchiveUnit[] = $this->getArchiveUnit(
+                            "Item",
+                            $attachment,
+                            null,
+                            $archiveUnitId. '_attachment_' . $i,
+                            $attachment->res_id
+                        );
+                    }
+                }
+                $i++;
+            }
+        }
+
+        if ($object->res_id) {
+            if ($type != 'Note' && $type != 'Email') {
+                $notes = $this->db->getNotes($object->res_id);
+                if ($notes) {
+                    $i = 1;
+                    foreach ($notes as $note) {
+                        $note->title = 'Note n° ' . $note->id;
+                        $archiveUnit->ArchiveUnit[] = $this->getArchiveUnit(
+                            "Note",
+                            $note,
+                            null,
+                            $archiveUnitId . '_note_' . $i,
+                            $note->id
+                        );
+                        $i++;
+                    }
+                }
+            }
+
+            if ($type != 'Email' && $type != 'Note') {
+                $emails = $this->db->getMails($object->res_id);
+                if ($emails) {
+                    $i = 1;
+                    foreach ($emails as $email) {
+                        $email->title = 'Email n° ' . $email->email_id;
+                        $archiveUnit->ArchiveUnit[] = $this->getArchiveUnit(
+                            "Email",
+                            $email,
+                            null,
+                            $archiveUnitId . '_email_' . $i,
+                            $email->email_id
+                        );
+                        $i++;
+                    }
+                }
+            }
+        }
+        if (count($archiveUnit->ArchiveUnit) == 0) {
+            unset($archiveUnit->ArchiveUnit);
+        }
+
+        return $archiveUnit;
+    }
+
+    private function getContent($type, $object = null, $relatedObjectReference = null)
+    {
+
+        $content = new stdClass();
+
+        switch ($type) {
+            case 'RecordGrp':
+                $content->DescriptionLevel = $type;
+                $content->Title = [];
+                $content->DocumentType = 'Dossier';
+
+                return $content;
+                break;
+            case 'File':
+                $content->DescriptionLevel = $type;
+
+                $sentDate = new DateTime($object->doc_date);
+                $receivedDate = new DateTime($object->admission_date);
+                $acquiredDate = new DateTime($object->creaction_date);
+                $content->SentDate = $sentDate->format(DateTime::ATOM);
+                $content->ReceivedDate = $receivedDate->format(DateTime::ATOM);
+                $content->AcquiredDate = $acquiredDate->format(DateTime::ATOM);
+
+                $content->Addressee = [];
+                $content->Keyword = [];
+
+                $keyword = $addressee = $entity = "";
+
+                if ($object->destination) {
+                    $res = array_key_exists($object->destination, $this->entities);
+                    if ($res === false) {
+                        $this->entities[$object->destination] = $entity = $this->db->getEntity($object->destination);
+                    } else {
+                        $entity = $this->entities[$object->destination];
+                    }
+                }
+
+                if ($object->exp_contact_id) {
+                    $contact = $this->db->getContact($object->exp_contact_id);
+                    $keyword = $this->getKeyword($contact);
+                    $addressee = $this->getAddresse($entity, "entity");
+                } elseif ($object->dest_contact_id) {
+                    $contact = $this->db->getContact($object->dest_contact_id);
+                    $addressee = $this->getAddresse($contact);
+                    $keyword = $this->getKeyword($entity, "entity");
+                } elseif ($object->exp_user_id) {
+                    $user = $this->db->getUserInformation($object->exp_user_id);
+                    $keyword = $this->getKeyword($user);
+                    $addressee = $this->getAddresse($entity, "entity");
+                }
+
+                if (!empty($keyword)) {
+                    $content->Keyword[] = $keyword;
+                }
+
+                if (!empty($addressee)) {
+                    $content->Addressee[] = $addressee;
+                }
+
+                $content->Source = '';
+
+                $content->DocumentType = $object->type_label;
+                $content->OriginatingAgencyArchiveUnitIdentifier = $object->alt_identifier;
+                $content->OriginatingSystemId = $object->res_id;
+
+                $content->Title = [];
+                $content->Title[] = $object->subject;
+                break;
+            case 'Item':
+            case 'Attachment':
+            case 'Response':
+            case 'Note':
+            case 'Email':
+                $content->DescriptionLevel = "Item";
+                $content->Title = [];
+                $content->Title[] = $object->title;
+
+                if ($type == "Item") {
+                    $content->DocumentType = "Pièce jointe";
+                    $date = new DateTime($object->creation_date);
+                    $content->CreatedDate = $date->format('Y-m-d');
+                } elseif ($type == "Note") {
+                    $content->DocumentType = "Note";
+                    $date = new DateTime($object->creation_date);
+                    $content->CreatedDate = $date->format('Y-m-d');
+                } elseif ($type == "Email") {
+                    $content->DocumentType = "Courriel";
+                    $date = new DateTime($object->creation_date);
+                    $content->CreatedDate = $date->format('Y-m-d');
+                } elseif ($type == "Response") {
+                    $content->DocumentType = "Réponse";
+                    $date = new DateTime($object->creation_date);
+                    $content->CreatedDate = $date->format('Y-m-d');
+                }
+
+                break;
+        }
+
+        if (isset($relatedObjectReference)) {
+            $content->RelatedObjectReference = new stdClass();
+            $content->RelatedObjectReference->References = [];
+
+            foreach ($relatedObjectReference as $key => $value) {
+                $reference = new stdClass();
+                if ($value) {
+                    $reference->ArchiveUnitRefId = 'letterbox_' . $key;
+                    $content->RelatedObjectReference->References[] = $reference;
+                } else {
+                    $destination = $this->db->getDestinationLetter($key);
+                    if (isset($destination)) {
+                        $res = array_key_exists($destination, $this->entities);
+                        if ($res === false) {
+                            $this->entities[$destination] = $entity = $this->db->getEntity($destination);
+                        } else {
+                            $entity = $this->entities[$destination];
+                        }
+
+                        $reference->RepositoryArchiveUnitPID = 'originator:' . $entity->business_id . ':' . $key;
+                        $content->RelatedObjectReference->References[] = $reference;
+                    }
+                }
+            }
+
+        }
+
+        if (isset($object->destination)) {
+            $content->OriginatingAgency = new stdClass();
+            $content->OriginatingAgency->Identifier = new stdClass();
+
+            $res = array_key_exists($object->destination, $this->entities);
+            if ($res === false) {
+                $this->entities[$object->destination] = $entity = $this->db->getEntity($object->destination);
+            } else {
+                $entity = $this->entities[$object->destination];
+            }
+            $content->OriginatingAgency->Identifier->value = $entity->business_id;
+
+            if (empty($content->OriginatingAgency->Identifier->value)) {
+                unset($content->OriginatingAgency);
+            }
+        }
+
+        if (isset($object->res_id)) {
+            $content->CustodialHistory = new stdClass();
+            $content->CustodialHistory->CustodialHistoryItem = [];
+
+            $histories = $this->db->getHistory($_SESSION['collections'][0]['view'], $object->res_id);
+            foreach ($histories as $history) {
+                if ($history->event_type != 'VIEW') {
+                    $content->CustodialHistory->CustodialHistoryItem[] = $this->getCustodialHistoryItem($history);
+                }
+            }
+
+            if (count($content->CustodialHistory->CustodialHistoryItem) == 0) {
+                unset($content->CustodialHistory);
+            }
+        }
+
+        return $content;
+    }
+
+    private function getManagement($letterbox = null)
+    {
+        $management = new stdClass();
+
+        if ($letterbox && $letterbox->type_id != 0) {
+            $docTypes = $this->db->getDocTypes($letterbox->type_id);
+
+            $management->AppraisalRule = new stdClass();
+            $management->AppraisalRule->Rule = new stdClass();
+            $management->AppraisalRule->Rule->value = $docTypes->retention_rule;
+            $management->AppraisalRule->StartDate = date("Y-m-d");
+            if ($docTypes->retention_final_disposition == "conservation") {
+                $management->AppraisalRule->FinalAction = "Keep";
+            } else {
+                $management->AppraisalRule->FinalAction = "Destroy";
+            }
+        }
+
+        if ((string) $this->xml->CONFIG->accessRuleCode) {
+            $management->AccessRule = new stdClass();
+            $management->AccessRule->Rule = new stdClass();
+            $management->AccessRule->Rule->value = (string)$this->xml->CONFIG->accessRuleCode;
+            $management->AccessRule->StartDate = date("Y-m-d");
+        }
+
+        return $management;
+    }
+
+    private function getBinaryDataObject($filePath, $id)
+    {
+        $binaryDataObject = new stdClass();
+
+        $pathInfo = pathinfo($filePath);
+
+        if ($id && $id != $pathInfo['filename']) {
+            $filename = $pathInfo['filename'] . '_' . $id . '.' . $pathInfo['extension'];
+        } else {
+            $filename = $pathInfo['filename'] . '_' . rand() . '.' . $pathInfo['extension'];
+        }
+
+        $binaryDataObject->id = $id;
+        $binaryDataObject->Uri = $filePath;
+        $binaryDataObject->MessageDigest = new stdClass();
+        $binaryDataObject->MessageDigest->value = hash_file('sha256', $filePath);
+        $binaryDataObject->MessageDigest->algorithm = "sha256";
+        $binaryDataObject->Size = filesize($filePath);
+
+
+        $binaryDataObject->Attachment = new stdClass();
+        $binaryDataObject->Attachment->filename = $filename;
+
+        $binaryDataObject->FileInfo = new stdClass();
+        $binaryDataObject->FileInfo->Filename = $filename;
+
+        $binaryDataObject->FormatIdentification = new stdClass();
+        $binaryDataObject->FormatIdentification->MimeType = mime_content_type($filePath);
+
+        return $binaryDataObject;
+    }
+
+    private function getKeyword($informations, $type = null)
+    {
+        $keyword = new stdClass();
+        $keyword->KeywordContent = new stdClass();
+
+        if ($type == "entity") {
+            $keyword->KeywordType = "corpname";
+            $keyword->KeywordContent->value = $informations->business_id;
+        } elseif ($informations->is_corporate_person == "Y") {
+            $keyword->KeywordType = "corpname";
+            $keyword->KeywordContent->value = $informations->society;
+        } else {
+            $keyword->KeywordType = "persname";
+            $keyword->KeywordContent->value = $informations->lastname . " " . $informations->firstname;
+        }
+
+        if (empty($keyword->KeywordContent->value)) {
+            return null;
+        }
+
+        return $keyword;
+    }
+
+    private function getAddresse($informations, $type = null)
+    {
+        $addressee = new stdClass();
+        if ($type == "entity") {
+            $addressee->Corpname = $informations->entity_label;
+            $addressee->Identifier = $informations->business_id;
+        } elseif ($informations->is_corporate_person == "Y") {
+            $addressee->Corpname = $informations->society;
+            $addressee->Identifier = $informations->contact_id;
+        } else {
+            $addressee->FirstName = $informations->firstname;
+            $addressee->BirthName = $informations->lastname;
+        }
+
+        if ((empty($addressee->Identifier) || empty($addressee->Corpname)) && (empty($addressee->FirstName) || empty($addressee->BirthName))) {
+            return null;
+        }
+
+        return $addressee;
+    }
+
+    private function getCustodialHistoryItem($history)
+    {
+        $date = new DateTime($history->event_date);
+
+        $custodialHistoryItem = new stdClass();
+        $custodialHistoryItem->value = $history->info;
+        $custodialHistoryItem->when = $date->format('Y-m-d');
+
+        return $custodialHistoryItem;
+    }
+
+    private function getEntity($entityId, $param)
+    {
+        $res = array_key_exists($entityId, $this->entities);
+        if ($res === false) {
+            $this->entities[$entityId] = $entity = $this->db->getEntity($entityId);
+        } else {
+            $entity = $this->entities[$entityId];
+        }
+
+        if (!$entity) {
+            return false;
+        }
+
+        if (!$entity->business_id) {
+            $businessId = $this->getEntityParent(
+                $entity->parent_entity_id,
+                'business_id'
+            );
+
+            if (!$businessId) {
+                return false;
+            }
+
+            $entity->business_id = $businessId;
+        }
+
+        if (!$entity->archival_agreement) {
+            $archivalAgreement = $this->getEntityParent(
+                $entity->parent_entity_id,
+                'archival_agreement'
+            );
+
+            if (!$archivalAgreement) {
+                return false;
+            }
+
+            $entity->archival_agreement = $archivalAgreement;
+        }
+
+        if (!$entity->archival_agency) {
+            $archivalAgency = $this->getEntityParent(
+                $entity->parent_entity_id,
+                'archival_agency'
+            );
+
+            if (!$archivalAgency) {
+                return false;
+            }
+
+            $entity->archival_agency = $archivalAgency;
+        }
+
+        return $entity;
+    }
+
+    private function getEntityParent($parentId, $param)
+    {
+        $res = array_key_exists($parentId, $this->entities);
+        if ($res === false) {
+            $this->entities[$parentId] = $entity = $this->db->getEntity($parentId);
+        } else {
+            $entity = $this->entities[$parentId];
+        }
+
+        if (!$entity) {
+            return false;
+        }
+
+        $res = false;
+
+        if ($param == 'business_id') {
+            if (!$entity->business_id) {
+                $res = $this->getEntityParent(
+                    $entity->parent_entity_id,
+                    'business_id'
+                );
+            } else {
+                $res = $entity->business_id;
+            }
+        }
+
+        if ($param == 'archival_agreement') {
+            if (!$entity->archival_agreement) {
+                $res = $this->getEntityParent(
+                    $entity->parent_entity_id,
+                    'archival_agreement'
+                );
+            } else {
+                $res = $entity->archival_agreement;
+            }
+        }
+
+        if ($param == 'archival_agency') {
+            if (!$entity->archival_agency) {
+                $res = $this->getEntityParent(
+                    $entity->parent_entity_id,
+                    'archival_agency'
+                );
+            } else {
+                $res = $entity->archival_agency;
+            }
+        }
+
+        return $res;
+    }
+}
diff --git a/src/app/external/exportSeda/class/ArchiveTransferReply.php b/src/app/external/exportSeda/class/ArchiveTransferReply.php
new file mode 100644
index 00000000000..957c7ec5244
--- /dev/null
+++ b/src/app/external/exportSeda/class/ArchiveTransferReply.php
@@ -0,0 +1,143 @@
+<?php
+
+/*
+*   Copyright 2008-2017 Maarch
+*
+*   This file is part of Maarch Framework.
+*
+*   Maarch Framework is free software: you can redistribute it and/or modify
+*   it under the terms of the GNU General Public License as published by
+*   the Free Software Foundation, either version 3 of the License, or
+*   (at your option) any later version.
+*
+*   Maarch Framework is distributed in the hope that it will be useful,
+*   but WITHOUT ANY WARRANTY; without even the implied warranty of
+*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*   GNU General Public License for more details.
+*
+*   You should have received a copy of the GNU General Public License
+*   along with Maarch Framework.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+require_once __DIR__ . DIRECTORY_SEPARATOR .'../DOMTemplateProcessor.php';
+require_once __DIR__ . '/AbstractMessage.php';
+
+class ArchiveTransferReply {
+
+    private $db;
+    public function __construct()
+    {
+        $this->db = new RequestSeda();
+    }
+
+    public function receive($data, $resIds)
+    {
+        $messageObject = $this->getMessageObject($data);
+        $abstractMessage = new AbstractMessage();
+        //$this->db->insertMessage($data, "ArchiveTransferReply");
+        $abstractMessage->saveXml($messageObject,"ArchiveTransferReply", ".xml");
+
+        foreach ($resIds as $resId) {
+            $abstractMessage->addAttachment($messageObject->MessageIdentifier->value, $resId, $messageObject->MessageIdentifier->value.".xml", "xml", "Réponse au transfert",2);
+        }
+    }
+
+    private function getMessageObject($data)
+    {
+        $messageObject = new stdClass();
+
+        $messageObject->Comment = $data->comment;
+        $messageObject->Date = $data->date;
+        $messageObject->MessageIdentifier =  new stdClass();
+        $messageObject->MessageIdentifier->value = $data->messageIdentifier->value;
+
+        $messageObject->MessageRequestIdentifier =  new stdClass();
+        $messageObject->MessageRequestIdentifier->value = $data->messageRequestIdentifier->value;
+
+        $messageObject->ReplyCode = $data->replyCode->value . ' : ' . $data->replyCode->name;
+
+        $messageObject->ArchivalAgency = $this->getOrganisation($data->archivalAgency);
+        $messageObject->TransferringAgency = $this->getOrganisation($data->transferringAgency);
+
+        return $messageObject;
+    }
+
+    private function getOrganisation($data)
+    {
+        $organisationObject = new stdClass();
+        $organisationObject->Identifier = new stdClass();
+        $organisationObject->Identifier->value = $data->id;
+
+        $organisationObject->OrganizationDescriptiveMetadata = new stdClass();
+        $organisationObject->OrganizationDescriptiveMetadata->Name = $data->name;
+        $organisationObject->OrganizationDescriptiveMetadata->LegalClassification = $data->legalClassification;
+
+        if ($data->address) {
+            $organisationObject->OrganizationDescriptiveMetadata->Address = $this->getAddress($data->address);
+        }
+
+        if ($data->communication) {
+            $organisationObject->OrganizationDescriptiveMetadata->Communication = $this->getCommunication($data->communication);
+        }
+
+        if ($data->contact) {
+            $organisationObject->OrganizationDescriptiveMetadata->Contact = $this->getContact($data->contact);
+        }
+
+        return $organisationObject;
+    }
+
+    private function getContact($data)
+    {
+        $listContact = [];
+        foreach ($data as $contact) {
+            $tmpContact =  new stdClass();
+            $tmpContact->DepartmentName = $contact->departmentName;
+            $tmpContact->PersonName = $contact->personName;
+
+            if ($contact->address){
+                $tmpContact->Address = [];
+                $tmpContact->Address = $this->getAddress($contact->address);
+            }
+
+            if ($contact->communication) {
+                $tmpContact->Communication = [];
+                $tmpContact->Communication = $this->getCommunication($contact->communication);
+            }
+            $listContact[] = $tmpContact;
+        }
+        return $listContact;
+    }
+
+    private function getAddress($data)
+    {
+        $listAddress = [];
+        foreach ($data as $address) {
+            $tmpAddress = new stdClass();
+            $tmpAddress->CityName = $address->cityName;
+            $tmpAddress->Country = $address->country;
+            $tmpAddress->PostCode = $address->postCode;
+            $tmpAddress->StreetName = $address->streetName;
+
+            $listAddress[] = $tmpAddress;
+        }
+        return $listAddress;
+    }
+
+    private function getCommunication($data)
+    {
+        $listCommunication = [];
+        foreach ($data as $communication) {
+            $tmpCommunication = new stdClass();
+            $tmpCommunication->Channel = $communication->channel;
+
+            if ($communication->completeNumber) {
+                $tmpCommunication->value = $communication->completeNumber;
+            } else {
+                $tmpCommunication->value = $communication->URIID;
+            }
+            $listCommunication[] = $tmpCommunication;
+        }
+        return $listCommunication;
+    }
+}
diff --git a/src/app/external/exportSeda/controllers/DOMTemplateProcessor.php b/src/app/external/exportSeda/controllers/DOMTemplateProcessor.php
new file mode 100644
index 00000000000..7283ae50eba
--- /dev/null
+++ b/src/app/external/exportSeda/controllers/DOMTemplateProcessor.php
@@ -0,0 +1,1236 @@
+<?php
+/*
+ * Copyright (C) 2015 Maarch
+ *
+ * This file is part of dependency xml.
+ *
+ * Dependency xml is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dependency xml is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with dependency xml.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * Process DOM XML Template documents
+ *
+ * @author Cyril Vazquez <cyril.vazquez@maarch.org>
+ */
+class DOMTemplateProcessor
+    extends \DOMXPath
+{
+    /**
+     * The array of parsed processing instructions
+     * @var array
+     */
+    protected $parsedPis = array();
+
+    /**
+     * The array of parsed text instructions
+     * @var array
+     */
+    protected $parsedTexts = array();
+
+    /**
+     * The storage of already merged nodes
+     * @var array
+     */
+    protected $mergedNodes;
+
+    /**
+     * The storage of already merged form nodes
+     * @var array
+     */
+    protected $mergedForms;
+
+    /**
+     * The data sources
+     * @var array
+     */
+    protected $sources = array();
+
+    /**
+     * The variables
+     * @var array
+     */
+    protected $variables = array();
+
+    /**
+     * Constructor
+     * @param DOMDocument $document
+     */
+    public function __construct($document)
+    {
+        parent::__construct($document);
+
+        $this->xinclude();
+        $this->xinclude();
+        $this->xinclude();
+        $this->xinclude();
+        $this->mergedNodes = new \SplObjectStorage();
+        $this->mergedForms = new \SplObjectStorage();
+
+        $this->bindVariable("_SESSION", $_SESSION);
+        $this->bindVariable("_SERVER", $_SERVER);
+        $this->bindVariable("_GET", $_GET);
+        $this->bindVariable("_POST", $_POST);
+        $this->bindVariable("_ENV", $_ENV);
+        $this->bindVariable("_FILES", $_FILES);
+    }
+
+    /**
+     * Process xinclude processing instructions
+     * @param DOMNode $node The context node. If omitted the method processes the entire document tree.
+     */
+    protected function xinclude($node = null)
+    {
+        if ($pis = $this->query("descendant-or-self::processing-instruction('xinclude')", $node)) {
+            foreach ($pis as $pi) {
+                $includeFragment = $this->document->createDocumentFragment();
+                $source = file_get_contents(__DIR__ . trim($pi->data));
+                if (!$source) {
+                    throw new \Exception("Error including Xml fragment: fragment '$pi->data' could not be parsed");
+                }
+
+                $includeFragment->appendXML($source);
+
+                $pi->parentNode->replaceChild($includeFragment, $pi);
+            }
+        }
+    }
+
+    /**
+     * Bind a variable
+     * @param string $name The name of the variable
+     * @param string &$variable The reference of the value
+     */
+    public function bindVariable($name, &$variable)
+    {
+        $this->variables[$name] = &$variable;
+    }
+
+    /**
+     * Set a source for merge
+     * @param string $name The name of the data source
+     * @param string $value The value
+     */
+    public function setSource($name, $value)
+    {
+        $this->sources[$name] = $value;
+    }
+
+    /**
+     * Remove empty elements and attributes
+     * @param DOMNode $node The context node. If omitted the entire document will be processed.
+     */
+    public function removeEmptyNodes($node=null)
+    {
+        if (!$node) {
+            $node = $this->document->documentElement;
+        }
+
+        switch($node->nodeType) {
+            case \XML_ELEMENT_NODE:
+                $childNodeList = $node->childNodes;
+                for ($i=$childNodeList->length-1; $i>=0; $i--) {
+                    $this->removeEmptyNodes($childNodeList->item($i));
+                }
+
+                $childNodeList = $node->childNodes;
+                if ($childNodeList->length == 0 && !$node->hasAttributes()) {
+                    $node->parentNode->removeChild($node);
+                }
+                break;
+
+            case \XML_ATTRIBUTE_NODE:
+                if (empty($node->value)) {
+                    $node->parentNode->removeChild($node);
+                }
+                break;
+
+            case \XML_TEXT_NODE:
+                if (ctype_space($node->nodeValue)) { //&& $node->previousSibling && $node->previousSibling->nodeType == \XML_TEXT_NODE) {
+                    $node->nodeValue = trim($node->nodeValue);
+                }
+                break;
+        }
+    }
+
+    /* -------------------------------------------------------------------------
+    - MERGE processing instructions
+    ------------------------------------------------------------------------- */
+    /**
+     * Merges the processing instructions on the given node and its chil nodes.
+     *
+     * @param string $node The context node. If omitted the entire document will be processed.
+     * @param string $source The data source. If omitted, all merge instruction path must be existing sources
+     */
+    public function merge($node = null, $source = null)
+    {
+        // Avoid garbage nodes merge
+        if (!isset($this->mergedNodes)) {
+            $this->mergedNodes = new \SplObjectStorage();
+        }
+
+        if (!isset($this->mergedForms)) {
+            $this->mergedForms = new \SplObjectStorage();
+        }
+
+        if ($node && $this->mergedNodes->contains($node)) {
+            return;
+        }
+
+        $mergeNodes = $this->query("descendant-or-self::processing-instruction('merge') | descendant-or-self::text()[contains(., '[?merge')] | descendant-or-self::*/@*[contains(., '[?merge')]", $node);
+
+        $this->mergedObjects = array();
+
+        foreach ($mergeNodes as $i => $mergeNode) {
+            switch ($mergeNode->nodeType) {
+                case XML_PI_NODE :
+                    if (!isset($this->parsedPis[$mergeNode->data])) {
+                        $this->parsedPis[$mergeNode->data] = $this->parse($mergeNode->data);
+                    }
+                    $instr = $this->parsedPis[$mergeNode->data];
+
+                    if ($merged = $this->mergePi($mergeNode, $instr, $source)) {
+                        if ($mergeNode->parentNode) {
+                            $mergeNode->parentNode->removeChild($mergeNode);
+                        }
+                    }
+                    break;
+
+                case XML_TEXT_NODE:
+                case XML_ELEMENT_NODE:
+                case XML_ATTRIBUTE_NODE:
+                default:
+                    $this->mergeTextNode($mergeNode, $source);
+            }
+        }
+
+        /*$this->mergePis($node, $source);
+
+        $this->mergeTextNodes($node, $source);*/
+
+        $this->mergeForms();
+
+        if ($node) {
+            $this->mergedNodes->attach($node);
+        }
+    }
+
+    protected function mergePi($pi, $instr, $source = null)
+    {
+        // Get value by reference
+        $value = &$this->getData($instr, $source);
+
+        // Use value with selected target
+        if (isset($instr->params['var'])) {
+            $this->addVar($instr->params['var'], $value);
+
+            $pi->parentNode->removeChild($pi);
+
+            return false;
+        }
+
+        // Get type of value
+        $type = gettype($value);
+        //var_dump($type);
+        //if (isset($instr->params['source']))
+        //    var_dump($instr->params['source']);
+
+        switch (true) {
+            // If value is scalar, merge text before Pi
+            case $type == 'string':
+            case $type == 'integer':
+            case $type == 'double':
+                return $this->mergeText($pi, $instr, $value);
+
+            // Value is bool, remove target sibling if false
+            case $type == 'boolean':
+                return $this->mergeBool($pi, $instr, $value);
+
+            // Value is null, no action
+            case $type == 'NULL':
+                return true;
+
+            // Value is array, merge target by iterating over array
+            case $type == 'array':
+                return $this->mergeArray($pi, $instr, $value);
+
+            case $type == 'object' :
+                switch (true) {
+                    // Object merged with a form
+                    case ($targetForm = $this->query("following-sibling::form", $pi)->item(0)) :
+                        $this->mergedForms->attach($targetForm, array($pi, $instr, $value));
+                        break;
+
+                    // ArrayObject -> merge array
+                    case ($value instanceof \ArrayAccess && $value instanceof \Iterator) :
+                        return $this->mergeArray($pi, $instr, $value);
+
+                    // DOMNode -> merge as xml
+                    case $value instanceof \DOMNode :
+                        return $this->mergeNode($pi, $instr, $value);
+
+                    // If value is an object but no form : merge string version if possible
+                    case method_exists($value, '__toString'):
+                        return $this->mergeText($pi, $instr, (string)$value);
+                }
+
+        }
+
+    }
+
+    protected function addVar($name, &$var)
+    {
+        $this->variables[$name] = $var;
+    }
+
+    protected function mergeForms()
+    {
+        $this->mergedForms->rewind();
+        while ($this->mergedForms->valid()) {
+            $index  = $this->mergedForms->key();
+            $targetForm = $this->mergedForms->current();
+            list($pi, $instr, $object) = $this->mergedForms->getInfo();
+
+            $params = $instr->params;
+
+            if (isset($params['source'])) {
+                $this->setSource($params['source'], $object);
+            }
+
+            $this->mergeObjectProperties($targetForm, $object, $params, $oname = false);
+
+            //$pi->parentNode->removeChild($pi);
+
+            $this->mergedForms->next();
+        }
+    }
+
+    protected function mergeTextNodes($node = null, $source = null)
+    {
+        $textNodes = $this->query("descendant-or-self::text()[contains(., '[?merge')] | descendant-or-self::*/@*[contains(., '[?merge')]", $node);
+
+        for ($i = 0, $l = $textNodes->length; $i < $l; $i++) {
+            $textNode = $textNodes->item($i);
+            $this->mergeTextNode($textNode, $source);
+        }
+    }
+
+    protected function mergeTextNode($textNode, $source = null)
+    {
+        //$nodeXml = $this->saveXml($textNode);
+        $nodeValue = $textNode->nodeValue;
+        if (isset($this->parsedTexts[$nodeValue])) {
+            $instructions = $this->parsedTexts[$nodeValue];
+        } else {
+            preg_match_all("#(?<pi>\[\?merge (?<instr>(?:(?!\?\]).)*)\?\])#", $nodeValue, $pis, PREG_SET_ORDER);
+            $instructions = array();
+            foreach ($pis as $i => $pi) {
+                $instructions[$pi['pi']] = $this->parse($pi['instr']);
+            }
+            $this->parsedTexts[$nodeValue] = $instructions;
+        }
+
+        foreach ($instructions as $pi => $instr) {
+            $value = $this->getData($instr, $source);
+            if (is_scalar($value) || is_null($value) || (is_object($value) && method_exists($value, '__toString'))) {
+                $mergedValue = str_replace($pi, (string)$value, $textNode->nodeValue);
+                $mergedValue = htmlentities($mergedValue);
+                $textNode->nodeValue = str_replace($pi, $value, $mergedValue);
+            }
+        }
+
+        // If text is in an attribute that is empty, remove attribute
+        if ($textNode->nodeType == XML_ATTRIBUTE_NODE && empty($textNode->value)) {
+            $textNode->parentNode->removeAttribute($textNode->name);
+        }
+    }
+
+    protected function mergeText($pi, $instr, $value)
+    {
+        $params = $instr->params;
+        switch (true) {
+            case isset($params['attr']):
+                if (!$targetNode = $this->query("following-sibling::*", $pi)->item(0)) {
+                    return true;
+                }
+                $targetNode->setAttribute($params['attr'], $value);
+                break;
+
+            case isset($params['render']):
+                if (!$params['render']) {
+                    $fragment = $value;
+                } else {
+                    $fragment = $params['render'];
+                }
+                if (!isset($this->fragments[$fragment])) {
+                    return true;
+                }
+                $targetNode = $this->fragments[$fragment]->cloneNode(true);
+                $this->merge($targetNode);
+                $pi->parentNode->insertBefore($targetNode, $pi);
+                break;
+
+            default:
+                $targetNode = $this->document->createTextNode($value);
+                $pi->parentNode->insertBefore($targetNode, $pi);
+        }
+
+        return true;
+    }
+
+    protected function mergeArray($pi, $instr, &$array)
+    {
+        $params = $instr->params;
+
+        if (isset($params['include'])) {
+            $filename = $params['include'];
+            $source = file_get_contents(__DIR__ . "/" . $filename);
+
+            $targetNode = $this->document->createDocumentFragment();
+            $targetNode->appendXML($source);
+
+        } elseif (!$targetNode = $this->query("following-sibling::*", $pi)->item(0)) {
+            return true;
+        }
+
+        reset($array);
+        if ($count = count($array)) {
+            $i = 0;
+            while ($i < $count) {
+                //do {
+                $itemNode = $targetNode->cloneNode(true);
+                $itemData = current($array);
+                if (isset($params['source'])) {
+                    $this->setSource($params['source'], $itemData);
+                }
+
+                $this->merge($itemNode, $itemData);
+                $pi->parentNode->insertBefore($itemNode, $pi);
+
+                @next($array);
+                $i++;
+                /*} while (
+                    @next($array) !== false
+                );*/
+            }
+        }
+        // Remove targetNode (row template)
+        if ($targetNode->parentNode) {
+            $targetNode = $targetNode->parentNode->removeChild($targetNode);
+        }
+
+        // Add to mergedNodes to prevent other calls to merge
+        $this->mergedNodes->attach($targetNode);
+
+        return true;
+    }
+
+    protected function mergeObject($pi, $instr, $object)
+    {
+        $params = $instr->params;
+        if (!$targetNode = $this->query("following-sibling::*", $pi)->item(0)) {
+            return true;
+        }
+
+        if (isset($params['source'])) {
+            $this->setSource($params['source'], $object);
+        }
+
+        $this->mergeObjectProperties($targetNode, $object, $params, $oname = false);
+
+        return true;
+    }
+
+    protected function mergeObjectProperties($targetNode, $object, $params, $oname = false)
+    {
+        foreach ($object as $pname => $pvalue) {
+            if ($oname) {
+                $pname = $oname . "." . $pname;
+            }
+
+            if (is_scalar($pvalue) || (is_object($pvalue) && method_exists($pvalue, '__toString'))) {
+                $this->mergeObjectProperty($targetNode, $pvalue, $params, $pname);
+            }
+            /*elseif (is_object($pvalue))
+                $this->mergeObjectProperties($targetNode, $pvalue, $params, $pname);
+            elseif (is_array($pvalue))
+                foreach ($pvalue as $key => $item)
+                    $this->mergeObjectProperties($targetNode, $pvalue, $params, $pname . "[$key]");*/
+        }
+    }
+
+    protected function mergeObjectProperty($targetNode, $value, $params, $name)
+    {
+        $elements = $this->query("descendant-or-self::*[@name='$name']", $targetNode);
+        for ($i = 0, $l = $elements->length; $i < $l; $i++) {
+            $element = $elements->item($i);
+            switch (strtolower($element->nodeName)) {
+                // Form Input
+                case 'input':
+                    switch ($element->getAttribute('type')) {
+                        case 'checkbox':
+                            if (is_bool($value)) {
+                                if ($value) {
+                                    $element->setAttribute('checked', 'true');
+                                } else {
+                                    $element->removeAttribute('checked');
+                                }
+                            } else {
+                                if ($element->getAttribute('value') == $value) {
+                                    $element->setAttribute('checked', 'true');
+                                } else {
+                                    $element->removeAttribute('checked');
+                                }
+                            }
+
+                            break;
+
+                        case 'radio':
+                            if ($element->getAttribute('value') == $value) {
+                                $element->setAttribute('checked', 'true');
+                            } else {
+                                $element->removeAttribute('checked');
+                            }
+                            break;
+
+                        default:
+                            $element->setAttribute('value', $value);
+                    }
+                    break;
+
+                // Select
+                case 'select':
+                    $value = $this->quote($value);
+                    if ($option = $this->query(".//option[@value=" . $value . "]", $element)->item(0)) {
+                        $option->setAttribute('selected', 'true');
+                        if ($optGroup = $this->query("parent::optgroup", $option)->item(0)) {
+                            $optGroup->removeAttribute('disabled');
+                        }
+                    }
+                    break;
+
+                // Textareas
+                case 'textarea':
+                    $element->nodeValue = $value;
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Merge a boolean
+     * @param DOMNode $pi
+     * @param string $instr
+     * @param boolean $bool
+     *
+     * @return bool
+     */
+    protected function mergeBool($pi, $instr, $bool)
+    {
+        $params = $instr->params;
+        if (isset($params['include'])) {
+            $res = $params['include'];
+            $targetNode = $this->document->createDocumentFragment();
+        } elseif (!$targetNode = $this->query("following-sibling::*", $pi)->item(0)) {
+            return true;
+        }
+
+        if (isset($params['attr'])) {
+            if ($bool == false) {
+                $targetNode->removeAttribute($params['attr']);
+            } else {
+                $targetNode->setAttribute($params['attr'], $params['attr']);
+            }
+        } else {
+            if (isset($params['source'])) {
+                $this->setSource($params['source'], $bool);
+            }
+            if ($bool == false) {
+                if ($targetNode->parentNode) {
+                    $parentNode = $targetNode->parentNode;
+                    $targetNode = $parentNode->removeChild($targetNode);
+                }
+
+                // Add to mergedNodes to prevent other calls to merge
+                $this->mergedNodes->attach($targetNode);
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Merge a node
+     * @param DOMNode $pi
+     * @param string $instr
+     * @param DOMNode $DOMNode
+     *
+     * @return bool
+     */
+    public function mergeNode($pi, $instr, $DOMNode)
+    {
+        $pi->parentNode->insertBefore($DOMNode, $pi);
+
+        return true;
+    }
+
+    /* ------------------------------------------------------------------------
+        Data sources management
+    ------------------------------------------------------------------------ */
+    protected function &getData($instr, $source = null)
+    {
+        //var_dump("getData");
+        //var_dump($instr);
+        //var_dump($source);
+
+        $value = null;
+
+        $steps = $instr->source;
+
+        // First step defines source
+        $type = $steps[0][0];
+        switch ($type) {
+            case 'arg':
+                $value = &$source;
+                break;
+            case 'source':
+                $name = $steps[0][1];
+                if (isset($this->sources[$name])) {
+                    $value = &$this->sources[$name];
+                } elseif (is_scalar($name)) {
+                    if ($name[0] == '"' || $name[0] == "'") {
+                        $value = substr($name, 1, -1);
+                    } elseif (is_numeric($name)) {
+                        $value = $name;
+                    }
+                }
+                break;
+            case 'var':
+                $name = $steps[0][1];
+                if (isset($this->variables[$name])) {
+                    $value = &$this->variables[$name];
+                }
+                break;
+            case 'method':
+                $route = $steps[0][1];
+                $methodRouter = new \core\Route\MethodRouter($route);
+                $serviceObject = $methodRouter->service->newInstance();
+                break;
+        }
+
+        for ($i = 1, $l = count($steps); $i < $l; $i++) {
+            $value = &$this->stepData($steps[$i], $value);
+        }
+
+        return $value;
+    }
+
+    protected function &stepData($step, $source)
+    {
+        //var_dump("stepData");
+        //var_dump($step);
+        //var_dump("from " . gettype($source));
+        $value = null;
+        switch ($step[0]) {
+            case 'func':
+                $value = &$this->stepFunc($step[1], $step[2], $source);
+                break;
+
+            case 'offset':
+                $key = &$this->getParamValue($step[1], $source);
+                if (is_array($source) && isset($source[$key])) {
+                    $value = &$source[$key];
+                }
+                break;
+
+            case 'prop':
+                if (isset($source->{$step[1]})) {
+                    $value = &$source->{$step[1]};
+                }
+                break;
+        }
+
+        return $value;
+    }
+
+    protected function &stepFunc($name, $params = array(), $source = null)
+    {
+        $value = null;
+        foreach ($params as $i => $param) {
+            $params[$i] = &$this->getParamValue($param, $source);
+        }
+
+        if (is_object($source) && method_exists($source, $name)) {
+            $value = call_user_func_array(array($source, $name), $params);
+
+            return $value;
+        }
+        //var_dump($params);
+        switch ($name) {
+            // Callback functions
+            case 'func':
+                $func = $params[0];
+                if (!isset($this->functions[$func])) {
+                    break;
+                }
+                $callback = $this->functions[$func];
+                array_unshift($params, $source);
+                array_unshift($params, $this);
+                $value = @call_user_func_array($callback, $params);
+                break;
+
+            // Array functions
+            case 'length':
+            case 'count':
+                $value = @count($source);
+                break;
+            case 'key':
+                $value = @key($source);
+                break;
+            case 'current':
+                $value = @current($source);
+                break;
+            case 'first':
+                $value = @reset($source);
+                break;
+            case 'next':
+                $value = @next($source);
+                break;
+            case 'prev':
+                $value = @prev($source);
+                break;
+            case 'end':
+                $value = @end($source);
+                break;
+            case 'pos':
+                $pos = null;
+                foreach ((array)$source as $key => $value) {
+                    $pos++;
+                    if ($key == @key($source)) {
+                        break;
+                    }
+                }
+                if (!is_null($pos)) {
+                    $value = $pos;
+                }
+                break;
+            case 'islast':
+                $value = ((@key($source) + 1) == @count($source));
+                break;
+            case 'slice':
+                $value = @array_slice($source, $params[0], $params[1]);
+                break;
+            case 'arraykeyexists':
+                $value = @array_key_exists($params[0], $source);
+                break;
+            case 'inarray':
+                $value = @in_array($params[0], $source);
+                break;
+
+            // Variable functions
+            case 'type':
+                $value = @gettype($source);
+                break;
+            case 'not':
+                $value = @!$source;
+                break;
+            case 'empty':
+                $value = @empty($source);
+                break;
+            case 'isset':
+                $value = @isset($source);
+                break;
+            case 'isarray':
+                $value = @is_array($source);
+                break;
+            case 'isbool':
+                $value = @is_bool($source);
+                break;
+            case 'isfloat':
+            case 'isdouble':
+            case 'isreal':
+                $value = @is_float($source);
+                break;
+            case 'isint':
+            case 'isinteger':
+            case 'islong':
+                $value = @is_int($source);
+                break;
+            case 'isnull':
+                $value = @is_null($source);
+                break;
+            case 'isnotnull':
+                $value = @!is_null($source);
+                break;
+            case 'isnumeric':
+                $value = @is_numeric($source);
+                break;
+            case 'isobject':
+                $value = @is_object($source);
+                break;
+            case 'isscalar':
+                $value = @is_scalar($source);
+                break;
+            case 'isstring':
+                $value = @is_string($source);
+                break;
+            case 'int':
+                $value = @intval($source);
+                break;
+            case 'float':
+                $value = @floatval($source);
+                break;
+            case 'string':
+                $value = @strval($source);
+                break;
+            case 'bool':
+                $value = @(bool)$source;
+                break;
+            case 'array':
+                if (!is_array($source)) {
+                    if (is_null($source)) {
+                        $value = [];
+                    } else {
+                        $value = [$source];
+                    }
+                } else {
+                    $value = $source;
+                }
+                break;
+            case 'attr':
+                if (isset($source->{$params[0]})) {
+                    $value = @$source->{$params[0]};
+                }
+                break;
+            case 'in':
+                $value = false;
+                $i = 0;
+                while (isset($params[$i])) {
+                    $value = $value || $source == $params[$i];
+                    $i++;
+                }
+                break;
+            case 'between':
+                if (isset($params[2]) && $params[2]) {
+                    $value = ($source > $params[0] && $source < $params[1]);
+                } else {
+                    $value = ($source >= $params[0] && $source <= $params[1]);
+                }
+                break;
+            case 'ifeq':
+                $value = ($source == $params[0]);
+                break;
+            case 'ifne':
+                $value = ($source != $params[0]);
+                break;
+            case 'ifgt':
+                $value = ($source > $params[0]);
+                break;
+            case 'ifgte':
+                $value = ($source >= $params[0]);
+                break;
+            case 'iflt':
+                $value = ($source < $params[0]);
+                break;
+            case 'iflte':
+                $value = ($source <= $params[0]);
+                break;
+            case 'contains':
+                $value = (strpos($source, $params[0]) !== false);
+                break;
+            case 'starts-with':
+                $value = (strpos($source, $params[0]) === 0);
+                break;
+            case 'ends-with':
+                $value = (strrpos($source, $params[0]) === (strlen($source) - strlen($params[0]) + 1));
+                break;
+            case 'bit':
+                $value = ($source & (int)$params[0]) > 0;
+                break;
+
+            case 'then':
+                if ($source) {
+                    $value = $params[0];
+                } elseif (isset($params[1])) {
+                    $value = $params[1];
+                }
+                break;
+
+            case 'coalesce':
+                if (is_null($source)) {
+                    $value = $params[0];
+                } else {
+                    $value = $source;
+                }
+                break;
+
+            // String functions
+            case 'format':
+            case 'fmt':
+                $value = @sprintf($params[0], $source);
+                break;
+            case 'match':
+                $value = (bool)@preg_match($params[0], $source);
+                break;
+            case 'upper':
+                $value = @strtoupper($source);
+                break;
+            case 'lower':
+                $value = @strtolower($source);
+                break;
+            case 'ucfirst':
+                $value = @ucfirst($source);
+                break;
+            case 'lcfirst':
+                $value = @lcfirst($source);
+                break;
+            case 'ucwords':
+                $value = @ucwords($source);
+                break;
+            case 'split':
+            case 'explode':
+                $value = @explode($params[0], $source);
+                break;
+            case 'substr':
+                if (isset($params[1])) {
+                    $value = @substr($source, $params[0], $params[1]);
+                } else {
+                    $value = @substr($source, $params[0]);
+                }
+                break;
+            case 'join':
+            case 'implode':
+                $value = @implode($params[0], $source);
+                break;
+            case 'constant':
+                $value = @constant($source);
+                if (is_null($value) && $params[0]) {
+                    $value = $source;
+                }
+                break;
+            case 'print':
+                $value = @print_r($source, true);
+                break;
+            case 'json':
+                if (isset($params[0])) {
+                    $options = \JSON_PRETTY_PRINT;
+                } else {
+                    $options = 0;
+                }
+                $value = @json_encode($source, $options);
+                break;
+            case 'parse':
+                if (isset($params[0])) {
+                    $value = @json_decode($source, $params[0]);
+                } else {
+                    $value = @json_decode($source);
+                }
+                break;
+            case 'encodehtml':
+                $value = @htmlentities($source);
+                break;
+            case 'decodehtml':
+                $value = @html_entity_decode($source);
+                break;
+            case 'base64':
+                $value = @base64_encode($source);
+                break;
+            case 'cat':
+                $value = @implode($params);
+                break;
+            case 'dump':
+                ob_start();
+                var_dump($source);
+                $value = @ob_get_clean();
+                break;
+            case 'translate':
+                if (is_string($source) && $this->translator) {
+                    $catalog = null;
+                    if (isset($params[0])) {
+                        $catalog = $params[0];
+                    }
+                    $context = null;
+                    if (isset($params[1])) {
+                        $context = $params[1];
+                    }
+                    $value = $this->translator->getText($source, $context, $catalog);
+                } else {
+                    $value = $source;
+                }
+                break;
+
+            // Number functions
+            case 'add':
+                $value = @($source + $params[0]);
+                break;
+            case 'mul':
+                $value = @($source * $params[0]);
+                break;
+            case 'div':
+                $value = @($source / $params[0]);
+                break;
+            case 'mod':
+                $value = @($source % $params[0]);
+                break;
+        }
+
+        return $value;
+    }
+
+    protected function &getParamValue($param, $source = null)
+    {
+        if ($param[0] == "'" || $param[0] == '"') {
+            $value = substr($param, 1, -1);
+        } elseif (is_numeric($param)) {
+            $value = $param;
+        } else {
+            $instr = $this->parse($param);
+            $value = &$this->getData($instr, $source);
+        }
+
+        return $value;
+    }
+
+    /* ------------------------------------------------------------------------
+        Merge instructions parser
+    ------------------------------------------------------------------------ */
+    protected function parse($instructionString, $sep = " ")
+    {
+        $args = $this->explode(trim($instructionString), $sep);
+
+        if (!count($args)) {
+            throw new \Exception("Invalid Template instruction : no main argument provided in $instructionString");
+        }
+
+        $parser = new \StdClass();
+        $parser->path = array_shift($args);
+        $parser->source = $this->getSource($parser->path);
+
+        $parser->params = array();
+
+        if (!count($args)) {
+            return $parser;
+        }
+
+        foreach ($args as $arg) {
+            if (preg_match('#^(?<name>\w+)\s*(=(["\'])(?<value>(?:[^\3\\\\]|\\\\.)*)\3)$#', $arg, $pair)) {
+                $parser->params[$pair['name']] = isset($pair['value']) ? $pair['value'] : null;
+            } elseif ($arg[0] == "@") {
+                $parser->params["attr"] = substr($arg, 1);
+            } elseif ($arg[0] == "$") {
+                $parser->params["var"] = substr($arg, 1);
+            } elseif ($arg[0] == "/") {
+                $parser->params["include"] = substr($arg, 1);
+            } else {
+                $parser->params["source"] = $arg;
+            }
+        }
+
+        return $parser;
+    }
+
+    protected function getSource($data)
+    {
+        $source = array();
+        $steps = $this->tokenize($data);
+        for ($i = 0, $l = count($steps); $i < $l; $i++) {
+            $step = $steps[$i];
+            switch (true) {
+                case $step == "" :
+                case $step == false :
+                    if ($i == 0) {
+                        $source[] = array('arg', '');
+                    } else {
+                        unset($step);
+                    }
+                    break;
+
+                //case $step[0] == ".":
+                //    $source[] = array('prop', substr($step, 1));
+                //    break;
+
+                case preg_match('#^\$(?<name>.*)$#', $step, $var):
+                    $source[] = array('var', $var['name']);
+                    break;
+
+                case preg_match('#^(?<ext>\w+):(?<name>.*)$#', $step, $ext):
+                    $source[] = array($ext['ext'], $ext['name']);
+                    break;
+
+                case preg_match('#^(?<name>[^(\/]+)\((?<params>.*)?\)$#', $step, $func) :
+                    $params = $this->explode($func['params'], ",");
+                    $source[] = array('func', $func['name'], $params);
+                    break;
+
+                case preg_match('#^\[(?<name>(?<enc>["\'])?[^\2]*\2?)\]$#', $step, $offset):
+                    $source[] = array('offset', $offset['name']);
+                    break;
+
+                case preg_match('#^\/(?<name>[^(]+)\((?<params>.*)?\)$#', $step, $method) :
+                    $params = $this->explode($method['params'], ",");
+                    $source[] = array('method', $method['name'], $params);
+                    break;
+
+                default:
+                    if ($i == 0) {
+                        $source[] = array('source', $step);
+                    } else {
+                        $source[] = array('prop', $step);
+                    }
+            }
+        }
+
+        return $source;
+    }
+
+    protected function explode($str, $sep)
+    {
+        $l = strlen($str);
+        $o = 0;
+        $esc = false;
+        $sq = false;
+        $dq = false;
+        $br = 0;
+        $sbr = 0;
+        $tok = array();
+
+        for ($i = 0; $i < $l; $i++) {
+            // Add token if separator found out of enclosures and brackets
+            if ($str[$i] == $sep && !$dq && !$sq && !$br && !$sbr) {
+                $tok[] = trim(substr($str, $o, $i - $o));
+                $o = $i + 1;
+                continue;
+            }
+
+            // Ignore character if escaped
+            if ($esc) {
+                $esc = false;
+                continue;
+            }
+
+            // Special characters that affect parsing
+            switch ($str[$i]) {
+                case "'":
+                    if (!$sq) $sq = true;
+                    else $sq = false;
+                    break;
+                case '"':
+                    if (!$dq) $dq = true;
+                    else $dq = false;
+                    break;
+                case '(':
+                    if (!$sq && !$dq) $br++;
+                    break;
+                case ')':
+                    if (!$sq && !$dq) $br--;
+                    break;
+                case '[':
+                    if (!$sq && !$dq) $sbr++;
+                    break;
+                case ']':
+                    if (!$sq && !$dq) $sbr--;
+                    break;
+                case '\\':
+                    $esc = true;
+                    break;
+            }
+        }
+        $tail = trim(substr($str, $o, $i - $o));
+        if ($tail !== "") {
+            $tok[] = $tail;
+        }
+
+        if ($sq || $dq || $br || $sbr || $esc) {
+            throw new \Exception("Invalid string: unexpected end of string at offset $i");
+        }
+
+        return $tok;
+    }
+
+    protected function tokenize($str)
+    {
+        $l = strlen($str);
+        $o = 0;
+        $esc = false;
+        $sq = false;
+        $dq = false;
+        $br = 0;
+        $sbr = false;
+        $steps = array();
+        $step = false;
+
+        // Function
+        for ($i = 0; $i < $l; $i++) {
+            // Tokenize only of out of enclosures
+            if (!$dq && !$sq && !$br) {
+                // Add token if dot found
+                if ($str[$i] == ".") {
+                    $steps[] = trim(substr($str, $o, $i - $o));
+                    $o = $i + 1;
+                    continue;
+                }
+
+                // Add token if opening square bracket
+                if ($str[$i] == "[") {
+                    $steps[] = trim(substr($str, $o, $i - $o));
+                    $o = $i + 1;
+                    $sbr = true;
+                    continue;
+                }
+
+                // Add token enclosed by square brackets
+                if ($str[$i] == "]" && $sbr) {
+                    $steps[] = trim(substr($str, $o - 1, $i - $o + 2));
+                    $o = $i + 1;
+                    $sbr = false;
+                    continue;
+                }
+            }
+
+            // Ignore character if escaped
+            if ($esc) {
+                $esc = false;
+                continue;
+            }
+
+            // Special characters that affect parsing
+            switch ($str[$i]) {
+                case "'":
+                    if (!$sq) $sq = true;
+                    else $sq = false;
+                    break;
+                case '"':
+                    if (!$dq) $dq = true;
+                    else $dq = false;
+                    break;
+                case '(':
+                    if (!$sq && !$dq) $br++;
+                    break;
+                case ')':
+                    if (!$sq && !$dq) $br--;
+                    break;
+                case '\\':
+                    $esc = true;
+                    break;
+            }
+        }
+        $tail = trim(substr($str, $o, $i - $o));
+        if ($tail !== false)
+            $steps[] = $tail;
+
+        if ($sq || $dq || $br || $sbr || $esc)
+            throw new \Exception("Invalid string: unexpected end of string at offset $i");
+
+        return $steps;
+    }
+}
diff --git a/src/app/external/exportSeda/controllers/ExportSEDATrait.php b/src/app/external/exportSeda/controllers/ExportSEDATrait.php
index 66a4238aaa9..d36b63b308a 100644
--- a/src/app/external/exportSeda/controllers/ExportSEDATrait.php
+++ b/src/app/external/exportSeda/controllers/ExportSEDATrait.php
@@ -34,6 +34,8 @@ use SrcCore\models\CurlModel;
 use SrcCore\models\ValidatorModel;
 use User\models\UserModel;
 
+use ExportSeda\models\AbstractMessage;
+
 trait ExportSEDATrait
 {
     public static function sendToRecordManagement(array $args)
@@ -412,11 +414,29 @@ trait ExportSEDATrait
         return ['filePath' => $summarySheetFilePath];
     }
 
+    public static function array2object($data){
+        if (!is_array($data)) {
+            return $data;
+        }
+        $object = new \stdClass();
+        foreach ($data as $name => $value) {
+            if (isset($name)) {
+                $object->{$name} = self::array2object($value);
+            }
+        }
+        return $object;
+    }
+
     public static function generateSEDAPackage(array $args)
     {
-        $encodedFile = '';
+        // var_dump($args); exit();
+        $data = [];
+        $data['messageObject'] = self::array2object($args["data"]["messageObject"]);
+        $data['type'] = $args["data"]["type"];
         
-        return ['encodedFile' => $encodedFile];
+        $informationsToSend = SendMessageController::generateMessageFile($data);
+        var_dump($informationsToSend); exit();
+        return $informationsToSend;
     }
 
     public static function checkAcknowledgmentRecordManagement(array $args)
diff --git a/src/app/external/exportSeda/controllers/RequestSeda.php b/src/app/external/exportSeda/controllers/RequestSeda.php
new file mode 100644
index 00000000000..a6da39154b7
--- /dev/null
+++ b/src/app/external/exportSeda/controllers/RequestSeda.php
@@ -0,0 +1,895 @@
+<?php
+
+/*
+*   Copyright 2008-2017 Maarch
+*
+*   This file is part of Maarch Framework.
+*
+*   Maarch Framework is free software: you can redistribute it and/or modify
+*   it under the terms of the GNU General Public License as published by
+*   the Free Software Foundation, either version 3 of the License, or
+*   (at your option) any later version.
+*
+*   Maarch Framework is distributed in the hope that it will be useful,
+*   but WITHOUT ANY WARRANTY; without even the implied warranty of
+*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*   GNU General Public License for more details.
+*
+*   You should have received a copy of the GNU General Public License
+*   along with Maarch Framework.  If not, see <http://www.gnu.org/licenses/>.
+*/
+namespace ExportSeda\controllers;
+
+// require_once "core/class/class_request.php";
+// require_once "core/class/class_resource.php";
+// require_once "core/class/docservers_controler.php";
+
+class RequestSeda
+{
+    // private $db;
+
+    // protected $statement;
+
+    // public function __construct($db = null)
+    // {
+
+    //     //create session if NO SESSION
+    //     if (empty($_SESSION['user'])) {
+    //         require_once('core/class/class_functions.php');
+    //         include_once('core/init.php');
+    //         require_once('core/class/class_portal.php');
+    //         require_once('core/class/class_db.php');
+    //         require_once('core/class/class_request.php');
+    //         require_once('core/class/class_core_tools.php');
+
+    //         //load Maarch session vars
+    //         $portal = new portal();
+    //         $portal->unset_session();
+    //         $portal->build_config();
+    //         $coreTools = new core_tools();
+    //         $_SESSION['custom_override_id'] = $coreTools->get_custom_id();
+    //         if (isset($_SESSION['custom_override_id'])
+    //             && ! empty($_SESSION['custom_override_id'])
+    //             && isset($_SESSION['config']['corepath'])
+    //             && ! empty($_SESSION['config']['corepath'])
+    //         ) {
+    //             $path = $_SESSION['config']['corepath'] . 'custom' . DIRECTORY_SEPARATOR
+    //                 . $_SESSION['custom_override_id'] . DIRECTORY_SEPARATOR;
+    //             set_include_path(
+    //                 $path . PATH_SEPARATOR . $_SESSION['config']['corepath']
+    //                 . PATH_SEPARATOR . get_include_path()
+    //             );
+    //         } elseif (isset($_SESSION['config']['corepath'])
+    //             && ! empty($_SESSION['config']['corepath'])
+    //         ) {
+    //             set_include_path(
+    //                 $_SESSION['config']['corepath'] . PATH_SEPARATOR . get_include_path()
+    //             );
+    //         }
+    //         // Load configuration from xml into session
+    //         $_SESSION['config']['app_id'] = $_SESSION['businessapps'][0]['appid'];
+    //         require_once('apps/maarch_entreprise/class/class_business_app_tools.php');
+
+    //         $businessAppTools = new business_app_tools();
+    //         $coreTools->build_core_config('core/xml/config.xml');
+
+    //         $businessAppTools->build_business_app_config();
+    //         $coreTools->load_modules_config($_SESSION['modules']);
+    //     }
+
+    //     $this->statement = [];
+    //     if ($db) {
+    //         $this->db = $db;
+    //     } else {
+    //         $this->db = new Database();
+    //     }
+
+    //     $query = "SELECT * FROM message_exchange WHERE reference = ?";
+    //     $this->statement['getMessageByReference'] = $this->db->prepare($query);
+
+    //     $query = "SELECT status FROM res_letterbox WHERE res_id = ?";
+    //     $this->statement['getStatusLetter'] = $this->db->prepare($query);
+
+    //     $query = "SELECT destination FROM res_letterbox WHERE res_id = ?";
+    //     $this->statement['getDestinationLetter'] = $this->db->prepare($query);
+
+    //     $query = "SELECT res_id, contact_id, filename, docserver_id, path, creation_date, modification_date, type_id, doc_date, admission_date, creation_date, exp_contact_id, dest_contact_id, destination, type_label, alt_identifier, subject
+    //               FROM res_view_letterbox
+    //               WHERE res_id = ?";
+    //     $this->statement['getLetter'] = $this->db->prepare($query);
+
+    //     $query = "SELECT * FROM entities WHERE entity_id = ?";
+    //     $this->statement['getEntity'] = $this->db->prepare($query);
+
+    //     $query = "SELECT * FROM notes WHERE identifier = ?";
+    //     $this->statement['getNotes'] = $this->db->prepare($query);
+
+    //     $query = "SELECT * FROM emails WHERE document->>'id' = ?";
+    //     $this->statement['getMails'] = $this->db->prepare($query);
+
+    //     $query = "SELECT * FROM doctypes WHERE type_id = ?";
+    //     $this->statement['getDocTypes'] = $this->db->prepare($query);
+
+    //     $query = "SELECT * FROM unit_identifier WHERE res_id = ?";
+    //     $this->statement['getUnitIdentifierByResId'] = $this->db->prepare($query);
+
+    //     $query =
+    //         "SELECT res_parent,res_child 
+    //         FROM res_linked 
+    //         WHERE coll_id = 'letterbox_coll' 
+    //         AND  (res_child = ? OR res_parent = ?)";
+    //     $this->statement['getLinks'] = $this->db->prepare($query);
+
+    //     $query = "SELECT * FROM contacts_v2 WHERE contact_id = ?";
+    //     $this->statement['getContact'] = $this->db->prepare($query);
+
+    //     $query = "SELECT * FROM docservers WHERE docserver_id = ?";
+    //     $this->statement['getDocServer'] = $this->db->prepare($query);
+
+    //     $query = "SELECT * FROM res_attachments WHERE res_id_master = ? AND status != 'DEL'";
+    //     $this->statement['getAttachments'] = $this->db->prepare($query);
+
+    //     $query = "SELECT * FROM history WHERE table_name = ? and record_id = ?";
+    //     $this->statement['getHistory'] = $this->db->prepare($query);
+
+    //     $query = "INSERT INTO unit_identifier VALUES (?,?,?,?)";
+    //     $this->statement['insertUnitIdentifier'] = $this->db->prepare($query);
+
+    //     $query = "DELETE FROM message_exchange WHERE message_id = ?";
+    //     $this->statement['deleteMessage'] = $this->db->prepare($query);
+
+    //     $query = "DELETE FROM unit_identifier WHERE res_id = ?";
+    //     $this->statement['deleteUnitIdentifier'] = $this->db->prepare($query);
+    // }
+
+    // public function getMessageByReference($reference)
+    // {
+    //     $queryParams = [];
+
+    //     $queryParams[] = $reference;
+
+    //     $query = "SELECT * FROM message_exchange WHERE reference = ?";
+
+    //     $smtp = $this->db->query($query, $queryParams);
+
+    //     $message = $smtp->fetchObject();
+
+    //     return $message;
+    // }
+
+    // public function getMessageByIdentifier($id)
+    // {
+    //     $queryParams = [];
+
+    //     $queryParams[] = $id;
+
+    //     $query = "SELECT * FROM message_exchange WHERE message_id = ?";
+
+    //     $smtp = $this->db->query($query, $queryParams);
+
+    //     $message = $smtp->fetchObject();
+
+    //     return $message;
+    // }
+
+    // public function getUnitIdentifierByMessageId($messageId)
+    // {
+    //     $queryParams = [];
+
+    //     $queryParams[] = $messageId;
+
+    //     $query = "SELECT * FROM unit_identifier WHERE message_id = ?";
+
+    //     $smtp = $this->db->query($query, $queryParams);
+        
+    //     $unitIdentifier = [];
+    //     while ($res = $smtp->fetchObject()) {
+    //         $unitIdentifier[] = $res;
+    //     }
+
+    //     return $unitIdentifier;
+    // }
+
+    // public function getUnitIdentifierByResId($resId)
+    // {
+    //     $queryParams = [];
+
+    //     $queryParams[] = $resId;
+
+    //     $this->statement['getUnitIdentifierByResId']->execute($queryParams);
+
+    //     $unitIdentifier = $this->statement['getUnitIdentifierByResId']->fetchObject();
+
+    //     return $unitIdentifier;
+    // }
+
+    // public function getLetter($resId)
+    // {
+    //     $queryParams = [];
+
+    //     $queryParams[] = $resId;
+
+    //     $this->statement['getLetter']->execute($queryParams);
+
+    //     $letterbox = $this->statement['getLetter']->fetchObject();
+
+    //     return $letterbox;
+    // }
+
+    // public function getStatusLetter($resId)
+    // {
+    //     $queryParams = [];
+
+    //     $queryParams[] = $resId;
+
+    //     $this->statement['getStatusLetter']->execute($queryParams);
+
+    //     $res = $this->statement['getStatusLetter']->fetchObject();
+
+    //     return $res->status;
+    // }
+
+    // public function getDestinationLetter($resId)
+    // {
+    //     $queryParams = [];
+
+    //     $queryParams[] = $resId;
+
+    //     $this->statement['getDestinationLetter']->execute($queryParams);
+
+    //     $res = $this->statement['getDestinationLetter']->fetchObject();
+
+    //     return $res->destination;
+    // }
+
+    // public function getLinks($resId)
+    // {
+    //     $queryParams = [];
+
+    //     $queryParams[] = $resId;
+    //     $queryParams[] = $resId;
+
+    //     $this->statement['getLinks']->execute($queryParams);
+    //     $links = [];
+    //     while ($res = $this->statement['getLinks']->fetchObject()) {
+    //         if ($resId == $res->res_parent) {
+    //             $links[] = $res->res_child;
+    //         } else {
+    //             $links[] = $res->res_parent;
+    //         }
+    //     }
+
+    //     return $links;
+    // }
+
+    // public function getLettersByStatus($status)
+    // {
+    //     $queryParams = [];
+
+    //     $queryParams[] = $status;
+
+    //     $query = "SELECT * FROM res_letterbox WHERE status = ?";
+
+    //     $smtp = $this->db->query($query, $queryParams);
+
+    //     $letters = [];
+    //     while ($res = $smtp->fetchObject()) {
+    //         $letters[] = $res;
+    //     }
+
+    //     return $letters;
+    // }
+
+    // public function getDocTypes($typeId)
+    // {
+    //     $queryParams = [];
+
+    //     $queryParams[] = $typeId;
+
+    //     $this->statement['getDocTypes']->execute($queryParams);
+
+    //     $docTypes = $this->statement['getDocTypes']->fetchObject();
+
+    //     return $docTypes;
+    // }
+
+    // public function getUserInformation($userId)
+    // {
+    //     $queryParams = [];
+
+    //     $queryParams[] = $userId;
+
+    //     $query = "SELECT * FROM users WHERE user_id = ?";
+
+    //     $smtp = $this->db->query($query, $queryParams);
+
+    //     $user = $smtp->fetchObject();
+
+    //     return $user;
+    // }
+
+    // public function getNotes($letterboxId)
+    // {
+    //     $queryParams = [];
+
+    //     $queryParams[] = $letterboxId;
+
+    //     $this->statement['getNotes']->execute($queryParams);
+
+    //     $notes = [];
+    //     while ($res = $this->statement['getEntity']->fetchObject()) {
+    //         $notes[] = $res;
+    //     }
+
+    //     return $notes;
+    // }
+
+    // public function getMails($letterboxId)
+    // {
+    //     $queryParams = [];
+
+    //     $queryParams[] = $letterboxId;
+
+    //     $this->statement['getMails']->execute($queryParams);
+
+    //     $mails = [];
+    //     while ($res = $this->statement['getMails']->fetchObject()) {
+    //         $mails[] = $res;
+    //     }
+
+    //     return $mails;
+    // }
+
+    // public function getEntity($entityId)
+    // {
+    //     $queryParams = [];
+
+    //     $queryParams[] = $entityId;
+
+    //     $this->statement['getEntity']->execute($queryParams);
+
+    //     $entity = $this->statement['getEntity']->fetchObject();
+
+    //     return $entity;
+    // }
+
+    // public function getContact($contactId)
+    // {
+    //     $queryParams = [];
+
+    //     $queryParams[] = $contactId;
+
+    //     $this->statement['getContact']->execute($queryParams);
+
+    //     $contact = $this->statement['getContact']->fetchObject();
+
+    //     return $contact;
+    // }
+
+    // public function getDocServer($docServerId)
+    // {
+    //     $queryParams = [];
+
+    //     $queryParams[] = $docServerId;
+
+    //     $this->statement['getDocServer']->execute($queryParams);
+
+    //     $docServers = $this->statement['getDocServer']->fetchObject();
+
+    //     return $docServers;
+    // }
+
+    // public function getAttachments($resIdMaster)
+    // {
+    //     $queryParams = [];
+
+    //     $queryParams[] = $resIdMaster;
+
+    //     $this->statement['getAttachments']->execute($queryParams);
+
+    //     $attachments = [];
+    //     while ($res = $this->statement['getAttachments']->fetchObject()) {
+    //         $attachments[] = $res;
+    //     }
+
+    //     return $attachments;
+    // }
+
+    // public function getReply($resIdMaster)
+    // {
+    //     $queryParams = [];
+
+    //     $queryParams[] = $resIdMaster;
+
+    //     $query = "SELECT * FROM res_attachments WHERE res_id_master = ? and type_id = 2 and status != 'DEL'";
+
+    //     $smtp = $this->db->query($query, $queryParams);
+
+    //     $res = $smtp->fetchObject();
+
+    //     return $res;
+    // }
+
+    // public function getHistory($tableName, $recordId)
+    // {
+    //     $queryParams = [];
+
+    //     $queryParams[] = $tableName;
+    //     $queryParams[] = $recordId;
+
+    //     $this->statement['getHistory']->execute($queryParams);
+
+    //     $history = [];
+    //     while ($res = $this->statement['getHistory']->fetchObject()) {
+    //         $history[] = $res;
+    //     }
+
+    //     return $history;
+    // }
+
+    // /*** Generates a local unique identifier
+    // @return string The unique id*/
+    // public function generateUniqueId()
+    // {
+    //     $parts = explode('.', microtime(true));
+    //     $sec   = $parts[0];
+    //     if (!isset($parts[1])) {
+    //         $msec = 0;
+    //     } else {
+    //         $msec = $parts[1];
+    //     }
+    //     $uniqueId = str_pad(base_convert($sec, 10, 36), 6, '0', STR_PAD_LEFT) . str_pad(base_convert($msec, 10, 16), 4, '0', STR_PAD_LEFT);
+    //     $uniqueId .= str_pad(base_convert(mt_rand(), 10, 36), 6, '0', STR_PAD_LEFT);
+
+    //     return $uniqueId;
+    // }
+
+
+    // public function insertMessage($messageObject, $type, $aArgs = [])
+    // {
+    //     $queryParams = [];
+
+    //     if (!empty($_SESSION['user']['UserId'])) {
+    //         $userId = $_SESSION['user']['UserId'];
+    //     } else {
+    //         $userId = $GLOBALS['login'];
+    //     }
+
+    //     if (empty($messageObject->messageId)) {
+    //         $messageObject->messageId = $this->generateUniqueId();
+    //     }
+
+    //     if (empty($aArgs['status'])) {
+    //         $status = "sent";
+    //     } else {
+    //         $status = $aArgs['status'];
+    //     }
+
+    //     if (empty($aArgs['fullMessageObject'])) {
+    //         $messageObjectToSave = $messageObject;
+    //     } else {
+    //         $messageObjectToSave = $aArgs['fullMessageObject'];
+    //     }
+
+    //     if (empty($aArgs['resIdMaster'])) {
+    //         $resIdMaster = null;
+    //     } else {
+    //         $resIdMaster = $aArgs['resIdMaster'];
+    //     }
+
+    //     if (empty($aArgs['filePath'])) {
+    //         $filePath = null;
+    //     } else {
+    //         $filePath = $aArgs['filePath'];
+    //         $filesize = filesize($filePath);
+
+    //         //Store resource on docserver
+
+    //         $resource = file_get_contents($filePath);
+    //         $pathInfo = pathinfo($filePath);
+    //         $storeResult = \Docserver\controllers\DocserverController::storeResourceOnDocServer([
+    //             'collId'            => 'archive_transfer_coll',
+    //             'docserverTypeId'   => 'ARCHIVETRANSFER',
+    //             'encodedResource'   => base64_encode($resource),
+    //             'format'            => $pathInfo['extension']
+    //         ]);
+
+    //         if (!empty($storeResult['errors'])) {
+    //             return ['error' => $storeResult['errors']];
+    //         }
+    //         $docserver_id = $storeResult['docserver_id'];
+    //         $filepath     = $storeResult['destination_dir'];
+    //         $filename     = $storeResult['file_destination_name'];
+    //         $docserver     = \Docserver\models\DocserverModel::getByDocserverId(['docserverId' => $docserver_id]);
+
+    //         $docserverType = \Docserver\models\DocserverTypeModel::getById(
+    //             ['id' => $docserver['docserver_type_id']]
+    //         );
+
+    //         $fingerprint = \Resource\controllers\StoreController::getFingerPrint([
+    //             'filePath' => $filePath,
+    //             'mode'     => $docserverType['fingerprint_mode'],
+    //         ]);
+    //     }
+
+    //     try {
+    //         $query = ("INSERT INTO message_exchange (
+	// 			message_id,
+	// 			schema,
+	// 			type,
+	// 			status,
+	// 			date,
+	// 			reference,
+	//             account_id ,
+	// 			sender_org_identifier,
+	// 			sender_org_name,
+	// 			recipient_org_identifier,
+	// 			recipient_org_name,
+	// 			archival_agreement_reference,
+	// 			reply_code,
+	// 			size,
+	// 			data,
+	// 			active,
+	// 			archived,
+    //             res_id_master,
+    //             docserver_id,
+    //             path,
+    //             filename,
+    //             fingerprint,
+    //             filesize)
+	// 			VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
+
+    //         $queryParams[] = $messageObject->messageId; // Message Id
+    //         $queryParams[] = "2.1"; //Schema
+    //         $queryParams[] = $type; // Type
+    //         $queryParams[] = $status; // Status
+    //         $queryParams[] = $messageObject->date; // Date
+    //         $queryParams[] = $messageObject->MessageIdentifier->value; // Reference
+    //         $queryParams[] = $userId; // Account Id
+    //         $queryParams[] = $messageObject->TransferringAgency->Identifier->value; // Sender org identifier id
+    //         $queryParams[] = $aArgs['SenderOrgNAme']; //SenderOrgNAme
+    //         $queryParams[] = $messageObject->ArchivalAgency->Identifier->value; // Recipient org identifier id
+    //         $queryParams[] = $aArgs['RecipientOrgNAme']; //RecipientOrgNAme
+    //         $queryParams[] = $messageObject->ArchivalAgreement->value; // Archival agreement reference
+    //         $queryParams[] = $messageObject->ReplyCode; //ReplyCode
+    //         $queryParams[] = 0; // size
+    //         $queryParams[] = json_encode($messageObjectToSave);//$messageObject; // Data
+    //         $queryParams[] = 1; // active
+    //         $queryParams[] = 0; // archived
+    //         $queryParams[] = $resIdMaster; // res_id_master
+    //         $queryParams[] = $docserver_id;
+    //         $queryParams[] = $filepath;
+    //         $queryParams[] = $filename;
+    //         $queryParams[] = $fingerprint;
+    //         $queryParams[] = $filesize;
+
+    //         $this->db->query($query, $queryParams);
+    //     } catch (Exception $e) {
+    //         return ['error' => $e];
+    //     }
+
+    //     return ['messageId' => $messageObject->messageId];
+    // }
+
+    // public function insertAttachment($data, $type)
+    // {
+    //     $fileInfos = array(
+    //         "tmpDir"      => $data->tmpDir,
+    //         "size"        => $data->size,
+    //         "format"      => $data->format,
+    //         "tmpFileName" => $data->tmpFileName,
+    //     );
+
+    //     $storeResult = array();
+
+    //     $resource = file_get_contents($data->tmpDir . '/' . $data->tmpFileName);
+    //     $pathInfo = pathinfo($data->tmpDir . '/' . $data->tmpFileName);
+    //     $storeResult = \Docserver\controllers\DocserverController::storeResourceOnDocServer([
+    //         'collId'            => 'attachments_coll',
+    //         'docserverTypeId'   => 'FASTHD',
+    //         'encodedResource'   => base64_encode($resource),
+    //         'format'            => $pathInfo['extension']
+    //     ]);
+
+    //     if (isset($storeResult['error']) && $storeResult['error'] <> '') {
+    //         $_SESSION['error'] = $storeResult['error'];
+    //     } else {
+    //         $resAttach = new resource();
+    //         $_SESSION['data'] = array();
+    //         array_push(
+    //             $_SESSION['data'],
+    //             array(
+    //                 'column' => "typist",
+    //                 'value' => ' ',
+    //                 'type' => "string",
+    //             )
+    //         );
+    //         array_push(
+    //             $_SESSION['data'],
+    //             array(
+    //                 'column' => "format",
+    //                 'value' => $data->format,
+    //                 'type' => "string",
+    //             )
+    //         );
+    //         array_push(
+    //             $_SESSION['data'],
+    //             array(
+    //                 'column' => "docserver_id",
+    //                 'value' => $storeResult['docserver_id'],
+    //                 'type' => "string",
+    //             )
+    //         );
+    //         array_push(
+    //             $_SESSION['data'],
+    //             array(
+    //                 'column' => "status",
+    //                 'value' => 'TRA',
+    //                 'type' => "string",
+    //             )
+    //         );
+    //         array_push(
+    //             $_SESSION['data'],
+    //             array(
+    //                 'column' => "offset_doc",
+    //                 'value' => ' ',
+    //                 'type' => "string",
+    //             )
+    //         );
+    //         array_push(
+    //             $_SESSION['data'],
+    //             array(
+    //                 'column' => "title",
+    //                 'value' => $data->title,
+    //                 'type' => "string",
+    //             )
+    //         );
+    //         array_push(
+    //             $_SESSION['data'],
+    //             array(
+    //                 'column' => "attachment_type",
+    //                 'value' => $data->attachmentType,
+    //                 'type' => "string",
+    //             )
+    //         );
+    //         array_push(
+    //             $_SESSION['data'],
+    //             array(
+    //                 'column' => "coll_id",
+    //                 'value' => 'letterbox_coll',
+    //                 'type' => "string",
+    //             )
+    //         );
+    //         array_push(
+    //             $_SESSION['data'],
+    //             array(
+    //                 'column' => "res_id_master",
+    //                 'value' => $data->resIdMaster,
+    //                 'type' => "integer",
+    //             )
+    //         );
+
+    //         /*if (isset($_REQUEST['contactidAttach']) && $_REQUEST['contactidAttach'] <> '' && is_numeric($_REQUEST['contactidAttach'])) {
+    //             array_push(
+    //                 $_SESSION['data'],
+    //                 array(
+    //                     'column' => "dest_contact_id",
+    //                     'value' => $_REQUEST['contactidAttach'],
+    //                     'type' => "integer",
+    //                 )
+    //             );
+    //         } else if (isset($_REQUEST['contactidAttach']) && $_REQUEST['contactidAttach'] != '' && !is_numeric($_REQUEST['contactidAttach'])) {
+    //             $_SESSION['data'][] = [
+    //                 'column' => 'dest_user',
+    //                 'value' => $_REQUEST['contactidAttach'],
+    //                 'type' => 'string',
+    //             ];
+    //         }
+
+    //         if (isset($_REQUEST['addressidAttach']) && $_REQUEST['addressidAttach'] <> '' && is_numeric($_REQUEST['addressidAttach'])) {
+    //             array_push(
+    //                 $_SESSION['data'],
+    //                 array(
+    //                     'column' => "dest_address_id",
+    //                     'value' => $_REQUEST['addressidAttach'],
+    //                     'type' => "integer",
+    //                 )
+    //             );
+    //         }
+    //         if(!empty($_REQUEST['chrono'])){
+    //             array_push(
+    //                 $_SESSION['data'],
+    //                 array(
+    //                     'column' => "identifier",
+    //                     'value' => $_REQUEST['chrono'],
+    //                     'type' => "string",
+    //                 )
+    //             );
+    //         }*/
+    //         array_push(
+    //             $_SESSION['data'],
+    //             array(
+    //                 'column' => "type_id",
+    //                 'value' => $type,
+    //                 'type' => "int",
+    //             )
+    //         );
+
+    //         array_push(
+    //             $_SESSION['data'],
+    //             array(
+    //                 'column' => "relation",
+    //                 'value' => 1,
+    //                 'type' => "int",
+    //             )
+    //         );
+
+    //         $id = $resAttach->load_into_db(
+    //             'RES_ATTACHMENTS',
+    //             $storeResult['destination_dir'],
+    //             $storeResult['file_destination_name'],
+    //             $storeResult['path_template'],
+    //             $storeResult['docserver_id'],
+    //             $_SESSION['data'],
+    //             $_SESSION['config']['databasetype']
+    //         );
+    //     }
+    //     return true;
+    // }
+
+    // public function insertUnitIdentifier($messageId, $tableName, $resId, $disposition = "")
+    // {
+    //     try {
+    //         $queryParams = [];
+
+    //         $queryParams[] = $messageId;
+    //         $queryParams[] = $tableName;
+    //         $queryParams[] = $resId;
+    //         $queryParams[] = $disposition;
+
+    //         $this->statement['insertUnitIdentifier']->execute($queryParams);
+    //     } catch (Exception $e) {
+    //         return false;
+    //     }
+
+    //     return true;
+    // }
+
+    // public function updateDataMessage($reference, $data)
+    // {
+    //     $queryParams = [];
+    //     $queryParams[] = $data;
+    //     $queryParams[] = $reference;
+
+    //     try {
+    //         $query = "UPDATE message_exchange SET data = ? WHERE reference = ?";
+
+    //         $smtp = $this->db->query($query, $queryParams);
+    //     } catch (Exception $e) {
+    //         return false;
+    //     }
+
+    //     return true;
+    // }
+
+    // public function updateStatusMessage($messageId, $status)
+    // {
+    //     $queryParams = [];
+    //     $queryParams[] = $status;
+    //     $queryParams[] = $messageId;
+
+    //     try {
+    //         $query = "UPDATE message_exchange SET status = ? WHERE message_id = ?";
+
+    //         $smtp = $this->db->query($query, $queryParams);
+    //     } catch (Exception $e) {
+    //         return false;
+    //     }
+
+    //     return true;
+    // }
+
+    // public function updateStatusLetterbox($resId, $status)
+    // {
+    //     $queryParams = [];
+    //     $queryParams[] = $status;
+    //     $queryParams[] = $resId;
+
+    //     try {
+    //         $query = "UPDATE res_letterbox SET status = ? WHERE res_id = ?";
+
+    //         $smtp = $this->db->query($query, $queryParams);
+    //     } catch (Exception $e) {
+    //         return false;
+    //     }
+
+    //     return true;
+    // }
+
+    // public function updateStatusAttachment($resId, $status)
+    // {
+    //     $queryParams = [];
+    //     $queryParams[] = $status;
+    //     $queryParams[] = $resId;
+
+    //     try {
+    //         $query = "UPDATE res_attachments SET status = ? WHERE res_id_master = ? AND type_id IN (1,2) ";
+
+    //         $smtp = $this->db->query($query, $queryParams);
+    //     } catch (Exception $e) {
+    //         return false;
+    //     }
+
+    //     return true;
+    // }
+
+    // public function deleteMessage($messageId)
+    // {
+    //     $queryParams = [];
+    //     $queryParams[] = $messageId;
+    //     try {
+    //         $this->statement['deleteMessage']->execute($queryParams);
+    //     } catch (Exception $e) {
+    //         return false;
+    //     }
+
+    //     return true;
+    // }
+
+    // public function deleteUnitIdentifier($resId)
+    // {
+    //     $queryParams = [];
+
+    //     $queryParams[] = $resId;
+    //     try {
+    //         $this->statement['deleteUnitIdentifier']->execute($queryParams);
+    //     } catch (Exception $e) {
+    //         return false;
+    //     }
+
+    //     return true;
+    // }
+
+    // public function getMessagesByReference($id)
+    // {
+    //     $queryParams = [];
+
+    //     $queryParams[] = $id;
+
+    //     $query = "SELECT * FROM message_exchange WHERE reference = ?";
+
+    //     return $this->db->query($query, $queryParams);
+    // }
+
+    // public function getMessageByIdentifierAndResId($aArgs = [])
+    // {
+    //     $queryParams = [];
+
+    //     $query = "SELECT * FROM message_exchange WHERE message_id = ? and res_id_master = ?";
+    //     $queryParams[] = $aArgs['message_id'];
+    //     $queryParams[] = $aArgs['res_id_master'];
+
+    //     $smtp = $this->db->query($query, $queryParams);
+
+    //     $message = $smtp->fetchObject();
+
+    //     return $message;
+    // }
+
+    // public function getEntitiesByBusinessId($businessId)
+    // {
+    //     $queryParams = [];
+
+    //     $queryParams[] = $businessId;
+
+    //     $query = "SELECT * FROM entities WHERE business_id = ?";
+
+    //     $smtp = $this->db->query($query, $queryParams);
+
+    //     while ($res = $smtp->fetchObject()) {
+    //         $entities[] = $res;
+    //     }
+
+    //     return $entities;
+    // }
+}
diff --git a/src/app/external/exportSeda/controllers/SendMessageController.php b/src/app/external/exportSeda/controllers/SendMessageController.php
index 748c8b6bf0f..2204c3ce4df 100755
--- a/src/app/external/exportSeda/controllers/SendMessageController.php
+++ b/src/app/external/exportSeda/controllers/SendMessageController.php
@@ -15,6 +15,7 @@
 namespace ExportSeda\controllers;
 
 use SrcCore\models\CoreConfigModel;
+use exportSeda\models\ArchiveTransfer;
 
 class SendMessageController
 {
@@ -38,47 +39,431 @@ class SendMessageController
 
     public static function generateMessageFile($aArgs = [])
     {
+        $tmpPath = CoreConfigModel::getTmpPath();
+
         $messageObject = $aArgs['messageObject'];
         $type          = $aArgs['type'];
 
+        $seda2Message = SendMessageController::initMessage(new \stdClass);
+
+        $seda2Message->MessageIdentifier->value = $messageObject->messageIdentifier;
+        $seda2Message->ArchivalAgreement->value = $messageObject->archivalAgreement;
+
+        $seda2Message->ArchivalAgency->Identifier->value = $messageObject->archivalAgency;
+        $seda2Message->TransferringAgency->Identifier->value = $messageObject->transferringAgency;
+
+
+        $seda2Message->DataObjectPackage->DescriptiveMetadata->ArchiveUnit[] = self::getArchiveUnit(
+            "RecordGrp",
+            null,
+            null,
+            'group_1',
+            null,
+            null
+        );
+
+        foreach($messageObject->dataObjectPackage->attachments as $attachment) {
+            $seda2Message->DataObjectPackage->BinaryDataObject[] = self::getBinaryDataObject(
+                $attachment->filePath,
+                $attachment->id
+            );
+
+            $pathInfo = pathinfo($attachment->filePath);
+            copy($attachment->filePath, $tmpPath . $pathInfo["basename"]);
+
+            if ($attachment->type == "mainDocument") {
+                $messageObject->dataObjectPackage->label = $attachment->label;
+                $messageObject->dataObjectPackage->originatingSystemId = $attachment->id;
+                
+                $seda2Message->DataObjectPackage->DescriptiveMetadata->ArchiveUnit[0] = self::getArchiveUnit(
+                    "File",
+                    $messageObject->dataObjectPackage,
+                    null,
+                    $attachment->id,
+                    "res_" . $attachment->id,
+                    null
+                );
+            } else {
+                if (!isset($attachment->retentionRule)) {
+                    $attachment->retentionRule = $messageObject->dataObjectPackage->retentionRule;
+                    $attachment->retentionFinalDisposition = $messageObject->dataObjectPackage->retentionFinalDisposition;
+                }
+
+                $seda2Message->DataObjectPackage->DescriptiveMetadata->ArchiveUnit[0]->ArchiveUnit[] = self::getArchiveUnit(
+                    $attachment->type,
+                    $attachment,
+                    null,
+                    $attachment->id,
+                    "res_" . $attachment->id,
+                    null
+                );
+            }
+        }
+
+        // TODO : Externaliser la fonction de création du xml final
         $DOMTemplate = new \DOMDocument();
         $DOMTemplate->load('modules/export_seda/resources/'.$type.'.xml');
         $DOMTemplateProcessor = new DOMTemplateProcessorController($DOMTemplate);
-        $DOMTemplateProcessor->setSource($type, $messageObject);
+        $DOMTemplateProcessor->setSource($type, $seda2Message);
         $DOMTemplateProcessor->merge();
         $DOMTemplateProcessor->removeEmptyNodes();
 
-        $tmpPath = CoreConfigModel::getTmpPath();
-        file_put_contents($tmpPath . $messageObject->MessageIdentifier->value . ".xml", $DOMTemplate->saveXML());
-
-        if ($messageObject->DataObjectPackage) {
-            foreach ($messageObject->DataObjectPackage->BinaryDataObject as $binaryDataObject) {
-                $base64_decoded = base64_decode($binaryDataObject->Attachment->value);
-                $file = fopen($tmpPath . $binaryDataObject->Attachment->filename, 'w');
-                fwrite($file, $base64_decoded);
-                fclose($file);
-            }
-        }
-        $filename = self::generateZip($messageObject, $tmpPath);
+        file_put_contents($tmpPath . $seda2Message->MessageIdentifier->value . ".xml", $DOMTemplate->saveXML());
 
-        return $filename;
+        var_dump(file_get_contents($tmpPath . $seda2Message->MessageIdentifier->value . ".xml")); 
+
+        $filename = self::generateZip($seda2Message, $tmpPath);exit();
+
+        $arrayReturn = [
+            "messageObject" => $seda2Message,
+            "encodedFilePath" => $filename,
+            "messageFilename" => $seda2Message->MessageIdentifier->value
+        ];
+
+        return $arrayReturn;
     }
 
-    private static function generateZip($messageObject, $tmpPath)
+    private static function generateZip($seda2Message, $tmpPath)
     {
         $zip = new \ZipArchive();
-        $filename = $tmpPath.$messageObject->MessageIdentifier->value. ".zip";
+        $filename = $tmpPath.$seda2Message->MessageIdentifier->value. ".zip";
 
         $zip->open($filename, \ZipArchive::CREATE);
 
-        $zip->addFile($tmpPath . $messageObject->MessageIdentifier->value . ".xml", $messageObject->MessageIdentifier->value . ".xml");
+        $zip->addFile($tmpPath . $seda2Message->MessageIdentifier->value . ".xml", $seda2Message->MessageIdentifier->value . ".xml");
 
-        if ($messageObject->DataObjectPackage) {
-            foreach ($messageObject->DataObjectPackage->BinaryDataObject as $binaryDataObject) {
+        if ($seda2Message->DataObjectPackage) {
+            foreach ($seda2Message->DataObjectPackage->BinaryDataObject as $binaryDataObject) {
                 $zip->addFile($tmpPath . $binaryDataObject->Attachment->filename, $binaryDataObject->Attachment->filename);
             }
         }
 
         return $filename;
     }
+
+    private static function initMessage($messageObject)
+    {
+        $date = new \DateTime;
+        $messageObject->Date = $date->format(\DateTime::ATOM);
+        $messageObject->MessageIdentifier = new \stdClass();
+        $messageObject->MessageIdentifier->value = "";
+
+        $messageObject->TransferringAgency = new \stdClass();
+        $messageObject->TransferringAgency->Identifier = new \stdClass();
+
+        $messageObject->ArchivalAgency = new \stdClass();
+        $messageObject->ArchivalAgency->Identifier = new \stdClass();
+
+        $messageObject->ArchivalAgreement = new \stdClass();
+
+        $messageObject->DataObjectPackage = new \stdClass();
+        $messageObject->DataObjectPackage->BinaryDataObject = [];
+        $messageObject->DataObjectPackage->DescriptiveMetadata = new \stdClass();
+        $messageObject->DataObjectPackage->ManagementMetadata = new \stdClass();
+
+        return $messageObject;
+    }
+
+    private function getBinaryDataObject($filePath, $id)
+    {
+        $binaryDataObject = new \stdClass();
+
+        $pathInfo = pathinfo($filePath);
+        if ($filePath) {
+            $filename = $pathInfo["basename"];
+        }
+
+        $binaryDataObject->id = "res_" . $id;
+        $binaryDataObject->MessageDigest = new \stdClass();
+        $binaryDataObject->MessageDigest->value = hash_file('sha256', $filePath);
+        $binaryDataObject->MessageDigest->algorithm = "sha256";
+        $binaryDataObject->Size = filesize($filePath);
+
+
+        $binaryDataObject->Attachment = new \stdClass();
+        $binaryDataObject->Attachment->filename = $filename;
+
+        $binaryDataObject->FileInfo = new \stdClass();
+        $binaryDataObject->FileInfo->Filename = $filename;
+
+        $binaryDataObject->FormatIdentification = new \stdClass();
+        $binaryDataObject->FormatIdentification->MimeType = mime_content_type($filePath);
+
+        return $binaryDataObject;
+    }
+
+    private function getArchiveUnit(
+        $type,
+        $object = null,
+        $attachments = null,
+        $archiveUnitId = null,
+        $dataObjectReferenceId = null,
+        $relatedObjectReference = null
+    ) {
+        $archiveUnit = new \stdClass();
+
+        if ($archiveUnitId) {
+            $archiveUnit->id = $archiveUnitId;
+        } else {
+            $archiveUnit->id = uniqid();
+        }
+
+        if (isset($object)) {
+            if ($relatedObjectReference) {
+                $archiveUnit->Content = self::getContent($type, $object, $relatedObjectReference);
+            } else {
+                $archiveUnit->Content = self::getContent($type, $object);
+            }
+
+            $archiveUnit->Management = self::getManagement($object);
+        } else {
+            $archiveUnit->Content = self::getContent($type);
+            $archiveUnit->Management = self::getManagement();
+        }
+
+
+        if ($dataObjectReferenceId) {
+            $archiveUnit->DataObjectReference = new \stdClass();
+            if ($type == 'File') {
+                $archiveUnit->DataObjectReference->DataObjectReferenceId = $dataObjectReferenceId;
+            } elseif ($type == 'Note') {
+                $archiveUnit->DataObjectReference->DataObjectReferenceId = $dataObjectReferenceId;
+            } elseif ($type == 'Email') {
+                $archiveUnit->DataObjectReference->DataObjectReferenceId = $dataObjectReferenceId;
+            } else {
+                $archiveUnit->DataObjectReference->DataObjectReferenceId = $dataObjectReferenceId;
+            }
+
+        }
+
+        $archiveUnit->ArchiveUnit = [];
+        if ($attachments) {
+            $i = 1;
+            foreach ($attachments as $attachment) {
+                if ($attachment->res_id_master == $object->res_id) {
+                    if ($attachment->attachment_type != "signed_response") {
+                        $archiveUnit->ArchiveUnit[] = self::getArchiveUnit(
+                            "Item",
+                            $attachment,
+                            null,
+                            $archiveUnitId. '_attachment_' . $i,
+                            $attachment->res_id
+                        );
+                    }
+                }
+                $i++;
+            }
+        }
+
+        if (count($archiveUnit->ArchiveUnit) == 0) {
+            unset($archiveUnit->ArchiveUnit);
+        }
+
+        return $archiveUnit;
+    }
+
+    private function getContent($type, $object = null, $relatedObjectReference = null)
+    {
+
+        $content = new \stdClass();
+
+        switch ($type) {
+            case 'RecordGrp':
+                $content->DescriptionLevel = $type;
+                $content->Title = [];
+                if ($object) {
+                    $content->Title[] = $object->label;
+                    $content->DocumentType = 'Document Principal';
+                } else {
+                    $content->DocumentType = 'Dossier';
+                }
+                break;
+            case 'File':
+                $content->DescriptionLevel = $type;
+
+                $sentDate = new \DateTime($object->modificationDate);
+                $acquiredDate = new \DateTime($object->creationDate);
+                if ($object->documentDate) {
+                    $receivedDate = new \DateTime($object->documentDate);
+                } else {
+                    $receivedDate = new \DateTime($object->receivedDate);
+                }
+                $content->SentDate = $sentDate->format(\DateTime::ATOM);
+                $content->ReceivedDate = $receivedDate->format(\DateTime::ATOM);
+                $content->AcquiredDate = $acquiredDate->format(\DateTime::ATOM);
+
+                $content->Addressee = [];
+                $content->Sender = [];
+                $content->Keyword = [];
+
+                if ($object->contacts) {
+                    foreach($object->contacts as $contactType => $contacts) {
+                        foreach($contacts as $contact) {
+                            if ($contactType == "senders") {
+                                $content->Sender[] = self::getAddresse($contact, $contactType);
+                            } else if ($contactType == "recipients") {
+                                $content->Addressee[] = self::getAddresse($contact, $contactType);
+                            }
+                            
+                        }
+                    }
+                }
+
+                if ($object->folders ) {
+                    $content->FilePlanPosition = [];
+                    $content->FilePlanPosition[] = new \stdClass;
+                    $content->FilePlanPosition[0]->value="";
+                    foreach($object->folders as $folder) {
+                        $content->FilePlanPosition[0]->value .= "/".$folder;
+                    }
+                }
+
+                if (!empty($keyword)) {
+                    $content->Keyword[] = $keyword;
+                }
+
+                if (!empty($addressee)) {
+                    $content->Addressee[] = $addressee;
+                }
+
+                $content->DocumentType = 'Document Principal';
+                $content->OriginatingAgencyArchiveUnitIdentifier = $object->chrono;
+                $content->OriginatingSystemId = $object->originatingSystemId;
+
+                $content->Title = [];
+                $content->Title[] = $object->label;
+                break;
+            case 'Item':
+            case 'attachment':
+            case 'response':
+            case 'note':
+            case 'email':
+            case 'summarySheet':
+                $content->DescriptionLevel = "Item";
+                $content->Title = [];
+                $content->Title[] = $object->label;
+
+                if ($type == "attachment") {
+                    $content->DocumentType = "Pièce jointe";
+                    $date = new \DateTime($object->creation_date);
+                    $content->CreatedDate = $date->format('Y-m-d');
+                } elseif ($type == "note") {
+                    $content->DocumentType = "Note";
+                    $date = new \DateTime($object->creation_date);
+                    $content->CreatedDate = $date->format('Y-m-d');
+                } elseif ($type == "email") {
+                    $content->DocumentType = "Courriel";
+                    $date = new \DateTime($object->creation_date);
+                    $content->CreatedDate = $date->format('Y-m-d');
+                } elseif ($type == "response") {
+                    $content->DocumentType = "Réponse";
+                    $date = new \DateTime($object->creation_date);
+                    $content->CreatedDate = $date->format('Y-m-d');
+                } elseif ($type == "summarySheet") {
+                    $content->DocumentType = "Fiche de liaison";
+                    $date = new \DateTime($object->creation_date);
+                    $content->CreatedDate = $date->format('Y-m-d');
+                }
+                break;
+        }
+
+        if (isset($relatedObjectReference)) {
+            $content->RelatedObjectReference = new \stdClass();
+            $content->RelatedObjectReference->References = [];
+
+            foreach ($relatedObjectReference as $key => $value) {
+                $reference = new \stdClass();
+                if ($value) {
+                    $reference->ArchiveUnitRefId = 'letterbox_' . $key;
+                    $content->RelatedObjectReference->References[] = $reference;
+                } else {
+                    if (isset($destination)) {
+                        $res = array_key_exists($destination, self::entities);
+                        $reference->RepositoryArchiveUnitPID = 'originator:' . $entity->business_id . ':' . $key;
+                        $content->RelatedObjectReference->References[] = $reference;
+                    }
+                }
+            }
+
+        }
+
+        if (isset($object->originatorAgency)) {
+            $content->OriginatingAgency = new \stdClass();
+            $content->OriginatingAgency->Identifier = new \stdClass();
+            $content->OriginatingAgency->Identifier->value = $object->originatorAgency->id;
+
+            if (empty($content->OriginatingAgency->Identifier->value)) {
+                unset($content->OriginatingAgency);
+            }
+        }
+
+        if (isset($object->history)) {
+            $content->CustodialHistory = new \stdClass();
+            $content->CustodialHistory->CustodialHistoryItem = [];
+            foreach($object->history as $history) {
+                $content->CustodialHistory->CustodialHistoryItem[] = self::getCustodialHistoryItem($history);
+            }
+
+            if (count($content->CustodialHistory->CustodialHistoryItem) == 0) {
+                unset($content->CustodialHistory);
+            }
+        }
+
+        return $content;
+    }
+
+    private function getManagement($valueInData = null)
+    {
+        $management = new \stdClass();
+
+        $management->AppraisalRule = new \stdClass();
+        $management->AppraisalRule->Rule = new \stdClass();
+        if ($valueInData->retentionRule) {
+            $management->AppraisalRule->Rule->value = $valueInData->retentionRule;
+            $management->AppraisalRule->StartDate = date("Y-m-d");
+            if (isset($valueInData->retentionFinalDisposition) && $valueInData->retentionFinalDisposition == "Conservation") {
+                $management->AppraisalRule->FinalAction = "Keep";
+            } else {
+                $management->AppraisalRule->FinalAction = "Destroy";
+            }
+        }
+        
+        if ($valueInData->accessRuleCode) {
+            $management->AccessRule = new \stdClass();
+            $management->AccessRule->Rule = new \stdClass();
+            $management->AccessRule->Rule->value = $valueInData->accessRuleCode;
+            $management->AccessRule->StartDate = date("Y-m-d");
+        }
+
+        return $management;
+    }
+
+    private function getCustodialHistoryItem($history)
+    {
+        $date = new \DateTime($history->event_date);
+
+        $custodialHistoryItem = new \stdClass();
+        $custodialHistoryItem->value = $history->info;
+        $custodialHistoryItem->when = $date->format('Y-m-d');
+
+        return $custodialHistoryItem;
+    }
+
+    private function getAddresse($informations, $type = null)
+    {
+        $addressee = new \stdClass();
+        
+        if ($informations->civility) {
+            $addressee->Gender = $informations->civility->label;
+        }
+        if ($informations->firstname) {
+            $addressee->FirstName = $informations->firstname;
+        }
+        if ($informations->lastname) {
+            $addressee->BirthName = $informations->lastname;
+        }
+        return $addressee;
+    }
+
+
 }
diff --git a/src/app/external/exportSeda/models/AbstractMessage.php b/src/app/external/exportSeda/models/AbstractMessage.php
new file mode 100644
index 00000000000..06c915de35b
--- /dev/null
+++ b/src/app/external/exportSeda/models/AbstractMessage.php
@@ -0,0 +1,182 @@
+<?php
+
+
+namespace ExportSeda\models;
+
+use ExportSeda\controllers\RequestSeda;
+use ExportSeda\controllers\DOMTemplateProcessorController;
+
+class AbstractMessage{
+
+    private $xml;
+    private $directoryMessage;
+    public function __construct()
+    {
+        $this->db = new RequestSeda();
+
+        $getXml = false;
+        $path = '';
+        if (file_exists(
+            $_SESSION['config']['corepath'] . 'custom' . DIRECTORY_SEPARATOR
+            . $_SESSION['custom_override_id'] . DIRECTORY_SEPARATOR . 'modules'
+            . DIRECTORY_SEPARATOR . 'export_seda'. DIRECTORY_SEPARATOR . 'xml'
+            . DIRECTORY_SEPARATOR . 'config.xml'
+        )) {
+            $path = $_SESSION['config']['corepath'] . 'custom' . DIRECTORY_SEPARATOR
+                . $_SESSION['custom_override_id'] . DIRECTORY_SEPARATOR . 'modules'
+                . DIRECTORY_SEPARATOR . 'export_seda'. DIRECTORY_SEPARATOR . 'xml'
+                . DIRECTORY_SEPARATOR . 'config.xml';
+            $getXml = true;
+        } elseif (file_exists(
+            $_SESSION['config']['corepath'] . 'modules'
+            . DIRECTORY_SEPARATOR . 'export_seda'.  DIRECTORY_SEPARATOR . 'xml'
+            . DIRECTORY_SEPARATOR . 'config.xml'
+        )) {
+            $path = $_SESSION['config']['corepath'] . 'modules' . DIRECTORY_SEPARATOR . 'export_seda'
+                . DIRECTORY_SEPARATOR . 'xml' . DIRECTORY_SEPARATOR . 'config.xml';
+            $getXml = true;
+        }
+
+        if ($getXml) {
+            $this->xml = simplexml_load_file($path);
+
+            $this->directoryMessage = (string) $this->xml->CONFIG->directoryMessage;
+        }
+    }
+
+    public function generatePackage($reference, $name)
+    {
+        $message = $this->db->getMessageByReference($reference);
+        $messageObject = json_decode($message->data);
+
+        if (!is_dir($this->directoryMessage)) {
+            umask(0);
+            mkdir($this->directoryMessage, 0777, true);
+        }
+
+        if (!is_dir($this->directoryMessage . DIRECTORY_SEPARATOR . $messageObject->MessageIdentifier->value)) {
+            umask(0);
+            mkdir($this->directoryMessage . DIRECTORY_SEPARATOR . $messageObject->MessageIdentifier->value, 0777, true);
+        }
+
+        $this->sendAttachment($messageObject);
+
+        $this->saveXml($messageObject, $name, ".xml");
+    }
+
+    public function saveXml($messageObject, $name, $extension)
+    {
+        if (isset($messageObject->DataObjectPackage)) {
+            if ($messageObject->DataObjectPackage->BinaryDataObject) {
+                foreach ($messageObject->DataObjectPackage->BinaryDataObject as $binaryDataObject) {
+                    unset($binaryDataObject->Attachment->value);
+                }
+            }
+        }
+
+        $DOMTemplate = new DOMDocument();
+        $DOMTemplate->preserveWhiteSpace = false;
+        $DOMTemplate->formatOutput = true;
+        $DOMTemplate->load(__DIR__ .DIRECTORY_SEPARATOR. '..'. DIRECTORY_SEPARATOR.'resources'.DIRECTORY_SEPARATOR.$name.'.xml');
+        $DOMTemplateProcessor = new DOMTemplateProcessor($DOMTemplate);
+        $DOMTemplateProcessor->setSource($name, $messageObject);
+        $DOMTemplateProcessor->merge();
+        $DOMTemplateProcessor->removeEmptyNodes();
+
+        try {
+            if (!is_dir($this->directoryMessage)) {
+                umask(0);
+                mkdir($this->directoryMessage, 0777, true);
+            }
+
+            if (!is_dir($this->directoryMessage . DIRECTORY_SEPARATOR . $messageObject->MessageIdentifier->value)) {
+                umask(0);
+                mkdir($this->directoryMessage . DIRECTORY_SEPARATOR . $messageObject->MessageIdentifier->value, 0777, true);
+            }
+
+            if (!file_exists($this->directoryMessage . DIRECTORY_SEPARATOR.$messageObject->MessageIdentifier->value.DIRECTORY_SEPARATOR. $messageObject->MessageIdentifier->value . $extension)) {
+                $DOMTemplate->save($this->directoryMessage . DIRECTORY_SEPARATOR.$messageObject->MessageIdentifier->value.DIRECTORY_SEPARATOR. $messageObject->MessageIdentifier->value . $extension);
+            }
+
+        } catch (Exception $e) {
+            return false;
+        }
+    }
+
+    public function addAttachment($reference, $resIdMaster, $fileName, $extension, $title, $type) {
+        $db = new RequestSeda();
+        $object = new stdClass();
+        $dir =  $this->directoryMessage . DIRECTORY_SEPARATOR . $reference . DIRECTORY_SEPARATOR;
+
+        $object->tmpDir = $dir;
+        $object->size = filesize($dir);
+        $object->format = $extension;
+        $object->tmpFileName = $fileName;
+        $object->title = $title;
+        $object->attachmentType = "simple_attachment";
+        $object->resIdMaster = $resIdMaster;
+
+        return $db->insertAttachment($object, $type);
+    }
+
+    private function sendAttachment($messageObject)
+    {
+        $messageId = $messageObject->MessageIdentifier->value;
+
+        foreach ($messageObject->DataObjectPackage->BinaryDataObject as $binaryDataObject) {
+            $dest = $this->directoryMessage . DIRECTORY_SEPARATOR . $messageId . DIRECTORY_SEPARATOR . $binaryDataObject->Attachment->filename;
+
+            if (!file_exists($dest)) {
+                copy($binaryDataObject->Uri, $dest);
+
+                unset($binaryDataObject->Uri);
+            }
+        }
+
+        $this->db->updateDataMessage($messageObject->MessageIdentifier->value, json_encode($messageObject));
+    }
+
+    public function addTitleToMessage($reference, $title = ' ')
+    {
+        $message = $this->db->getMessageByReference($reference);
+
+        $messageObject = json_decode($message->data);
+
+        $messageObject->DataObjectPackage->DescriptiveMetadata->ArchiveUnit[0]->Content->Title[0] = $title;
+
+        $this->db->updateDataMessage($reference, json_encode($messageObject));
+
+        return true;
+    }
+
+    public function changeStatus($reference, $status)
+    {
+        $message = $this->db->getMessageByReference($reference);
+        $listResId = $this->db->getUnitIdentifierByMessageId($message->message_id);
+
+        for ($i=0; $i < count($listResId); $i++) {
+            $this->db->updateStatusLetterbox($listResId[$i]->res_id, $status);
+        }
+
+        return true;
+    }
+
+    public function createPDF($name, $body)
+    {
+        $pdf = new PDF("p", "pt", "A4");
+        $pdf->SetAuthor("MAARCH");
+        $pdf->SetTitle($name);
+
+        $pdf->SetFont('times', '', 12);
+        $pdf->SetTextColor(50, 60, 100);
+
+        $pdf->AddPage('P');
+
+        $pdf->SetAlpha(1);
+
+        $pdf->MultiCell(0, 10, utf8_decode($body), 0, 'L');
+
+        $dir = $_SESSION['config']['tmppath'] . $name . '.pdf';
+        $pdf->Output($dir, "F");
+    }
+}
diff --git a/src/app/external/exportSeda/models/Acknowledgement.php b/src/app/external/exportSeda/models/Acknowledgement.php
new file mode 100644
index 00000000000..a4546c8bf9d
--- /dev/null
+++ b/src/app/external/exportSeda/models/Acknowledgement.php
@@ -0,0 +1,137 @@
+<?php
+
+/*
+*   Copyright 2008-2017 Maarch
+*
+*   This file is part of Maarch Framework.
+*
+*   Maarch Framework is free software: you can redistribute it and/or modify
+*   it under the terms of the GNU General Public License as published by
+*   the Free Software Foundation, either version 3 of the License, or
+*   (at your option) any later version.
+*
+*   Maarch Framework is distributed in the hope that it will be useful,
+*   but WITHOUT ANY WARRANTY; without even the implied warranty of
+*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*   GNU General Public License for more details.
+*
+*   You should have received a copy of the GNU General Public License
+*   along with Maarch Framework.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+require_once __DIR__ . DIRECTORY_SEPARATOR .'../DOMTemplateProcessor.php';
+require_once __DIR__ . '/AbstractMessage.php';
+
+class Acknowledgement {
+
+	public function __construct()
+	{
+	}
+
+	public function receive($data, $resIds)
+	{
+	    $messageObject = $this->getMessageObject($data);
+	    $abstractMessage = new AbstractMessage();
+        $abstractMessage->saveXml($messageObject,"Acknowledgement", ".xml");
+
+		foreach ($resIds as $resId) {
+            $abstractMessage->addAttachment($messageObject->MessageIdentifier->value, $resId, $messageObject->MessageIdentifier->value.".xml", "xml", "Accusé de réception",1);
+        }
+
+        return $messageObject;
+	}
+
+    private function getMessageObject($data)
+    {
+        $messageObject = new stdClass();
+
+        $messageObject->Comment = $data->comment;
+        $messageObject->Date = $data->date;
+        $messageObject->MessageIdentifier = $data->messageIdentifier;
+        $messageObject->MessageReceivedIdentifier = $data->messageReceivedIdentifier;
+
+        $messageObject->Receiver = $this->getOrganisation($data->receiver);
+        $messageObject->Sender = $this->getOrganisation($data->sender);
+
+        return $messageObject;
+    }
+
+    private function getOrganisation($data)
+    {
+        $organisationObject = new stdClass();
+        $organisationObject->Identifier = new stdClass();
+        $organisationObject->Identifier->value = $data->id;
+
+        $organisationObject->OrganizationDescriptiveMetadata = new stdClass();
+        $organisationObject->OrganizationDescriptiveMetadata->Name = $data->name;
+        $organisationObject->OrganizationDescriptiveMetadata->LegalClassification = $data->legalClassification;
+
+        if ($data->address) {
+            $organisationObject->OrganizationDescriptiveMetadata->Address = $this->getAddress($data->address);
+        }
+
+        if ($data->communication) {
+            $organisationObject->OrganizationDescriptiveMetadata->Communication = $this->getCommunication($data->communication);
+        }
+
+        if ($data->contact) {
+            $organisationObject->OrganizationDescriptiveMetadata->Contact = $this->getContact($data->contact);
+        }
+
+        return $organisationObject;
+    }
+
+    private function getContact($data)
+    {
+        $listContact = [];
+        foreach ($data as $contact) {
+            $tmpContact =  new stdClass();
+            $tmpContact->DepartmentName = $contact->departmentName;
+            $tmpContact->PersonName = $contact->personName;
+
+            if ($contact->address){
+                $tmpContact->Address = [];
+                $tmpContact->Address = $this->getAddress($contact->address);
+            }
+
+            if ($contact->communication) {
+                $tmpContact->Communication = [];
+                $tmpContact->Communication = $this->getCommunication($contact->communication);
+            }
+            $listContact[] = $tmpContact;
+        }
+        return $listContact;
+    }
+
+    private function getAddress($data)
+    {
+	    $listAddress = [];
+        foreach ($data as $address) {
+            $tmpAddress = new stdClass();
+            $tmpAddress->CityName = $address->cityName;
+            $tmpAddress->Country = $address->country;
+            $tmpAddress->PostCode = $address->postCode;
+            $tmpAddress->StreetName = $address->streetName;
+
+            $listAddress[] = $tmpAddress;
+        }
+        return $listAddress;
+    }
+
+    private function getCommunication($data)
+    {
+        $listCommunication = [];
+        foreach ($data as $communication) {
+            $tmpCommunication = new stdClass();
+            $tmpCommunication->Channel = $communication->channel;
+
+            if ($communication->completeNumber) {
+                $tmpCommunication->value = $communication->completeNumber;
+            } else {
+                $tmpCommunication->value = $communication->URIID;
+            }
+            $listCommunication[] = $tmpCommunication;
+        }
+        return $listCommunication;
+    }
+}
diff --git a/src/app/external/exportSeda/models/ArchiveTransfer.php b/src/app/external/exportSeda/models/ArchiveTransfer.php
new file mode 100644
index 00000000000..87de4f2a7a5
--- /dev/null
+++ b/src/app/external/exportSeda/models/ArchiveTransfer.php
@@ -0,0 +1,876 @@
+<?php
+
+/*
+*   Copyright 2008-2017 Maarch
+*
+*   This file is part of Maarch Framework.
+*
+*   Maarch Framework is free software: you can redistribute it and/or modify
+*   it under the terms of the GNU General Public License as published by
+*   the Free Software Foundation, either version 3 of the License, or
+*   (at your option) any later version.
+*
+*   Maarch Framework is distributed in the hope that it will be useful,
+*   but WITHOUT ANY WARRANTY; without even the implied warranty of
+*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*   GNU General Public License for more details.
+*
+*   You should have received a copy of the GNU General Public License
+*   along with Maarch Framework.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+require_once __DIR__ . DIRECTORY_SEPARATOR .'../RequestSeda.php';
+require_once __DIR__ . DIRECTORY_SEPARATOR .'../DOMTemplateProcessor.php';
+require_once __DIR__ . '/AbstractMessage.php';
+
+class ArchiveTransfer
+{
+    private $db;
+    private $abstractMessage;
+    private $externalLink;
+    private $xml;
+    protected $entities;
+
+    public function __construct()
+    {
+        $this->db = new RequestSeda();
+        $this->abstractMessage = new AbstractMessage();
+        $_SESSION['error'] = "";
+
+        $getXml = false;
+        $path = '';
+        if (file_exists(
+            $_SESSION['config']['corepath'] . 'custom' . DIRECTORY_SEPARATOR
+            . $_SESSION['custom_override_id'] . DIRECTORY_SEPARATOR . 'modules'
+            . DIRECTORY_SEPARATOR . 'export_seda'. DIRECTORY_SEPARATOR . 'xml'
+            . DIRECTORY_SEPARATOR . 'config.xml'
+        )) {
+            $path = $_SESSION['config']['corepath'] . 'custom' . DIRECTORY_SEPARATOR
+                . $_SESSION['custom_override_id'] . DIRECTORY_SEPARATOR . 'modules'
+                . DIRECTORY_SEPARATOR . 'export_seda'. DIRECTORY_SEPARATOR . 'xml'
+                . DIRECTORY_SEPARATOR . 'config.xml';
+            $getXml = true;
+        } elseif (file_exists(
+            $_SESSION['config']['corepath'] . 'modules'
+            . DIRECTORY_SEPARATOR . 'export_seda'.  DIRECTORY_SEPARATOR . 'xml'
+            . DIRECTORY_SEPARATOR . 'config.xml'
+        )) {
+            $path = $_SESSION['config']['corepath'] . 'modules' . DIRECTORY_SEPARATOR . 'export_seda'
+                . DIRECTORY_SEPARATOR . 'xml' . DIRECTORY_SEPARATOR . 'config.xml';
+            $getXml = true;
+        }
+
+        if ($getXml) {
+            $this->xml = simplexml_load_file($path);
+        }
+
+        $this->entities = [];
+    }
+
+    public function receive($listResId)
+    {
+        if (!$listResId) {
+            return false;
+        }
+
+        $messageObject = new stdClass();
+        $messageObject = $this->initMessage($messageObject);
+
+        if (!empty($_SESSION['error'])) {
+            return;
+        }
+
+        $messageObject->DataObjectPackage->DescriptiveMetadata->ArchiveUnit[] = $this->getArchiveUnit(
+            "RecordGrp",
+            null,
+            null,
+            'group_1',
+            null,
+            null
+        );
+
+        $result = $startDate = $endDate = '';
+        $i = 1;
+        foreach ($listResId as $resId) {
+            $this->externalLink = false;
+
+            if (!empty($result)) {
+                $result .= ',';
+            }
+            $result .= $resId;
+
+            $letterbox = $this->db->getLetter($resId);
+            $attachments = $this->db->getAttachments($letterbox->res_id);
+            $notes = $this->db->getNotes($letterbox->res_id);
+            $mails = $this->db->getMails($letterbox->res_id);
+            $links = $this->db->getLinks($letterbox->res_id);
+
+            $relatedObjectReference = [];
+            if (is_array($links)) {
+                foreach ($links as $link) {
+                    if (!array_search($link, $listResId)) {
+                        $relatedObjectReference[$link] = false;
+                    } else {
+                        $relatedObjectReference[$link] = true;
+                    }
+                }
+            } else {
+                if (!array_search($links, $listResId)) {
+                    $relatedObjectReference[$links] = false;
+                } else {
+                    $relatedObjectReference[$links] = true;
+                }
+            }
+
+            $archiveUnitId = 'letterbox_' . $resId;
+            if ($letterbox->filename) {
+                $docServers = $this->db->getDocServer($letterbox->docserver_id);
+                $uri = str_replace("##", DIRECTORY_SEPARATOR, $letterbox->path);
+                $uri = str_replace("#", DIRECTORY_SEPARATOR, $uri);
+                $uri .= $letterbox->filename;
+                $filePath = $docServers->path_template . $uri;
+
+                if (!file_exists($filePath)) {
+                    $_SESSION['error'] = _ERROR_FILE_NOT_EXIST;
+                    return;
+                }
+
+                $messageObject->DataObjectPackage->DescriptiveMetadata->ArchiveUnit[0]->ArchiveUnit[] = $this->getArchiveUnit(
+                    "File",
+                    $letterbox,
+                    $attachments,
+                    $archiveUnitId,
+                    $letterbox->res_id,
+                    $relatedObjectReference
+                );
+
+                $messageObject->DataObjectPackage->BinaryDataObject[] = $this->getBinaryDataObject(
+                    $filePath,
+                    $_SESSION['collections'][0]['table'] . '_' . $letterbox->res_id
+                );
+            } else {
+                $messageObject->DataObjectPackage->DescriptiveMetadata->ArchiveUnit[0]->ArchiveUnit[] = $this->getArchiveUnit(
+                    "File",
+                    $letterbox,
+                    null,
+                    null,
+                    null,
+                    $relatedObjectReference
+                );
+            }
+
+            if ($attachments) {
+                $j = 1;
+                foreach ($attachments as $attachment) {
+                    $docServers = $this->db->getDocServer($attachment->docserver_id);
+
+                    $uri = str_replace("##", DIRECTORY_SEPARATOR, $attachment->path);
+                    $uri = str_replace("#", DIRECTORY_SEPARATOR, $uri);
+                    $uri .= $attachment->filename;
+
+                    $filePath = $docServers->path_template . $uri;
+                    if ($attachment->attachment_type == "signed_response") {
+                        $messageObject->DataObjectPackage->DescriptiveMetadata->ArchiveUnit[0]->ArchiveUnit[] = $this->getArchiveUnit(
+                            "Response",
+                            $attachment,
+                            null,
+                            'attachment_'. $i. '_'. $j,
+                            "response_" . $attachment->res_id
+//                            $archiveUnitId
+                        );
+
+                        $messageObject->DataObjectPackage->BinaryDataObject[] = $this->getBinaryDataObject(
+                            $filePath,
+                            $_SESSION['collections'][1]['table'] . '_'.  $attachment->res_id
+                        );
+                        $j++;
+                    } else {
+                        $messageObject->DataObjectPackage->BinaryDataObject[] = $this->getBinaryDataObject(
+                            $filePath,
+                            $_SESSION['collections'][1]['table']. '_'.  $attachment->res_id
+                        );
+                    }
+                }
+            }
+
+            if ($notes) {
+                foreach ($notes as $note) {
+                    $id = 'note_'.$note->id;
+                    $filePath = $_SESSION['config']['tmppath']. DIRECTORY_SEPARATOR. $id. '.pdf';
+
+                    $this->abstractMessage->createPDF($id, $note->note_text);
+                    $messageObject->DataObjectPackage->BinaryDataObject[] = $this->getBinaryDataObject($filePath, $id);
+                }
+            }
+
+            if ($mails) {
+                foreach ($mails as $mail) {
+                    $id = 'email_'.$mail->email_id;
+                    $filePath = $_SESSION['config']['tmppath']. DIRECTORY_SEPARATOR. $id. '.pdf';
+                    $body = str_replace('###', ';', $mail->email_body);
+                    $data = 'email n°' . $mail->email_id . '
+' .'de ' . $mail->sender_email . '
+' . 'à ' . $mail->to_list . '
+' . 'objet : ' . $mail->email_object . '
+' . 'corps : ' . strip_tags(html_entity_decode($body));
+
+                    $this->abstractMessage->createPDF($id, $data);
+                    $messageObject->DataObjectPackage->BinaryDataObject[] = $this->getBinaryDataObject($filePath, $id);
+                }
+            }
+
+            $format = 'Y-m-d H:i:s.u';
+            $creationDate = DateTime::createFromFormat($format, $letterbox->creation_date);
+            if ($startDate == '') {
+                $startDate = $creationDate;
+            } elseif ( date_diff($startDate, $creationDate) > 0 ) {
+                $startDate = $creationDate;
+            }
+
+            $modificationDate = DateTime::createFromFormat($format, $letterbox->modification_date);
+            if ($endDate == '') {
+                $endDate = $modificationDate;
+            } elseif ( date_diff($endDate, $modificationDate) < 0) {
+                $endDate = $modificationDate;
+            }
+
+            $i++;
+        }
+
+        $originator = "";
+        foreach ($messageObject->DataObjectPackage->DescriptiveMetadata->ArchiveUnit[0]->ArchiveUnit as $archiveUnit) {
+            if (!empty($archiveUnit->Content->OriginatingAgency->Identifier->value)) {
+                $originator = $archiveUnit->Content->OriginatingAgency->Identifier->value;
+                break;
+            }
+        }
+
+        if (!empty($originator)) {
+            $messageObject->DataObjectPackage->DescriptiveMetadata->ArchiveUnit[0]->Content->OriginatingAgency = new stdClass();
+            $messageObject->DataObjectPackage->DescriptiveMetadata->ArchiveUnit[0]->Content->OriginatingAgency->Identifier = new stdClass();
+            $messageObject->DataObjectPackage->DescriptiveMetadata->ArchiveUnit[0]->Content->OriginatingAgency->Identifier->value = $messageObject->DataObjectPackage->DescriptiveMetadata->ArchiveUnit[0]->ArchiveUnit[0]->Content->OriginatingAgency->Identifier->value;
+        } else {
+            $_SESSION['error'] = _ERROR_ORIGINATOR_EMPTY;
+        }
+
+        $messageObject->DataObjectPackage->DescriptiveMetadata->ArchiveUnit[0]->Content->StartDate = $startDate->format('Y-m-d');
+        $messageObject->DataObjectPackage->DescriptiveMetadata->ArchiveUnit[0]->Content->EndDate = $endDate->format('Y-m-d');
+
+        $messageSaved = $this->saveMessage($messageObject);
+
+        foreach ($listResId as $resId) {
+            $this->db->insertUnitIdentifier($messageSaved['messageId'], "res_letterbox", $resId);
+        }
+
+        return $result;
+    }
+
+    public function deleteMessage($listResId)
+    {
+        if (!$listResId) {
+            return false;
+        }
+
+        $resIds = [];
+        if (!is_array($listResId)) {
+            $resIds[] = $listResId;
+        } else {
+            $resIds = $listResId;
+        }
+
+
+        foreach ($resIds as $resId) {
+            $unitIdentifier = $this->db->getUnitIdentifierByResId($resId);
+            $this->db->deleteMessage($unitIdentifier->message_id);
+            $this->db->deleteUnitIdentifier($resId);
+        }
+
+        return true;
+    }
+
+    private function saveMessage($messageObject)
+    {
+        $data = new stdClass();
+
+        $data->messageId                             = $messageObject->MessageIdentifier->value;
+        $data->date                                  = $messageObject->Date;
+
+        $data->MessageIdentifier                     = new stdClass();
+        $data->MessageIdentifier->value              = $messageObject->MessageIdentifier->value;
+
+        $data->TransferringAgency                    = new stdClass();
+        $data->TransferringAgency->Identifier        = new stdClass();
+        $data->TransferringAgency->Identifier->value = $messageObject->TransferringAgency->Identifier->value;
+
+        $data->ArchivalAgency                        = new stdClass();
+        $data->ArchivalAgency->Identifier            = new stdClass();
+        $data->ArchivalAgency->Identifier->value     = $messageObject->ArchivalAgency->Identifier->value;
+
+        $data->ArchivalAgreement                     = new stdClass();
+        $data->ArchivalAgreement->value              = $messageObject->ArchivalAgreement->value;
+
+        $data->ReplyCode                             = $messageObject->ReplyCode;
+
+        $aArgs                                       = [];
+        $aArgs['fullMessageObject']                  = $messageObject;
+        $aArgs['SenderOrgNAme']                      = "";
+        $aArgs['RecipientOrgNAme']                   = "";
+
+        $messageId = $this->db->insertMessage($data, "ArchiveTransfer", $aArgs);
+
+        return $messageId;
+    }
+
+    private function initMessage($messageObject)
+    {
+
+        $this->directoryMessage = (string) $this->xml->CONFIG->directoryMessage;
+
+        if (!$this->directoryMessage || !is_dir($this->directoryMessage)) {
+            $_SESSION['error'] .= _DIRECTORY_MESSAGE_REQUIRED;
+            return;
+        }
+
+        $date = new DateTime;
+        $messageObject->Date = $date->format(DateTime::ATOM);
+        $messageObject->MessageIdentifier = new stdClass();
+        $messageObject->MessageIdentifier->value = $_SESSION['user']['UserId'] . "-" . date('Ymd-His');
+
+        $messageObject->TransferringAgency = new stdClass();
+        $messageObject->TransferringAgency->Identifier = new stdClass();
+
+        $messageObject->ArchivalAgency = new stdClass();
+        $messageObject->ArchivalAgency->Identifier = new stdClass();
+
+        $messageObject->ArchivalAgreement = new stdClass();
+
+        foreach ($_SESSION['user']['entities'] as $entity) {
+            $res = array_key_exists($entity['ENTITY_ID'], $this->entities);
+            if ($res === false) {
+                $this->entities[$entity['ENTITY_ID']] = $entity = $this->db->getEntity($entity['ENTITY_ID']);
+            } else {
+                $entity = $this->entities[$entity['ENTITY_ID']];
+            }
+
+            if ($entity) {
+                if (!(string) $this->xml->CONFIG->senderOrgRegNumber) {
+                    $_SESSION['error'] .= _TRANSFERRING_AGENCY_SIREN_REQUIRED;
+                }
+
+                if (!$entity->archival_agency) {
+                    $_SESSION['error'] .= _ARCHIVAL_AGENCY_SIREN_REQUIRED;
+                }
+
+                if (!$entity->archival_agreement) {
+                    $_SESSION['error'] .= _ARCHIVAL_AGREEMENT_REQUIRED;
+                }
+
+                if (!empty($_SESSION['error'])) {
+                    return;
+                }
+
+                $messageObject->TransferringAgency->Identifier->value = (string) $this->xml->CONFIG->senderOrgRegNumber;
+                $messageObject->ArchivalAgency->Identifier->value = $entity->archival_agency;
+                $messageObject->ArchivalAgreement->value = $entity->archival_agreement;
+            } else {
+                $_SESSION['error'] .= _NO_ENTITIES;
+            }
+        }
+
+        $messageObject->DataObjectPackage = new stdClass();
+        $messageObject->DataObjectPackage->BinaryDataObject = [];
+        $messageObject->DataObjectPackage->DescriptiveMetadata = new stdClass();
+        $messageObject->DataObjectPackage->ManagementMetadata = new stdClass();
+
+        return $messageObject;
+    }
+
+    private function getArchiveUnit(
+        $type,
+        $object = null,
+        $attachments = null,
+        $archiveUnitId = null,
+        $dataObjectReferenceId = null,
+        $relatedObjectReference = null
+    ) {
+        $archiveUnit = new stdClass();
+
+        if ($archiveUnitId) {
+            $archiveUnit->id = $archiveUnitId;
+        } else {
+            $archiveUnit->id = uniqid();
+        }
+
+        if (isset($object)) {
+            if ($relatedObjectReference) {
+                $archiveUnit->Content = $this->getContent($type, $object, $relatedObjectReference);
+            } else {
+                $archiveUnit->Content = $this->getContent($type, $object);
+            }
+
+            $archiveUnit->Management = $this->getManagement($object);
+        } else {
+            $archiveUnit->Content = $this->getContent($type);
+            $archiveUnit->Management = $this->getManagement();
+        }
+
+
+        if ($dataObjectReferenceId) {
+            $archiveUnit->DataObjectReference = new stdClass();
+            if ($type == 'File') {
+                $archiveUnit->DataObjectReference->DataObjectReferenceId = $_SESSION['collections'][0]['table'] . '_' .$dataObjectReferenceId;
+            } elseif ($type == 'Note') {
+                $archiveUnit->DataObjectReference->DataObjectReferenceId = 'note_' .$dataObjectReferenceId;
+            } elseif ($type == 'Email') {
+                $archiveUnit->DataObjectReference->DataObjectReferenceId = 'email_' .$dataObjectReferenceId;
+            } else {
+                $archiveUnit->DataObjectReference->DataObjectReferenceId = $_SESSION['collections'][1]['table'] . '_' .$dataObjectReferenceId;
+            }
+
+        }
+
+        $archiveUnit->ArchiveUnit = [];
+        if ($attachments) {
+            $i = 1;
+            foreach ($attachments as $attachment) {
+                if ($attachment->res_id_master == $object->res_id) {
+                    if ($attachment->attachment_type != "signed_response") {
+                        $archiveUnit->ArchiveUnit[] = $this->getArchiveUnit(
+                            "Item",
+                            $attachment,
+                            null,
+                            $archiveUnitId. '_attachment_' . $i,
+                            $attachment->res_id
+                        );
+                    }
+                }
+                $i++;
+            }
+        }
+
+        if ($object->res_id) {
+            if ($type != 'Note' && $type != 'Email') {
+                $notes = $this->db->getNotes($object->res_id);
+                if ($notes) {
+                    $i = 1;
+                    foreach ($notes as $note) {
+                        $note->title = 'Note n° ' . $note->id;
+                        $archiveUnit->ArchiveUnit[] = $this->getArchiveUnit(
+                            "Note",
+                            $note,
+                            null,
+                            $archiveUnitId . '_note_' . $i,
+                            $note->id
+                        );
+                        $i++;
+                    }
+                }
+            }
+
+            if ($type != 'Email' && $type != 'Note') {
+                $emails = $this->db->getMails($object->res_id);
+                if ($emails) {
+                    $i = 1;
+                    foreach ($emails as $email) {
+                        $email->title = 'Email n° ' . $email->email_id;
+                        $archiveUnit->ArchiveUnit[] = $this->getArchiveUnit(
+                            "Email",
+                            $email,
+                            null,
+                            $archiveUnitId . '_email_' . $i,
+                            $email->email_id
+                        );
+                        $i++;
+                    }
+                }
+            }
+        }
+        if (count($archiveUnit->ArchiveUnit) == 0) {
+            unset($archiveUnit->ArchiveUnit);
+        }
+
+        return $archiveUnit;
+    }
+
+    private function getContent($type, $object = null, $relatedObjectReference = null)
+    {
+
+        $content = new stdClass();
+
+        switch ($type) {
+            case 'RecordGrp':
+                $content->DescriptionLevel = $type;
+                $content->Title = [];
+                $content->DocumentType = 'Dossier';
+
+                return $content;
+                break;
+            case 'File':
+                $content->DescriptionLevel = $type;
+
+                $sentDate = new DateTime($object->doc_date);
+                $receivedDate = new DateTime($object->admission_date);
+                $acquiredDate = new DateTime($object->creaction_date);
+                $content->SentDate = $sentDate->format(DateTime::ATOM);
+                $content->ReceivedDate = $receivedDate->format(DateTime::ATOM);
+                $content->AcquiredDate = $acquiredDate->format(DateTime::ATOM);
+
+                $content->Addressee = [];
+                $content->Keyword = [];
+
+                $keyword = $addressee = $entity = "";
+
+                if ($object->destination) {
+                    $res = array_key_exists($object->destination, $this->entities);
+                    if ($res === false) {
+                        $this->entities[$object->destination] = $entity = $this->db->getEntity($object->destination);
+                    } else {
+                        $entity = $this->entities[$object->destination];
+                    }
+                }
+
+                if ($object->exp_contact_id) {
+                    $contact = $this->db->getContact($object->exp_contact_id);
+                    $keyword = $this->getKeyword($contact);
+                    $addressee = $this->getAddresse($entity, "entity");
+                } elseif ($object->dest_contact_id) {
+                    $contact = $this->db->getContact($object->dest_contact_id);
+                    $addressee = $this->getAddresse($contact);
+                    $keyword = $this->getKeyword($entity, "entity");
+                } elseif ($object->exp_user_id) {
+                    $user = $this->db->getUserInformation($object->exp_user_id);
+                    $keyword = $this->getKeyword($user);
+                    $addressee = $this->getAddresse($entity, "entity");
+                }
+
+                if (!empty($keyword)) {
+                    $content->Keyword[] = $keyword;
+                }
+
+                if (!empty($addressee)) {
+                    $content->Addressee[] = $addressee;
+                }
+
+                $content->Source = '';
+
+                $content->DocumentType = $object->type_label;
+                $content->OriginatingAgencyArchiveUnitIdentifier = $object->alt_identifier;
+                $content->OriginatingSystemId = $object->res_id;
+
+                $content->Title = [];
+                $content->Title[] = $object->subject;
+                break;
+            case 'Item':
+            case 'Attachment':
+            case 'Response':
+            case 'Note':
+            case 'Email':
+                $content->DescriptionLevel = "Item";
+                $content->Title = [];
+                $content->Title[] = $object->title;
+
+                if ($type == "Item") {
+                    $content->DocumentType = "Pièce jointe";
+                    $date = new DateTime($object->creation_date);
+                    $content->CreatedDate = $date->format('Y-m-d');
+                } elseif ($type == "Note") {
+                    $content->DocumentType = "Note";
+                    $date = new DateTime($object->creation_date);
+                    $content->CreatedDate = $date->format('Y-m-d');
+                } elseif ($type == "Email") {
+                    $content->DocumentType = "Courriel";
+                    $date = new DateTime($object->creation_date);
+                    $content->CreatedDate = $date->format('Y-m-d');
+                } elseif ($type == "Response") {
+                    $content->DocumentType = "Réponse";
+                    $date = new DateTime($object->creation_date);
+                    $content->CreatedDate = $date->format('Y-m-d');
+                }
+
+                break;
+        }
+
+        if (isset($relatedObjectReference)) {
+            $content->RelatedObjectReference = new stdClass();
+            $content->RelatedObjectReference->References = [];
+
+            foreach ($relatedObjectReference as $key => $value) {
+                $reference = new stdClass();
+                if ($value) {
+                    $reference->ArchiveUnitRefId = 'letterbox_' . $key;
+                    $content->RelatedObjectReference->References[] = $reference;
+                } else {
+                    $destination = $this->db->getDestinationLetter($key);
+                    if (isset($destination)) {
+                        $res = array_key_exists($destination, $this->entities);
+                        if ($res === false) {
+                            $this->entities[$destination] = $entity = $this->db->getEntity($destination);
+                        } else {
+                            $entity = $this->entities[$destination];
+                        }
+
+                        $reference->RepositoryArchiveUnitPID = 'originator:' . $entity->business_id . ':' . $key;
+                        $content->RelatedObjectReference->References[] = $reference;
+                    }
+                }
+            }
+
+        }
+
+        if (isset($object->destination)) {
+            $content->OriginatingAgency = new stdClass();
+            $content->OriginatingAgency->Identifier = new stdClass();
+
+            $res = array_key_exists($object->destination, $this->entities);
+            if ($res === false) {
+                $this->entities[$object->destination] = $entity = $this->db->getEntity($object->destination);
+            } else {
+                $entity = $this->entities[$object->destination];
+            }
+            $content->OriginatingAgency->Identifier->value = $entity->business_id;
+
+            if (empty($content->OriginatingAgency->Identifier->value)) {
+                unset($content->OriginatingAgency);
+            }
+        }
+
+        if (isset($object->res_id)) {
+            $content->CustodialHistory = new stdClass();
+            $content->CustodialHistory->CustodialHistoryItem = [];
+
+            $histories = $this->db->getHistory($_SESSION['collections'][0]['view'], $object->res_id);
+            foreach ($histories as $history) {
+                if ($history->event_type != 'VIEW') {
+                    $content->CustodialHistory->CustodialHistoryItem[] = $this->getCustodialHistoryItem($history);
+                }
+            }
+
+            if (count($content->CustodialHistory->CustodialHistoryItem) == 0) {
+                unset($content->CustodialHistory);
+            }
+        }
+
+        return $content;
+    }
+
+    private function getManagement($letterbox = null)
+    {
+        $management = new stdClass();
+
+        if ($letterbox && $letterbox->type_id != 0) {
+            $docTypes = $this->db->getDocTypes($letterbox->type_id);
+
+            $management->AppraisalRule = new stdClass();
+            $management->AppraisalRule->Rule = new stdClass();
+            $management->AppraisalRule->Rule->value = $docTypes->retention_rule;
+            $management->AppraisalRule->StartDate = date("Y-m-d");
+            if ($docTypes->retention_final_disposition == "conservation") {
+                $management->AppraisalRule->FinalAction = "Keep";
+            } else {
+                $management->AppraisalRule->FinalAction = "Destroy";
+            }
+        }
+
+        if ((string) $this->xml->CONFIG->accessRuleCode) {
+            $management->AccessRule = new stdClass();
+            $management->AccessRule->Rule = new stdClass();
+            $management->AccessRule->Rule->value = (string)$this->xml->CONFIG->accessRuleCode;
+            $management->AccessRule->StartDate = date("Y-m-d");
+        }
+
+        return $management;
+    }
+
+    private function getBinaryDataObject($filePath, $id)
+    {
+        $binaryDataObject = new stdClass();
+
+        $pathInfo = pathinfo($filePath);
+
+        if ($id && $id != $pathInfo['filename']) {
+            $filename = $pathInfo['filename'] . '_' . $id . '.' . $pathInfo['extension'];
+        } else {
+            $filename = $pathInfo['filename'] . '_' . rand() . '.' . $pathInfo['extension'];
+        }
+
+        $binaryDataObject->id = $id;
+        $binaryDataObject->Uri = $filePath;
+        $binaryDataObject->MessageDigest = new stdClass();
+        $binaryDataObject->MessageDigest->value = hash_file('sha256', $filePath);
+        $binaryDataObject->MessageDigest->algorithm = "sha256";
+        $binaryDataObject->Size = filesize($filePath);
+
+
+        $binaryDataObject->Attachment = new stdClass();
+        $binaryDataObject->Attachment->filename = $filename;
+
+        $binaryDataObject->FileInfo = new stdClass();
+        $binaryDataObject->FileInfo->Filename = $filename;
+
+        $binaryDataObject->FormatIdentification = new stdClass();
+        $binaryDataObject->FormatIdentification->MimeType = mime_content_type($filePath);
+
+        return $binaryDataObject;
+    }
+
+    private function getKeyword($informations, $type = null)
+    {
+        $keyword = new stdClass();
+        $keyword->KeywordContent = new stdClass();
+
+        if ($type == "entity") {
+            $keyword->KeywordType = "corpname";
+            $keyword->KeywordContent->value = $informations->business_id;
+        } elseif ($informations->is_corporate_person == "Y") {
+            $keyword->KeywordType = "corpname";
+            $keyword->KeywordContent->value = $informations->society;
+        } else {
+            $keyword->KeywordType = "persname";
+            $keyword->KeywordContent->value = $informations->lastname . " " . $informations->firstname;
+        }
+
+        if (empty($keyword->KeywordContent->value)) {
+            return null;
+        }
+
+        return $keyword;
+    }
+
+    private function getAddresse($informations, $type = null)
+    {
+        $addressee = new stdClass();
+        if ($type == "entity") {
+            $addressee->Corpname = $informations->entity_label;
+            $addressee->Identifier = $informations->business_id;
+        } elseif ($informations->is_corporate_person == "Y") {
+            $addressee->Corpname = $informations->society;
+            $addressee->Identifier = $informations->contact_id;
+        } else {
+            $addressee->FirstName = $informations->firstname;
+            $addressee->BirthName = $informations->lastname;
+        }
+
+        if ((empty($addressee->Identifier) || empty($addressee->Corpname)) && (empty($addressee->FirstName) || empty($addressee->BirthName))) {
+            return null;
+        }
+
+        return $addressee;
+    }
+
+    private function getCustodialHistoryItem($history)
+    {
+        $date = new DateTime($history->event_date);
+
+        $custodialHistoryItem = new stdClass();
+        $custodialHistoryItem->value = $history->info;
+        $custodialHistoryItem->when = $date->format('Y-m-d');
+
+        return $custodialHistoryItem;
+    }
+
+    private function getEntity($entityId, $param)
+    {
+        $res = array_key_exists($entityId, $this->entities);
+        if ($res === false) {
+            $this->entities[$entityId] = $entity = $this->db->getEntity($entityId);
+        } else {
+            $entity = $this->entities[$entityId];
+        }
+
+        if (!$entity) {
+            return false;
+        }
+
+        if (!$entity->business_id) {
+            $businessId = $this->getEntityParent(
+                $entity->parent_entity_id,
+                'business_id'
+            );
+
+            if (!$businessId) {
+                return false;
+            }
+
+            $entity->business_id = $businessId;
+        }
+
+        if (!$entity->archival_agreement) {
+            $archivalAgreement = $this->getEntityParent(
+                $entity->parent_entity_id,
+                'archival_agreement'
+            );
+
+            if (!$archivalAgreement) {
+                return false;
+            }
+
+            $entity->archival_agreement = $archivalAgreement;
+        }
+
+        if (!$entity->archival_agency) {
+            $archivalAgency = $this->getEntityParent(
+                $entity->parent_entity_id,
+                'archival_agency'
+            );
+
+            if (!$archivalAgency) {
+                return false;
+            }
+
+            $entity->archival_agency = $archivalAgency;
+        }
+
+        return $entity;
+    }
+
+    private function getEntityParent($parentId, $param)
+    {
+        $res = array_key_exists($parentId, $this->entities);
+        if ($res === false) {
+            $this->entities[$parentId] = $entity = $this->db->getEntity($parentId);
+        } else {
+            $entity = $this->entities[$parentId];
+        }
+
+        if (!$entity) {
+            return false;
+        }
+
+        $res = false;
+
+        if ($param == 'business_id') {
+            if (!$entity->business_id) {
+                $res = $this->getEntityParent(
+                    $entity->parent_entity_id,
+                    'business_id'
+                );
+            } else {
+                $res = $entity->business_id;
+            }
+        }
+
+        if ($param == 'archival_agreement') {
+            if (!$entity->archival_agreement) {
+                $res = $this->getEntityParent(
+                    $entity->parent_entity_id,
+                    'archival_agreement'
+                );
+            } else {
+                $res = $entity->archival_agreement;
+            }
+        }
+
+        if ($param == 'archival_agency') {
+            if (!$entity->archival_agency) {
+                $res = $this->getEntityParent(
+                    $entity->parent_entity_id,
+                    'archival_agency'
+                );
+            } else {
+                $res = $entity->archival_agency;
+            }
+        }
+
+        return $res;
+    }
+}
diff --git a/src/app/external/exportSeda/models/ArchiveTransferReply.php b/src/app/external/exportSeda/models/ArchiveTransferReply.php
new file mode 100644
index 00000000000..957c7ec5244
--- /dev/null
+++ b/src/app/external/exportSeda/models/ArchiveTransferReply.php
@@ -0,0 +1,143 @@
+<?php
+
+/*
+*   Copyright 2008-2017 Maarch
+*
+*   This file is part of Maarch Framework.
+*
+*   Maarch Framework is free software: you can redistribute it and/or modify
+*   it under the terms of the GNU General Public License as published by
+*   the Free Software Foundation, either version 3 of the License, or
+*   (at your option) any later version.
+*
+*   Maarch Framework is distributed in the hope that it will be useful,
+*   but WITHOUT ANY WARRANTY; without even the implied warranty of
+*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*   GNU General Public License for more details.
+*
+*   You should have received a copy of the GNU General Public License
+*   along with Maarch Framework.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+require_once __DIR__ . DIRECTORY_SEPARATOR .'../DOMTemplateProcessor.php';
+require_once __DIR__ . '/AbstractMessage.php';
+
+class ArchiveTransferReply {
+
+    private $db;
+    public function __construct()
+    {
+        $this->db = new RequestSeda();
+    }
+
+    public function receive($data, $resIds)
+    {
+        $messageObject = $this->getMessageObject($data);
+        $abstractMessage = new AbstractMessage();
+        //$this->db->insertMessage($data, "ArchiveTransferReply");
+        $abstractMessage->saveXml($messageObject,"ArchiveTransferReply", ".xml");
+
+        foreach ($resIds as $resId) {
+            $abstractMessage->addAttachment($messageObject->MessageIdentifier->value, $resId, $messageObject->MessageIdentifier->value.".xml", "xml", "Réponse au transfert",2);
+        }
+    }
+
+    private function getMessageObject($data)
+    {
+        $messageObject = new stdClass();
+
+        $messageObject->Comment = $data->comment;
+        $messageObject->Date = $data->date;
+        $messageObject->MessageIdentifier =  new stdClass();
+        $messageObject->MessageIdentifier->value = $data->messageIdentifier->value;
+
+        $messageObject->MessageRequestIdentifier =  new stdClass();
+        $messageObject->MessageRequestIdentifier->value = $data->messageRequestIdentifier->value;
+
+        $messageObject->ReplyCode = $data->replyCode->value . ' : ' . $data->replyCode->name;
+
+        $messageObject->ArchivalAgency = $this->getOrganisation($data->archivalAgency);
+        $messageObject->TransferringAgency = $this->getOrganisation($data->transferringAgency);
+
+        return $messageObject;
+    }
+
+    private function getOrganisation($data)
+    {
+        $organisationObject = new stdClass();
+        $organisationObject->Identifier = new stdClass();
+        $organisationObject->Identifier->value = $data->id;
+
+        $organisationObject->OrganizationDescriptiveMetadata = new stdClass();
+        $organisationObject->OrganizationDescriptiveMetadata->Name = $data->name;
+        $organisationObject->OrganizationDescriptiveMetadata->LegalClassification = $data->legalClassification;
+
+        if ($data->address) {
+            $organisationObject->OrganizationDescriptiveMetadata->Address = $this->getAddress($data->address);
+        }
+
+        if ($data->communication) {
+            $organisationObject->OrganizationDescriptiveMetadata->Communication = $this->getCommunication($data->communication);
+        }
+
+        if ($data->contact) {
+            $organisationObject->OrganizationDescriptiveMetadata->Contact = $this->getContact($data->contact);
+        }
+
+        return $organisationObject;
+    }
+
+    private function getContact($data)
+    {
+        $listContact = [];
+        foreach ($data as $contact) {
+            $tmpContact =  new stdClass();
+            $tmpContact->DepartmentName = $contact->departmentName;
+            $tmpContact->PersonName = $contact->personName;
+
+            if ($contact->address){
+                $tmpContact->Address = [];
+                $tmpContact->Address = $this->getAddress($contact->address);
+            }
+
+            if ($contact->communication) {
+                $tmpContact->Communication = [];
+                $tmpContact->Communication = $this->getCommunication($contact->communication);
+            }
+            $listContact[] = $tmpContact;
+        }
+        return $listContact;
+    }
+
+    private function getAddress($data)
+    {
+        $listAddress = [];
+        foreach ($data as $address) {
+            $tmpAddress = new stdClass();
+            $tmpAddress->CityName = $address->cityName;
+            $tmpAddress->Country = $address->country;
+            $tmpAddress->PostCode = $address->postCode;
+            $tmpAddress->StreetName = $address->streetName;
+
+            $listAddress[] = $tmpAddress;
+        }
+        return $listAddress;
+    }
+
+    private function getCommunication($data)
+    {
+        $listCommunication = [];
+        foreach ($data as $communication) {
+            $tmpCommunication = new stdClass();
+            $tmpCommunication->Channel = $communication->channel;
+
+            if ($communication->completeNumber) {
+                $tmpCommunication->value = $communication->completeNumber;
+            } else {
+                $tmpCommunication->value = $communication->URIID;
+            }
+            $listCommunication[] = $tmpCommunication;
+        }
+        return $listCommunication;
+    }
+}
-- 
GitLab