<?php
namespace Modules\Consultation\Controller;

use Entity\Model\AoContFour;
use Entity\Model\ConsultDocDefault;
use Entity\Model\Fourniss;
use Entity\Model\Grpfou;
use Helpers\Session\Enums\MenuTopEnum;
use Helpers\Session\Session;
use Modules\Ajax\WebService\EnvoiMail;
use Modules\Consultation\Enums\TypeConsultationsEnums;
use Modules\Consultation\Service\ConsultationPanierService;
use Modules\Consultation\Service\EnvoieExcelService;
use Modules\GlobalApplication\Repository\Societe;
use Skeleton\Controller\Controller;
use Modules\Consultation\Repository\GestionConsultation;
use Helpers\Trad\Trad;
use Helpers\Ariane\Ariane;
use Entity\Model\AoEntet;
use Modules\Consultation\Repository\Consultation;
use GuzzleHttp\Psr7\Response;
use Helpers\Outil\Mail;
use Entity\Model\Hastutil;
use Modules\Consultation\Repository\AoEvent;
use Helpers\ChampsSupplementaire\ChampSupp;
use Helpers\Outil\Roles;
use Helpers\Outil\Sql;
use Entity\Model\Docatt;
use Entity\Model\AoFour;
use Entity\Model\AoLigne;
use Modules\Consultation\Service\ConsultationService;
use Helpers\Fichier\Fichier;
use Helpers\Parametres\Constante;
use Entity\Model\AoQstQ;
use Entity\Model\AoDocAttendus;
use Entity\Model\AoPijo;
use Entity\Model\AoClaus;
use Modules\Consultation\Repository\Reponse;
use Helpers\ChargeDocument\ChargeDocument;
use Helpers\Outil\Outils;
use Helpers\Outil\Date;
use Entity\Model\AoExcFofo;
use Modules\Ajax\Repository\Listes;
use Modules\Consultation\MenuContextuel\GestionMenuContextuel;
use Helpers\Session\ParseBase1;
use Helpers\User\User;
use Modules\Consultation\Repository\Contributor;

class GestionConsultationController extends Controller
{
    public function indexAction(): string
    {
        $post   = $this->request->getParsedBody();
        $filtre = $this->request->getAttribute('filtre');

        $listeAO = [];
        if (isset($post['listeAO'])) {
            $listeAO = unserialize($post['listeAO'], ["allowed_classes" => false]);
            unset($post['listeAO']);
        }
        if (!$post) {
            if ($filtre == 'A_ENVOYER') {
                $post['filter_Statut'] = 'ENVO';
                $post['ACHETEUR']      = $_SESSION["Session_Login"];
            } elseif ($filtre == 'MES_CONSUTATION') {
                $post['filter_Statut'] = 'PRCO';
                $post['ACHETEUR']      = $_SESSION["Session_Login"];
            } elseif ($filtre == 'ACCORD_CONFIDENTIALITE_A_VALIDER') {
                $post['filter_Statut'] = 'ACAV';
                $post['ACHETEUR']      = $_SESSION["Session_Login"];
            } elseif ($filtre == 'NON_CLOS') {
                $post['filter_Statut'] = 'NON_CLOS';
            } elseif ($filtre == 'questionSansReponse') {
                $post['questionSansReponse'] = 'on';
                $post['ACHETEUR']      = $_SESSION["Session_Login"];
            } else {
                $user = (new Hastutil($this->pdo))->find($_SESSION["Session_Login"], ['FILT_CDE']);
                if (sql::boolSql($user['FILT_CDE'])) {
                    $post['ACHETEUR'] = $_SESSION["Session_Login"];
                }
            }
        }
        
        $trad = $this->getTranslationService();

        if ($listeAO) {
            $post['recharge_'] = $trad->t('Consultations créées');
        } else {
            $listeAO = [];
        }

        $listeStatut = [
            '' => $trad->t('Toutes les consultations'),
            'PREP' => $trad->t('Préparation'),
            'VALC' => $trad->t('Validation en cours'),
            'PRCO' => $trad->t('En préparation et en cours'),
            'ACAV' => $trad->t('Accord de confidentialité à valider'),
            'ENCO' => $trad->t('En cours'),
            'ENVO' => $trad->t('A envoyer'),
            'TERM' => $trad->t('Terminé'),
            'NON_CLOS' => $trad->t('Non closes'),
        ];

        $droit = [
            'HA_AO_ADM' => Roles::droitsUtilisateur($this->pdo, 'HA_AO_ADM', $_SESSION["Session_Login"]),
            'HA_AO_CMV' => Roles::droitsUtilisateur($this->pdo, 'HA_AO_CMV', $_SESSION["Session_Login"]),
            'HA_AO_TRA' => Roles::droitsUtilisateur($this->pdo, 'HA_AO_TRA', $_SESSION["Session_Login"]),
            'HA_AO_SUP' => Roles::droitsUtilisateur($this->pdo, 'HA_AO_SUP', $_SESSION["Session_Login"]),
        ];

        $isContrib = (new Contributor($this->pdo))->isContributor($_SESSION["Session_Login"]);

        if ($isContrib && (!$droit['HA_AO_ADM'] && !$droit['HA_AO_CMV'])) {
            $post['contributions'] = 'on';
        }

        $listeRepo   = new Listes($this->pdo);
        $listeGrpSoc = $listeRepo->findGroupedCompanies();

        $paginator = new \Helpers\Pagination\PaginatorGestion();
        $paginator->generate(0, 'NO_AO');

        $gestionAO_REPO    = new GestionConsultation($this->pdo);
        $listeConsultation = $gestionAO_REPO->listeConsultation($post, $listeAO);
        $infopagination    = \Helpers\Pagination\PaginatorGestion::getInfoPagination();

        $menuContextuel = new GestionMenuContextuel($this->pdo, $this->router, $trad, $droit);

        foreach ($listeConsultation as &$consult) {
            $consult['menuContextuel'] = $menuContextuel->generate($consult);
            // @phpstan-ignore-next-line
            $consult['Statut'] = $listeStatut[$consult['Statut']] ?? '';
        }

        Ariane::generate(0, $trad->t('Gestion Consultations'), $post, $infopagination['nbrArticle']);

        $filtreAvance = new \Helpers\Filter\FiltreAvance\GeneratorCs($post, 'AO_ENTET', 'AO_ENTET.NO_AO', $this->pdo, $this->getTranslationService());
        $filtreAvance->setFiltre('DTE_AO', 'date', $trad->t('Date de création'));
        $filtreAvance->setFiltre('DTE_VALID_AO', 'date', $trad->t('Date de validation'));
        $filtreAvance->setFiltre('EMETTEUR', 'liste', $trad->t('Centre émetteur'), '', 'Ajax.liste.centreEmetteur', 'Centre');
        $filtreAvance->setFiltre('CODE_FAM', 'liste', $trad->t('Famille'), '', 'Ajax.liste.famille', 'famille');
        $filtreAvance->setFiltre('COD_LNG', 'liste', $trad->t('Langue'), '', 'Ajax.liste.langues', 'langues');
        $filtreAvance->setFiltre('PRESCRIPTEUR', 'liste', $trad->t('Prescripteur'), '', 'Ajax.liste.utilisateur', 'hastutil');
        $filtreAvance->setFiltre('ACH', 'liste', $trad->t('Acheteur'), '', 'Ajax.liste.utilisateur', 'hastutil');
        $filtreAvance->setFiltre('DEL_REP', 'date', $trad->t('Réponse attendue le'));

        $filtreAvance->setFiltre('OBJET_AO', 'text', $trad->t('Objet'));

        $filtreAvance->setFiltre('VARIANTE', 'bool', $trad->t('Variante autorisée ?'), '', null, null, 'bdd');
        $filtreAvance->setFiltre('ACC_CONF', 'bool', $trad->t('Accord de confidentialité ?'), '', null, null, 'bdd');
        $filtreAvance->setFiltre('REPDEV', 'bool', $trad->t('Réponse obligatoire dans la devise de la consultation ?'), '', null, null, 'bdd');

        $filtreAvance->setFiltre('ARTICLE', 'liste', $trad->t('Article'), '', 'Ajax.liste.articles', 'articles', null, true);
        
        $filtreAvance->setFiltre('NO_DA', 'liste', $trad->t('Demande d’achat'), '', 'Ajax.liste.demandeAchat', 'DaEntet', null, true);

        $listeTypeConsultation = [
            '' => $trad->t('Toutes les consultations'),
            'I' => $trad->t('RFI'),
            'Q' => $trad->t('RFQ'),
            'P' => $trad->t('RFP'),
        ];

        if (Roles::droitsUtilisateur($this->pdo, 'HA_DA_CRE') || Roles::GetALL()) {
            $P2PActive = 1;
        } else {
            $P2PActive = 0;
        }

        if (!Session::verifySessionTypeMenuTop(MenuTopEnum::P2P) && !Session::verifySessionTypeMenuTop(MenuTopEnum::S2C)) {
            Session::setSessionTypeMenuTop();
        }

        return $this->renderer->render('@Consultation/GestionConsultation/index', [
            'menuActive' => Session::verifySessionTypeMenuTop(MenuTopEnum::P2P) ? 'eproc' : 'Consultations',
            'menuLeft' => 'gestionAO',
            'infoPagination' => $infopagination,
            'listeConsultation' => $listeConsultation,
            'user' => (new Hastutil($this->pdo))->find($_SESSION['Session_Login']),
            'post' => $post,
            'listeStatut' => $listeStatut,
            'filtreAvance' => $filtreAvance->getFiltres(),
            'initFiltreAvance' => $filtreAvance->getInit(),
            'listeTypeConsultation' => $listeTypeConsultation,
            'listeAO' => serialize($listeAO),
            'droit' => $droit,
            'contribOnly' => $isContrib && (!$droit['HA_AO_ADM'] && !$droit['HA_AO_CMV']),
            'P2PActive' => $P2PActive,
            'listeGrpSoc' => $listeGrpSoc,
            'container' => $this->contenaire,
        ]);
    }

