<?php
namespace Modules\ProjetAchat\Controller;

use Entity\Model\AoEntet;
use Entity\Model\Centre;
use Modules\ProjetAchat\Service\CompanyService;
use Skeleton\Controller\Controller;
use GuzzleHttp\Psr7\Response;
use Helpers\Ariane\Ariane;
use Helpers\Validator\Validator;
use Helpers\Trad\Trad;
use Entity\Model\DoarType;
use Entity\Model\DoarCal;
use Modules\ProjetAchat\WebService\Projet;
use Helpers\Outil\Sql;
use Entity\Model\Doa;
use Helpers\ChampsSupplementaire\ChampSupp;
use Modules\ProjetAchat\Repository\ProjetAchat;
use Modules\ProjetAchat\Service\ModeleProjetService;
use Entity\Model\Hastutil;
use Entity\Model\Societe;
use Modules\ProjetAchat\Repository\BibliothequeDonnee;
use Modules\GlobalApplication\Repository\Societe as SocieteRepo;
use Helpers\Outil\treeview;
use Helpers\Outil\Date;

use Modules\ProjetAchat\Service\ModeleService;
use Psr\Container\ContainerInterface;
use Skeleton\Renderer\RendererInterface;
use Skeleton\Router;
use Tamtamchik\SimpleFlash\Flash;
use Modules\ProjetAchat\Repository\DoaEvent;
use Modules\ProjetAchat\WebService\planning;
use Modules\GlobalApplication\Repository\DocumentsRattaches;
use Helpers\Outil\Roles;
use Modules\ProjetAchat\Service\HierarchyService;
use Modules\ProjetAchat\Service\BibliothequeService;
use Helpers\Outil\Outils;
use Helpers\Parametres\Constante;
use Modules\ProjetAchat\Repository\Acteur;
use Modules\ProjetAchat\Service\DoublonsService;
use Modules\ProjetAchat\Repository\Modele;
use Modules\ProjetAchat\MenuContextuel\GestionProjetMenuContextuel;
use Modules\ProjetAchat\MenuContextuel\GestionModeleMenuContextuel;

class ModeleProjetController extends Controller
{

    /**
     * @var Flash
     */
    private $flash;

    /**
     * @var ModeleService
     */
    private $modelService;

    /**
     * @var CompanyService
     */
    private $companyService;

    /**
     * @var modeleProjetService
     */
    protected $modeleProjetService;
    

    /**
     * @var hierarchyService
     */
    protected $hierarchyService;
    

    /**
     * @var BibliothequeService
     */
    protected $bibliothequeService;
    


    
    public function __construct(RendererInterface $renderer, \PDO $pdo, Router $router, ContainerInterface $contenaire)
    {
        parent::__construct($renderer, $pdo, $router, $contenaire);
        $this->modelService = new ModeleService($this->pdo);
        $this->companyService = new CompanyService($this->pdo);
        $this->modeleProjetService = new ModeleProjetService($pdo);
        $this->hierarchyService = new HierarchyService($pdo);
        $this->bibliothequeService = new BibliothequeService();
        $this->flash = new Flash();
    }

