<?php

namespace Modules\Consultation\Service;

use Entity\Model\AoContFour;
use Entity\Model\AoExcFofo;
use Entity\Model\AoFour;
use Entity\Model\AoLigne;
use Entity\Model\AoPijo;
use Entity\Model\AoClaus;
use Entity\Model\AoQstTh;
use Entity\Model\AoRepSl;
use Entity\Model\ConsultDocDefault;
use Entity\Model\Hastutil;
use Helpers\Trad\ITrad;
use Modules\Evaluation\Repository\BibliothequeDeQuestions;
use Helpers\Outil\Sql;
use Entity\Model\Docatt;
use Modules\Consultation\Repository\Consultation;
use Entity\Model\AoQstQ;
use Entity\Model\AoQstR;
use Helpers\Fichier\Fichier;
use Entity\Model\AoEntet;
use Modules\Consultation\Repository\AoEvent;
use Entity\Model\AoRetParLigne;
use Entity\Model\AoDocAttendus;
use Entity\Model\AoPlann;
use Helpers\ChampsSupplementaire\ChampSupp;
use Modules\Consultation\Repository\GestionConsultation;
use Modules\Consultation\Repository\Reponse;
use Modules\ProjetAchat\Service\ActionService;
use Helpers\Outil\Mail;
use Helpers\Outil\Outils;
use Helpers\Outil\Date;
use Helpers\Session\ParseBase1;
use Skeleton\Router;

class ConsultationService
{
    private \PDO $pdo;
    private ITrad $trad;
    private ?Router $router;

    public function __construct(\PDO $pdo, ITrad $trad, ?Router $router = null)
    {
        $this->pdo = $pdo;
        $this->trad = $trad;
        $this->router = $router;
    }
    
    public function deleteComposant(string $idAO, string $composant, bool $all = true, bool $accordConf = false) : void
    {
        if ($composant=='COMP_FOURNISS') {
            /** delete fournisseur **/
            $aoFour = new AoFour($this->pdo);
            $aoFour->delete(['NO_AO' => $idAO]);
        } elseif ($composant=='COMP_LIGNE') {
            /** delete ligne **/
            $aoLigne = new AoLigne($this->pdo);
            $allLigne = $aoLigne->fetchAll([], ['filter_egal_NO_AO' => $idAO]);
            $aoLigne->delete(['NO_AO' => $idAO]);
            
            foreach ($allLigne as $ligne) {
                Sql::deleteMemos($this->pdo, $ligne['NM_DCOMP']);
                sql::deleteMemos($this->pdo, $ligne['NM_ST_AV']);
            }
        } elseif ($composant=='COMP_PJ') {
            /** delete PJ **/
            $aoPJ = new AoPijo($this->pdo);
            $allPj = $aoPJ->fetchAll([], ['filter_egal_NO_AO' => $idAO]);
            $aoPJ->delete(['NO_AO' => $idAO]);
            
            foreach ($allPj as $pj) {
                unlink((new ParseBase1())->getRep()->pj.$pj['NOM_FIC']);
            }
        } elseif ($composant=='COMP_DOC_ATT') {
            /** delete doc attendu **/
            $aoDocAttendu = new AoDocAttendus($this->pdo);
            $aoDocAttendu->delete(['NO_AO' => $idAO]);
        } elseif ($composant=='COMP_DOC_INT') {
            /** delete doc interne + file + memo **/
            $docAtt = new Docatt($this->pdo);
            $listeDoc = $docAtt->fetchAll([], ['filter_egal_NO_DA' => 'AO_ENTET', 'filter_egal_COD_ENR' => str_pad($idAO, 9, '0', STR_PAD_LEFT)]);
            
            foreach ($listeDoc as $doc) {
                $docAtt->delete([
                'NO_DA' => 'AO_ENTET',
                'COD_ENR' => str_pad($idAO, 9, '0', STR_PAD_LEFT)
                ]);
                if ($all || $doc['NO_ORDRE'] != $accordConf) {
                    unlink((new ParseBase1())->getRep()->pj.$doc['NOM_FIC']);
                    sql::deleteMemos($this->pdo, $doc['NM_COMM']);
                }
            }
        } elseif ($composant=='COMP_CLAUSE') {
            /** delete clause + memo **/
            $aoClause = new AoClaus($this->pdo);
            $listeClause = $aoClause->fetchAll([], ['filter_egal_NO_AO' => $idAO]);
            $aoClause->delete(['NO_AO' => $idAO]);
            
            foreach ($listeClause as $clause) {
                sql::deleteMemos($this->pdo, $clause['NM_PARAG']);
            }
        } elseif ($composant=='COMP_QUEST') {
            /** delete Question (AO_QST_TH - AO_QST_R - AO_QST_Q) + memo **/
            $aoQstTh = new AoQstTh($this->pdo);
            $themePere = $aoQstTh->fetchAll([], ['filter_egal_NO_AO' => $idAO, 'filter_egal_ID_PERE' => '']);
            
            $bibliotheque = new BibliothequeDeQuestions($this->pdo);
            foreach ($themePere as $theme) {
                if ($theme['ID_THEME'] != 'APRIX' || $all) {
                    $bibliotheque->deleteTheme('AO', $idAO, $theme['ID_THEME']);
                }
            }
        }
    }
    