    public function ajaxDetailEnteteAction(): string
    {
        $idAO = $this->request->getAttribute('idAO');

        $gestionAO_REPO    = new GestionConsultation($this->pdo);
        $ligneConsultation = $gestionAO_REPO->listeLigneConsultation($idAO);

        return $this->renderer->render('@Consultation/GestionConsultation/detailConsultation', [
            'listeLigneConsultation' => $ligneConsultation,
        ]);
    }

    public function popupListeFournisseurAction(): string
    {
        $idAO = $this->request->getAttribute('idAO');

        $trad = $this->getTranslationService();

        $gestionAO_REPO = new GestionConsultation($this->pdo);
        $listeFourniss  = $gestionAO_REPO->listeFournisseurConsultation($idAO);

        return $this->renderer->render('@Consultation/GestionConsultation/popupListeFournisseur', [
            'listeFourniss' => $listeFourniss,
        ]);
    }

    public function popupTransfereAction(): string
    {
        $idAO = $this->request->getAttribute('idAO');

        $aoEntetEntity = new AoEntet($this->pdo);
        $infoEntete    = $aoEntetEntity->find($idAO);

        $consultation     = new Consultation($this->pdo);
        $listeAcheteurTMP = $consultation->getListeAcheteurForTransfere($infoEntete['TYPE_SG'], $infoEntete['CODE_STE']);

        if (!$listeAcheteurTMP) {
            return $this->renderer->render('@popup-erreur/information', [
                'message' => $this->getTranslationService()->t('Il n\'y a pas d\'acheteur pouvant recevoir cette consultation.'),
            ]);
        }

        $listeAcheteur = [];
        foreach ($listeAcheteurTMP as $acheteur) {
            if ($acheteur['CODE'] != $_SESSION["Session_Login"]) {
                $listeAcheteur[$acheteur['CODE']] = $acheteur['NOM'];
            }
        }

        return $this->renderer->render('@Consultation/GestionConsultation/popuptransmettre', [
            'listeAcheteur' => $listeAcheteur,
            'idAO' => $idAO,
        ]);
    }

    public function ajaxTransfereAction()
    {
        $idAO = $this->request->getAttribute('idAO');
        $post = $this->request->getParsedBody();
        $trad = $this->getTranslationService();

        $aoEntete     = new AoEntet($this->pdo);
        $consultation = $aoEntete->find($idAO);

        $newProprio = $post['DESTINATAIRE'];
        $oldPoprio  = $consultation['ACH'];

        $hastutilEntity = new Hastutil($this->pdo);

        $infoProprio    = $hastutilEntity->find($newProprio);
        $infoOldProprio = $hastutilEntity->find($oldPoprio);

        $message = Trad::strbuild(
            $trad->t('Consultation transmise de @1@ à @2@'),
            $infoOldProprio['NOM'],
            $infoProprio['NOM']
        );

        $aoEvent = new AoEvent($this->pdo);
        $aoEvent->rqInsertEvent($idAO, 'TRA', $message);

        $aoEntete->update(['ACH' => $newProprio], $idAO);

        $listeCS = (new ChampSupp($this->pdo))->getInfoValueCs('AO_ENTET', ChampSupp::autoCompletCodeEnr($idAO));

        Mail::generateMail(
            $this->pdo,
            $this->getTranslationService(),
            $infoProprio['EMAIL'],
            'AO_TRANSFERT',
            $infoProprio['COD_LNG'],
            [
                'NAO' => $idAO,
                'TITREAO' => Sql::getMemo($this->pdo, $consultation['NM_TITRE']),
                'OBJETAO' => $consultation['OBJET_AO'],
                'NOM_ACH' => $infoOldProprio['NOM'],
                'NOMACH' => $infoOldProprio['NOM'],
            ],
            $listeCS
        );

        return new Response(200);
    }