    /**
     * @return mixed
     */
    public function detailsAction()
    {
        $post = $this->request->getParsedBody();
        $trad = $this->getTranslationService();

        $idObjet = $this->request->getAttribute('idObjet');
        $typeObjet = $this->request->getAttribute('typeObjet');
        $model = $this->modelService->findModel($idObjet)[0];

        // Projet non existant
        if (!$model) {
            return $this->redirect('Index.Index.error');
        }

        $societes = (new SocieteRepo($this->pdo))->listRestrictedSocieteForUser();
        if ($societes !== null) {
            $societeArray = array_column($societes, 'CODE_STE');

            $aoEntet = new AoEntet($this->pdo);
            $societe = new Societe($this->pdo);
            if ($model['NO_AO_LIE']) {
                $infoAo = $aoEntet->find($model['NO_AO_LIE']);

                if ($infoAo['TYPE_SG'] == 'S' && !in_array($infoAo['CODE_STE'], $societeArray)) {
                    unset($model['NO_AO_LIE']);
                } elseif ($infoAo['TYPE_SG'] == 'G') {
                    $getSoc = $societe->fetchAll([], ['filter_egal_GROUPE' => $infoAo['CODE_STE']]);

                    $present = false;
                    foreach ($getSoc as $grpSoc) {
                        if (in_array($grpSoc['CODE_STE'], $societeArray)) {
                            $present = true;
                            break;
                        }
                    }

                    if (!$present) {
                        unset($model['NO_AO_LIE']);
                    }
                }
            }
        }

        if ($typeObjet=='D') {
            $menuContextuel = new GestionProjetMenuContextuel($this->pdo, $this->router, $trad);
            $menuContextuel = $menuContextuel->generate($model, false);
        } else {
            $menuContextuel = new GestionModeleMenuContextuel($this->pdo, $this->router, $trad);
            $menuContextuel = $menuContextuel->generate($model, false);
        }

        $bibliothqueRepo = new BibliothequeDonnee($this->pdo);
        $modeleRepo = new Modele($this->pdo);
        $projetAchatRepo = new ProjetAchat($this->pdo);
        $doaEventRepo = new DoaEvent($this->pdo);
        
        $modeleProjetService = new ModeleProjetService($this->pdo);

        $createrEvent = $doaEventRepo->getNameCreate($idObjet, $typeObjet=='M');
        $listeCategorie = $bibliothqueRepo->getListeCategorie($typeObjet, $idObjet);
        $hierarchyList = $bibliothqueRepo->getHierarchyList($typeObjet, $idObjet);
        
        $listeStatut = $this->modeleProjetService->listeStatut($trad);
        
        foreach ($listeCategorie as &$val) {
            if ($val['ID_PARENT']=='0') {
                $val['ID_PARENT'] = '';
            }
        }
        foreach ($hierarchyList as &$val) {
            if ($val['ID_PARENT']=='0') {
                $val['ID_PARENT'] = '';
            }
        }
        
        $_SESSION['DROIT']['DOA_MACT'] = 1;

        $droit = [
            'DOA_DOA_CM' => Roles::droitsUtilisateur($this->pdo, 'DOA_DOA_CM', $_SESSION["Session_Login"]),
            'DOA_DOA_TT' => Roles::droitsUtilisateur($this->pdo, 'DOA_DOA_TT', $_SESSION["Session_Login"]),
            'DOA_MOD_CM' => Roles::droitsUtilisateur($this->pdo, 'DOA_MOD_CM', $_SESSION["Session_Login"]),
            'DOA_MOD_TT' => Roles::droitsUtilisateur($this->pdo, 'DOA_MOD_TT', $_SESSION["Session_Login"]),
            'DOA_IMP_MO' => Roles::droitsUtilisateur($this->pdo, 'DOA_IMP_MO', $_SESSION["Session_Login"]),
            'DOA_DOC_CM' => Roles::droitsUtilisateur($this->pdo, 'DOA_DOC_CM', $_SESSION["Session_Login"]),
            'DOA_DOC_VI' => Roles::droitsUtilisateur($this->pdo, 'DOA_DOC_VI', $_SESSION["Session_Login"]),
            'DOA_MACT'   => Roles::droitsUtilisateur($this->pdo, 'DOA_MACT', $_SESSION["Session_Login"]),
            'DOA_AJ_REP' => Roles::droitsUtilisateur($this->pdo, 'DOA_AJ_REP', $_SESSION["Session_Login"]),
            'HA_AO_CMV'  => Roles::droitsUtilisateur($this->pdo, 'HA_AO_CMV', $_SESSION['Session_Login']),
            'HA_AO_ADM'  => Roles::droitsUtilisateur($this->pdo, 'HA_AO_ADM', $_SESSION['Session_Login']),
        ];

        $canEdit = ($typeObjet == 'B'
                || ($typeObjet == 'M' && (($droit['DOA_MOD_CM'] && $model['PROPRIETAIRE'] == $_SESSION["Session_Login"]) || $droit['DOA_MOD_TT']))
                || ((($typeObjet == 'D' &&
                        ! Sql::toBool($model['SUSPENDU'] ?? false)
                        && (($model['STATUT']??'')=='I' || ($model['STATUT']??'')== 'P'))
                        && (($droit['DOA_DOA_CM'] && $model['PROPRIETAIRE'] == $_SESSION["Session_Login"]) || $droit['DOA_DOA_TT'])
                    ) || ($droit['DOA_AJ_REP']) && ($model['STATUT']??'')== 'E')
                );

        $treeView = new treeview();

        /** Donnée **/
        $treeBibliothequeCategory =  $this->bibliothequeService->treeBibliotheque('', $listeCategorie, $post, $canEdit? ($this->contenaire->get('baseUrl').'IconeV2/Misc/menu_contextuel.png'):'');
        $treeBibliothequeCategory =  $treeView->array_filter_and_tags($treeBibliothequeCategory);
        
        /** Tâches **/
        $treeHierarchy = $this->hierarchyService->treeHierarchy(null, $hierarchyList??[], $post, $canEdit? ($this->contenaire->get('baseUrl').'IconeV2/Misc/menu_contextuel.png'):'');
        $treeHierarchy = $treeView->array_filter_and_tags($treeHierarchy);

        /** planning **/
        $listePlanning = $projetAchatRepo->listePlanningHistorise($idObjet);
        
        $idPlanning = 0;
        if ($listePlanning) {
            $idPlanning = $listePlanning[0]['ID_VERSION'];
            
            $listeSelectPlanning = [];
            
            foreach ($listePlanning as $planning) {
                $libelleSelect = $planning['ID_VERSION'].' - '.Date::dateConverte($planning['DATE_HISTO']).' - '.(Outils::heureConverte($planning['HEURE_HISTO']));
                if ($planning['COMMENTAIRE']) {
                    $libelleSelect .= ' - '.$planning['COMMENTAIRE'];
                }

                $listeSelectPlanning[$planning['ID_VERSION']] = $libelleSelect;
            }
        }
        
        $webService = new planning();
        $retourWSDL = $webService->generatePlanning($idObjet, 0);
        
        $retour = new \SimpleXMLElement($retourWSDL->responseData);
        $pathInfoFile = pathinfo($retour->NomFichier);

        $url = $pathInfoFile['basename'];
        
        $urlPlanning = $this->router->generateUri('GlobalApplication.ChargeDocument.chargeDocument', [
            'emplacement' => 'tmp',
            'urlFichier' => $url,
            'modeAffichage' => 0
        ]);
        /** ******** **/
        
        /** Document **/
        $post['NO_DA'] = 'DOA';
        $idDoc = str_pad($idObjet, 9, '0', STR_PAD_LEFT);
        
        $docAtt = new DocumentsRattaches($this->pdo);
        $listeDocument= $docAtt->detail($idDoc, $post);
        
        foreach ($listeDocument as &$doc) {
            $docExistInData = $projetAchatRepo->docExistInData($idObjet, $doc['NO_ORDRE']);
            $doc['Delete'] = true;
            if ($docExistInData) {
                $doc['NOM_DATA'] = $docExistInData['NOM_DATA'];
                $doc['Delete'] = ($model['STATUT'] == 'T' || $projetAchatRepo->dataIsTerminer($idObjet, $docExistInData['ID_DATA']))? false:true;
            }
        }

        /** ******** **/
        
        /** Element concernés **/
        $champSupp = new ChampSupp($this->pdo);
        $listeElemTmp = $projetAchatRepo->getListElem($idObjet);
        
        $listObjet = $champSupp->getLinkedObjectsList();
        $listeElem = [];
        foreach ($listeElemTmp as $elem) {
            $libelle = $modeleProjetService->generateLibelleTypeElement($elem['TYPE_ELEM'], $elem['ID_ELEM']);
            
            $listeElem[] = [
                'TYPE_ELEM' => $elem['TYPE_ELEM'],
                'LIB_ELEM' => $listObjet[$elem['TYPE_ELEM']],
                'CODE' => $elem['ID_ELEM'],
                'LIBELLE' => $libelle,
            ];
        }

        /** liste famille **/
        if (sql::boolSql($model['IS_PERE']) || $model['ID_PERE'] != '0') {
            $listFamily = $modeleRepo->getListFamily(sql::boolSql($model['IS_PERE']) ? $idObjet:$model['ID_PERE'], $idObjet);
        }
        
        /** ***************** **/
        
        $model['DATE_CREAT'] = Date::dateConverte($model['DATE_CREAT']);

        if (strpos($_SESSION['ariane'][$_SESSION['ariane']['last']]['path'], $this->contenaire->get('baseUrl').'/ProjetAchat/listeModeleImport') === 0) {
            $indiceAriane = 3;
        } else {
            $indiceAriane = 1;
        }
        
        Ariane::generate($indiceAriane, $typeObjet=='M'? $trad->t('Détails modèle'):$trad->t('Détails projet'), $post);


        
        return $this->renderer->render('@projetAchat/ProjetAchat/details', [
            'menuActive'                => 'ProjetAchat',
            'flash'                     => $this->flash,
            'model'                     => $model,
            "canCreate"                 => roles::droitsUtilisateur($this->pdo, 'DOA_DOA_CM'),
            'login'                     => $_SESSION["Session_Login"],
            'treeBibliotheque'          => $treeBibliothequeCategory,
            'treeHierarchy'             => $treeHierarchy,
            'post'                      => $post,
            'typeObjet'                 => $typeObjet,
            'idObjet'                   => $idObjet,
            'statut'                    => $model['STATUT'],
            'afilliatedCompanies'       => $this->companyService->findExplicitCompaniesLinkedToModel($idObjet, "S"),
            'afilliatedGroupedCompanies'=> $this->companyService->findExplicitCompaniesLinkedToModel($idObjet, "G"),
            'createrEvent'              => $createrEvent,
            'listeStatut'               => $listeStatut,
            'urlPlanning'               => $urlPlanning,
            'listePlanning'             => $listeSelectPlanning??[],
            'idLastPlanning'            => $idPlanning,
            'listeElem'                 => $listeElem,
            'idForDoc'                  => $idDoc,
            'listeDocument'             => $listeDocument,
            'droit'                     => $droit,
            'listeFamily'               => $listFamily??[],
            'canEdit'                   => $canEdit,
            'menuContextuel'            => $menuContextuel
        ]);
    }

