<?php
namespace Traits\Validator;

use Entity\Model\CaEntet;
use Entity\Model\CaLigne;
use Entity\Model\Codecomp;
use Entity\Model\Codgest;
use Entity\Model\Parametr;
use Entity\Model\Sectimpu;
use Entity\Model\SousFamille;
use Entity\Model\Sscptana;
use Entity\Model\SSiteSto;
use Entity\Model\TVA;
use Entity\Model\Unites;
use Helpers\Outil\Sql;
use Helpers\Trad\ITrad;
use Helpers\Trad\Trad;
use Helpers\Validator\Validator;
use Modules\Ajax\Repository\Listes;
use PDO;

trait Zoom
{
    abstract public function getTrad() :ITrad;
    
    /**
     *
     * @param string $entity            : Entity (repertoir src\Entity)
     * @param mixed $value              : valeur à vérifier
     * @param string $nomChamp          : titre du champs  vérifier
     * @param \PDO $pdo
     * @param boolean $null             : null autorisé ou non ? pas autorisé par defaut
     * @param array $post               : filtre eventuelle sur l'entity
     * @param string $messageSpecifique : message spéficique
     * @return bool
     */
    public function zoom(string $entity, $value, string $nomChamp, PDO $pdo, $null = false, $post = [], $messageSpecifique = '', $selectTable = []): bool
    {
        if (strtoupper($entity) == 'SOCIETE') {
            return $this->societeZoom($value, $nomChamp, $pdo, $null, $post, $messageSpecifique);
        }

        $test = $entity;
        $value = mb_strtoupper(trim($value));
        if ($value == '' && $null) {
            return true;
        }

        if ((!$value) && !$null) {
            $this->validate += 1;
            $this->error .= '<br />' . Trad::strBuild($this->getTrad()->t('Le champ @1@ ne peut pas être vide.'), $nomChamp);
            return false;
        }

        // TODO : remove dynamic call to class
        $generatorEntity = "\\Entity\\Model\\" . trim($entity);

        /** @var \Helpers\QueryBuilder\QueryBuilder */
        $entityQb = new $generatorEntity($pdo);

        $primaryKey = $entityQb->getPrimaryKey();

        if (isset($this->listeValueEntite[$test]) && in_array($value, $this->listeValueEntite[$test])) {
            return true;
        }

        $contents = $entityQb->findAll(
            null,
            $selectTable,
            ['filter_egal_' . $primaryKey => $value] + $post,
            $entityQb,
            true
        );

        if ($contents) {
            $this->listeValueEntite[$test][] = $value;
        }

        if (! empty($contents)) {
            return true;
        }

        $this->validate += 1;

        if ($messageSpecifique != '') {
            $this->error .= '<br />' . Trad::strBuild($this->getTrad()->t('Le champ @1@ @2@.'), $nomChamp, $messageSpecifique);
        } else {
            if (strlen($value) > 100) {
                $value = substr($value, 0, 100) . '...';
                $this->error .= '<br />' . Trad::strBuild($this->getTrad()->t('Le code saisi @1@ n\'est pas présent dans la liste des @2@.'), $value, $nomChamp);
            } else {
                //si le client met un code avec un @, cela part en time out.
                $this->error .= '<br />' . Trad::strBuild($this->getTrad()->t('Le code saisi @1@ n\'est pas présent dans la liste des @2@.'), $value, $nomChamp);
            }
        }

        return false;
    }

    /**
     * @param mixed $value              : valeur à vérifier
     * @param string $nomChamp          : titre du champs  vérifier
     * @param \PDO $pdo
     * @param boolean $null             : null autorisé ou non ? pas autorisé par defaut
     * @param string $messageSpecifique : message spéficique
     * @return bool
     */
    public function tauxTVA($value, string $nomChamp, $pdo, $null = false, $messageSpecifique = '') : bool
    {
        if (($value==='' || $value===null) && $null) {
            return true;
        }
    
        if ((!$value) && !$null) {
            $this->validate += 1;
            $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('Le champ @1@ ne peut pas être vide.'), $nomChamp);
            return false;
        }

        $query = "SELECT CODE_TVA, LIBELLE FROM TVA with (nolock) where CODE_TVA = :codeTaux";