    public function ajaxValiderAction(
        AoEntet $aoEntete,
        AoFour $aoFour,
        AoLigne $aoLigne,
        Docatt $docAttEntity,
        AoQstQ $aoqst,
        AoDocAttendus $aoDocInt,
        AoPijo $aoPijo,
        AoClaus $aoClause,
        AoContFour $aoContFour,
        ConsultDocDefault $consultDocDefault
    ) {
        $idAO = $this->request->getAttribute('idAO');
        $post = $this->request->getParsedBody();

        $trad = $this->getTranslationService();

        $consultation = $aoEntete->find($idAO);

        if ($consultation['DTE_LANCEMENT'] === '00000000') {
            $aoEntete->update([
                'DTE_LANCEMENT' => date('Ymd')
            ], ['NO_AO' => (int) $idAO]);
        }

        $consultation = $aoEntete->find($idAO);
        $typeConsult  = TypeConsultationsEnums::tryFrom($consultation['RFI_Q']) ?? TypeConsultationsEnums::RFQ;

        $listeFrs   = $aoFour->findAll(['NO_AO' => $idAO]);
        $listeLigne = $aoLigne->findAll(['NO_AO' => $idAO]);

        $listeQst          = $aoqst->findAll(['NO_AO' => $idAO]);
        $listeDocInt       = $aoDocInt->findAll(['NO_AO' => $idAO]);
        $listePj           = $aoPijo->findAll(['NO_AO' => $idAO]);
        $listeDocPJDefault = $consultDocDefault->findAll([
            'TYPE_DOC' => 'P',
            'COD_LNG ' => $consultation['COD_LNG'],
            'POUR_' . $typeConsult->name => true
        ]);
        $listeClause       = $aoClause->findAll(['NO_AO' => $idAO]);

        $messageBloquant    = '';
        $messageNonBloquant = '';

        $consultationService = new ConsultationService($this->pdo, $this->getTranslationService(), $this->router);

        if (Sql::boolSql($consultation['ACC_CONF']) == true) {
            $infoDoc = $docAttEntity->find(['NO_DA' => 'AO_ENTET', 'COD_ENR' => str_pad($idAO, 9, '0', STR_PAD_LEFT), 'NO_ORDRE' => $consultation['ACC_CONF_NODOC']]);

            if (!$infoDoc) {
                $messageBloquant .= '<br />' . $trad->t('L\'accord de confidentialité n\'est pas renseigné.');
            }
        }

        if (isset($consultation['DTE_LANCEMENT'])
            && ($consultation['DTE_LANCEMENT'] != '')
            && ($consultation['DTE_LANCEMENT'] < date('Ymd'))
        ) {
            $messageBloquant .= '<br />' . $trad->t('La date de lancement est inférieure à la date du jour.');
        }

        if (empty($listeLigne) && Sql::boolSql($consultation['COMP_LIGNE']) == true) {
            $messageBloquant .= '<br />' . $trad->t('La consultation n\'a aucun poste');
        }
        if (empty($listeFrs)) {
            if (sql::boolSql($consultation['AO_PUBLIC']) == true) {
                $messageNonBloquant .= '<br />' . $trad->t('Il n\'y a pas de fournisseur pour cette consultation');
            } else {
                $messageBloquant .= '<br />' . $trad->t('Il faut au moins 1 fournisseur pour une consultation non "publique".');
            }
        }

        if (Sql::boolSql($consultation['COMP_PJ']) && Sql::boolSql($consultation['COMP_CLAUSE'])) {
            foreach (array_filter($listeDocPJDefault, fn($doc) => Sql::toBool($doc[$typeConsult->name . '_OBLIG'])) as $docPJDefaultOblig) {
                $find = array_find(
                    $listePj,
                    fn($pj) => $pj['TITRE'] == $docPJDefaultOblig['TITRE_DOC']
                );
                if ($find == null) {
                    $messageBloquant .= '<br />' . Trad::strBuild($trad->t('Le document de la consultation "@1@" est obligatoire mais non renseigné.'), $docPJDefaultOblig['TITRE_DOC']);
                }
            }

            foreach (array_filter($listeDocPJDefault, fn($doc) => Sql::toBool($doc['POUR_' . $typeConsult->name] && !Sql::toBool($doc[$typeConsult->name . '_OBLIG']))) as $docPJDefaultRecommande) {
                $find = array_find(
                    $listePj,
                    fn($pj) => $pj['TITRE'] == $docPJDefaultRecommande['TITRE_DOC']
                );
                if ($find == null) {
                    $messageNonBloquant .= '<br />' . Trad::strBuild($trad->t('Le document de la consultation "@1@" est recommandé mais non renseigné.'), $docPJDefaultRecommande['TITRE_DOC']);
                }
            }
        }

        foreach ($listeFrs as $frs) {
            $consultationService->checkAoFourContactWithAoContFour($idAO, $frs['CODE_FOU'], $frs['TYPE_FG']);

            $allContactsByFrsOnAO = $aoContFour->findAll([
                'NO_AO' => $idAO,
                'CODE_FOUR' => $frs['CODE_FOU'],
                'TYPE_FG' => $frs['TYPE_FG']
            ], ['EMAILCONT']);

            if ($frs['EMAILCONT']) {
                $allContactsByFrsOnAO[] = ['EMAILCONT' => $frs['EMAILCONT']];
            }

            if ($allContactsByFrsOnAO == []) {
                $messageBloquant .= '<br />' . $trad->t('Certains fournisseurs n\'ont pas de contact pour la consultation.');
                break;
            }
        }

        if (!$listeQst && !$listeDocInt && !$listePj && !$listeLigne && !$listeClause) {
            if ($typeConsult == TypeConsultationsEnums::RFI) {
                $messageBloquant .= '<br />' . $trad->t('Il doit y avoir au moins une question, un document interne, un document attendu, une clause ou une pièce jointe pour une consultation.');
            }
        }

        // on vérifie s'il existe un questionnaire pour acheteur/contributeur
        if (count((new Reponse($this->pdo))->getContributorsQuestions($idAO)) > 0) {
            // si oui, on doit avoir une date limite de réponse pour les contributeurs
            if ($consultation['DTE_LIMIT_CONTRIB'] == '00000000') {
                $messageBloquant .= '<br />' . $trad->t('La date limite de réponse des contributeurs est obligatoire.');
            }

            if ($consultation['DTE_LIMIT_CONTRIB'] < $consultation['DEL_REP']) {
                $messageBloquant .= '<br />' . $trad->t('La date limite de réponse des contributeurs ne peut être antérieure à la date limite de réponse des fournisseurs.');
            }
        }

        /*$paramDoc = sql::paravrac($this->pdo, 'PARAMGEN', 'CTRL_DOC_ATT_FOURN_SUR_AO');
        $explodeParamDoc = explode('|', $paramDoc);*/

        if ($messageBloquant == '' && $messageNonBloquant == '') {
            $consultationService->validateConsultation($idAO);

            return $this->createJsonResponse(['path' => $this->router->generateUri('Consultation.GestionConsultation.index')]);
        } else {
            return new Response(443, [], $this->renderer->render('@popup-erreur/erreurAlerteEtAvertissement', [
                'params' => [
                    'statut' => $messageBloquant ? 'B' : 'O',
                    'alerte' => $messageBloquant,
                    'avertissement' => $messageNonBloquant,
                    'div' => 'page'
                ],
                'pathURL' => $this->router->generateUri('Consultation.GestionConsultation.confirmationValidate', ['idAO' => $idAO]),
                'entity' => $post['entity'],
                'div' => $post['div'],
                'form' => $post['form'],
            ]));
        }
    }

    public function confirmationValidateAction()
    {
        $idAO = $this->request->getAttribute('idAO');

        $consultationService = new ConsultationService($this->pdo, $this->getTranslationService(), $this->router);
        $consultationService->validateConsultation($idAO);

        return new Response(200, [], json_encode(['path' => $this->router->generateUri('Consultation.GestionConsultation.index')]));
    }


    public function ajaxDevaliderAction(): Response
    {
        $idAO = $this->request->getAttribute('idAO');

        $aoEvent = new AoEvent($this->pdo);
        $aoEvent->rqInsertEventAO($idAO, 'DEV');

        $AoEntet = new AoEntet($this->pdo);
        $AoEntet->update([
            'DTE_VALID_AO' => '00000000',
            'EVE_VALPREP' => '0',
        ], $idAO);

        $aoFour = new AoFour($this->pdo);
        $aoFour->update(['EVE_IMP' => '0'], ['NO_AO' => $idAO]);

        return new Response(200, [], json_encode(['path' => $this->router->generateUri('Consultation.GestionConsultation.index')]));
    }