    /**
     * @return Response|string
     * @throws \Exception
     */
    public function createEditAction()
    {
        $type = $this->request->getAttribute('type');
        $typeSource = $this->request->getAttribute('typeSource');
        $idProjet = $this->request->getAttribute('idProjet');
        $post = $this->request->getParsedBody();

        $trad = $this->getTranslationService();
        $modeleProjetService = new ModeleProjetService($this->pdo);
        $doa = new Doa($this->pdo);
        $projetAchatRepo = new ProjetAchat($this->pdo);
        
        $initProjet = false;
        $modeInitialisation = false;
        
        /**
         * Si l'on vient du regroupement de projet
         */
        if (isset($post['listeSelectInput'])) {
            $titre = $trad->t('Création projet père');
            $titreAriane = $trad->t('Nouveau Projet Achat');
            $listeSelectInput = $post['listeSelectInput'];
            
            $listeId = [];
            foreach ($listeSelectInput as $key => $selectInput) {
                $selectInput;
                $listeId[] = substr($key, 21);
            }
            
            $listeImplodeFils = implode(',', $listeId);
            $liste = $projetAchatRepo->getListeProjetByListId($listeImplodeFils);
            $dateDeb = '99999999';
            $dateFin = '00000000';
            $presicripteurDifferent = false;
            $presicripteur = '';
            
            
            foreach ($liste as $val) {
                if ($val['DATE_DEB'] < $dateDeb) {
                    $dateDeb = $val['DATE_DEB'];
                }
                
                if ($val['DATE_FIN'] > $dateFin) {
                    $dateFin = $val['DATE_FIN'];
                }
                
                if ($presicripteur == '') {
                    $presicripteur = $val['PRESCRIPTEUR'];
                }
                
                if ($val['PRESCRIPTEUR'] != $presicripteur && !$presicripteurDifferent) {
                    $presicripteurDifferent = true;
                }
            }
            
            $prescripteur = $presicripteurDifferent? $_SESSION["Session_Login"]:$liste['0']['PRESCRIPTEUR'];
            
            $hastutil = new Hastutil($this->pdo);
            $prescripteurInfo = $hastutil->find($prescripteur);
            
            $detailProjet['PROPRIETAIRE'] = $_SESSION["Session_Login"];
            $detailProjet['CTR_EMETT'] = $prescripteurInfo['CTR_ADR'];
            $detailProjet['DATE_DEB'] = $dateDeb;
            $detailProjet['DATE_FIN'] = $dateFin;
            $detailProjet['PRESCRIPTEUR'] = $prescripteur;
            $initProjet = true;
            
            $parametrageSaisieCode = $modeleProjetService->getParametrageReference($type=='M'? true:false);
        } elseif ($idProjet != 'noId' && !$typeSource) {
            /**
             * Modification d'un modèle ou d'un projet
             */
            $detailProjet = $projetAchatRepo->detailProjetAchat($idProjet);

            $concatTitle = ' : '.$detailProjet['REF'].', '.$trad->t('Créé par').' '.($detailProjet['CODE_USER']? $detailProjet['NOM_EVENT']:$detailProjet['NOM_PROPRIO']);

            if ($type=='M') {
                $titre = $trad->t('Modification du modèle').$concatTitle;
                $titreAriane = $trad->t('Modification Modèle');
            } else {
                $titre = $trad->t('Modification du projet').$concatTitle;
                $titreAriane = $trad->t('Modification projet');
                
                if ($detailProjet['STATUT'] == 'I') {
                    $modeInitialisation = true;
                }
            }
        } elseif ($typeSource) {
            
            /**
             * Création d'un projet depuis un modele
             * Création d'un modele depuis un projet
             * Duplication projet ou modele
             */
            if ($type=='M') {
                if ($type == $typeSource) {
                    $titre = $trad->t('Duplication d\'un modèle');
                    $titreAriane = $trad->t('Nouveau modèle');
                } else {
                    $titre = $trad->t('Créer un modèle depuis un projet');
                    $titreAriane = $trad->t('Nouveau modèle');
                }
            } else {
                if ($type == $typeSource) {
                    $titre = $trad->t('Duplication d\'un projet');
                    $titreAriane = $trad->t('Dupliquer projet');
                } else {
                    $titre = $trad->t('Créer un projet depuis un modèle');
                    $titreAriane = $trad->t('Nouveau Projet Achat');
                }
            }
            $initProjet = true;
            $parametrageSaisieCode = $modeleProjetService->getParametrageReference($type=='M'? true:false);
        } else {
            
            /**
             * Création projet ou modele
             */
       
            $parametrageSaisieCode = $modeleProjetService->getParametrageReference($type=='M'? true:false);
            
            if ($type=='M') {
                $titre = '';
                $titreAriane = $trad->t('Nouveau Modèle');
            } else {
                $titre = '';
                $titreAriane = $trad->t('Nouveau Projet Achat');
                
                if (sql::paravrac($this->pdo, 'PARAMGEN', 'DOA_STATUT_INIT_ACTIF')=='O') {
                    $modeInitialisation = true;
                }
            }
            
            $detailProjet['PROPRIETAIRE'] = $_SESSION["Session_Login"];
            $detailProjet['PRESCRIPTEUR'] = $_SESSION["Session_Login"];
            $hastutil = new Hastutil($this->pdo);
            $prescripteurInfo = $hastutil->find($_SESSION["Session_Login"]);
            $detailProjet['CTR_EMETT'] = $prescripteurInfo['CTR_ADR'];

            $paramPlanning = Sql::paravrac($this->pdo, 'PARAMGEN', 'DOA_PLANNING_EN_CALCUL_AUTO');
            $detailProjet['MODEPLANNING'] = $paramPlanning=='O'? true:false;
        }
        
        if ($initProjet && $idProjet != 'noId') {
            $detailProjetSource = $doa->find($idProjet);
            
            $detailProjet['PROPRIETAIRE'] = $_SESSION["Session_Login"];
            $detailProjet['PRESCRIPTEUR'] = $_SESSION["Session_Login"];
            $detailProjet['ID_CAL'] = $detailProjetSource['ID_CAL'];
            $detailProjet['CODE_OPE'] = $detailProjetSource['CODE_OPE'];
            $detailProjet['ID_TYPE'] = $detailProjetSource['ID_TYPE'];
            $detailProjet['MODEPLANNING'] = Sql::boolSql($detailProjetSource['MODEPLANNING']);

            if (!$detailProjetSource) {
                return $this->redirect('Index.Index.error');
            }
        }

        /** Partie initialisation formulaire **/
        $DoarType = new DoarType($this->pdo);
        $listeTMPID = $DoarType->fetchAll();
        
        
        
        $listeTMPID = (new ProjetAchat($this->pdo))->getDoarTypeList();
        foreach ($listeTMPID as $item) {
            $listeType[$item['ID']] = $item['LIB'];
        }

        $projetAchatRepo = new ProjetAchat($this->pdo);
        $listeTMPOP = $projetAchatRepo->getListDoarOpe();
        
        foreach ($listeTMPOP as $item) {
            $listeOpe[$item['CODE_OPE']] = $item['LIB'];
        }

        $DoarCal = new DoarCal($this->pdo);
        $listeCalTMP = $DoarCal->fetchAll();
        
        foreach ($listeCalTMP as $item) {
            $listeCal[$item['ID']] = $item['LIB'];
            
            if (sql::boolSql($item['DEFAUT']) && !($detailProjet['ID_CAL']??null)) {
                $detailProjet['ID_CAL'] = $item['ID'];
            }
        }

        if (!$typeSource) {
            if ($type=='M') {
                $ariane1 = $this->router->generateUri('ProjetAchat.GestionModele.index');
                $titre1 = $trad->t('Gestion');
            } else {
                $ariane1 = $this->router->generateUri('ProjetAchat.GestionProjetAchat.index');
                $titre1 = $trad->t('Gestion');
            }
        
            Ariane::generate(0, $titre1, $post, null, $ariane1);
        }

        $editOnly = in_array($detailProjet['STATUT']??[], ['E']);

        Ariane::generate(1, $titreAriane, $post);
        
        return $this->renderer->render('@projetAchat/ProjetAchat/nouveau', [
            'menuActive'                => 'ProjetAchat',
            'listeType'                 => $listeType,
            'listeOpe'                  => $listeOpe??null,
            'listeCal'                  => $listeCal,
            'post'                      => $detailProjet??[],
            'type'                      => $type,
            'typeSource'                => $typeSource,
            'titre'                     => $titre,
            'idProjet'                  => $idProjet,
            'parametrageSaisieCode'     => $parametrageSaisieCode??'A',
            'pathBack'                  => Ariane::getBackPath(),
            'listeSelectInput'          => $listeSelectInput??[],
            'modeInitialisation'        => $modeInitialisation,
            'editOnlyLib'               => ($editOnly || Sql::toBool($detailProjet['SUSPENDU'] ?? false)) ? 'READONLY' : '',
        ]);
    }