        $data = $pdo->prepare($query);

        $data->bindParam(':codeTaux', $value, PDO::PARAM_INT);

        $data->execute();

        $contents = $data->fetch(PDO::FETCH_ASSOC);

        if ($contents) {
            return true;
        }

        $this->validate += 1;

        if ($messageSpecifique != '') {
            $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('Le champ @1@ @2@.'), $nomChamp, $messageSpecifique);
        } else {
            $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('Le code saisi @1@ n\'est pas présent dans la liste des @2@.'), $value, $nomChamp);
        }
        
        return false;
    }
    
    
    
    /**
     * POUR TOUT LES VALIDATOR SUIVANT
     *
     *
     * @param string $value         : value a vérifier
     * @param string $nomChamp      : titre du champs à verifier
     * @param \PDO $pdo
     * @param boolean $null             : null autorisé ou non ? pas autorisé par defaut
     * @param array $post               : filtre eventuelle sur l'entity
     * @return bool
     */
    
    public function societeZoom(string $value, string $nomChamp, $pdo, $null = false, $post = [], string $messageSpecifique = '') : bool
    {
        if (trim($value)=='' && $null) {
            return true;
        }
    
        if (trim($value)=='' && !$null) {
            $this->validate += 1;
            $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('Le champ @1@ ne peut pas être vide.'), $nomChamp);
            return false;
        }
        $value = trim($value);

        $xml=simplexml_load_string($_SESSION['OXAPRC_LOGUSR_XML']);
        if ($xml->UsrMultiSoc != 'true' && !empty($_SESSION['Session_Login'])) {
            $societe = new \Modules\Ajax\Repository\Validator($pdo);
            $societe = $societe->societe(strtoupper($value), $post);
            if (!is_array($societe) || !$societe) {
                $this->validate += 1;
                if ($messageSpecifique != '') {
                    $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('Le champ @1@ @2@.'), $nomChamp, $messageSpecifique);
                } else {
                    $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('Le code saisi @1@ n\'est pas présent dans la liste des @2@.'), $value, $nomChamp);
                }
                return false;
            } else {
                return true;
            }
        } else {
            $societe = new \Modules\Ajax\Repository\Validator($pdo);
            $contents = $societe->allSociete(strtoupper($value), $post);

            foreach ($contents as $content) {
                return true;
            }
            
            $this->validate += 1;
            if ($messageSpecifique != '') {
                $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('Le champ @1@ @2@.'), $nomChamp, $messageSpecifique);
            } else {
                $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('Le code saisi @1@ n\'est pas présent dans la liste des @2@.'), $value, $nomChamp);
            }

            return false;
        }
    }
    
    public function numeroCommandeZoom(string $value, string $nomChamp, $pdo, $null = false, $post = []) : bool
    {
        
        if (trim($value)=='' && $null) {
            return true;
        }
    
        if (trim($value)=='' && !$null) {
            $this->validate += 1;
            $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('Le champ @1@ ne peut pas être vide.'), $nomChamp);
            return false;
        }
        
        $value = trim($value);
        
        $cde = new \Modules\Ajax\Repository\Validator($pdo);
        $cde = $cde->numeroDeCommande($value, $post);
        if (!isset($cde['NO_CDE'])) {
            $this->validate += 1;
            $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('Le code saisi @1@ n\'est pas présent dans la liste des @2@.'), $value, $nomChamp);
            return false;
        } else {
            return true;
        }
    }
    
    public function deviseZoom(string $value, string $nomChamp, $pdo, $null = false, $post = []) : bool
    {
        
        if (trim($value)=='' && $null) {
            return true;
        }
    
        if (trim($value)=='' && !$null) {
            $this->validate += 1;
            $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('Le champ @1@ ne peut pas être vide.'), $nomChamp);
            return false;
        }
        
        $value = trim($value);

        $devise = new \Modules\Ajax\Repository\Validator($pdo);
        if ($devise->devise($value)) {
            return true;
        } else {
            $this->validate += 1;
            $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('Le code saisi @1@ n\'est pas présent dans la liste des @2@.'), $value, $nomChamp);
            return false;
        }
    }
    
    public function sectionImputationZoom(string $value, string $nomChamp, $pdo, $null = false, $post = []) : bool
    {
        $today = Date('Ymd');
        
        if (trim($value)=='' && $null) {
            return true;
        }

        if (trim($value)=='' && !$null) {
            $this->validate += 1;
            if (!isset($this->listeValue['sectionImputationZoom'][$value]['error'])) {
                $this->listeValue['sectionImputationZoom'][$value]['error'] = $this->getTrad()->t('Le champ @1@ ne peut pas être vide.');
            }
            $this->error .= '<br />'.Trad::strBuild($this->listeValue['sectionImputationZoom'][$value]['error'], $nomChamp);
            return false;
        }
        
        $value = trim($value);
        
        if (!isset($this->listeValue['sectionImputationZoom'][$value])) {
            $sectionImputation = new \Modules\Ajax\Repository\Validator($pdo);
            $sectionImputation = $this->listeValue['sectionImputationZoom'][$value] = $sectionImputation->sectionImputation($value, $post);
        } else {
            $sectionImputation = $this->listeValue['sectionImputationZoom'][$value];
        }

        if (is_array($sectionImputation) && count($sectionImputation)>0) {
            // date de validité min bloquante
            if (isset($post['min_bloquant']) && $post['min_bloquant'] == 1 && $sectionImputation['DATE_DEB']>$today) {
                $this->validate += 1;
                $this->error .= '<br />'.$this->getTrad()->t('Cette section d\'imputation n\'est pas encore valide pour cette période.');
                return false;
            }
            // date de validité max bloquante
            if (isset($post['max_bloquant']) && $post['max_bloquant'] == 1 && $sectionImputation['DATE_FIN']<$today && $sectionImputation['DATE_FIN']!='00000000') {
                $this->validate += 1;
                $this->error .= '<br />'.$this->getTrad()->t('Cette section d\'imputation n\'est plus valide pour cette période.');
                return false;
            }

            return true;
        } else {
            $this->validate += 1;
            $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('Le code saisi @1@ n\'est pas présent dans la liste des @2@.'), $value, $nomChamp);
            return false;
        }
    }
    
    public function codeGestionZoom(
        string $value,
        string $nomChamp,
        $pdo,
        bool $canBeNull = false,
        $post = []
    ) : bool {
        $value = trim($value);
        if (empty($value) && $canBeNull) {
            return true;
        }
    
        if (empty($value) && !$canBeNull) {
            $this->validate += 1;
            $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('Le champ @1@ ne peut pas être vide.'), $nomChamp);
            return false;
        }

        $validator = new \Modules\Ajax\Repository\Validator($pdo);
        if (! $validator->cg(
            strtoupper($value),
            $post['CODE_SI'],
            $post['NUM_LOT']??'',
            $post['AUTHACHAT']??0,
            $post['CODE_STE']??'',
            $post['valide_obligatoire']??0,
            $post['cgParId']??0
        )) {
            $this->validate += 1;
            $this->error .= '<br />'.Trad::strBuild(
                $this->getTrad()->t('Le code saisi @1@ n\'est pas présent dans la liste des @2@.'),
                $value,
                $nomChamp
            );
            return false;
        }
        
        return true;
    }

    /**
     * @param array<string> $codeGest entity Codegest
     * @param array<string> $commande entity CaEntet
     */
    public function cgValidForCommande(
        array $codeGest,
        array $commande,
        ITrad $trad
    ) : bool {
        if ($this->isDateBetween(
            $commande['DTE_PERIO'],
            $codeGest['DTEVALMIN'],
            $codeGest['DTEVALMAX'],
        )) {
            $this->validate += 1;
            $this->error .= '<br />'. Trad::strBuild(
                $trad->t('@1@ n’est plus valide pour cette période.'),
                $trad->t('Ce code gestion')
            );
            return false;
        }
        return true;
    }

    /**
     * @param array<string> $codeComp entity CodeComp
     * @param array<string> $commande entity CaEntet
     */
    public function codeCompValidForCommande(
        array $codeComp,
        array $commande,
        ITrad $trad
    ) : bool {
        if ($this->isDateBetween(
            $commande['DTE_PERIO'],
            $codeComp['DATE_DEB'],
            $codeComp['DATE_FIN'],
        )) {
            $this->validate += 1;
            $this->error .= '<br />'. Trad::strBuild(
                $trad->t('@1@ n’est plus valide pour cette période.'),
                $trad->t('Ce code complémentaire')
            );
            return false;
        }
        return true;
    }

    /**
     * @param array<string> $sousComptAna entity CodeComp
     * @param array<string> $commande entity CaEntet
     */
    public function sousComptAnaValidForCommande(
        array $sousComptAna,
        array $commande,
        ITrad $trad
    ) : bool {
        if ($this->isDateBetween(
            $commande['DTE_PERIO'],
            $sousComptAna['DATE_MINI'],
            $sousComptAna['DATE_MAXI'],
        )) {
            $this->validate += 1;
            $this->error .= '<br />'. Trad::strBuild(
                $trad->t('@1@ n’est plus valide pour cette période.'),
                $trad->t('Ce sous compte d’analyse')
            );
            return false;
        }
        return true;
    }

    // TODO : move somewhere else
    private function isDateBetween(
        string $date,
        string $min,
        string $max
    ) :bool {
        return (
            $max == '00000000' || $max >= $date
        ) && (
            $min == '00000000' || $min <= $date
        );
    }

    /**
     * TODO : move somewhere else
     */
    /**
     * isDateMin
     *
     *
     * @param ITrad $trad
     * @param string $subject
     * @param string $date
     * @param string $min
     * @return bool
     */
    public function isDateMin(
        ITrad $trad,
        string $subject,
        string $date,
        string $min,
        bool $bloquant = true
    ) {
        if ($min != '00000000' && $min > $date) {
            if ($bloquant) {
                $this->setError(Trad::strBuild(
                    $trad->t('@1@ n’est pas encore valide pour cette période.'),
                    $subject
                ));
            } else {
                $this->setErrorNonBloquant(Trad::strBuild(
                    $trad->t('@1@ n’est pas encore valide pour cette période.'),
                    $subject
                ));
            }
            return false;
        }
        return true;
    }
    /**
     * TODO : move somewhere else
     */
    /**
     * isDateMax
     *
     *
     * @param ITrad $trad
     * @param string $subject
     * @param string $date
     * @param string $max
     * @return bool true if subject is valid, false otherwise
     */
    public function isDateMax(
        ITrad $trad,
        string $subject,
        string $date,
        string $max,
        bool $bloquant = true
    ) {
        if ($max != '00000000' && $max < $date) {
            if ($bloquant) {
                $this->setError(Trad::strBuild(
                    $trad->t('@1@ n’est plus valide pour cette période.'),
                    $subject
                ));
            } else {
                $this->setErrorNonBloquant(Trad::strBuild(
                    $trad->t('@1@ n’est plus valide pour cette période.'),
                    $subject
                ));
            }
            return false;
        }
        return true;
    }

    public static function getImpSubject(ITrad $trad, string $classImp) :string
    {
        switch ($classImp) {
            case Codgest::class:
                return $trad->t('Ce code gestion');
            case Sectimpu::class:
                return $trad->t('Cette section d’imputation');
            case Codecomp::class:
                return $trad->t('Ce code complémentaire');
            case Sscptana::class:
                return $trad->t('Ce sous compte d’analyse');
        }
        throw new \Exception('Invalid imputation class "'.$classImp.'"');
    }

    /**
     * entityDateValidation
     *
     * @param string $classParent
     * @param string $classChild
     * @param ITrad $trad,
     * @param string $impDateMin
     * @param string $impDateMax
     * @param string $dateRef
     *
     * @return void
     */
    public function entityDateValidation(
        string $classParent,
        string $classChild,
        ITrad $trad,
        string $impDateMin,
        string $impDateMax,
        string $dateRef
    ) {
        $paramtr = new Parametr($this->pdo);
        $subject = self::getImpSubject($trad, $classChild);

        switch ($paramtr->getDateMinValiType($classParent, $classChild)) {
            case 'B':
                $this->isDateMin($trad, $subject, $dateRef, $impDateMin, true);
                break;
            case 'N':
                $this->isDateMin($trad, $subject, $dateRef, $impDateMin, false);
                break;
            default:
            // No validation required
        }

        switch ($paramtr->getDateMaxValiType($classParent, $classChild)) {
            case 'B':
                $this->isDateMax($trad, $subject, $dateRef, $impDateMax, true);
                break;
            case 'N':
                $this->isDateMax($trad, $subject, $dateRef, $impDateMax, false);
                break;
            default:
            // No validation required
        }
    }

    
    public function codeComplementaireZoom(string $value, string $nomChamp, $pdo, $null = false, $post = []) : bool
    {
        $today = Date('Ymd');
        
        if (trim($value)=='' && $null) {
            return true;
        }
    
        if (trim($value)=='' && !$null) {
            $this->validate += 1;
            if (!isset($this->listeValue['codeComplementaireZoom'][$value]['error'])) {
                $this->listeValue['codeComplementaireZoom'][$value]['error'] = $this->getTrad()->t('Le champ @1@ ne peut pas être vide.');
            }
            
            $this->error .= '<br />'.Trad::strBuild($this->listeValue['codeComplementaireZoom'][$value]['error'], $nomChamp);
            return false;
        }

        $value = trim($value);
        
        if (!isset($this->listeValue['codeComplementaireZoom'][$value])) {
            $codeComplementaire = new \Modules\Ajax\Repository\Validator($pdo);
            $codeComplementaire = $this->listeValue['codeComplementaireZoom'][$value] = $codeComplementaire->codeComplementaire($value, $post);
        } else {
            $codeComplementaire = $this->listeValue['codeComplementaireZoom'][$value];
        }
        
        if (is_array($codeComplementaire) && count($codeComplementaire)>0) {
            // date de validité min bloquante
            if (isset($post['min_bloquant']) && $post['min_bloquant'] == 1 && $codeComplementaire['DATE_DEB']>$today) {
                $this->validate += 1;
                $this->error .= '<br />'.$this->getTrad()->t('Ce code complémentaire n\'est pas encore valide pour cette période.');
                return false;
            }
            // date de validité max bloquante
            if (isset($post['max_bloquant']) && $post['max_bloquant'] == 1 && $codeComplementaire['DATE_FIN']<$today && $codeComplementaire['DATE_FIN']!='00000000') {
                $this->validate += 1;
                $this->error .= '<br />'.$this->getTrad()->t('Ce code complémentaire n\'est plus valide pour cette période.');
                return false;
            }

            return true;
        } else {
            $this->validate += 1;
            $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('Le code saisi @1@ n\'est pas présent dans la liste des @2@.'), $value, $nomChamp);
            return false;
        }
    }
    
    public function sousCompteAnalyseZoom(string $value, string $nomChamp, $pdo, $null = false, $post = []) : bool
    {
        $today = Date('Ymd');
        
        if (trim($value)=='' && $null) {
            return true;
        }
    
        if (trim($value)=='' && !$null) {
            $this->validate += 1;
            if (!isset($this->listeValue['sousCompteAnalyseZoom'][$value]['error'])) {
                $this->listeValue['sousCompteAnalyseZoom'][$value]['error'] = $this->getTrad()->t('Le champ @1@ ne peut pas être vide.');
            }
            $this->error .= '<br />'.Trad::strBuild($this->listeValue['sousCompteAnalyseZoom'][$value]['error'], $nomChamp);
            return false;
        }

        $value = trim($value);

        if (!isset($this->listeValue['sousCompteAnalyseZoom'][$value])) {
            $sousCompteAnalyse = new \Modules\Ajax\Repository\Validator($pdo);
            $this->listeValue['sousCompteAnalyseZoom'][$value] = $sousCompteAnalyse = $sousCompteAnalyse->sousCompteAnalyse($value, $post);
        } else {
            $sousCompteAnalyse = $this->listeValue['sousCompteAnalyseZoom'][$value];
        }
        
        if (is_array($sousCompteAnalyse) && count($sousCompteAnalyse)>0) {
            // date de validité min bloquante
            if (isset($post['min_bloquant']) && $post['min_bloquant'] == 1 && $sousCompteAnalyse['DATE_MINI']>$today) {
                $this->validate += 1;
                if (!isset($this->listeValue['sousCompteAnalyseZoom'][$value]['error']['periode'])) {
                    $this->listeValue['sousCompteAnalyseZoom'][$value]['error']['periode'] = $this->getTrad()->t('Ce sous compte d\'analyse n\'est pas encore valide pour cette période.');
                }

                $this->error .= '<br />'.$this->listeValue['sousCompteAnalyseZoom'][$value]['error']['periode'];
                return false;
            }
            // date de validité max bloquante
            if (isset($post['max_bloquant']) && $post['max_bloquant'] == 1 && $sousCompteAnalyse['DATE_MAXI']<$today && $sousCompteAnalyse['DATE_MAXI']!='00000000') {
                $this->validate += 1;
                if (!isset($this->listeValue['sousCompteAnalyseZoom'][$value]['error']['periode'])) {
                    $this->listeValue['sousCompteAnalyseZoom'][$value]['error']['sousCompte'] = $this->getTrad()->t('Ce sous compte d\'analyse n\'est plus valide pour cette période.');
                }
                $this->error .= '<br />'.$this->listeValue['sousCompteAnalyseZoom'][$value]['error']['sousCompte'];
                return false;
            }

            return true;
        } else {
            $this->validate += 1;
            if (!isset($this->listeValue['sousCompteAnalyseZoom'][$value]['error']['code'])) {
                $this->listeValue['sousCompteAnalyseZoom'][$value]['error']['code'] = $this->getTrad()->t('Le code saisi @1@ n\'est pas présent dans la liste des @2@.');
            }
            $this->error .= '<br />'.Trad::strBuild($this->listeValue['sousCompteAnalyseZoom'][$value]['error']['code'], $value, $nomChamp);
            return false;
        }
    }
    
    public function zoomRequete(string $value, string $nomChamp, $requete, $pdo, $null = false, $post = []) : bool
    {
        
        if (trim($value)=='' && $null) {
            return true;
        }
        
        if (trim($value)=='' && !$null) {
            $this->validate += 1;
            $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('Le champ @1@ ne peut pas être vide.'), $nomChamp);
            return false;
        }
        
        $value = trim($value);
        
        $validator = new \Modules\Ajax\Repository\Validator($pdo);
        if ($validator->$requete(strtoupper($value), $post)) {
            return true;
        } else {
            $this->validate += 1;
            $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('Le code saisi @1@ n\'est pas présent dans la liste des @2@.'), $value, $nomChamp);
            return false;
        }
    }
    
    public function utilisateurZoom(string $value, string $nomChamp, $pdo, $null = false, $post = []) : bool
    {
        if (trim($value)=='' && $null) {
            return true;
        }
    
        if (trim($value)=='' && !$null) {
            $this->validate += 1;
            $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('Le champ @1@ ne peut pas être vide.'), $nomChamp);
            return false;
        }

        $value = trim($value);
        
        $utilisateur = new \Modules\Ajax\Repository\Validator($pdo);
        if ($utilisateur->utilisateur($value, $post)) {
            return true;
        } else {
            $this->validate += 1;
            $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('Le code saisi @1@ n\'est pas présent dans la liste des @2@.'), $value, $nomChamp);
            return false;
        }
    }
    
    public function demandeurZoom(string $value, string $nomChamp, $pdo, $null = false, $post = []) : bool
    {
        
        if (trim($value)=='' && $null) {
            return true;
        }
    
        if (trim($value)=='' && !$null) {
            $this->validate += 1;
            $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('Le champ @1@ ne peut pas être vide.'), $nomChamp);
            return false;
        }
            
        $value = trim($value);

        $demandeur = new \Modules\Ajax\Repository\Validator($pdo);
        if ($demandeur->demandeur($value, $post)) {
            return true;
        } else {
            $this->validate += 1;
            $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('Le code saisi @1@ n\'est pas présent dans la liste des @2@.'), $value, $nomChamp);
            return false;
        }
    }
    
    public function acheteurZoom(string $value, string $nomChamp, $pdo, $null = false, $post = []) : bool
    {
        
        if (trim($value)=='' && $null) {
            return true;
        }
    
        if (trim($value)=='' && !$null) {
            $this->validate += 1;
            $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('Le champ @1@ ne peut pas être vide.'), $nomChamp);
            return false;
        }

        $value = trim($value);
            
        $demandeur = new \Modules\Ajax\Repository\Validator($pdo);
        if ($demandeur->acheteur($value, $post)) {
            return true;
        } else {
            $this->validate += 1;
            $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('Le code saisi @1@ n\'est pas présent dans la liste des @2@.'), $value, $nomChamp);
            return false;
        }
    }
    
    public function accordCadreZoom(string $value, string $nomChamp, $pdo, $null = false, $post = []) : bool
    {
        
        if (trim($value)=='' && $null) {
            return true;
        }
    
        if (trim($value)=='' && !$null) {
            $this->validate += 1;
            $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('Le champ @1@ ne peut pas être vide.'), $nomChamp);
            return false;
        }
            
        $value = trim($value);

        $accordCadre = new \Modules\Ajax\Repository\Validator($pdo);
        $accordCadre = $accordCadre->accordCadre($value, $post);

        if (is_array($accordCadre) && count($accordCadre)>0) {
            if ($accordCadre['TYPE_FG']=='G') {
                $FsAcd = new \Entity\Model\FsAcd($this->pdo);
                $FsAcd = $FsAcd->fetchAll([], ['filter_egal_CODE_ACD'=> $value]);
                // on vérifie si dans le groupement fournisseur de cet accord-cadre, il existe au moins un fournisseur valide et si la DA est de type Execution qu'il ne soit pas un prospect
                if (count($FsAcd)>0) {
                    foreach ($FsAcd as $fournisseur) {
                        $fourniss = (new Listes($this->pdo))
                            ->Fournisseur(
                                [
                                    'filter_egal_CODE' => $fournisseur['CODE_FOU'],
                                    'valide' => 1,
                                    'TYPE_FRS' => $post['PROSPECT'] ?? ''
                                ],
                                'CODE, RS, RECEP_AUTO, PER_REC_AUTO, REMISE'
                            );
                        if (count($fourniss)>0) {
                            return true;
                        }
                    }
                }
                $this->validate += 1;
                $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('Aucun fournisseur du groupement n’est disponible pour l\'accord-cadre @1@.'), $value);
                return false;
            } else {
                $fourniss = (new Listes($this->pdo))
                    ->Fournisseur([
                        'filter_egal_CODE' => $accordCadre['CODE_FOUR'], 'valide' => 1, 'TYPE_FRS' => $post['PROSPECT'] ?? ''], 'CODE, RS, RECEP_AUTO, PER_REC_AUTO, REMISE, PROSPECT');
                if (count($fourniss)==0) {
                    $this->validate += 1;
                    $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('L\'accord-cadre @1@ a un fournisseur non valide.'), $value);
                    return false;
                }
            }
            return true;
        } else {
            $this->validate += 1;
            $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('Le code saisi @1@ n\'est pas présent dans la liste des @2@.'), $value, $nomChamp);
            return false;
        }
    }
    
    public function fournisseurZoom(string $value, string $nomChamp, $pdo, $null = false, $post = []) : bool
    {
        
        if (trim($value)=='' && $null) {
            return true;
        }
    
        if (trim($value)=='' && !$null) {
            $this->validate += 1;
            $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('Le champ @1@ ne peut pas être vide.'), $nomChamp);
            return false;
        }
        $value = trim($value);
            
        $fournisseur = new \Modules\Ajax\Repository\Validator($pdo);
        if ($fournisseur->fournisseur($value, $post)) {
            return true;
        } else {
            $this->validate += 1;
            $this->error .= '<br />'.Trad::strBuild(
                $this->getTrad()->t('Le code saisi @1@ n\'est pas présent '
                    .'dans la liste des @2@.'), // TODO
                $value,
                $nomChamp
            ).($post['messageCompl']??'');
            return false;
        }
    }
    
    public function siteStockZoom(string $value, string $nomChamp, $pdo, $null = false, $post = []) : bool
    {
        
        if (trim($value)=='' && $null) {
            return true;
        }
    
        if (trim($value)=='' && !$null) {
            $this->validate += 1;
            $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('Le champ @1@ ne peut pas être vide.'), $nomChamp);
            return false;
        }
        
        $value = trim($value);

        $SsItesto = new SSiteSto($this->pdo);
        if (is_array($SsItesto->find($value, [], $post))) {
            if ($post['CODE_ART']??'' != '') {
                $Sstocklo = new \Entity\Model\Sstocklo($this->pdo);
                $Sstocklo = $Sstocklo->find(['SITE' => $value, 'CODE_ART' => $post['CODE_ART'], 'CODE_STE' => $post['filter_egal_CODE_STE']]);
                if (is_array($Sstocklo)) {
                    if (isset($post['date_art_ouvert']) && $post['date_art_ouvert'] != '' && $Sstocklo['DTE_FERM'] != '00000000' && $Sstocklo['DTE_FERM'] < $post['date_art_ouvert']) {
                        $this->validate += 1;
                        $this->error .= '<br />'.$this->getTrad()->t('Article fermé sur ce site.');
                        return false;
                    }
                } else {
                    $this->validate += 1;
                    $this->error .= '<br />'.$this->getTrad()->t('Article non stocké sur ce site.');
                    return false;
                }
            }
            return true;
        } else {
            $this->validate += 1;
            $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t("Le code saisi @1@ n'est pas présent dans la liste des @2@"), $value, $nomChamp);
            return false;
        }
    }
    
    public function sousFamilleZoom(string $value, string $nomChamp, $pdo, $null = false, $post = []) : bool
    {
        
        if (trim($value)=='' && $null) {
            return true;
        }
    
        if (trim($value)=='' && !$null) {
            $this->validate += 1;
            $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('Le champ @1@ ne peut pas être vide.'), $nomChamp);
            return false;
        }
            
        $value = trim($value);

        $fournisseur = new \Modules\Ajax\Repository\Validator($pdo);
        if ($fournisseur->SousFamille($value, $post)) {
            return true;
        } else {
            $this->validate += 1;
            $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('Le code saisi @1@ n\'est pas présent dans la liste des @2@.'), $value, $nomChamp).($post['messageCompl']??'');
            return false;
        }
    }
    
    /**
     * uniteZoom
     *
     * @param  string $value
     * @param  string $nomChamp
     * @param  \PDO $pdo
     * @param  bool $null
     * @param  array<mixed> $post
     * @return bool
     */
    public function uniteZoom(string $value, string $nomChamp, $pdo, $null = false, $post = []) : bool
    {
        if (trim($value)=='' && $null) {
            return true;
        }

        if (trim($value)=='' && !$null) {
            $this->validate += 1;
            $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('Le champ @1@ ne peut pas être vide.'), $nomChamp);
            return false;
        }

        $value = trim($value);

        $uniteEntity = new Unites($this->pdo);
        $unite = $uniteEntity->find($value);
        if ($unite) {
            if (isset($post['ssFamille']) && $post['ssFamille'] != '') {
                $param = Sql::paravrac($this->pdo, 'PARAMGEN', 'SFAM_CTRL_UNITE');
                
                if ($param != '') {
                    $sousFamilleEntity = new SousFamille($this->pdo);
                    $sousFamille = $sousFamilleEntity->find($post['ssFamille']);
                        
                    if ($sousFamille['UNITEGEST'] != '') {
                        if (mb_strtoupper($sousFamille['UNITEGEST']) != $value) {
                            if ($param=='N') {
                                $this->nonBloquant = 1;
                                $this->errorNonBloquant = '<br />'.trad::strBuild($this->getTrad()->t('L\'unité @1@ n\'est pas autorisée pour cette sous-famille. Unité de gestion: @2@.'), $value, $sousFamille['UNITEGEST']);
                            } elseif ($param=='B') {
                                $this->validate += 1;
                                $this->error = '<br />'.trad::strBuild($this->getTrad()->t('L\'unité @1@ n\'est pas autorisée pour cette sous-famille. Unité de gestion: @2@.'), $value, $sousFamille['UNITEGEST']);
                            }
                        }
                    }
                }
            }

            return true;
        } else {
            $this->validate += 1;
            $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('Le code saisi @1@ n\'est pas présent dans la liste des @2@.'), $value, $nomChamp).($post['messageCompl']??'');
            return false;
        }
    }
}