    public function ajaxDevaliderSelectFrsAction(): Response
    {
        $idAO = $this->request->getAttribute('idAO');

        $AoFour   = new AoFour($this->pdo);
        $listeFrs = $AoFour->findAll(['NO_AO' => $idAO]);

        $fouRetenu = false;
        foreach ($listeFrs as $frs) {
            if (Sql::toBool($frs['FOU_RETEN'])) {
                $fouRetenu = true;
                break;
            }
        }

        $aoEvent = new AoEvent($this->pdo);
        $aoEvent->rqInsertEventAO($idAO, $fouRetenu ? 'DCH' : 'DEV');

        $AoEntet = new AoEntet($this->pdo);
        $AoEntet->update([
            'VALCHXFOU' => '00000000',
        ], $idAO);

        $AoFour = new AoFour($this->pdo);
        foreach ($AoFour->findAll(["NO_AO" => $idAO]) as $fourni) {
            $fourni["FOU_RETEN"] = false;
            $AoFour->update(["FOU_RETEN" => $fourni["FOU_RETEN"]], ["NO_AO" => $idAO, "CODE_FOU" => $fourni["CODE_FOU"]]);
        }

        return new Response(200, [], json_encode(['path' => $this->router->generateUri('Consultation.GestionConsultation.index')]));
    }

    public function ajaxImpressionAction(): string
    {
        $idAO            = $this->request->getAttribute('idAO');
        $tousFournisseur = $this->request->getAttribute('tousFournisseur'); //Tout = T, Fournisseur = U
        $typeFG          = $this->request->getAttribute('typeFG');
        $codeFrs         = $this->request->getAttribute('codeFrs');

        $consultationWSDL = new \Modules\Consultation\WebService\Consultation();
        $xmlResult        = $consultationWSDL->impressionConsultation($idAO, false, $tousFournisseur, $typeFG, $codeFrs);


        $reponse = new \SimpleXMLElement($xmlResult->responseData);

        $url = Fichier::URLDownload($reponse->FichierPDF);

        $message = Fichier::UploadClient($url, $reponse->FichierPDF);

        return $message;
    }

    public function envoyerAction(): string
    {
        $idAO = $this->request->getAttribute('idAO');

        $trad = $this->getTranslationService();

        $listeType = [
            'M' => $trad->t('Marché'),
            'P' => $trad->t('Ponctuelle')
        ];

        $listeReponse = [
            'T' => $trad->t('Tous les fournisseurs'),
            'U' => $trad->t('Un fournisseur'),
        ];

        $aoEntet      = new AoEntet($this->pdo);
        $consultation = $aoEntet->find($idAO);

        $AoExcFofo = new AoExcFofo($this->pdo);
        // $paramExcelDefaut = $AoExcFofo->getForm($consultation);

        $aoEvent      = new AoEvent($this->pdo);
        $AOEventCreat = $aoEvent->getNameCreate($idAO);

        $GestionConsultationRepo = new GestionConsultation($this->pdo);

        $initListeFrs = (new AoFour($this->pdo))->findAll(['NO_AO' => $idAO]);

        $consultationService = new ConsultationService($this->pdo, $trad);
        foreach ($initListeFrs as $frs) {
            $consultationService->checkAoFourContactWithAoContFour((int) $idAO, $frs['CODE_FOU'], $frs['TYPE_FG']);
        }

        $listeFrs = $GestionConsultationRepo->getListeFourniss($idAO);

        $AoContFour = new AoContFour($this->pdo);

        foreach ($listeFrs as &$frs) {
            $listeContact = [];

            $listeContactTMP = $AoContFour->findAll(['NO_AO' => $idAO, 'CODE_FOUR' => $frs['CODE_FOU'], 'TYPE_FG' => $frs['TYPE_FG']], ['NOM_CTCT', 'EMAILCONT']);

            // Pas de vérification si un email existe : c'est désormais obligatoire en 1200ab
            foreach ($listeContactTMP as $ctc) {
                $listeContact[$ctc['EMAILCONT']] = $ctc['NOM_CTCT'];
            }
            $listeContact[$frs['EMAILCONT']] = $frs['NOM_CTCT'];

            // TODO : merge query
            $paramExcelByfrs = $AoExcFofo->getDefaultParamsParFrs(
                (string) $consultation['CODE_STE'],
                (string) $consultation['EMETTEUR'],
                (string) $frs['CODE_FOU']
            );

            $frs['listeContact'] = $listeContact;
            if ($paramExcelByfrs) {
                // Vérification de l'existence du fichier
                $testFileExist = false;
                $formatExcel   = $AoExcFofo->find([// TODO : merge query
                    'CODEFORM' => $paramExcelByfrs['CODEFORM'] ?? '',
                    'VERSFORM' => $paramExcelByfrs['VERSFORM'] ?? ''
                ]);
                if ($formatExcel) {
                    $fileExcel = explode('|', $formatExcel['CHEMFORM']);
                    $infoExcel = pathinfo($fileExcel[0]);

                    $testFileExist = file_exists(
                        (new ParseBase1())->getRep()->pj
                        . '\\' . $fileExcel[1]
                        . '.' . ($infoExcel['extension'] ?? '')
                    );
                }

                if ($testFileExist) {
                    $frs['typeFormatExcel'] = $paramExcelByfrs['CODEFORM'] ?? '';
                    $frs['versionFormat']   = $paramExcelByfrs['VERSFORM'] ?? '';
                }
            }

            // $listeContact[] = $trad->t('Choisir un contact');
        }

        Ariane::generate(3, $trad->t('Envoyer consultation'));

        return $this->renderer->render('@Consultation/GestionConsultation/envoyer', [
            'idAO' => $idAO,
            'menuActive' => Session::verifySessionTypeMenuTop(MenuTopEnum::P2P) ? 'eproc' : 'Consultations',
            'menuLeft' => 'gestionAO',
            'listeType' => $listeType,
            'listeReponse' => $listeReponse,
            'listeFrs' => $listeFrs,
            'consultation' => $consultation,
            'AOEventCreat' => $AOEventCreat,
        ]);
    }