    /**
     * @return Response|string
     */
    public function validateAction()
    {
        $type = $this->request->getAttribute('type');
        $typeSource = $this->request->getAttribute('typeSource');
        $idProjet = $this->request->getAttribute('idProjet');
        $post   = $this->request->getParsedBody();
      
        $trad = $this->getTranslationService();
        $doa = new Doa($this->pdo);
        
        $modeleProjetService = new ModeleProjetService($this->pdo);
        $parametrageSaisieCode = $modeleProjetService->getParametrageReference($type=='M'? true:false);
        
        $validator = $this->createValidator();
        
        if ($parametrageSaisieCode!='A' && $idProjet == 'noId') {
            $validator->isStringSansEspace($trad->t('Référence'), $post['REF'], ($parametrageSaisieCode=='M'? 1:0), 30);
            $validator->isTrue($doa->find($post['REF']), $trad->t('Ce code existe déjà.'));
        }
        
        $validator->isStringAvecEspace($trad->t('Libellé'), $post['LIB'], 1, 300);
        $validator->isStringAvecEspace($trad->t('Description'), $post['DESCR'], 0, 3000);
        
        if ($type == 'D') {
            $validator->isFalse($post['ID_TYPE'], Trad::strBuild($trad->t('Le champ @1@ ne peut pas être vide.'), $trad->t('Type de projet')));
        }
        //$validator->isFalse($post['CODE_OPE'], Trad::strBuild($trad->t('Le champ @1@ ne peut pas être vide.'), $trad->t('Opération')));
        $validator->zoom('HASTUTIL', $post['PROPRIETAIRE'], $trad->t('Propriétaire'), $this->pdo, false);
        
        if (sql::paravrac($this->pdo, 'PARAMGEN', 'DOA_STATUT_INIT_ACTIF')!='O') {
            $validator->isFalse($post['ID_CAL'], Trad::strBuild($trad->t('Le champ @1@ ne peut pas être vide.'), $trad->t('Calendrier')));
            $validator->isCheck($post['MODEPLANNING']);
        }
        
        if ($type=='D') {
            $validator->zoom('HASTUTIL', $post['PRESCRIPTEUR'], $trad->t('Prescripteur'), $this->pdo, false);
            $validator->zoom('CENTRE', $post['CTR_EMETT'], $trad->t('Centre Emetteur'), $this->pdo, false);
            $validator->isDate($post['DATE_DEB'], '', '', false, $trad->t('Date de début prévue'));
            $validator->isDate($post['DATE_FIN'], '', '', false, $trad->t('Date fin prévue'));
            $validator->isCoherenceDate($post['DATE_DEB'], $post['DATE_FIN']);
            
            $specifique = new \Helpers\Additional\Specifique\Specifique();

            $specifiqueValidator = $specifique->specifique('\\Modules\\ProjetAchat\\Service\\projetAchatSpecifique', 'validatorCoherenceMontant', $validator, $this->pdo, $idProjet, $post);
            if ($specifiqueValidator) {
                $validator = $specifiqueValidator;
            }
        }
        
        if ($idProjet != 'noId') {
            $idDoa = champSupp::autoCompletCodeEnr($idProjet);
            $validator->validatorCS('DOA', $idDoa, $post, $this->pdo, '', '', '', '', $type=='M'? false:null);
        } else {
            $validator->validatorCS('DOA', '', $post, $this->pdo, '', '', '', '', $type=='M'? false:null);
        }
        
        if ($validator->isValid()) {
            $arrayDoa= [
                'LIB' => $post['LIB'],
                'DESCR' => $post['DESCR'],
                'ID_TYPE' => $post['ID_TYPE'],
                'CODE_OPE' => $post['CODE_OPE'],
                'ID_CAL' => $post['ID_CAL'],
                'PROPRIETAIRE' => $post['PROPRIETAIRE'],
                'numerique_MODEPLANNING' => Sql::setBoolSql(($post['MODEPLANNING']??null))
            ];
            
            
            if ($type=='D') {
                $arrayDoa['PRESCRIPTEUR'] = $post['PRESCRIPTEUR'];
                $arrayDoa['CTR_EMETT'] = $post['CTR_EMETT'];
                $arrayDoa['DATE_DEB'] = $post['DATE_DEB'];
                $arrayDoa['DATE_FIN'] = $post['DATE_FIN'];
            }

            $arrayTmpDOA= $arrayDoa;
            $arrayTmpDOA['MODEPLANNINGTrueFalse'] =Sql::convertBooleenCheckboxForWsdlTrueFalse($post['MODEPLANNING']??null);
            
            if ($typeSource) {
                if ($parametrageSaisieCode=='A' || ($parametrageSaisieCode=='I')) {
                    $arrayDoa['REF'] = '';
                } else {
                    $arrayDoa['REF'] = $post['REF'];
                }
                $arrayTmpDOA['REF'] = $arrayDoa['REF'];
                
                $projetWSDL = new Projet();
                $xmlResult = $projetWSDL->wsdlDuplication($idProjet, ($type=='M'? true:false), $arrayTmpDOA, $post);
                
                $reponse = new \SimpleXMLElement($xmlResult->responseData);
                if ($reponse->Statut == "O") {
                    $infoDoa['ID'] = (int)$reponse->NewID_DOA;
                    
                    if ($type == 'D') {
                        $modeleProjetService->recalculePlanning($infoDoa['ID'], $type);

                        if (sql::paravrac($this->pdo, 'PARAMGEN', 'DOA_STATUT_INIT_ACTIF')=='O') {
                            $statut = 'I';
                        } else {
                            $statut = 'P';
                        }

                        $doa->update(['STATUT' => $statut], $infoDoa['ID']);
                    }
                } else {
                    return $this->renderer->render('@popup-erreur/ErreurCreation', [
                        'ErreurValid' => $reponse->MsgErreur,
                    ]);
                }
            } elseif ($idProjet != 'noId') {
                /* SPEC 4654 */
                
                if ($type == 'D') {
                    $origineDoa = $doa->find($idProjet);
    
                    $messageRepercution = '';
                    $repercution = [];
                    $acteurRepo = new Acteur($this->pdo);
                    if ($origineDoa['PROPRIETAIRE'] != $arrayDoa['PROPRIETAIRE']) {
                        $countTask = $acteurRepo->countResponsableTaskFound($idProjet, $arrayDoa['PROPRIETAIRE'])['COUNT']??0;
                        $countAction = $acteurRepo->countActeurActionFound($idProjet, $arrayDoa['PROPRIETAIRE'])['COUNT']??0;
                        
                        if ($countTask || $countAction) {
                            $messageRepercution .= trad::strBuild($trad->t('Voulez-vous répercuter le changement du champ @1@ sur le(s) @2@ responsable(s) de tâche(s) trouvée(s) et le(s) @3@ RACI d\'action(s) trouvé(s) ?'), $trad->t('propriétaire'), $countTask, $countAction).'</br>';
                        
                            $repercution[] = [
                                'OLD' => $origineDoa['PROPRIETAIRE'],
                                'NEW' => $arrayDoa['PROPRIETAIRE'],
                            ];
                        }
                    }
    
                    if ($origineDoa['PRESCRIPTEUR'] != ($arrayDoa['PRESCRIPTEUR'] ?? '')) {
                        $countTask = $acteurRepo->countResponsableTaskFound($idProjet, $arrayDoa['PROPRIETAIRE'])['COUNT']??0;
                        $countAction = $acteurRepo->countActeurActionFound($idProjet, $arrayDoa['PROPRIETAIRE'])['COUNT']??0;
                        if ($countTask || $countAction) {
                            $messageRepercution = trad::strBuild($trad->t('Voulez-vous répercuter le changement du champ @1@ sur le(s) @2@ responsable(s) de tâche(s) trouvée(s) et le(s) @3@ RACI d\'action(s) trouvé(s) ?'), $trad->t('prescripteur'), $countTask, $countAction).'</br>';
                        
                            $repercution[] = [
                                'OLD' => $origineDoa['PRESCRIPTEUR'] ?? '',
                                'NEW' => $arrayDoa['PRESCRIPTEUR'] ?? '',
                            ];
                        }
                    }
                    
                    $modeleProjetService = new ModeleProjetService($this->pdo);
                    $listeTypeActeur = $modeleProjetService->generateListTypeActeur('DOA', $trad);
            
                    if ($listeTypeActeur) {
                        foreach ($listeTypeActeur as $key => $acteur) {
                            $numFix = explode('|', $key);
                            //@phpstan-ignore-next-line Parameter #3 $pad_string of function str_pad expects string, int given.
                            $idProjetForCS = str_pad($idProjet, 9, 0, STR_PAD_LEFT);
        
                            $valueCS = ChampSupp::getValueCS('DOA', $idProjetForCS, $numFix[1], $this->pdo);
                            $keyCS = 'CS_EXTENTION'.Constante::spliter.'DOA'.Constante::spliter.$idProjetForCS.Constante::spliter.$numFix[1];
                            if ($valueCS != $post[$keyCS] && $valueCS && $post[$keyCS]) {
                                $countTask = $acteurRepo->countResponsableTaskFound($idProjet, $post[$keyCS], null, false)['COUNT']??0;
                                $countAction = $acteurRepo->countActeurActionFound($idProjet, $post[$keyCS], null, false)['COUNT']??0;
                                if ($countTask || $countAction) {
                                    $messageRepercution = trad::strBuild($trad->t('Voulez-vous répercuter le changement du champ @1@ sur le(s) @2@ responsable(s) de tâche(s) trouvée(s) et le(s) @3@ RACI d\'action(s) trouvé(s) ?'), $acteur, $countTask, $countAction).'</br>';
                                
                                    $repercution[] = [
                                        'OLD' => $valueCS,
                                        'NEW' => $post[$keyCS],
                                    ];
                                }
                            }
                        }
                    }
                }

                $doa->update($arrayDoa, $idProjet);
                ChampSupp::updateCS($post, $this->pdo);
                
                ModeleProjetService::updateDoaEvent($this->pdo, $idProjet, $type, $trad->t('Modification de l\'entête.'));
                
                $infoDoa['ID'] = $idProjet;
            } else {
                if ($parametrageSaisieCode=='A' || (trim($parametrageSaisieCode)=='I')) {
                    $creationProjetWB = new Projet();
                    $retourXML = $creationProjetWB->getNumRefProjet($type=='M'? true:false);
                    $reponse = new \SimpleXMLElement($retourXML->responseData);
                    $arrayDoa['REF'] = $reponse->NumRef;
                } else {
                    $arrayDoa['REF'] = $post['REF'];
                }
                
                if ($type=='D') {
                    if (sql::paravrac($this->pdo, 'PARAMGEN', 'DOA_STATUT_INIT_ACTIF')=='O') {
                        $arrayDoa['STATUT'] = 'I';
                    } else {
                        $arrayDoa['STATUT'] = 'P';
                    }
                } else {
                    $arrayDoa['STATUT'] = 'P';
                }
                
                $arrayDoa['DATE_CREAT'] = date('Ymd');
                $arrayDoa['numerique_MODELE'] =  ($type=='M'? '0x54':'0x46');

                $doa->insert($arrayDoa);
                $infoDoa['ID'] = $doa->getLastInsertId('DOA', 'ID');

                if ($infoDoa['ID'] === false) {
                    return $this->renderer->render('@popup-erreur/ErreurCreation', [
                        'ErreurValid' => $trad->t('Une erreur s\'est produite lors de la création du Projet Achat, veuillez ré-essayer.'),
                        'desactiveRow' => true,
                    ]);
                }

                //@phpstan-ignore-next-line
                $idDoa = champSupp::autoCompletCodeEnr($infoDoa['ID']);
                ChampSupp::ajouterCS($post, $this->pdo, $idDoa);

                $this->modeleProjetService->insertEventCreate((int)$idDoa, $type, $arrayDoa['PROPRIETAIRE']);
            }
            
            $regroupDoublons = false;
            foreach ($post as $key => $value) {
                $value;
                if (strpos($key, 'save_selected_projet_') === 0) {
                    $regroupDoublons = true;
                    break;
                }
            }
            
            if ($regroupDoublons) {
                $doublonsService = new DoublonsService($this->pdo, $this->getTranslationService());
                $doublonsService->updateFamille($infoDoa['ID'], $post, false);
            }

            //@phpstan-ignore-next-line Variable $messageRepercution might not be defined.
            if ($messageRepercution) {
                return $this->renderer->render('@popup-erreur/confirmationSuppresion', [
                    'pathURL' => $this->router->generateUri('ProjetAchat.ModeleProjet.ajaxConfirmationRepercussion', ['idProjet' => $infoDoa['ID']]),
                    'message' => $messageRepercution,
                    'div' => 'redirect',
                    //@phpstan-ignore-next-line Variable $repercution might not be defined.
                    'form' => serialize(['listeRepercution' => $repercution])
                ]);
            } else {
                $path = $this->router->generateUri('ProjetAchat.ModeleProjet.details', ['typeObjet' => $type, 'idObjet' => $infoDoa['ID']]);
                
                return new Response(443, [
                    
                ], (string) \json_encode([
                    'statut' => 'O',
                    'path' => $path,
                ]));
            }
        } else {
            return $this->renderer->render('@popup-erreur/ErreurCreation', [
                'ErreurValid' => $validator->getError(),
                'desactiveRow' => true,
            ]);
        }
    }