    public function duplicateComposant(string $idAOOrigine, string $idNewAo, string $composant, bool $newAccord = false, string $societe = '', bool $dontDuplicateAccConf = false) : void
    {
        $consultationRepo = new Consultation($this->pdo);
        if ($composant=='COMP_FOURNISS') {
            $consultationRepo->duplicateFrsAO($idAOOrigine, $idNewAo);
            
            $consultationRepo = new Consultation($this->pdo);
            $listeAoFour = $consultationRepo->getListeFrsAo($idNewAo);
            $aoFourRepo = new AoFour($this->pdo);
    
            foreach ($listeAoFour as $frs) {
                if (Sql::boolSql($frs['GEREPORTAIL'])) {
                    $ctcFound = $consultationRepo->getOxalinkUser($frs['CODE_FOU'], $frs['EMAILCONT']);
    
                    if (!$ctcFound) {
                        $ctcUpdate = $consultationRepo->getOxalinkUser($frs['CODE_FOU']);
    
                        if ($ctcUpdate) {
                            $aoFourRepo->update([
                            'NOM_CTCT'   => $ctcUpdate['NOM'],
                            'TEL_CTCT'   => $ctcUpdate['TEL'],
                            'FAX_CTCT'   => $ctcUpdate['FAX'],
                            'POR_CTCT'   => $ctcUpdate['TELPORT'],
                            'EMAILCONT'  => $ctcUpdate['EMAIL'],
                            ], ['NO_AO' => $idNewAo, 'CODE_FOU' => $frs['CODE_FOU']]);
                        }
                    }
                } else {
                    $ctcFound = $consultationRepo->getContactFrs($frs['CODE_FOU'], $frs['EMAILCONT']);
                    
                    if (!$ctcFound) {
                        $ctcUpdate = $consultationRepo->getContactFrs($frs['CODE_FOU']);
    
                        if ($ctcUpdate) {
                            $aoFourRepo->update([
                            'NOM_CTCT'   => $ctcUpdate['NOM'],
                            'TEL_CTCT'   => $ctcUpdate['TEL'],
                            'FAX_CTCT'   => $ctcUpdate['FAX'],
                            'POR_CTCT'   => $ctcUpdate['TELPORT'],
                            'EMAILCONT'  => $ctcUpdate['EMAIL'],
                            ], ['NO_AO' => $idNewAo, 'CODE_FOU' => $frs['CODE_FOU']]);
                        }
                    }
                }

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

                $allContactFour = $AoContFour->findAll(['NO_AO' => $idAOOrigine]);

                foreach ($allContactFour as $contactFour) {
                    $AoContFour->insert([
                        'NO_AO'     => $idNewAo,
                        'CODE_FOUR' => $contactFour['CODE_FOUR'],
                        'TYPE_FG'   => $contactFour['TYPE_FG'],
                        'NUM_ORDRE' => $contactFour['NUM_ORDRE'],
                        'NOM_CTCT'  => $contactFour['NOM_CTCT'],
                        'TEL_CTCT'  => $contactFour['TEL_CTCT'],
                        'FAX_CTCT'  => $contactFour['FAX_CTCT'],
                        'POR_CTCT'  => $contactFour['POR_CTCT'],
                        'EMAILCONT' => $contactFour['EMAILCONT']
                    ]);
                    $consultationService = new ConsultationService($this->pdo, $this->trad);
                    $consultationService->checkAoFourContactWithAoContFour((int) $idNewAo, $contactFour['CODE_FOUR'], $contactFour['TYPE_FG']);
                }
            }
        } elseif ($composant=='COMP_LIGNE') {
            $aoLigne = new AoLigne($this->pdo);
            $listeLigne = $aoLigne->fetchAll([], ['filter_egal_NO_AO' => $idAOOrigine]);
            
            foreach ($listeLigne as $ligne) {
                $memoDesComp = sql::updateMemo($this->pdo, '', sql::getMemo($this->pdo, $ligne['NM_DCOMP']));
                $memoStAv = sql::updateMemo($this->pdo, '', sql::getMemo($this->pdo, $ligne['NM_ST_AV']));
                
                if (!$societe) {
                    $societe = $ligne['CODE_STE'];
                }
                
                $aoLigne->insert([
                'NO_AO' => $idNewAo,
                'NO_PO' => $ligne['NO_PO'],
                'NO_DA' => $ligne['NO_DA'],
                'NO_PO_DA' => $ligne['NO_PO_DA'],
                'CHIF_EXEC' => $ligne['CHIF_EXEC']??'',
                'CODE_ART' => $ligne['CODE_ART']??'',
                'DES' => $ligne['DES']??'',
                'QTE' => $ligne['QTE']??'',
                'DELAI' => $ligne['DELAI']??'',
                'UNITE' => $ligne['UNITE']??'',
                'NM_DCOMP' => $memoDesComp,
                'BUDGET' => $ligne['BUDGET']??'',
                'CODE_STE' => $societe,
                'SSFAMILLE' => $ligne['SSFAMILLE']??'',
                'NM_ST_AV' => $memoStAv,
                'numerique_ST_APLIG' => Sql::setBoolSql(sql::boolSql($ligne['ST_APLIG'])),
                'TITREST' => $ligne['TITREST']??'',
                'COD_FAB' => $ligne['COD_FAB']??'',
                'COD_GAM' => $ligne['COD_GAM']??'',
                'REF_FAB' => $ligne['REF_FAB']??'',
                'PRIX_REF' => $ligne['PRIX_REF']??'',
                ]);
            }
        } elseif ($composant=='COMP_PJ') {
            $aoPJ = new AoPijo($this->pdo);
            $allPj = $aoPJ->fetchAll([], ['filter_egal_NO_AO' => $idAOOrigine]);

            foreach ($allPj as $pj) {
                if (!empty($pj['NOM_FIC'])) {
                    $newFile = Fichier::copyFileFicPJ($pj['NOM_FIC']);
                }
                $aoPJ->insert([
                'NO_AO' => $idNewAo,
                'NO_ORDRE' => $pj['NO_ORDRE'],
                'TYPE_PJ' => $pj['TYPE_PJ'],
                'TITRE' => $pj['TITRE'],
                'numerique_COPIE' => Sql::setBoolSql(sql::boolSql($pj['COPIE'])),
                'numerique_LECTURE' => Sql::setBoolSql(sql::boolSql($pj['LECTURE'])),
                'numerique_IMP_PJ' => Sql::setBoolSql(sql::boolSql($pj['IMP_PJ'])),
                'numerique_IMP_TITRE' => Sql::setBoolSql(sql::boolSql($pj['IMP_TITRE'])),
                'NOM_FIC' => $newFile['newPath'] ?? '',
                'NOM_ORI' => $pj['NOM_ORI'],
                'FIC_PDF' => $pj['FIC_PDF'],
                ]);
            }
        } elseif ($composant=='COMP_DOC_ATT') {
            $aoDocAttendu = new AoDocAttendus($this->pdo);
            
            $listeDoc = $aoDocAttendu->fetchAll([], ['filter_egal_NO_AO' => $idAOOrigine]);
            
            foreach ($listeDoc as $doc) {
                $aoDocAttendu->insert([
                'NO_AO' => $idNewAo,
                'NUM_ORDRE' => $doc['NUM_ORDRE'],
                'CODE_DOC' => $doc['CODE_DOC'],
                'TITRE_DOC' => $doc['TITRE_DOC'],
                'COMMENTAIRE' => $doc['COMMENTAIRE'],
                'numerique_OBLIGATOIRE' => Sql::setBoolSql(sql::boolSql($doc['OBLIGATOIRE'])),
                ]);
            }
        } elseif ($composant=='COMP_DOC_INT') {
            $aoEntet = new AoEntet($this->pdo);
            $infoConsult = $aoEntet->find($idAOOrigine);
            
            $docAtt = new Docatt($this->pdo);
            $listeDoc = $docAtt->fetchAll([], ['filter_egal_NO_DA' => 'AO_ENTET', 'filter_egal_COD_ENR' => str_pad($idAOOrigine, 9, "0", STR_PAD_LEFT)]);
            
            foreach ($listeDoc as $doc) {
                if ($infoConsult['ACC_CONF_NODOC'] == $doc['NO_ORDRE'] && $newAccord) {
                } elseif (!$newAccord && $dontDuplicateAccConf) {
                } else {
                    $idMemo = sql::updateMemo($this->pdo, '', sql::getMemo($this->pdo, $doc['NM_COMM']));
                    
                    $newFile = Fichier::copyFileFicPJ($doc['NOM_FIC']);
                    
                    $docAtt->insert([
                    'NO_DA' => $doc['NO_DA'],
                    'NO_ORDRE' => $doc['NO_ORDRE'],
                    'TYPE_PJ' => $doc['TYPE_PJ'],
                    'TITRE' => $doc['TITRE'],
                    'numerique_COPIE' => sql::setBoolSql(sql::boolSql($doc['COPIE'])),
                    'NOM_FIC' => $newFile['newPath'],
                    'DT_PARUT' => $doc['DT_PARUT'],
                    'DT_VALID' => $doc['DT_VALID'],
                    'COD_ENR' => str_pad($idNewAo, 9, '0', STR_PAD_LEFT),
                    'AUTEUR' => $doc['AUTEUR'],
                    'CENTRE' => $doc['CENTRE'],
                    'NM_COMM' => $idMemo,
                    'NOM_ORI' => $doc['NOM_ORI'],
                    'numerique_FI_TECH' => sql::setBoolSql(sql::boolSql($doc['FI_TECH'])),
                    'CODE_FOU' => $doc['CODE_FOU'],
                    'numerique_NPRELANCE' => sql::setBoolSql(sql::boolSql($doc['NPRELANCE'])),
                    'numerique_PJ_CDE' => sql::setBoolSql(sql::boolSql($doc['PJ_CDE'])),
                    'numerique_GERE_PAR_PARTENAIRE' => sql::setBoolSql(sql::boolSql($doc['GERE_PAR_PARTENAIRE'])),
                    'numerique_DOC_INUTILE' => sql::setBoolSql(sql::boolSql($doc['DOC_INUTILE'])),
                    'CODE_CAT' => $doc['CODE_CAT'],
                    'DTE_DERNREL' => $doc['DTE_DERNREL'],
                    'numerique_CONTRATCDE' => sql::setBoolSql(sql::boolSql($doc['CONTRATCDE'])),
                    ]);
                    
                    if ($infoConsult['ACC_CONF_NODOC'] == $doc['NO_ORDRE']) {
                        $aoEntetEntity = new AoEntet($this->pdo);
                        $aoEntetEntity->update(['ACC_CONF_NODOC' => $doc['NO_ORDRE']], $idNewAo);
                    }
                }
            }
        } elseif ($composant=='COMP_CLAUSE') {
            $aoClause = new AoClaus($this->pdo);
            $listeClause = $aoClause->fetchAll([], ['filter_egal_NO_AO' => $idAOOrigine]);
            
            foreach ($listeClause as $clause) {
                $idMemos = sql::updateMemo($this->pdo, '', sql::getMemo($this->pdo, $clause['NM_PARAG']));
                
                $aoClause->insert([
                'NO_AO' => $idNewAo,
                'NO_ORDRE' => $clause['NO_ORDRE'],
                'NM_PARAG' => $idMemos,
                ]);
            }
        } elseif ($composant=='COMP_QUEST') {
            $aoQstTh = new AoQstTh($this->pdo);
            $themePere = $aoQstTh->fetchAll([], ['filter_egal_NO_AO' => $idAOOrigine]);
            
            foreach ($themePere as $theme) {
                $idMemo = sql::updateMemo($this->pdo, '', sql::getMemo($this->pdo, $theme['NM_COM']));
                
                $aoQstTh->insert([
                'NO_AO' => $idNewAo,
                'ID_THEME' => $theme['ID_THEME'],
                'ID_PERE' => $theme['ID_PERE'],
                'LIB_THEME' => $theme['LIB_THEME'],
                'NM_COM' => $idMemo,
                'NM_ORDRE' => $theme['NM_ORDRE'],
                'POIDS' => $theme['POIDS'],
                'THEME_LIE' => $theme['THEME_LIE'],
                ]);
            }
            $aoQstQ = new AoQstQ($this->pdo);
            $listeQuestion = $aoQstQ->fetchAll([], ['filter_egal_NO_AO' => $idAOOrigine]);
                        
            foreach ($listeQuestion as $question) {
                $idMemo = sql::updateMemo($this->pdo, '', sql::getMemo($this->pdo, $question['NM_COM']));
                $idMemo = sql::updateMemo($this->pdo, '', sql::getMemo($this->pdo, $question['NM_COM']));
                
                $aoQstQ->insert([
                'NO_AO' => $idNewAo,
                'ID_THEME' => $question['ID_THEME'],
                'ID_QUEST' => $question['ID_QUEST'],
                'G_B_QST_LIE' => $question['G_B_QST_LIE'],
                'LIB_QUEST' => $question['LIB_QUEST'],
                'NM_COM' => $idMemo,
                // @phpstan-ignore-next-line TODO MSA regarder le $ligne['QUEST_FOUR']
                'numerique_QUEST_FOUR' => Sql::setBoolSql(sql::boolSql($question['QUEST_FOUR'] ?? false)),
                'TYPE_REP' => $question['TYPE_REP'],
                'NOTE_FAUX' => $question['NOTE_FAUX'],
                'NOTE_VRAI' => $question['NOTE_VRAI'],
                'NUM_FORMAT' => $question['NUM_FORMAT'],
                'NUM_MIN' => $question['NUM_MIN'],
                'NUM_MAX' => $question['NUM_MAX'],
                'POIDS' => $question['POIDS'],
                'NM_ORDRE' => $question['NM_ORDRE'],
                'ID_MODEL' => $question['ID_MODEL'],
                ]);
            }
            
            $aoQstR = new AoQstR($this->pdo);
            $listeReponse = $aoQstR->fetchAll([], ['filter_egal_NO_AO' => $idAOOrigine]);
            
            foreach ($listeReponse as $reponse) {
                $idMemo = sql::updateMemo($this->pdo, '', sql::getMemo($this->pdo, $reponse['NM_COM']));
                
                $aoQstR->insert([
                'NO_AO' => $idNewAo,
                'ID_THEME' => $reponse['ID_THEME'],
                'ID_QUEST' => $reponse['ID_QUEST'],
                'ID_REP' => $reponse['ID_REP'],
                'TXT_REP' => $reponse['TXT_REP'],
                'NM_COM' => $idMemo,
                // @phpstan-ignore-next-line TODO MSA regarder le $ligne['COM_MANUEL']
                'numerique_COM_MANUEL' => Sql::setBoolSql(sql::boolSql($reponse['COM_MANUEL'] ?? false)),
                'NOTE' => $reponse['NOTE'],
                ]);
            }
        }
    }
    