    public function ajaxEnvoieAction()
    {

        $idAO = $this->request->getAttribute('idAO');
        $post = $this->request->getParsedBody();

        $trad = $this->getTranslationService();

        $validator = $this->createValidator();

        $validator->isCheck($post['formatExcel']);
        $validator->isCheck($post['parMail']);

        $listeFrs    = [];
        $listeFrsAcc = [];
        $listeExcel  = [];
        /* On récupere les informations des fournisseurs, si ils ont selectionné ou pas etc.. */
        $aoExFofo   = new AoExcFofo($this->pdo);
        $AoContFour = new AoContFour($this->pdo);

        $aoEntet      = new AoEntet($this->pdo);
        $consultation = $aoEntet->find($idAO);

        foreach (array_keys($post) as $key) {
            if (strpos($key, 'ligneFrs') === 0) {
                $lineNbr = substr($key, 8);

                [$typeFG, $fourniss] = explode(Constante::spliter, $lineNbr);

                $validator->isCheck($post['parMail' . $lineNbr]);
                $validator->isCheck($post['formatExcel' . $lineNbr]);

                if ($post['parMail' . $lineNbr]) {
                    $emailKeysWithCtctName = [];

                    foreach ($post as $key => $value) {
                        if (stripos($key, 'emailChecked' . $lineNbr) !== false) {
                            $endOfKey                                                    = explode('_', $key)[1];
                            $emailKeysWithCtctName['email' . $lineNbr . '_' . $endOfKey] = 'ctc' . $lineNbr . '_' . $endOfKey;
                        }
                    }

                    $listofEmails = [];
                    foreach ($emailKeysWithCtctName as $email => $ctcName) {
                        $adresseMailValide = $validator->adresseMail($trad->t('Email'), $post[$email], 1, 120);
                        $nomCtctValide     = $validator->isStringAvecEspace($trad->t('Nom'), $post[$ctcName], 0, 25);
                        if ($adresseMailValide && $nomCtctValide) {
                            if (str_contains($email, '_JS')
                                && !$AoContFour->find([
                                    'NO_AO' => $idAO,
                                    'CODE_FOUR' => $fourniss,
                                    'TYPE_FG' => $typeFG,
                                    'EMAILCONT' => $post[$email]
                                ])
                            ) {
                                $toInsertInDBIfDataIsValid[] = [
                                    'NO_AO' => $idAO,
                                    'CODE_FOUR' => $fourniss,
                                    'TYPE_FG' => $typeFG,
                                    'EMAILCONT' => $post[$email],
                                    'NOM_CTCT' => $post[$ctcName],
                                ];
                            }
                        }
                        $listofEmails[] = $post[$email];
                    }
                }

                if ($post['formatExcel' . $lineNbr]) {
                    $splitFormat = explode('|', $post['typeFormatExcel' . $lineNbr]);

                    $testFileExist = false;
                    $formatExcel   = $aoExFofo->find(['CODEFORM' => $splitFormat[0], 'VERSFORM' => $splitFormat[1]]);
                    if ($formatExcel) {
                        $fileExcel = explode('|', $formatExcel['CHEMFORM']);
                        $infoExcel = pathinfo($fileExcel[0]);

                        $testFileExist = file_exists(
                            (new ParseBase1())->getRep()->pj
                            . '\\' . $fileExcel[1]
                            . '.' . ($infoExcel['extension'] ?? '')
                        );
                    }
                    $RSFourniss = (new Fourniss($this->pdo))->find(['CODE' => $fourniss], ['RS'])['RS'] ?? '';
                    $validator->isFalse($testFileExist, Trad::strBuild($trad->t('Le fichier du format @1@ version @2@ est introuvable pour le fournisseur @3@ (@4@).'), $splitFormat[0], $splitFormat[1], $RSFourniss, $fourniss));
                } else {
                    $splitFormat = [];
                }

                $infoLigne = [
                    'ACC_CONF' => $post['ACC_CONF' . $lineNbr],
                    'CODE_FOU' => $fourniss,
                    'TYPE_FG' => $typeFG,
                    'parMail' => $post['parMail' . $lineNbr],
                    'formatExcel' => $post['formatExcel' . $lineNbr],
                    'emails' => isset($listofEmails) ? implode(',', $listofEmails) : '',
                    'typeFormatExcel' => $splitFormat[0] ?? '',
                    'versionFormat' => $splitFormat[1] ?? '',
                ];

                if ($post['ACC_CONF' . $lineNbr] == '1') {
                    $listeFrsAcc[$fourniss] = $infoLigne;
                } elseif ($post['formatExcel' . $lineNbr]) {
                    $listeExcel[$fourniss] = $infoLigne;
                } else {
                    $listeFrs[$fourniss] = $infoLigne;
                }
            }
        }

        $listeUrl = [];
        if ($validator->isValid()) {
            if (isset($toInsertInDBIfDataIsValid)) {
                foreach ($toInsertInDBIfDataIsValid as $newContact) {
                    $AoContFour->insert(
                        array_merge($newContact, [
                            'NUM_ORDRE' => (int) $AoContFour->getMaxNumOrdre($idAO, $newContact['CODE_FOUR'], $newContact['TYPE_FG']) + 1,
                            'FAX_CTCT' => '',
                            'TEL_CTCT' => '',
                            'POR_CTCT' => '',
                        ])
                    );
                }
            }
            $chargeDoc = new ChargeDocument();

            $hastutilEntity = new Hastutil($this->pdo);
            $user           = $hastutilEntity->find($consultation['ACH']);
            $consultRepo    = new Consultation($this->pdo);

            /* Si un accord de confidentialité à été selectionné */
            if (Sql::boolSql($consultation['ACC_CONF']) == true) {
                /* On duplique dans TMP pour chaque fournisseur selectionné l'accord de confidentialité, pour l'envoie par mail ou pour chaque l'afficher a l'utilisateur */
                $docAtt = new Docatt($this->pdo);
                $idDoc  = str_pad($idAO, 9, '0', STR_PAD_LEFT);

                $infoDoc   = $docAtt->find(['NO_DA' => 'AO_ENTET', 'COD_ENR' => $idDoc, 'NO_ORDRE' => $consultation['ACC_CONF_NODOC']]);
                $path_info = pathinfo($infoDoc['NOM_FIC']);

                foreach ($listeFrsAcc as &$frs) {
                    $new_name = 'Consult_' . $idAO . '_' . $frs['CODE_FOU']
                        . '_' . str_replace('t| ', '', $trad->t('Accord de Confidentialité'))
                        . '.' . ($path_info['extension'] ?? '');

                    $oldFic = (new ParseBase1())->getRep()->pj . $infoDoc['NOM_FIC'];
                    $newFic = (new ParseBase1())->getRep()->tmp . $new_name;

                    copy($oldFic, $newFic);

                    $frs['pj']       = $new_name;
                    $frs['sourcePJ'] = $newFic;

                    if ($frs['parMail']) {
                        $listeOxalink    = [];
                        $listeNonOxalink = [];

                        // Vérification si l'utilisateur a acces à Oxalink
                        $allEmails = [];
                        if (str_contains($frs['emails'], ',')) {
                            $allEmails = explode(',', $frs['emails']);
                        } else {
                            $allEmails[] = $frs['emails'];
                        }

                        foreach ($allEmails as $currentEmail) {
                            // TODO : merge queries
                            $infoFrs = $consultRepo->checkIfCtcHasOxalinkAccess($idAO, $frs['TYPE_FG'], $frs['CODE_FOU'], $currentEmail);

                            if (!empty($infoFrs['CODE_FOUR']) && $consultRepo->doesFournissHasAContactWithOxalinkAccess($infoFrs['CODE_FOUR']) > 0) {
                                $listeOxalink[] = $currentEmail;
                            } else {
                                if (!$infoFrs) {
                                    $infoFrs = (new Fourniss($this->pdo))->find($frs['CODE_FOU'], ['COD_LNG']);
                                }
                                $listeNonOxalink[] = $currentEmail;
                            }
                        }

                        $infoMail = [
                            'NAO' => $idAO,
                            'TITREAO' => sql::getMemo($this->pdo, $consultation['NM_TITRE']),
                            'OBJETAO' => $consultation['OBJET_AO'],
                            'NOM_ACH' => $user['NOM'],
                            'RS_SOC' => Outils::convertLibelleGlobal($this->pdo, $consultation['TYPE_SG'] == 'S' ? 'Societe' : 'GrpSociete', '', $consultation['CODE_STE']),
                            'URL' => Sql::paravrac($this->pdo, 'PF_OXALINK', 'URLACCESOXALINK')
                        ];

                        if (count($listeOxalink) > 0 && !empty($infoFrs)) {
                            Mail::generateMail(
                                $this->pdo,
                                $this->getTranslationService(),
                                implode(',', $listeOxalink),
                                'EXT_FOU_ACCCONF_LINK',
                                $infoFrs['COD_LNG'] ?? $infoFrs['GRPFOU_COD_LNG'],
                                $infoMail,
                                []
                            );
                        }
                        if (count($listeNonOxalink) > 0) {
                            Mail::generateMail(
                                $this->pdo,
                                $this->getTranslationService(),
                                implode(',', $listeNonOxalink),
                                'AO_FOU_ACCORD_CONF',
                                $infoFrs['COD_LNG'] ?? $infoFrs['GRPFOU_COD_LNG'],
                                $infoMail,
                                [],
                                [0 => ($frs['sourcePJ'])]
                            );
                        }
                    } else {
                        $url = $frs['pj'];

                        $urlJS = $this->router->generateUri('GlobalApplication.ChargeDocument.chargeDocument', [
                            'emplacement' => 'tmp',
                            'urlFichier' => $url,
                            'modeAffichage' => 0
                        ]);

                        $listeUrl[] = $urlJS;
                    }

                    $aoEvent = new AoEvent($this->pdo);
                    $aoEvent->rqInsertEventAO($idAO, 'ENV', $trad->t('Demande de signature de l\'accord de confidentialité'), $frs['CODE_FOU'], $frs['TYPE_FG']);

                    $aoDaRep = new AoFour($this->pdo);
                    $aoDaRep->update([
                        'FIC_ACC_CONF_SIGNE' => '',
                    ], ['NO_AO' => $idAO, 'CODE_FOU' => $frs['CODE_FOU'], 'TYPE_FG' => $frs['TYPE_FG']]);
                }
            }

            $attachements     = (new AoPijo($this->pdo))->findAll(['NO_AO' => $idAO]);
            $attachementsList = [];

            foreach ($attachements as $doc) {
                $file =
                    (new ParseBase1())->getRep()->pj
                    . DIRECTORY_SEPARATOR
                    . ltrim($doc['NOM_FIC'], '\\/');
                if (is_file($file)) {
                    Fichier::copyFile(
                        $file,
                        $dest = (new ParseBase1())->getRep()->tmp . $doc['NOM_ORI']
                    );
                    $attachementsList[] = $dest;
                }
            }

            $reponse = null;
            if ($listeFrs) {
                foreach ($listeFrs as $key => &$frs) {
                    if (empty($frs['emails'])) { // TODO : why can it be empty ?
                        continue;
                    }

                    // TODO : move queries elsewhere
                    if ($consultRepo->doesFournissHasAContactWithOxalinkAccess($frs['CODE_FOU']) == 0) {
                        continue;
                    }
                    $infoFrs = (new Fourniss($this->pdo))->find(['CODE' => $frs['CODE_FOU']]);

                    $infoMail = [
                        'NAO' => $idAO,
                        'TITREAO' => sql::getMemo($this->pdo, $consultation['NM_TITRE']),
                        'RS_SOC' => Outils::convertLibelleGlobal($this->pdo, $consultation['TYPE_SG'] == 'S' ? 'Societe' : 'GrpSociete', '', $consultation['CODE_STE']),
                        'OBJETAO' => $consultation['OBJET_AO'],
                        'NOM_ACH' => $user['NOM'],
                        'DTE_VALID_AO' => Date::dateConverte($consultation['DTE_VALID_AO']),
                        'DTE_LANCEMENT' => Date::dateConverte($consultation['DTE_LANCEMENT']),
                        'URL' => Sql::paravrac($this->pdo, 'PF_OXALINK', 'URLACCESOXALINK'),
                        'DATEREPAO' => Date::dateConverte($consultation['DEL_REP']),
                    ];

                    Mail::generateMail(
                        $this->pdo,
                        $this->getTranslationService(),
                        $frs['emails'],
                        'EXT_FOU_INFOAO_LINK',
                        $infoFrs['COD_LNG'],
                        $infoMail,
                        [],
                        $attachementsList
                    );

                    (new AoEvent($this->pdo))->rqInsertEventAO($idAO, 'ENV', '', $frs['CODE_FOU'], $frs['TYPE_FG']);

                    unset($listeFrs[$key]);
                }

                $consultWsdl = new \Modules\Consultation\WebService\Consultation();
                $xmlResult   = $consultWsdl->sendConsultation($idAO, $post['typeConsult'], $listeFrs);
                $reponse     = new \SimpleXMLElement($xmlResult->responseData);
            }

            if ($listeExcel) {
                $envoieExcelService = new EnvoieExcelService($this->pdo, $this->getTranslationService(), $this->router);
                foreach ($listeExcel as $excel) {
                    $listeUrl = array_merge($listeUrl, (array) $envoieExcelService->generationEnvoieExcel(
                        $idAO,
                        $excel,
                        $consultation,
                        $user
                    ));
                }
            }

            if (is_null($reponse) || $reponse->Retour == "O") {
                if ($reponse) {
                    foreach ($reponse->ListeDoc->Doc as $doc) {
                        if ($doc->Fichier != '') {
                            if (($listeFrs[(string) $doc->Message]['parMail'] ?? null) === 0) {
                                $url = $doc->Fichier;

                                $urlJS = $this->router->generateUri('GlobalApplication.ChargeDocument.chargeDocument', [
                                    'emplacement' => 'tmp',
                                    'urlFichier' => $url,
                                    'modeAffichage' => 0
                                ]);

                                $listeUrl[] = $urlJS;
                            }
                        }
                    }
                }

                return new Response(200, [], json_encode([
                    'statut' => 'O',
                    'file' => $listeUrl,
                    'content' => $this->renderer->render('@popup-erreur/information', [
                        'message' => $trad->t('La consultation a bien été envoyée au(x) fournisseur(s).'),
                    ])
                ]));
            } else {
                return new Response(200, [], json_encode([
                    'statut' => 'O',
                    'content' => $this->renderer->render('@popup-erreur/ErreurXml', [
                        'ErreurValid' => $reponse,
                    ]),
                ]));
            }
        } else {
            return new Response(200, [], json_encode([
                'statut' => 'E',
                'content' => $this->renderer->render('@popup-erreur/ErreurCreation', [
                    'ErreurValid' => $validator->getError(),
                ])
            ]));
        }
    }