    public function ajaxConfirmationRepercussionAction()
    {
        $idProjet = $this->request->getAttribute('idProjet');

        $post = $this->request->getParsedBody();
        $post =  unserialize($post['form'], ["allowed_classes" => false]);

        $listeRepercution = $post['listeRepercution'];

        foreach ($listeRepercution as $repercution) {
            $projetAchatEntity = new ProjetAchat($this->pdo);
            $projetAchatEntity->updateResponsableAction($idProjet, $repercution['OLD'], $repercution['NEW'], true);
            $projetAchatEntity->updateResponsableTaches($idProjet, $repercution['OLD'], $repercution['NEW']);
            $projetAchatEntity->updateResponsableRaciAction($idProjet, $repercution['OLD'], $repercution['NEW'], true);
        }


        $path = $this->router->generateUri('ProjetAchat.ModeleProjet.details', ['typeObjet' => 'D', 'idObjet' => $idProjet]);
        return new Response(200, [], (string) \json_encode(['path' => $path]));
    }
    
    public function ajaxCentreEmetteurAction()
    {
        $post   = $this->request->getParsedBody();
        
        $hastutil = new Hastutil($this->pdo);
        $prescripteur = $hastutil->find($post['PRESCRIPTEUR']);
        
        if ($prescripteur) {
            $statut =  'O';
        } else {
            $statut =  'E';
        }
        
        return new Response(200, [
            
        ], (string) \json_encode([
            'statut' => $statut,
            'CENTER' => $prescripteur['CTR_ADR']??'',
        ]));
    }
    