    public function validateConsultation(string $idAO) : void
    {
        $aoQstQ = new AoQstQ($this->pdo);
        $aoQstQ->update(['G_B_QST_LIE' => ''], ['NO_AO' => $idAO]);
        
        $aoQstTh = new AoQstTh($this->pdo);
        $aoQstTh->update(['THEME_LIE' => ''], ['NO_AO' => $idAO]);


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

        $aoPijo = new AoPijo($this->pdo);
        // on supprime les PJ qui n'ont pas de fichier renseigné
        $aoPijo->delete(['NO_AO' => $idAO, 'NOM_FIC' => '']);
        
        if (Sql::toBool($consultation['ENVOI_EMAIL_AUTO_FRS']??'')) {
            $acheteur = (new Hastutil($this->pdo))->find($consultation['ACH']);
        
            $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'       => $acheteur['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']),
                'NOMACH'        => $acheteur['NOM'],
            ];
            $consultRepo = new Consultation($this->pdo);

            $listeOxalink = [];
            $listeNonOxalink = [];

            $allCtcts = $consultRepo->getAllCtcWithCheckIfOxalinkAccess($idAO);

            foreach ($allCtcts as $currentCtct) {
                if ($currentCtct['fourHasContactWithOxalinkAccess']) {
                    $listeOxalink[] = $currentCtct;
                } else {
                    $listeNonOxalink[] = $currentCtct;
                }
            }
            
            foreach ($listeOxalink as $ctct) {
                if (Sql::boolSql($consultation['ACC_CONF']) == true) {
                    Mail::generateMail(
                        $this->pdo,
                        $this->trad,
                        $ctct['EMAILCONT'],
                        'EXT_FOU_ACCCONF_LINK',
                        $ctct['COD_LNG'],
                        $infoMail,
                        [],
                    );
                } else {
                    $infoMail['NOM_ACH'] = $infoMail['NOMACH'];
                    Mail::generateMail(
                        $this->pdo,
                        $this->trad,
                        $ctct['EMAILCONT'],
                        'EXT_FOU_INFOAO_LINK',
                        $ctct['COD_LNG'],
                        $infoMail,
                        [],
                    );
                }

                $message = Sql::boolSql($consultation['ACC_CONF']) == true
                    ? 'Demande de signature de l\'accord de confidentialité'
                    : '';
                $aoEvent->rqInsertEventAO($idAO, 'ENV', $message, $ctct['CODE_FOUR'], $ctct['TYPE_FG']);
            }

            $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']);

            if (Sql::boolSql($consultation['ACC_CONF']) == true) {
                foreach ($listeNonOxalink as $ctctNonOxalink) {
                    $new_name = 'Consult_'.$idAO.'_'.$ctctNonOxalink['CODE_FOUR']
                    .'_'.str_replace('t| ', '', $this->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);

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

                    Mail::generateMail(
                        $this->pdo,
                        $this->trad,
                        $ctctNonOxalink['EMAILCONT'],
                        'AO_FOU_ACCORD_CONF',
                        $ctctNonOxalink['COD_LNG'],
                        $infoMail,
                        [],
                        [$ctctNonOxalink['sourcePJ']]
                    );

                    $aoEvent->rqInsertEventAO($idAO, 'ENV', 'Demande de signature de l\'accord de confidentialité', $ctctNonOxalink['CODE_FOUR'], $ctctNonOxalink['TYPE_FG']);
                }
            } else {
                $AoExcFofo = new AoExcFofo($this->pdo);

                $listeFrs = [];
                foreach ($listeNonOxalink as $ctctNonOxalink) {
                    if (!isset($listeFrs[$ctctNonOxalink['CODE_FOUR']])) {
                        $listeFrs[$ctctNonOxalink['CODE_FOUR']] = [
                            'CODE_FOU'          => $ctctNonOxalink['CODE_FOUR'],
                            'TYPE_FG'           => $ctctNonOxalink['TYPE_FG'],
                            'parMail'           => 'true',
                            'emails'            => $ctctNonOxalink['EMAILCONT']
                        ];

                        // TODO : merge queries
                        $paramExcelByfrs = $AoExcFofo->find([
                            'SOCIETE' => $consultation['CODE_STE'],
                            'CTRE' => $consultation['EMETTEUR'],
                            'CODE_FOU' => $ctctNonOxalink['CODE_FOUR']
                        ]);
                        $paramExcelDefaut = $AoExcFofo->getForm($consultation);

                        if ($paramExcelByfrs) {
                            $listeFrs[$ctctNonOxalink['CODE_FOUR']]['typeFormatExcel'] = $paramExcelByfrs['CODEFORM']??'';
                            $listeFrs[$ctctNonOxalink['CODE_FOUR']]['versionFormat'] = $paramExcelByfrs['VERSFORM']??'';
                        } else {
                            $listeFrs[$ctctNonOxalink['CODE_FOUR']]['typeFormatExcel'] = $paramExcelDefaut['CODEFORM']??'';
                            $listeFrs[$ctctNonOxalink['CODE_FOUR']]['versionFormat'] = $paramExcelDefaut['VERSFORM']??'';
                        }
                    } else {
                        $listeFrs[$ctctNonOxalink['CODE_FOUR']]['emails'] .= ','.$ctctNonOxalink['EMAILCONT'];
                    }
                }

                $envoieExcelService = new EnvoieExcelService($this->pdo, $this->trad, $this->router);
                
                foreach ($listeFrs as $key => &$frs) {
                    if ($frs['typeFormatExcel'] !== '' && $frs['versionFormat'] !== '') {
                        $envoieExcelService->generationEnvoieExcel(
                            $idAO,
                            $frs,
                            $consultation,
                            $acheteur
                        );
                        unset($listeFrs[$key]);
                    }
                }

                $consultWsdl = new \Modules\Consultation\WebService\Consultation();
                $xmlResult = $consultWsdl->sendConsultation($idAO, "P", $listeFrs);
                $reponse = new \SimpleXMLElement($xmlResult->responseData);
            }
        }
        