    public function creerPanierAction(): string
    {
        $idAO = $this->request->getAttribute('idAO');

        $trad = $this->getTranslationService();

        $listeType = [
            'F' => $trad->t('Fournisseur'),
            'G' => $trad->t('Groupement'),
        ];

        $aoEntet = new AoEntet($this->pdo);
        $consult = $aoEntet->find($idAO);

        if ($consult['TYPE_SG'] == 'G') {
            if ($_SESSION['Session_Login'] && !Societe::hasMultiSoc()) {
                $societe  = new \Modules\Ajax\Repository\Listes($this->pdo);
                $societes = $societe->societe($consult['CODE_STE']);
            } else {
                $societes = new \Entity\Model\Societe($this->pdo);
                $societes = $societes->fetchAll([], ['filter_egal_GROUPE' => $consult['CODE_STE']]);
            }

            $listeSoc = [];
            foreach ($societes as $soc) {
                $listeSoc[$soc['CODE_STE']] = $soc['RAIS_SOC'] . ' (' . $soc['CODE_STE'] . ')';
            }
        }

        $aoFour   = new AoFour($this->pdo);
        $listeFrs = $aoFour->findAll(['NO_AO' => $idAO, 'FOU_RETEN' => 'T'], []);

        $reponse = new Reponse($this->pdo);

        foreach ($listeFrs as &$frs) {
            if ($frs['TYPE_FG'] == 'G') {
                $listeTmp = $reponse->getFrsByGrp($frs['CODE_FOU']);

                $listeFrsOnGrp = [];
                foreach ($listeTmp as $val) {
                    $listeFrsOnGrp[$val['CODE']] = $val['RS'] . ' (' . $val['CODE'] . ')';
                    ;
                }
                $frs['listeFrs'] = $listeFrsOnGrp;
            }
        }

        Ariane::generate(1, $trad->t('Sélection de fournisseur'));

        return $this->renderer->render('@Consultation/GestionConsultation/creerPanier', [
            'menuActive' => Session::verifySessionTypeMenuTop(MenuTopEnum::P2P) ? 'eproc' : 'Consultations',
            'menuLeft' => 'gestionAO',
            'idAO' => $idAO,
            'listeType' => $listeType,
            'listeFrs' => $listeFrs,
            'listeSoc' => $listeSoc ?? [],
        ]);
    }