    public function deleteAction()
    {
        $idModele = $this->request->getAttribute('idProjet');
        
        $doaEntity = new Doa($this->pdo);
        $doa = $doaEntity->find($idModele);
        
        $projetWSDL = new Projet();
        $retourXml = $projetWSDL->wsdlSupDOA($idModele);
        
        $reponse = new \SimpleXMLElement($retourXml->responseData);
        
        if ($reponse->Statut=='O') {
            if (Sql::boolSql($doa['MODELE'])) {
                $path = $this->router->generateUri('ProjetAchat.GestionModele.index');
            } else {
                if ($doa['ID_PERE'] != '0') {
                    $filsExiste = $doaEntity->fetchAll([], ['filter_egal_ID_PERE' => $doa['ID_PERE']]);
                    if (!$filsExiste) {
                        $doaEntity->update([
                            'numerique_IS_PERE' => Sql::setBoolSql(0),
                            'numerique_SUSPENDU' => sql::setBoolSql(0),
                        ], $doa['ID_PERE']);
                    }
                }
                
                
                $path = $this->router->generateUri('ProjetAchat.GestionProjetAchat.index');
            }
            
            return new Response(200, [
                
            ], (string) \json_encode([
                'statut' => 'O',
                'path'   => $path,
                'pathOnlyRedirect' => true,
            ]));
        } else {
            return new Response(443, [
                
            ], $this->renderer->render('@popup-erreur/ErreurCreation', [
                'ErreurValid' => $reponse->MsgErreur,
            ]));
        }
    }
}