        $aoEvent = new AoEvent($this->pdo);
        $aoEvent->rqInsertEventAO($idAO, 'VAL');

        $noEvent = $aoEvent->getLastOrder($idAO, 'VAL')['MAX_NUM_ORDRE'];

        $AoEntet->update([
            'DTE_VALID_AO' => date('Ymd'),
            'EVE_VALPREP' => $noEvent,
        ], $idAO);
    }

    /**
     * @return array
     *      arrayRepFrs : Liste des dernières réponse par Frs
     *      arrayCompare : Liste du prix le plus bas pour chaque ligne
     *      arraySelected : Liste des frs selectionné pour chaque ligne (si AO_REP vide, on met le plus bras par défaut)
     *      totalFrs : Cumul des lignes frs
     *      totalSelected : Cumul des lignes selectionné frs
     */
    public function calculeChoixFrs(string $idAO, &$listeFrs) : array
    {
        $aoDocAttendu = new AoDocAttendus($this->pdo);
        $docAttenduActif = $aoDocAttendu->find(['NO_AO' => $idAO, 'OBLIGATOIRE' => 'T']);
        
        $reponseRepo = new Reponse($this->pdo);
        $gestionConsu = new GestionConsultation($this->pdo);
        $ligneConsultation = $gestionConsu->listeLigneConsultation($idAO);
        
        $arrayRepFrs = [];
        $totalFrs = [];
        $totalSelected = [];
        $arrayCompare = [];
        $arraySelected = [];

        $aoRepSl = new AoRepSl($this->pdo);
        
        //On boucle sur tout les fournisseurs
        foreach ($listeFrs as &$frs) {
            //init du calcule par fournisseur
            $totalFrs[$frs['CODE_FOU']] = 0;
            $totalSelected[$frs['CODE_FOU']] = 0;
            //On boucle sur toute les lignes de consultation (par fournisseur)
            foreach ($ligneConsultation as $ligne) {
                $infoRep = $reponseRepo->getInfoRep($idAO, $frs['CODE_FOU'], $frs['TYPE_FG'], $ligne['NO_PO']);

                $listePJ = null;

                if ($infoRep) {
                    $listeRepSl = $aoRepSl->findAll([
                    'NO_AO' => $idAO,
                    'NO_PO_AO' => $ligne['NO_PO'],
                    'DTE_REP' => $infoRep['DTE_REP'],
                    'CODE_FOU' => $infoRep['CODE_FOU'],
                    'TYPE_FG' => $infoRep['TYPE_FG'],
                    'C_V' => $infoRep['C_V'],
                    ]);

                    $totalSousLigne = 0;

                    if ($listeRepSl) {
                        foreach ($listeRepSl as $row) {
                            $totalSousLigne += (float)$row['QTE_PROP'] * (float)$row['PU'];
                        }

                        $infoRep['TOTAL_REPSL'] = $totalSousLigne;
                    }

                    $note = $reponseRepo->getNoteFrs($idAO, $frs['CODE_FOU'], $frs['TYPE_FG'], $infoRep['C_V'], $infoRep['DTE_REP']);
                    
                    $frs['NOTE'] = $note[0];
                    
                    $frs['DTE_REP'] = $infoRep['DTE_REP'];
                    
                    if ($docAttenduActif) {
                        $listePJ = $reponseRepo->getListDocAtt($idAO, $frs['TYPE_FG'], $frs['CODE_FOU'], $infoRep['C_V'], $infoRep['DTE_REP'], true);
                    }
                    
                    $frs['C_V'] = $infoRep['C_V'];
                    $frs['docAbsent'] = $listePJ? true:false;
                    $frs['repDepasse'] = $infoRep['DTELIMIT']<date('Ymd');
                    
                    $arrayRepFrs[$frs['CODE_FOU']][$ligne['NO_PO']] = $infoRep;
                    $totalFrs[$frs['CODE_FOU']] += ((float)$infoRep['QTE']*(float)$infoRep['PU']);
                    
                    //Genere le tableau des prix les plus bas (afin de mettre la case en vert dans la vue)
                    if (isset($arrayCompare[$ligne['NO_PO']])) {
                        if ((float)$infoRep['PU'] == 0) {
                            if ((float)$totalSousLigne && (float)$arrayCompare[$ligne['NO_PO']]['savePU'] > (float)$totalSousLigne) {
                                $arrayCompare[$ligne['NO_PO']] = [
                                'CODE_FOU' => $frs['CODE_FOU'],
                                'TYPE_FG' => $frs['TYPE_FG'],
                                'C_V' => $infoRep['C_V'],
                                'saveQTE' => $infoRep['QTE'],
                                'savePU' => $totalSousLigne
                                ];
                            }
                        } else {
                            if (((float) $arrayCompare[$ligne['NO_PO']]['savePU'] > (float)$infoRep['PU'])) {
                                $arrayCompare[$ligne['NO_PO']] = [
                                'CODE_FOU' => $frs['CODE_FOU'],
                                'TYPE_FG' => $frs['TYPE_FG'],
                                'C_V' => $infoRep['C_V'],
                                'saveQTE' => $infoRep['QTE'],
                                'savePU' => $infoRep['PU']
                                ];
                            }
                        }
                    } elseif ((float)$infoRep['PU'] != 0) {
                        $arrayCompare[$ligne['NO_PO']] = [
                        'CODE_FOU' => $frs['CODE_FOU'],
                        'TYPE_FG' => $frs['TYPE_FG'],
                        'C_V' => $infoRep['C_V'],
                        'saveQTE' => $infoRep['QTE'],
                        'savePU' => $infoRep['PU']
                        ];
                    } elseif ($totalSousLigne != 0) {
                        $arrayCompare[$ligne['NO_PO']] = [
                        'CODE_FOU' => $frs['CODE_FOU'],
                        'TYPE_FG' => $frs['TYPE_FG'],
                        'C_V' => $infoRep['C_V'],
                        'saveQTE' => $infoRep['QTE'],
                        'savePU' => $totalSousLigne
                        ];
                    }
                    
                    
                    //Genere table de fournisseur au prix le plus bas si aucun fournisseur n'a été séléctionné pour cette ligne
                    if ($infoRep['CODE_FOU'] == '') {
                        $arraySelected[$ligne['NO_PO']] =  $arrayCompare[$ligne['NO_PO']]??'';
                    } else {
                        if ($infoRep['CODE_FOU'] == $frs['CODE_FOU']) {
                            $arraySelected[$ligne['NO_PO']] =  [
                            'CODE_FOU' => $frs['CODE_FOU'],
                            'TYPE_FG' => $frs['TYPE_FG'],
                            'C_V' => $infoRep['C_V'],
                            'saveQTE' => $infoRep['QTE'],
                            'savePU' => $infoRep['PU']
                            ];
                        }
                    }
                }
            }
        }

        //On insère la ligne par defaut si elle n'existe pas déjà
        $aoRetParLigne = new AoRetParLigne($this->pdo);
        /** @var array<mixed> $selected */
        foreach ($arraySelected as $key => $selected) {
            if ($selected['CODE_FOU'] != '') {
                $checkLigne = $aoRetParLigne->find([
                'NO_AO' => $idAO,
                'NO_PO' => $key,
                'CODE_FOU' => $selected['CODE_FOU'],
                'TYPE_FG' => $selected['TYPE_FG'],
                'RET_CV' => $selected['C_V']
                ]);
                
                if (!$checkLigne) {
                    $aoRetParLigne->insert([
                        'NO_AO' => $idAO,
                        'NO_PO' => $key,
                        'CODE_FOU' => $selected['CODE_FOU'],
                        'TYPE_FG' => $selected['TYPE_FG'],
                        'RET_CV' => $selected['C_V']
                    ]);
                }
                
                $totalSelected[$selected['CODE_FOU']] += ((float)$selected['saveQTE']*(float)$selected['savePU']);
            }
        }

        $returnArray = [];

        $returnArray = [
        'arrayRepFrs' => $arrayRepFrs,
        'totalFrs' => $totalFrs,
        'totalSelected' => $totalSelected,
        'arrayCompare' => $arrayCompare,
        'arraySelected' => $arraySelected,
        ];
        
        return $returnArray;
    }
    
    /**
     * Summary of addFourniss
     * @param string $idAO
     * @param string $typFG
     * @param string $codeFou
     * @param string $idRecord
     * @return bool|array<mixed>
     */
    public function addFourniss(string $idAO, string $typFG, string $codeFou, string $idRecord = null)
    {
        $aoEntet = new AoEntet($this->pdo);
        $infoEntet = $aoEntet->find($idAO);
        if ($infoEntet && $infoEntet['VALCHXFOU'] != '00000000') {
            return false;
        }
        
        $gestionConsu = new GestionConsultation($this->pdo);
        $reponse = new Reponse($this->pdo);
        $aoFourEntity = new AoFour($this->pdo);
        $aoContFour = new AoContFour($this->pdo);
        
        if ($typFG == 'F') {
            $frs = $gestionConsu->getInfoFrs($codeFou);
            $contactfrs = $gestionConsu->getContactFrs($codeFou);
        } else {
            $frs = $gestionConsu->getInfoGrpFrs($codeFou);
            $contactfrs = $gestionConsu->getContactGrpFrs($codeFou);
        }
        
        $frsExist = $aoFourEntity->find([
        'NO_AO'     => $idAO,
        'TYPE_FG'   => $typFG,
        'CODE_FOU'  => $frs['CODE']??'',
        ]);
        
        if ($frsExist) {
            return true;
        }
        
        $noCol = $reponse->getMaxCol($idAO);
        
        $aoFourEntity->insert([
        'NO_AO'     => $idAO,
        'CODE_FOU'  => $frs['CODE']??'',
        'NOM_CTCT'  => '',
        'TEL_CTCT'  => '',
        'FAX_CTCT'  => '',
        'POR_CTCT'  => '',
        'EMAILCONT' => '',
        'ADR'       => $frs['ADR']??'',
        'VILLE'     => $frs['VILLE']??'',
        'PAYS'      => $frs['CODE_PAYS']??'',
        'CPOSTAL'   => $frs['CPOSTAL']??'',
        'VILLE1'    => $frs['VILLE1']??'',
        'RET_CV'    => 'C',
        'TYPE_FG'   => $typFG,
        'NO_COL'    => ((int)($noCol['MAX_NO_COL']??'0')) +1
        ]);

        $aoEvent = new AoEvent($this->pdo);
        $aoEvent->rqInsertEventAO($idAO, 'AJF', '', $frs['CODE'], $typFG);

        $anchor = '<a target="_blank" href="' . $this->router->generateUri('Consultation.AjoutFournisseur.editFournisseur', ['idAO' => $idAO, 'idFrs' => ($frs['CODE']??''), 'typeFG' => $typFG, 'changeContact' => 1]) .'"> ' . ($frs['RS']??'') . ' (' . ($frs['CODE']??'') . ')</a>';

        if ($typFG == 'F') {
            $actionService = new ActionService($this->pdo);
            $actionService->insertInfoConsultToProject($codeFou, (int)$idAO, (int)$idRecord);
        }
        
        $countContact = count($contactfrs);
        if ($countContact == 0) {
            return ['error' => $this->trad->t('Aucun contact n\'est présent sur la fiche du fournisseur') . ' ' . $anchor . '.'];
        }

        $contactInserted = 0;
        if ($countContact == 1) {
            if (trim($contactfrs[0]['EMAIL']) != '') {
                $aoContFour->insert([
                    'NO_AO'     => $idAO,
                    'CODE_FOUR' => $frs['CODE'],
                    'TYPE_FG'   => $typFG,
                    'NOM_CTCT'  => $contactfrs[0]['NOM']??'',
                    'TEL_CTCT'  => $contactfrs[0]['TEL']??'',
                    'FAX_CTCT'  => $contactfrs[0]['FAX']??'',
                    'POR_CTCT'  => $contactfrs[0]['TELPORT']??'',
                    'EMAILCONT' => $contactfrs[0]['EMAIL'],
                    'NUM_ORDRE' => 1
                ]);
                $contactInserted++;
            } else {
                return ['error' => $this->trad->t('Aucun contact avec un email n\'est présent sur la fiche du fournisseur') . ' ' . $anchor . '.'];
            }
        }

        if ($countContact > 1 && $contactInserted == 0) {
            foreach ($contactfrs as $contact) {
                if (Sql::toBool($contact['CTC_CONSULT']??'')) {
                    $aoContFour->insert([
                        'NO_AO'     => $idAO,
                        'CODE_FOUR'  => $frs['CODE']??'',
                        'TYPE_FG'   => $typFG,
                        'NOM_CTCT'  => $contact['NOM']??'',
                        'TEL_CTCT'  => $contact['TEL']??'',
                        'FAX_CTCT'  => $contact['FAX']??'',
                        'POR_CTCT'  => $contact['TELPORT']??'',
                        'EMAILCONT' => $contact['EMAIL']??'',
                        'NUM_ORDRE'  => intval($aoContFour->getMaxNumOrdre($idAO, $frs['CODE'], $typFG)) + 1
                    ]);
                    $contactInserted++;
                }
            }
        }

        $consultationService = new ConsultationService($this->pdo, $this->trad);
        $consultationService->checkAoFourContactWithAoContFour((int) $idAO, $codeFou, $typFG);
        
        if ($contactInserted == 0) {
            return ['error' => $this->trad->t('Aucun contact n\'est affecté en tant que Contact Consultation sur la fiche du fournisseur') . ' ' . $anchor . '.'];
        }

        return true;
    }

    /**
     * @param array<mixed> $article
     */
    public function addArticleToConsult(string $idConsult, $article, bool $articleGenerique = false) : void
    {
        $aoEntet = new AoEntet($this->pdo);
        $infoEntet = $aoEntet->find($idConsult);

        $gestionConsultation = new GestionConsultation($this->pdo);
        $idLigne = (int)$gestionConsultation->getMaxLigneAo($idConsult)['MAX_PO'];
        $idLigne = $idLigne + 1;

        if ($articleGenerique) {
            $prix =  '0';
        } else {
            $prix = $article['PX_ART'];
        }

        $aoLigne = new AoLigne($this->pdo);
        $aoLigne->insert([
        'NO_AO'         => $idConsult,
        'NO_PO'         => $idLigne,
        'NO_DA'         => 0,
        'NO_PO_DA'      => 0,
        'CODE_ART'      => $article['COD_ART'],
        'DES'           => $article['DES_ART'],
        'NM_DCOMP'      => Sql::updateMemo($this->pdo, '', $article['DES_ART']),
        'QTE'           => 1,
        'UNITE'         => $article['COD_UNIT'],
        'DELAI'         => '00000000',
        'BUDGET'        => 0,
        'PRIX_REF'      => $prix,
        'SSFAMILLE'     => $article['COD_SFAM'],
        'COD_FAB'       => $article['COD_FAB'],
        'COD_GAM'       => $article['COD_GAM'],
        'REF_FAB'       => $article['COD_FAB']??'',
        'CODE_STE'      => $infoEntet['CODE_STE'],
        ]);

        $aoPlann = new AoPlann($this->pdo);
        $aoPlann->insert([
        'NO_AO' => $idConsult,
        'NO_PO' => $idLigne,
        'DTE' => '00000000',
        'QTE' => 0,
        ]);

        $champSupp = new ChampSupp($this->pdo);
        $listeCS = $champSupp->getInfoCS('AO_LIGNE');

        foreach ($listeCS as $cs) {
            $valueCS = '';
            if ($cs['TAB_SOUR'] == 'ARTICLES' && $article['COD_ART'] != '') {
                $idCS = $article['COD_ART'];
                $valueCS = ChampSupp::getValueCS($cs['TAB_SOUR'], $idCS, $cs['CHP_SOUR'], $this->pdo);
            } elseif ($cs['TAB_SOUR'] == 'AO_ENTET') {
                $idCS = $champSupp::autoCompletCodeEnr($idConsult, '', 'AO_ENTETE');
                $valueCS = ChampSupp::getValueCS($cs['TAB_SOUR'], $idCS, $cs['CHP_SOUR'], $this->pdo);
            }

            $idCSLigne = $champSupp::autoCompletCodeEnr($idConsult, $idLigne, 'AO_LIGNE');
            $champSupp->insertChampSupp('AO_LIGNE', $idCSLigne, $cs['NUM_FIX'], $valueCS, $this->pdo);
        }
    }

    /**
     * @param array<mixed> $infoEntet
     * @param array<mixed> $article
     */
    public function getPrixRef($infoEntet, $article) : string
    {
        $consultation = new Consultation($this->pdo);
        $prixRef = 0;

        if ($article['REF_FAB'] != '' && $article['COD_FAB'] != '') {
            $prixRef = $consultation->getPrixRef($infoEntet['TYPE_SG'], $infoEntet['CODE_STE'], true, $article);
        }

        if (!$prixRef) {
            $prixRef = $consultation->getPrixRef($infoEntet['TYPE_SG'], $infoEntet['CODE_STE'], false, $article);
        }

        return $prixRef;
    }

    /**
     * Summary of createDefaultDocumentsReponses
     * @param string $idAo
     * @param string $codeLangue
     * @param string $RFI_Q
     * @return void
     */
    public function createDefaultDocumentsReponses(string $idAo, string $codeLangue, string $RFI_Q): void
    {
        $ConsultDocDefaut = new ConsultDocDefault($this->pdo);
        switch ($RFI_Q) {
            case 'I':
                $typeConsult = 'POUR_RFI';
                break;

            case 'P':
                $typeConsult = 'POUR_RFP';
                break;
            
            default:
                $typeConsult = 'POUR_RFQ';
                break;
        }
        $listeDocRep = $ConsultDocDefaut->findAll(
            ['TYPE_DOC' => 'A', 'COD_LNG ' => $codeLangue, $typeConsult => 'T'],
            [],
            ['tri_NUM_ORDRE' => 'ASC']
        );

        $aoDocAttendu = new AoDocAttendus($this->pdo);

        foreach ($listeDocRep as $doc) {
            $aoDocAttendu->insert([
                'NO_AO' => $idAo,
                'NUM_ORDRE' => $doc['NUM_ORDRE'],
                'CODE_DOC' => "",
                'TITRE_DOC' => $doc['TITRE_DOC'],
                'COMMENTAIRE' => "",
                'numerique_OBLIGATOIRE' => Sql::setBoolSql(false),
                ]);
        }
    }

    /**
     * Summary of createDefaultRfxDocuments
     * @param string $idAo
     * @param string $codeLangue
     * @param string $RFI_Q
     * @return void
     */
    public function createDefaultRfxDocuments(string $idAo, string $codeLangue, string $RFI_Q): void
    {
        $docDefaut = new ConsultDocDefault($this->pdo);
        switch ($RFI_Q) {
            case 'I':
                $typeConsult = 'POUR_RFI';
                break;

            case 'P':
                $typeConsult = 'POUR_RFP';
                break;
            
            default:
                $typeConsult = 'POUR_RFQ';
                break;
        }

        $listeDocRep = $docDefaut->findAll(
            ['TYPE_DOC' => 'P', 'COD_LNG ' => $codeLangue, $typeConsult => true],
            [],
            ['tri_NUM_ORDRE' => 'ASC']
        );

        $aoPijo = new AoPijo($this->pdo);

        foreach ($listeDocRep as $doc) {
            // TODO : this is terrible, empty PIJO should not exist,
            // default doc should only be used to display and autocomplete pijo creation
            $aoPijo->insert([
                'NO_AO' => $idAo,
                'NO_ORDRE' => $doc['NUM_ORDRE'],
                'TYPE_PJ' => "PJ",
                'TITRE' => $doc['TITRE_DOC'],
                'LECTURE' => Sql::toBool(true),
            ]);
        }
    }
    
    /**
     * Permet d'obtenir les paramètres par défault de pour les champs
     * défini par l'admin
     * @param array<mixed> $consultation
     * @return bool[]
     */
    public function getChampsObligatoireCreatEditConsult(&$consultation = []): array
    {
        if ($consultation != []) {
            $listOfSwitch = [
                'ACC_CONF' => 'O',
                'AO_PUBLIC' => 'O',
                'REPDEV' => 'O',
                'VARIANTE' => 'O',
            ];
    
            foreach ($listOfSwitch as $name => $default) {
                $consultation[$name]  ??= Sql::paravrac($this->pdo, 'OXAPROC', 'CONSULT_CREAT_' . $name) ?: $default;
            }
        }
        
        $listOfInput = [
            "EMETTEUR" => true,
            "CODE_STE" => true,
            "ACH" => true,
            "DEL_REP" => true,
            "DEVISE" => true,
            "COMMENT_INT" => false,
            "OBJET_AO" => false,
            "DESCR" => false,
            "PRESCRIPTEUR" => false,
            "DTE_LANCEMENT" => false,
            "HEURE_LANCEMENT" => false,
            "HEURE_CLOTURE" => false,
            "BUDG_ENT" => false,
        ];
        
        foreach ($listOfInput as $name => $default) {
            $champsObligatoire[$name]   = Sql::toBool(Sql::paravrac($this->pdo, 'OXAPROC', 'CONSULT_CREAT_' . $name) ?: $default);
        }
        
        return $champsObligatoire;
    }

    /**
     * This method has for objective to verify if the frs in AO_FOUR has a contact from AO_CONTFOUR
     * ! Cette fonction est appellé plusieurs fois afin de s'assurer qu'il y est toujours le contact principal (le premier) de AO_CONTFOUR
     * ! qui soit transféré dans AO_FOUR pour que l'envoi des différents emails depuis MAGIC se fasse correctement
     * @return void
     */
    public function checkAoFourContactWithAoContFour(int $idAO, string $codeFrs, string $typeFG)
    {
        $AoFour = new AoFour($this->pdo);
        $AoContFour = new AoContFour($this->pdo);

        $aoActualFourniss = $AoFour->find(['NO_AO' => (int) $idAO, 'CODE_FOU' => $codeFrs, 'TYPE_FG' => $typeFG]);
        $aoActualContactsFour = $AoContFour->findAll(['NO_AO' => (int) $idAO, 'CODE_FOUR' => $codeFrs, 'TYPE_FG' => $typeFG]);

        if (!isset($aoActualFourniss['EMAILCONT']) || trim($aoActualFourniss['EMAILCONT']) == '') {
            $allNames = array_map(fn($ctc) => $ctc['NOM_CTCT'], $aoActualContactsFour);
            $allEmails = array_map(fn($ctc) => $ctc['EMAILCONT'], $aoActualContactsFour);

            if (!in_array($aoActualFourniss['NOM_CTCT'], $allNames) || !in_array($aoActualFourniss['EMAILCONT'], $allEmails)) {
                $AoFour->update([
                    'NOM_CTCT'  => $aoActualContactsFour[0]['NOM_CTCT']??'',
                    'EMAILCONT' => $aoActualContactsFour[0]['EMAILCONT']??'',
                    'TEL_CTCT'  => $aoActualContactsFour[0]['TEL_CTCT']??'',
                    'POR_CTCT'  => $aoActualContactsFour[0]['POR_CTCT']??'',
                    'FAX_CTCT'  => $aoActualContactsFour[0]['FAX_CTCT']??'',
                ], [
                    'NO_AO'     => (int) $idAO,
                    'CODE_FOU'  => $codeFrs,
                    'TYPE_FG'   => $typeFG,
                ]);
                // TODO: Réimplémenter la façon dont sont géré les contacts. Fait pour l'envoi des mails par Magic...
                $AoContFour->delete(['NO_AO' => (int) $idAO, 'CODE_FOUR' => $codeFrs, 'TYPE_FG' => $typeFG, 'EMAILCONT' => $aoActualContactsFour[0]['EMAILCONT']]);
            }
        }
        foreach ($aoActualContactsFour as $aoContFourContact) {
            if (($aoContFourContact['EMAILCONT']??'') === ($aoActualFourniss['EMAILCONT']??'')) {
                $AoContFour->delete([
                    'NO_AO'     => (int) $idAO,
                    'CODE_FOUR'  => $codeFrs,
                    'TYPE_FG'   => $typeFG,
                    'EMAILCONT' => $aoContFourContact['EMAILCONT']??''
                ]);
            }
            if (($aoContFourContact['NOM_CTCT']??'') === ($aoActualFourniss['NOM_CTCT']??'')) {
                $AoContFour->delete([
                    'NO_AO'     => (int) $idAO,
                    'CODE_FOUR'  => $codeFrs,
                    'TYPE_FG'   => $typeFG,
                    'NOM_CTCT' => $aoContFourContact['NOM_CTCT']??''
                ]);
            }
        }
    }
}