    public function ajaxCreerPanierAction()
    {
        $idAO = $this->request->getAttribute('idAO');
        $post = $this->request->getParsedBody();

        $trad = $this->getTranslationService();

        $aoEntet = new AoEntet($this->pdo);
        $consult = $aoEntet->find($idAO);

        $frsRet    = [];
        $validator = $this->createValidator();
        if ($consult['TYPE_SG'] == 'G') {
            $validator->isFalse($post['SOCIETE'], Trad::strBuild($trad->t('Le champ @1@  est un champ obligatoire.'), $trad->t('Choix de la société')));

            $frsRet['entete']['!value'] = $post['SOCIETE'];
        }

        $aoFour   = new AoFour($this->pdo);
        $listeFrs = $aoFour->findAll(['NO_AO' => $idAO, 'FOU_RETEN' => 'T'], []);

        $frsSelectionner = false;
        $frsRet['FRS']   = [];
        $listeFrsFinal   = [];
        foreach ($listeFrs as $frs) {
            if ($frs['TYPE_FG'] == 'G') {
                $validator->isFalse($post['choixFrs' . $frs['CODE_FOU']], Trad::strBuild($this->getTranslationService()->t('Veuillez saisir le fournisseur lié au groupement @1@.'), $frs['CODE_FOU']));
                $listeFrsFinal[$frs['TYPE_FG'] . Constante::spliter . $frs['CODE_FOU']] = $post['choixFrs' . $frs['CODE_FOU']];
            }


            $frsRet['FRS'][] = [
                '!TYPE_FG' => $frs['TYPE_FG'],
                '!CODE' => $frs['CODE_FOU'],
                '_chk' => ['!value' => ($post['frsSelected' . $frs['TYPE_FG'] . Constante::spliter . $frs['CODE_FOU']] ?? null)],
                '_select' => ['!value' => ($post['choixFrs' . $frs['CODE_FOU']] ?? null)]
            ];

            if (isset($post['frsSelected' . $frs['TYPE_FG'] . Constante::spliter . $frs['CODE_FOU']])) {
                $listeFrsFinal[$frs['TYPE_FG'] . Constante::spliter . $frs['CODE_FOU']] = ($post['frsSelected' . $frs['TYPE_FG'] . Constante::spliter . $frs['CODE_FOU']] ?? null);
            }

            if (isset($post['frsSelected' . $frs['TYPE_FG'] . Constante::spliter . $frs['CODE_FOU']])) {
                $frsSelectionner = true;
            }
        }

        $validator->isFalse($frsSelectionner, $trad->t('Veuillez sélectionner au moins un fournisseur'));

        if ($validator->isValid()) {
            $consultationPanierService = new ConsultationPanierService($this->pdo, $trad, $idAO);
            $controleSociete           = $consultationPanierService->controleSociete($post['SOCIETE'] ?? '');

            if (!is_null($controleSociete)) {
                return $this->createJsonResponse([
                    'statut' => 'E',
                    'responseText' => $this->renderer->render('@popup-erreur/ErreurCreation', ['ErreurValid' => $controleSociete]),
                ]);
            }

            $consultationPanierService->createPanier($this->pdoOxaFT, $listeFrsFinal, $post['SOCIETE'] ?? '', $post);

            Session::setSessionTypeMenuTop();
            return $this->createJsonResponse(['statut' => 'O']);
        } else {
            return $this->createJsonResponse([
                'statut' => 'E',
                'responseText' => $this->renderer->render(
                    '@popup-erreur/ErreurCreation',
                    ['ErreurValid' => $validator->getError()]
                ),
            ]);
        }
    }

    public function popupExportAction(): string
    {
        $post['multiSelectexportRFOBLI1'] = 'AO_ENTET.NO_AO';

        return $this->renderer->render('@GlobalApplication/Popup/popupExport', [
            'pathExport' => $this->router->generateUri('Consultation.GestionConsultation.export'),
            'formFilter' => 'filtre_Consultation',
            'coloneExport' => $this->_exportGetTab(),
            'tabObli' => ['AO_ENTET.CODE'],
            'post' => $post,
            'modeDebug' => false,
        ]);
    }

    public function exportAction(): string
    {
        $post = $this->request->getParsedBody();
        $trad = $this->getTranslationService();

        $arrayMultiSelect = array_filter($post, function ($k) {
            return (bool) stristr($k, 'multiSelect');
        }, ARRAY_FILTER_USE_KEY);

        // Filter any unauthorized fields
        $arrayMultiSelect = array_intersect(
            $arrayMultiSelect,
            array_keys($this->_exportGetTab())
        );

        $listeCS = [];
        foreach ($arrayMultiSelect as $key => &$multiSelect) {
            if (substr($multiSelect, 0, 12) == 'CS_EXTENSION') {
                $listeCS[] = substr($multiSelect, 12);
                unset($arrayMultiSelect[$key]);
            }
        }

        $listeSelect = implode(',', $arrayMultiSelect);

        if (empty($post['okFilter'])) {
            $post = [];
        }

        $listeAO = [];
        if (isset($post['listeAO'])) {
            $listeAO = unserialize($post['listeAO'], ["allowed_classes" => false]);
            unset($post['listeAO']);
        }


        $gestionAO_REPO    = new GestionConsultation($this->pdo);
        $listeConsultation = $gestionAO_REPO->listeConsultation($post, $listeAO, $listeSelect);

        $aoEntet                       = new AoEntet($this->pdo);
        $listeChps                     = $aoEntet->getArchitecture($this->getTranslationService());
        $listeChps['oxaExport_STATUS'] = [
            'nomChamp' => $this->getTranslationService()->t('Statut'),
            'type' => 'TEXT'
        ];

        $champSupp = new ChampSupp($this->pdo);

        //On récupère la liste des champs DATE & BOOL afin de les traités après
        $listeChpsDate = [];
        $listeChpsBool = [];
        $listeChpsMemo = [];
        $keyValue      = [];
        foreach ($listeChps as $key => $value) {
            if ($key == 'oxaExport_STATUS') {
                $keyValue[$key] = $value['nomChamp'];
            } else {
                $keyValue['AO_ENTET.' . $key] = $value['nomChamp'];
            }

            if (isset($value['type'])) {
                if ($value['type'] == 'DATE') {
                    $listeChpsDate[] = $key;
                }
                if ($value['type'] == 'RADIO') {
                    $listeChpsBool[] = $key;
                }
                if ($value['type'] == 'MEMO') {
                    $listeChpsMemo[] = $key;
                }
            }
        }

        $tab = [];
        //On génère l'entete du fichier d'export
        foreach ($arrayMultiSelect as $value) {
            $tab[$value] = $keyValue[$value];
        }

        $repoChampSup = new ChampSupp($this->pdo);
        foreach ($listeCS as &$cs) {
            $cs                                   = $repoChampSup->getinfoOneCs('AO_ENTET', $cs);
            $tab['CS_EXTENSION' . $cs['NUM_FIX']] = $cs['NOM'];
        }

        $listeStatut = [
            '' => '',
            'PREP' => $trad->t('Préparation'),
            'ENCO' => $trad->t('En cours'),
            'TERM' => $trad->t('Terminé'),
        ];

        $oui = $trad->t('Oui');
        $non = $trad->t('Non');
        foreach ($listeConsultation as &$ligne) {
            foreach ($listeCS as $csRFx) {
                $value = null;
                $idCS  = $champSupp->autoCompletCodeEnr($ligne['NO_AO'], '', 'AO_ENTET');
                /** @phpstan-ignore-next-line */
                $value = $champSupp->generateChampSupp('AO_ENTET', $idCS, $csRFx['NUM_FIX']);
                $value = $value[0]['VALUECHAMPSUPP'];

                /** @phpstan-ignore-next-line */
                if ($csRFx['TYPE'] == 'LOGIQUE') {
                    $value = $value == 'O' ? $oui : $non;
                }

                /** @phpstan-ignore-next-line */
                $ligne['CS_EXTENSION' . $csRFx['NUM_FIX']] = $value;
            }

            if (isset($ligne['oxaExport_STATUS'])) {
                $ligne['oxaExport_STATUS'] = $listeStatut[$ligne['oxaExport_STATUS']];
            }

            foreach ($listeChpsDate as $chps) {
                if (isset($ligne[$chps])) {
                    $ligne[$chps] = Date::dateConverte($ligne[$chps]);
                }
            }

            foreach ($listeChpsBool as $chps) {
                if (isset($ligne[$chps])) {
                    $ligne[$chps] = Sql::toBool($ligne[$chps]) ? $oui : $non;
                }
            }

            foreach ($listeChpsMemo as $chps) {
                if (isset($ligne[$chps])) {
                    $ligne[$chps] = Sql::getMemo($this->pdo, $ligne[$chps]);
                }
            }
        }

        \Helpers\ExportTo\Outils::gestionEmailAsync2(
            'export_RFx_' . date('Ymd'),
            $listeConsultation,
            $this->JWTKEY,
            $this->router,
            $this->getTranslationService(),
            $tab
        );

        return 'ok';
    }

    /**
     * @return mixed[]
     */
    private function _exportGetTab(): array
    {
        $tab       = [];
        $listeChps = (new AoEntet($this->pdo))->getArchitecture($this->getTranslationService());
        foreach ($listeChps as $key => $value) {
            $tab['AO_ENTET.' . $key] = $value['nomChamp'];
        }

        $listeTmpCS = (new ChampSupp($this->pdo))->getInfoCS('AO_ENTET');
        foreach ($listeTmpCS as $cs) {
            $tab['CS_EXTENSION' . $cs['NUM_FIX']] = 'CS - ' . $cs['NOM'];// TODO : translate CS ?
        }

        $tab['oxaExport_STATUS'] = $this->getTranslationService()->t('Statut');

        return $tab;
    }


    public function popupCommunicationFournisseurAction(): string
    {
        $idAO = $this->request->getAttribute('idAO');
        $trad = $this->getTranslationService();

        return $this->renderer->render('@Consultation/ChoixFournisseur/popupCommunicationFournisseur', [
            'idAO' => $idAO,
            'trad' => $trad,
        ]);
    }


    public function envoieEmailCommunicationFournisseurAction(): Response
    {
        $post      = $this->request->getParsedBody();
        $idAO      = $this->request->getAttribute('idAO');
        $trad      = $this->getTranslationService();
        $validator = $this->createValidator();

        $infoFou    = (new AoFour($this->pdo))->findAll(['NO_AO' => $idAO]);
        $AoContFour = new AoContFour($this->pdo);
        $Fourniss   = new Fourniss($this->pdo);
        $Grpfou     = new Grpfou($this->pdo);

        $validator->isStringAvecEspace(
            $trad->t('Sujet du mail'),
            $post['EMAIL_SUBJECT'],
            1,
            100
        );
        $validator->isStringAvecEspace(
            $trad->t('Email'),
            $post['EMAIL_BODY'],
            1,
            3000
        );

        if ($validator->getError()) {
            return new Response(
                445,
                [],
                $validator->getError()
            );
        }

        $emails = '';
        $i      = 0;

        $emailNonEnvoye = [];

        $allContactsByFour = [];
        foreach ($infoFou as $key => $id) {
            $consultationService = new ConsultationService($this->pdo, $this->getTranslationService());
            $consultationService->checkAoFourContactWithAoContFour($idAO, $id['CODE_FOU'], $id['TYPE_FG']);

            $allContactsByFour = $AoContFour->findAll([
                'NO_AO' => $idAO,
                'CODE_FOUR' => $id['CODE_FOU'],
                'TYPE_FG' => $id['TYPE_FG'],
            ], ['EMAILCONT', 'CODE_FOUR', 'TYPE_FG']);
            // ! Ajout de l'email du contact présent sur AO_FOUR
            $allContactsByFour[] = [
                'EMAILCONT' => $id['EMAILCONT'],
                'CODE_FOUR' => $id['CODE_FOU'],
                'TYPE_FG' => $id['TYPE_FG'],
            ];

            foreach ($allContactsByFour as $contact) {
                if ($contact['EMAILCONT']) {
                    $emails .= ($i == 0) ? $contact['EMAILCONT'] : ',' . $contact['EMAILCONT'];
                    $i++;
                } else {
                    if ($id['TYPE_FG'] == 'F') {
                        $emailNonEnvoye[$id['CODE_FOU']] = $Fourniss->find($id['CODE_FOU'])['RS'] ?? '';
                    } else {
                        $emailNonEnvoye[$id['CODE_FOU']] = $Grpfou->find($id['CODE_FOU'])['RS'] ?? '';
                    }
                }
            }
            unset($infoFou[$key]); // Suppression ici pour ne pas qu'un event soit créé par la suite
        }

        if (empty($emails)) {
            return new Response(
                443,
                [],
                $trad->t('Aucun contact fournisseur sur votre consultation ne dispose d\'un email.')
            );
        }

        $aoEntet      = new AoEntet($this->pdo);
        $consultation = $aoEntet->find($idAO);

        $hastutilEntity = new Hastutil($this->pdo);
        $user           = $hastutilEntity->find($consultation['ACH']);

        $post['EMAIL_BODY'] = $post['EMAIL_BODY'] . "\r\n\r\n" . $trad->t('Cordialement') . ",\r\n\r\n" . $user['NOM'];

        (new EnvoiMail())->envoiMail([
            'destinataires' => '',
            'sujet' => $post['EMAIL_SUBJECT'],
            'message' => $post['EMAIL_BODY'],
            'copie ' => '',
            'copie_cachee' => $emails,
            'pj' => [],
        ]);

        $AoEvent = new AoEvent($this->pdo);
        foreach ($allContactsByFour as $frs) {
            $message = $trad->t('Sujet de la communication envoyé à') . ' ' . $frs['EMAILCONT'] . ' : ' . $post['EMAIL_SUBJECT'];
            $AoEvent->rqInsertEventAO($idAO, 'CFR', $message, $frs['CODE_FOUR'], $frs['TYPE_FG']);
        }

        if (count($emailNonEnvoye) > 0) {
            $contactInfo = '';
            $i           = 0;
            foreach ($emailNonEnvoye as $codeFour => $RS) {
                $contactInfo .= ($i == 0) ? $RS . ' (' . $codeFour . ')' : ', ' . $RS . ' (' . $codeFour . ')';
                $i++;
            }
            return new Response(
                443,
                [],
                $trad->t('Un email n\'a pu être envoyé aux fournisseurs suivants') . $trad->colon() . '<br>' . $contactInfo . '.<br>' . $trad->t('Un email a bien été envoyé aux autres fournisseurs.')
            );
        }

        return new Response(200, [], $trad->t('Un email a bien été envoyé aux fournisseurs.'));
    }
}
