<?php

namespace Modules\Facture\Controller;

use Entity\Model\Paravrac;
use GuzzleHttp\Psr7\Response;
use Skeleton\Controller\Controller;
use Helpers\ChampsSupplementaire\ChampSupp;
use Helpers\Outil\Sql;
use Helpers\Pagination\Paginator;
use Helpers\Trad\Trad;
use Helpers\Outil\Roles;
use Helpers\Validator\Validator;
use Helpers\Parametres\Constante;
use Entity\Model\FacLigTravail;
use Helpers\Additional\Specifique\Specifique;
use Modules\Facture\Repository\CreationFacture;
use Entity\Model\Codgest;
use Modules\Facture\MenuContextuel\AffectationMenuContextuel;
use Modules\Facture\MenuContextuel\SuiviEventMenuContextuel;

class AjaxFactureController extends Controller
{


    /***************************************************** CREATION/MODIFICATION ENTETE FACTURE *****************************************************/
    // CALCUL DE LA DATE DE PERIODE ENTETE FACTURE
    public function calculDatePeriodeAction()
    {
        $post = $this->request->getParsedBody();
        $validator = $this->createValidator();
        $date = $post['DATE_FAFO'];
        $validator->isDate($date);
        $validator->isDate($post['DATE_ENR']);

        // Calcul DTAE_ECH
        $dateReturn['DTAE_ECH'] = $this->calculDateEch($post, $date, $this->pdo);

        $dateConverte = new \Helpers\Outil\Date();
        // Calcul DATE_PER
        // SPEC 4284 : modification de l'initialisation de la date de période en prenant compte des dates prévisionnelles globales ou par société pour les sous-périodes
        if (\Helpers\Outil\Roles::droit($this->pdo, 'SPER_AVEC_OUV_FERM') && \Helpers\Outil\Roles::droit($this->pdo, 'CTRL_SSPERIODE_FAC')) {
            $CreationFacture = new \Modules\Facture\Repository\CreationFacture($this->pdo);
            $resultSousPer = $CreationFacture->ouvertureSousPeriode($date, $post['societe'], 1);
            $sousPeriodeOuverte = 0;
            if (isset($resultSousPer['ETAT']) && (
                $resultSousPer['ETAT'] == 'O' ||
                ($resultSousPer['ETAT'] == '' && $resultSousPer['DATE_DEB'] <= $date && ($resultSousPer['DATE_FIN'] >= $date || $resultSousPer['PREV_CLOSING_DATE'] >= $date || $resultSousPer['PREV_CLOSING_DATE_STE'] >= $date))
            )) {
                $sousPeriodeOuverte = 1;
            }

            if ($sousPeriodeOuverte) {
                $dateReturn['DATE_PER'] = $post['DATE_FAFO'];
            } else {
                $resultPremSousPeriode = $CreationFacture->DatepremiereSousPeriode($date, $post['societe']);
                if ($resultPremSousPeriode['DATE_DEB'] ?? false) {
                    $dateReturn['DATE_PER'] = $dateConverte->dateConverte($resultPremSousPeriode['DATE_DEB']);
                } else {
                    $resultDerniereSousPeriode = $CreationFacture->DateDernièreSousPeriode($date, $post['societe']);
                    if ($resultDerniereSousPeriode['DATE_FIN']) {
                        $dateReturn['DATE_PER'] = $dateConverte->dateConverte($resultDerniereSousPeriode['DATE_FIN']);
                    } else {
                        $dateReturn['DATE_PER'] = $dateConverte->dateConverte(date("Ymd"));
                    }
                }
            }
        } else {
            $dateReturn['DATE_PER'] = $dateConverte->dateConverte(date("Ymd"));
        }

        $dateReturn['DTAE_ECH'] = $dateConverte->dateConverte($dateReturn['DTAE_ECH']);
        return new Response(200, [], (string) \json_encode($dateReturn));
    }

    // CALCUL DE LA DATE D'ECHEANCE ENTETE FACTURE
    public static function calculDateEch($post, $date, $pdo)
    {
        // Date pour la base de calcul
        if (! (new Paravrac($pdo))->getFlag('PARAMGEN', 'DECHFACT') && (($post['DATE_FAFO'] ?? '00000000') != '00000000' && ($post['DATE_FAFO'] ?? '') != '')) {
            $baseCalcul = $date;
        } else {
            $baseCalcul = $post['DATE_ENR'];
        }
        $anneeBaseCalcul = substr($baseCalcul, 0, 4);
        $baseCalcul = substr($baseCalcul, 0, 4) . '-' . substr($baseCalcul, 4, 2) . '-' . substr($baseCalcul, 6);

        if (($post['DATE_ORDO'] ?? 0) != 0) {
            $jourOrdo = substr($post['DATE_ORDO'], 0, 2);
            $moisOrdo = substr($post['DATE_ORDO'], -2);
            $baseCalcul = date("Y-m-d", (strtotime($anneeBaseCalcul . "-" . $moisOrdo . "-" . $jourOrdo) ?: 0));
        }


        // Calcul DTAE_ECH
        if ($post['COND_PAIE'] != '') {
            $condpaie = new \Entity\Model\CondPaie($pdo);
            $condpaie = $condpaie->find($post['COND_PAIE']);
            if ($condpaie) {
                // Si Paiement Fin De Mois
                if (\Helpers\Outil\Sql::boolSql($condpaie['FIN_D_MOI'])) {
                    $moisAAjouter = floor($condpaie['DELAI_PAI'] / 30);
                    $jourAAjouter = $condpaie['DELAI_PAI'] - $moisAAjouter * 30;
                    $baseCalculFinMois = date("Y-m-d", strtotime("last day of " . $baseCalcul));
                    $day = date("d", strtotime($baseCalculFinMois));

                    if ($day === '31') {
                        $baseCalculFinMois = date("Y-m-d", strtotime("30 " . date("F Y", strtotime($baseCalculFinMois))));
                    }
                    
                    $DTAE_ECH = date("Y-m-d", strtotime("$baseCalculFinMois + $moisAAjouter months $jourAAjouter days"));
                    // Si ordonnance, ajout jour de l'ordonnance
                    if (($post['DATE_ORDO'] ?? 0) != 0) {
                        $DTAE_ECH = date("Y-m-d", strtotime("$DTAE_ECH +$jourOrdo days"));
                    }
                    // Ajout Quantième
                    $DTAE_ECH = date("Y-m-d", (strtotime("$DTAE_ECH +" . $condpaie['QUANT_PAI'] . " days") ?: 0));
                } else {
                    // Si Paiement Calendaire
                    $DTAE_ECH = date("Y-m-d", (strtotime("$baseCalcul + " . $condpaie['DELAI_PAI'] . " days") ?: 0));
                }

                return $DTAE_ECH = date("Ymd", (strtotime($DTAE_ECH) ?: 0));
            }
        }

        return date("Ymd");
    }

    // RECUPERATION DE LA LONGEUR DU CODE POSTAL SELON LE PAYS
    public function getLONGCPAction()
    {
        $post = $this->request->getParsedBody();

        $country = new \Entity\Model\Country($this->pdo);
        $country = $country->find($post['PAYS']);

        return new Response(200, [], (string) \json_encode($country));
    }

    /***************************************************** SAISIE DES AFFECTATIONS *****************************************************/
    // VERIFICATION DE LA QUANTITE PAR LIGNE
    public function verifQteLigneAction()
    {
        $trad = $this->getTranslationService();
        $post = $this->request->getParsedBody();
        $erreur = '';

        // $qte = str_replace(' ', '', $post['qte']);
        // $qte_init = str_replace(' ', '', $post['qte_init']);
        $qte_eclatementLigneInitiale = str_replace(' ', '', $post['qte_eclatementLigneInitiale'] ?? 0);

        // vérification de la quantité pour eclatement ligne
        if ($post['typeAction'] == 'eclatementLigne' && (float)$qte_eclatementLigneInitiale <= 0) {
            $erreur .= '<br /> ' . $trad->t('La quantité de la ligne initiale ne peut pas être inférieure ou égale à 0.');
        }

        // DOSSIER 30072 : suppression du controle
        // vérification de la quantité par rapport à la quantité facturable (sauf pour eclatement ligne et ligne manuelle)
        // if($post['typeAction']=='' && $qte>$qte_init)
        //     $erreur .= '<br /> '.$trad->t('La quantité de la ligne ne peut pas être supérieure à la quantité facturable.');

        return new Response(200, [], (string) \json_encode(['erreur' => $erreur]));
    }

    // VERIFICATION DU PRIX UNITAIRE REMISE PAR LIGNE
    public function verifPuRemiseLigneAction()
    {
        $trad = $this->getTranslationService();
        $post = $this->request->getParsedBody();
        $erreur = '';

        $pu_remise = str_replace(' ', '', $post['pu_remise']);
        $type = $post['type'];

        // DOSSIER 30892 : SUPPRESSION DE CONTROLE SI FACTURE
        // si avoir, pu_remise doivent être négatif
        if ($type == 'A') {
            if ((int)$pu_remise > 0) {
                $erreur .= '<br /> ' . $trad->t('Le pu remisé de la ligne ne peut pas être positif.');
            }
        }

        return new Response(200, [], (string) \json_encode(['erreur' => $erreur]));
    }

    // VERIFICATION DU MONTANT HT PAR LIGNE
    public function verifHTLigneAction()
    {
        $post = $this->request->getParsedBody();
        $erreur = '';

        $trad = $this->getTranslationService();

        $qte = str_replace(' ', '', $post['qte']);
        $pu_remise = str_replace(' ', '', $post['pu_remise']);
        $montant = str_replace(' ', '', $post['montant']);
        $type = $post['type'];
        $mtt_init_eclatementLigneInitiale = str_replace(' ', '', $post['mtt_init_eclatementLigneInitiale'] ?? 0);
        $mtt_eclatementLigneInitiale = str_replace(' ', '', $post['mtt_eclatementLigneInitiale'] ?? 0);

        $fourchetteMontantMin = round($qte * $pu_remise - 0.005, 2);
        $fourchetteMontantMax = round($qte * $pu_remise + 0.005, 2);


        // si avoir, montant doivent être négatif // si facture, different de 0
        if ($type == 'F') {
            if ($post['typeAction'] == 'eclatementLigne' && $mtt_init_eclatementLigneInitiale > 0 && $mtt_eclatementLigneInitiale <= 0) {
                $erreur .= '<br /> ' . $trad->t('Le montant de la ligne initiale ne peut pas être inférieur ou égal à 0.');
            } elseif ($post['typeAction'] == 'eclatementLigne' && $mtt_init_eclatementLigneInitiale < 0 && $mtt_eclatementLigneInitiale >= 0) {
                $erreur .= '<br /> ' . $trad->t('Le montant de la ligne initiale ne peut pas être supérieur ou égal à 0.');
            }
            // elseif($montant==0) $erreur .= '<br /> '.$trad->t('Le montant HT de la ligne ne peut pas être égal à zéro.');
        } else {
            if ($post['typeAction'] == 'eclatementLigne' && $mtt_eclatementLigneInitiale >= 0) {
                $erreur .= '<br /> ' . $trad->t('Le montant de la ligne initiale ne peut pas être supérieur ou égal à 0.');
            }
            if ($montant > 0) {
                $erreur .= '<br /> ' . $trad->t('Le montant HT de la ligne ne peut pas être positif.');
            }
        }

        // tolérance du montant HT
        if ($post['verificationMontantQte'] && ($montant < $fourchetteMontantMin || $montant > $fourchetteMontantMax)) {
            $erreur = '<br /> ' . Trad::strBuild($trad->t('Le montant facturé de la ligne doit être compris entre @1@ et @2@ ; cet écart nécessite la variation du prix unitaire et de la quantité (passer par le calcul pourcentage).'), $fourchetteMontantMin, $fourchetteMontantMax);
        }

        return new Response(200, [], (string) \json_encode(['erreur' => $erreur]));
    }

    // VERIFICATION DU MONTANT TVA PAR LIGNE
    public function verifTVALigneAction()
    {
        $post = $this->request->getParsedBody();
        $erreur = '';

        $trad = $this->getTranslationService();

        $montant = str_replace(' ', '', $post['montant']);
        $tauxTva = str_replace(' ', '', $post['tauxTva']);
        $montantTva = str_replace(' ', '', $post['montantTva']);
        $type = $post['type'];

        // DOSSIER 30892 : SUPPRESSION DE CONTROLE SI FACTURE
        // si avoir, pu_remise et montant doivent être négatif
        if ($type == 'A') {
            if ($montantTva > 0 && $tauxTva != 0) {
                $erreur .= '<br /> ' . $trad->t('Le montant de TVA de la ligne ne peut pas être positif.');
            }
        }

        // si le montant HT != 0 et taux de tva != 0, TVA ne peut pas être égal à 0
        if ($montant != 0 && $montantTva == 0 && $tauxTva != 0) {
            $erreur .= '<br /> ' . $trad->t('Le montant de TVA de la ligne ne peut pas être égal à 0.');
        }

        if ($tauxTva == 0 && $montantTva != 0) {
            $erreur .= '<br /> ' . $trad->t('Le montant de TVA de la ligne doit être égal à 0.');
        } else {
            // DOSSIER 33156 : augmentation de l'écart -> passage de 0.005 à 0.05
            // DOSSIER 35088: augmentation de l'écart -> passage à 1
            $fourchetteMontantTVAMin = round($montant * $tauxTva / 100) - 1;
            $fourchetteMontantTVAMax = round($montant * $tauxTva / 100) + 1;

            if ($montantTva < $fourchetteMontantTVAMin || $montantTva > $fourchetteMontantTVAMax) {
                $erreur .= '<br /> ' . Trad::strBuild($trad->t('Le montant de TVA de la ligne doit être compris entre @1@ et @2@.'), $fourchetteMontantTVAMin, $fourchetteMontantTVAMax);
            }
        }

        return new Response(200, [], (string) \json_encode(['erreur' => $erreur]));
    }

    // INITIALISATION SELON ARTICLE
    public function changeArticleAction()
    {
        $post = $this->request->getParsedBody();

        $articles = new \Entity\Model\Articles($this->pdo);
        $siSteArt = new \Entity\Model\SiSteArt($this->pdo);
        $cdcSteAr = new \Entity\Model\CdcSteAr($this->pdo);
        $scaSteAr = new \Entity\Model\ScaSteAr($this->pdo);

        $articles = $articles->find($post['CODE_ART']);
        $result = ['DESIGN' => ($articles['DESIGN'] ?? ''), 'SSFAM' => ($articles['SSFAM'] ?? '')];

        $steSi = \Helpers\Outil\Roles::droit($this->pdo, 'SISECTOR', 'PARAMSTE') ? $post['CODE_STE'] : '';
        $steCdc = \Helpers\Outil\Roles::droit($this->pdo, 'CDCSECTO', 'PARAMSTE') ? $post['CODE_STE'] : '';
        $steSca = \Helpers\Outil\Roles::droit($this->pdo, 'SCASECTO', 'PARAMSTE') ? $post['CODE_STE'] : '';

        $si = $siSteArt->find(['CODE_ART' => $post['CODE_ART'], 'CODE_STE' => $steSi]);
        $result['CODE_SI'] = $si['SI'] ?? '';
        $result['codeGestionSaisie'] = Sql::boolSql($si['SICODG'] ?? 0);
        $result['codeGestionObligatoire'] = Sql::boolSql($si['IMPCODG'] ?? 0) == 1 ? 'false' : 'true';
        $result['CODE_CDC'] = $cdcSteAr->find(['CODE_ART' => $post['CODE_ART'], 'CODE_STE' => $steCdc])['CDC'] ?? '';
        $result['CODE_SCA'] = $scaSteAr->find(['CODE_ART' => $post['CODE_ART'], 'CODE_STE' => $steSca])['SCA'] ?? '';

        return new Response(200, [], (string) \json_encode($result));
    }

    // INITIALISATION SELON SOUS FAMILLE
    public function changeSousFamilleAction()
    {
        $post = $this->request->getParsedBody();


        $result = [];
        $result['si'] = '';
        $result['cdc'] = '';
        $result['sca'] = '';

        $creationFacture = new CreationFacture($this->pdo);
        $result['si'] = $creationFacture->getSiSousFamille($post) ?? '';
        $result['cdc'] = $creationFacture->getCdcSousFamille($post) ?? '';
        $result['sca'] = $creationFacture->getScaSousFamille($post) ?? '';

        if ($result['si'] != '') {
            $sectimpu = new \Entity\Model\Sectimpu($this->pdo);
            $sectimpu = $sectimpu->find($result['si']);
            $result['codeGestionSaisie'] = $codeGestionSaisie = Sql::boolSql($sectimpu['SICODG']);
            $result['codeGestionNonObligatoire'] = $codeGestionNonObligatoire = Sql::boolSql($sectimpu['IMPCODG']) == 1 ? 'false' : 'true';
        }

        if ($post['CODE_SI'] != '' || $post['CODE_CDC'] != '' || $post['CODE_SCA'] != '') {
            $listeImputation = [];

            if ($result['si'] != '' && $result['si'] != $post['CODE_SI']) {
                $listeImputation['SI'] = [
                    'Titre' => 'SI',
                    'OldValeur' => $post['CODE_SI'],
                    'NewValeur' => $result['si'],
                    'codeGestionSaisie' => $codeGestionSaisie,
                    'codeGestionNonObligatoire' => $codeGestionNonObligatoire,
                ];
            }
            if ($result['cdc'] != '' && $result['cdc'] != $post['CODE_CDC']) {
                $listeImputation['CDC'] = [
                    'Titre' => 'CDC',
                    'OldValeur' => $post['CODE_CDC'],
                    'NewValeur' => $result['cdc'],
                ];
            }
            if ($result['sca'] != '' && $result['sca'] != $post['CODE_SCA']) {
                $listeImputation['SCA'] = [
                    'Titre' => 'SCA',
                    'OldValeur' => $post['CODE_SCA'],
                    'NewValeur' => $result['sca'],
                ];
            }

            if (count($listeImputation) > 0) {
                $params = [
                    'listeImputation' => $listeImputation,
                    'encodeImputation' => json_encode($listeImputation),
                    'idLigne' => $post['ID_LIGNE'],
                    'titrePopup'  => '',

                ];
                return new Response(443, [], $this->renderer->render('@ajax-facture/ajaxSousFamille', ['params' => $params]));
            }
        }

        return new Response(200, [], (string) \json_encode($result));
    }

    // VALIDATION DE L'ECLATEMENT DE LIGNE
    public function validerEclatementAction()
    {
        $post = $this->request->getParsedBody();

        $trad = $this->getTranslationService();

        $erreur = '';
        $idLigneInitEclatement = $post['idLigneInitEclatement'];

        $facture = new \Entity\Model\FactEnt($this->pdo);
        $facture = $facture->find($post['facture']);
        $data = array();
        foreach ($post['tblIdLigne'] as $idLigne) {
            $data[$idLigne] = array();
            $data[$idLigne]['typeAction'] = '';

            foreach ($post['data'] as $key => $value) {
                $tblKey = explode('-', $key);
                if (isset($tblKey[1]) && $tblKey[1] == $idLigne) {
                    $data[$idLigne][$tblKey[0]] = $value;
                }
                $tblKey = explode('debut-----fin', $key);
                if (count($tblKey) > 1) {
                    $data[$idLigne][$key] = $value;
                }
            }
        }

        $testQte = 1;

        foreach ($data as $key => $ligne) {
            $qte = $data[$key]['QUANTITE'] = $ligne['QUANTITE'] = str_replace(' ', '', $ligne['QUANTITE']);
            $pu_remise = $data[$key]['PU_REMISE'] = $ligne['PU_REMISE'] = str_replace(' ', '', $ligne['PU_REMISE']);
            $taux_tva = $data[$key]['TAUX_TVA'];
            $montant_init = $data[$key]['MONTANT_INIT'] = $ligne['MONTANT_INIT'] = str_replace(' ', '', $ligne['MONTANT_INIT']);
            $montant = $data[$key]['MONTANT'] = $ligne['MONTANT'] = str_replace(' ', '', $ligne['MONTANT']);
            $mt_tva = $data[$key]['MT_TVA'] = $ligne['MT_TVA'] = str_replace(' ', '', $ligne['MT_TVA']);

            // si la réception n'est pas en montant
            if ($ligne['ligneEnMontant'] == 0) {
                // vérification de la quantité pour eclatement ligne
                if ($ligne['NO_LIGNE'] == $idLigneInitEclatement && $qte <= 0) {
                    $erreur .= '<br /> ' . $trad->t('La quantité de la ligne initiale ne peut pas être inférieure ou égale à 0.');
                    $testQte = 0;
                }

                // DOSSIER 30892 : SUPPRESSION DE CONTROLE SI FACTURE
                // si avoir, pu_remise doivent être négatif
                if ($facture['TYPE'] == 'A') {
                    if ($pu_remise > 0) {
                        $erreur .= '<br /> ' . Trad::strBuild($trad->t('Le pu remisé de la ligne @1@ de la commande @2@ ne peut pas être positif.'), $ligne['NUM_LICDE'], $ligne['NUM_CDE']);
                    }
                }

                // tolérance du montant HT par ligne : (QUANTITE * PU) - 0.005 < Montant HT > (QUANTITE * PU) + 0.005
                $fourchetteMontantMin = round(($qte * $pu_remise - 0.005), 2);
                $fourchetteMontantMax = round(($qte * $pu_remise + 0.005), 2);
                
                if ($montant < $fourchetteMontantMin || $montant > $fourchetteMontantMax) {
                    $erreur .= '<br /> ' . Trad::strBuild($trad->t('Le montant HT de la ligne @1@ de la commande @2@ n\'est pas compris dans une fourchette acceptable.'), $ligne['NUM_LICDE'], $ligne['NUM_CDE']);
                }
            }

            // DOSSIER 30892 : SUPPRESSION DE CONTROLE SI FACTURE
            // si avoir, pu_remise, montant et TVA doivent être négatif
            if ($facture['TYPE'] == 'F') {
                if ($ligne['NO_LIGNE'] == $idLigneInitEclatement && $montant_init > 0 && $montant <= 0) {
                    $erreur .= '<br /> ' . $trad->t('Le montant de la ligne initiale ne peut pas être inférieur ou égal à 0.');
                } elseif ($ligne['NO_LIGNE'] == $idLigneInitEclatement && $montant_init < 0 && $montant >= 0) {
                    $erreur .= '<br /> ' . $trad->t('Le montant de la ligne initiale ne peut pas être supérieur ou égal à 0.');
                }
            } else {
                if ($ligne['NO_LIGNE'] == $idLigneInitEclatement && $montant >= 0) {
                    $erreur .= '<br /> ' . $trad->t('Le montant de la ligne initiale ne peut pas être supérieur ou égal à 0.');
                } elseif ($montant > 0) {
                    $erreur .= '<br /> ' . Trad::strBuild($trad->t('Le montant HT de la ligne @1@ de la commande @2@ ne peut pas être positif.'), $ligne['NUM_LICDE'], $ligne['NUM_CDE']);
                }

                if ($mt_tva > 0) {
                    $erreur .= '<br /> ' . Trad::strBuild($trad->t('Le montant de TVA  de la ligne @1@ de la commande @2@ ne peut pas être positif.'), $ligne['NUM_LICDE'], $ligne['NUM_CDE']);
                }

                if ($ligne['NO_LIGNE'] == $idLigneInitEclatement && $montant >= 0) {
                    $erreur .= '<br /> ' . $trad->t('Le montant de la ligne initiale ne peut pas être supérieur ou égal à 0.');
                }
            }

            // tolérance du montant TVA par ligne : (MONTANT HT * TAUX_TVA / 100) - 1  <= Montant TVA => (MONTANT HT * TAUX_TVA / 100) + 1
            // DOSSIER 33156 : augmentation de l'écart -> passage de 0.005 à 0.05
            // DOSSIER 35088: augmentation de l'écart -> passage à 1
            $fourchetteMontantTVAMin =  round($montant * $taux_tva / 100) - 1;
            $fourchetteMontantTVAMax =  round($montant * $taux_tva / 100) + 1;

            if ($mt_tva < $fourchetteMontantTVAMin || $mt_tva > $fourchetteMontantTVAMax) {
                $erreur .= '<br /> ' . Trad::strBuild($trad->t('Le montant de TVA  de la ligne @1@ de la commande @2@ n\'est pas compris dans une fourchette acceptable.'), $ligne['NUM_LICDE'], $ligne['NUM_CDE']);
            }


            if ($erreur == '' && $testQte) {
                $data[$key]['QUANTITE_INIT'] = $data[$key]['QUANTITE'];
            }
        }
        $creationFacture = new CreationFacture($this->pdo);

        if ($erreur == '') {
            foreach ($data as $key => $ligne) {
                if (is_array($ligne)) {
                    $idLigne = $ligne['NO_LIGNE'];
                    if ($ligne['NO_LIGNE'] == $idLigneInitEclatement) {
                        $creationFacture->updateLigneFacLigTravail($post['facture'], $idLigne, $ligne);
                    } else {
                        $creationFacture->insertLigneFacLigTravail($post['facture'], $idLigneInitEclatement, $idLigne, $ligne);

                        $listeCSFac = $creationFacture->infoCSLigTravail($post['facture'], $idLigneInitEclatement);
                        foreach ($listeCSFac as $cs) {
                            ChampSupp::insertChampSupp('FAC_LIG_TRAVAIL', ChampSupp::autoCompletCodeEnr($post['facture'], $idLigne, 'FAC_LIG'), $cs['NUM_FIX'], $cs['VALEUR'], $this->pdo);
                        }
                    }
                }
            }
        }
        return new Response(200, [], (string) \json_encode(['erreur' => $erreur, 'data' => $data]));
    }

    // AFFICHAGE D'UNE LIGNE D'AFFECTATION : LIGNE MANUELLE, ECLATEMENT DE LIGNE
    public function ligneAffectationAction(): string
    {
        $spliter = Constante::spliter;
        $post = $this->request->getParsedBody();
        $droits['HA_FA_MOLI'] = Roles::droitsUtilisateur($this->pdo, 'HA_FA_MOLI');

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

        $validator = $this->createValidator();

        $fourniss = new \Entity\Model\Fourniss($this->pdo);
        $country = new \Entity\Model\Country($this->pdo);
        $sectimpu = new \Entity\Model\Sectimpu($this->pdo);
        $Codgest = new \Entity\Model\Codgest($this->pdo);
        $Codecomp = new \Entity\Model\Codecomp($this->pdo);
        $Sscptana = new \Entity\Model\Sscptana($this->pdo);

        $listeCS = ChampSupp::listeIdCS('FAC_LIG', $this->pdo);

        // DOSSIER 30276 + 31844
        $params['IS_CG_ACTIVE'] = $_SESSION['IS_CG_ACTIVE'] && \Helpers\Outil\Roles::droit($this->pdo, 'CODE_GESTION_PAR_ID');
        $creationFacture = new \Modules\Facture\Repository\CreationFacture($this->pdo);
        $numLot = $creationFacture->numLot()['NUM_LOT'] ?? '1';

        $facture = new \Entity\Model\FactEnt($this->pdo);
        $facture = $facture->find($post['facture']);

        $societe = $facture['CODE_STE'];

        if (Roles::droit($this->pdo, 'IMP_BO_SI__FA_' . $societe, 'PARAMSOC', true) == 'O') {
            $saisieNonObligatoire['SI'] = true;
        } elseif (Roles::droit($this->pdo, 'IMP_BO_SI__FA_', 'PARAMGEN', true) == 'O') {
            $saisieNonObligatoire['SI'] = true;
        } else {
            $saisieNonObligatoire['SI'] = false;
        }

        if (Roles::droit($this->pdo, 'IMP_BO_CDC_FA_' . $societe, 'PARAMSOC', true) == 'O') {
            $saisieNonObligatoire['CDC'] = true;
        } elseif (Roles::droit($this->pdo, 'IMP_BO_CDC_FA_', 'PARAMGEN', true) == 'O') {
            $saisieNonObligatoire['CDC'] = true;
        } else {
            $saisieNonObligatoire['CDC'] = false;
        }

        if (Roles::droit($this->pdo, 'IMP_BO_SCA_FA_' . $societe, 'PARAMSOC', true) == 'O') {
            $saisieNonObligatoire['SCA'] = true;
        } elseif (Roles::droit($this->pdo, 'IMP_BO_SCA_FA_', 'PARAMGEN', true) == 'O') {
            $saisieNonObligatoire['SCA'] = true;
        } else {
            $saisieNonObligatoire['SCA'] = false;
        }

        $steSi = \Helpers\Outil\Roles::droit($this->pdo, 'SISECTOR', 'PARAMSTE') ? $facture['CODE_STE'] : '';
        $steCDC = \Helpers\Outil\Roles::droit($this->pdo, 'CDCSECTO', 'PARAMSTE') ? $facture['CODE_STE'] : '';
        $steSCA = \Helpers\Outil\Roles::droit($this->pdo, 'SCASECTO', 'PARAMSTE') ? $facture['CODE_STE'] : '';

        $typeTva = new \Entity\Model\TypeTVA($this->pdo);
        $typeTva = $typeTva->fetchAll();
        $listeTypeTva = array();
        foreach ($typeTva as $key => $value) {
            $listeTypeTva[$value['CODE_TTV']] = $value['LIBELLE'];
        }
        if (!isset($listeTypeTva[''])) {
            $params['AddTypeTvaVide'] = 1;
        }

        $typeAction = '';
        $listeCde = array();

        if (isset($post['data'][0]) && $post['data'][0]['typeAction'] == '') {
        } else {
            $listeCde = $post['data'];
        }

        $detailFac = $creationFacture->detailFactTravail($post['facture']);
        $idLastLigne = ($detailFac['NUM_LIG'] ?? 0) + 1;

        if (isset($post['typeAction']) && $post['typeAction'] == 'duplicationLigne') {
            $typeAction = $post['typeAction'];
        }

        if ($typeAction != 'duplicationLigne') {
            foreach ($listeCde as $key => $value) {
                $listeCde[$key]['SELECT_LIGNE'] = $validator->isCheck($value['SELECT_LIGNE']);
                $idLigne = $idLastLigne;
                if ($value['typeAction'] == 'ligneManuelle') {
                    $listeCde[$key]['SELECT_LIGNE'] = 1;
                    $listeCde[$key]['CODE_STE'] = $facture['CODE_STE'];
                    $listeCde[$key]['NUM_FACT'] = $facture['NUM_FACT'];
                    $pays_fourniss = $fourniss->find($facture['CODE_FOUR'])['CODE_PAYS'];
                    $pays_fourniss_cee = Sql::boolSql($country->find($pays_fourniss)['PAYSCEE']);

                    $pays_install = '';
                    $pays_install_cee = 0;
                    if (\Helpers\Outil\Roles::droit($this->pdo, 'PAYSINSTAL', 'PARAMGEN', true) !== null && \Helpers\Outil\Roles::droit($this->pdo, 'PAYSINSTAL', 'PARAMGEN', true) != '') {
                        $pays_install = \Helpers\Outil\Roles::droit($this->pdo, 'PAYSINSTAL', 'PARAMGEN', true);
                        $pays_install_cee = Sql::boolSql($country->find($pays_install)['PAYSCEE'] ?? true);
                    }

                    if ($pays_install != '' && ($pays_install == $pays_fourniss || ($pays_install_cee && $pays_fourniss_cee))) {
                        $parametr = (new \Entity\Model\Parametr($this->pdo))->get();
                        $listeCde[$key]['TAUX_TVA'] = number_format($parametr->TX_TVA, 2);
                    } else {
                        $listeCde[$key]['TAUX_TVA'] = number_format(0, 2);
                    }



                    $listeCde[$key]['TYPE_TVA'] = $fourniss->find($facture['CODE_FOUR'])['TYP_TVA'];

                    $typeTvaSpecifique = \Helpers\Additional\Specifique\Specifique::specifique('\\Modules\\Facture\\Service\\TypeTVASpecifique', 'getTypeTVA', $this->pdo, $facture['CODE_FOUR'], $facture['CODE_STE']);
                    if ($typeTvaSpecifique) {
                        $listeCde[$key]['TYPE_TVA'] = $typeTvaSpecifique;
                    }

                    //TODO SPEC 4961
                    $listeCde[$key]['RECEP_EN_MONTANT'] = 1;

                    // SPECIFIQUE : Initialisation SI par celui de l'entête
                    $listeCde[$key]['CODE_SI'] = \Helpers\Additional\Specifique\Specifique::specifique('\\Modules\\Facture\\Repository\\CsCreationFacture', 'initCsSI', 'FAC_ENT', str_pad($facture['NUM_FACT'], 9, 0, STR_PAD_LEFT), $this->pdo);

                    // SPECIFIQUE : Initialisation CDC spécifique
                    $specifique = new \Helpers\Additional\Specifique\Specifique();
                    $namespaceSpecifique = $specifique->specifiqueFunction('\\Modules\\Outil\\CompteComptable');
                    if (class_exists($namespaceSpecifique)) {
                        $paramsCdcSpec = ['societe' => $facture['CODE_STE'], 'fournisseur' => $facture['CODE_FOUR'], 'codeEnrLigne' => str_pad($post['facture'], 9, '0', STR_PAD_LEFT) . $idLigne];
                        $listeCde[$key] = array_merge($listeCde[$key], \Helpers\Additional\Specifique\Specifique::specifique('\\Modules\\Outil\\CompteComptable', 'initCompteComptable', $this->pdo, $paramsCdcSpec));
                    }
                } elseif ($value['typeAction'] == 'eclatementLigneInit') {
                    $indexEclatementLigneInit = $key;
                    $typeAction = 'eclatementLigneInit';

                    // SPECIFIQUE : Initialisation CDC spécifique
                    $specifique = new \Helpers\Additional\Specifique\Specifique();
                    $namespaceSpecifique = $specifique->specifiqueFunction('\\Modules\\Outil\\SousFamille');
                    if (class_exists($namespaceSpecifique)) {
                        $paramsCdcSpec = ['societe' => $facture['CODE_STE'], 'CODE_CDC' => $listeCde[$key]['CODE_CDC']];
                        $resultSousFamille = \Helpers\Additional\Specifique\Specifique::specifique('\\Modules\\Outil\\SousFamille', 'initSousfamilleSelonCdc', $this->pdo, $paramsCdcSpec);
                        $listeCde[$key]['sousFamilleReadonly'] = $resultSousFamille['sousFamilleReadonly'];
                        $listeCde[$key]['listeSousFamille'] = $resultSousFamille['listeSousFamille'];
                    }
                } elseif ($value['typeAction'] == 'eclatementLigne') {
                    $listeCde[$key]['QUANTITE'] = 0;
                    $listeCde[$key]['MONTANT'] = 0;
                    $listeCde[$key]['MT_TVA'] = 0;

                    // SPECIFIQUE : Initialisation CDC spécifique
                    $specifique = new \Helpers\Additional\Specifique\Specifique();
                    $namespaceSpecifique = $specifique->specifiqueFunction('\\Modules\\Outil\\SousFamille');
                    if (class_exists($namespaceSpecifique)) {
                        $paramsCdcSpec = ['societe' => $facture['CODE_STE'], 'CODE_CDC' => $listeCde[$key]['CODE_CDC']];
                        $resultSousFamille = \Helpers\Additional\Specifique\Specifique::specifique('\\Modules\\Outil\\SousFamille', 'initSousfamilleSelonCdc', $this->pdo, $paramsCdcSpec);
                        $listeCde[$key]['sousFamilleReadonly'] = $resultSousFamille['sousFamilleReadonly'];
                        $listeCde[$key]['listeSousFamille'] = $resultSousFamille['listeSousFamille'];
                    }
                }

                // Ligne en montant : réception en montant ou terme de paiement en montant, manuelle et sans numéro de ligne de commande
                if ($listeCde[$key]['RECEP_EN_MONTANT'] == 1 || ($listeCde[$key]['NUM_TERME'] != 0 && $listeCde[$key]['TP_QUANT'] == 0) || ($listeCde[$key]['NUM_LICDE'] == 0 || ($listeCde[$key]['LIG_MAN'] ?? 0) == 1)) {
                    $listeCde[$key]['ligneEnMontant'] = 1;
                } else {
                    $listeCde[$key]['ligneEnMontant'] = 0;
                }

                if (isset($value['CODE_SI']) && $value['CODE_SI'] != '') {
                    $si = $sectimpu->find(['CODE_SI' => $value['CODE_SI'], 'CODE_STE' => $steSi]);
                    $listeCde[$key]['codeGestionSaisie'] = Sql::boolSql($si['SICODG'] ?? false);
                    $listeCde[$key]['codeGestionObligatoire'] = Sql::boolSql($si['IMPCODG'] ?? false) == 1 ? 'false' : 'true';
                    $listeCde[$key]['LIBELLE_SI'] = $si['LIBELLE'] ?? '';

                    if ($params['IS_CG_ACTIVE']) {
                        $cg_ligne = $Codgest->find(['CODE_GES' => $value['ID_CG'], 'CODE_STE' => $steSi, 'CODE_SI' => $value['CODE_SI'], 'NUM_LOT' => $numLot]);
                        $listeCde[$key]['codeGestion'] = $cg_ligne['CODE_AFF'] ?? '';
                        $listeCde[$key]['LIBELLE_CDG'] = $cg_ligne['LIB_GES'] ?? '';
                    }
                } else {
                    $listeCde[$key]['codeGestionSaisie'] = 0;
                    $listeCde[$key]['codeGestionObligatoire'] = 0;
                }

                if ($value['typeAction'] == '') {
                    $last_NO_LIGNE = $idLastLigne;
                }
            }

            if ($typeAction == 'eclatementLigneInit') {
                $last_NO_LIGNE_tmp = $post['last_NO_LIGNE_tmp'] + 1;
                $listeCde[$last_NO_LIGNE_tmp] = $listeCde[$indexEclatementLigneInit];
                $listeCde[$last_NO_LIGNE_tmp]['NO_LIGNE_PERE'] = $listeCde[$indexEclatementLigneInit]['NO_LIGNE'];
                $listeCde[$last_NO_LIGNE_tmp]['NO_LIGNE'] = $idLastLigne;
                $listeCde[$last_NO_LIGNE_tmp]['QUANTITE'] = 0;
                $listeCde[$last_NO_LIGNE_tmp]['MONTANT'] = 0;
                $listeCde[$last_NO_LIGNE_tmp]['MT_TVA'] = 0;
                foreach ($listeCde[$last_NO_LIGNE_tmp] as $k => $val) {
                    $tbKeyCs = explode($spliter, $k);
                    if (count($tbKeyCs) > 1) {
                        $listeCde[$last_NO_LIGNE_tmp][implode($spliter, $tbKeyCs) . $spliter . $last_NO_LIGNE_tmp] = $listeCde[$indexEclatementLigneInit][implode($spliter, $tbKeyCs)] ?? $listeCde[$indexEclatementLigneInit][implode($spliter, $tbKeyCs) . $spliter . $listeCde[$indexEclatementLigneInit]['NO_LIGNE']];

                        $listeCde[$last_NO_LIGNE_tmp]['CS' . $tbKeyCs[3]] = $listeCde[$indexEclatementLigneInit][implode($spliter, $tbKeyCs)];

                        unset($listeCde[$last_NO_LIGNE_tmp][$k]);
                    }
                }
                $listeCde[$last_NO_LIGNE_tmp]['typeAction'] = 'eclatementLigne';
            }
        } else {
            $infoFacLig = $creationFacture->infoLigneTravail($post['facture'], $post['ligFact']);
            $listeCSFac = $creationFacture->infoCSLigTravail($post['facture'], $post['ligFact']);
            
            $calculFac = $creationFacture->detailSelectFactTravail($post['facture']);
            $montant = floatval($facture['TOTAL_HT']) - floatval($calculFac['HT'] ?? 0);

            foreach ($listeCde as &$cde) {
                $cde = array_merge($cde, $infoFacLig);
                if (isset($cde['CODE_SI']) && $cde['CODE_SI'] != '') {
                    $si = $sectimpu->find(['CODE_SI' => $cde['CODE_SI'], 'CODE_STE' => $steSi]);
                    $cde['codeGestionSaisie'] = Sql::boolSql($si['SICODG']);
                    $cde['codeGestionObligatoire'] = Sql::boolSql($si['IMPCODG']) == 1 ? 'false' : 'true';
                    $cde['LIBELLE_SI'] = $si['LIBELLE'];

                    if ($params['IS_CG_ACTIVE']) {
                        if ($cg_ligne = $Codgest->find(['CODE_GES' => $cde['ID_CG'], 'CODE_STE' => $steSi, 'CODE_SI' => $cde['CODE_SI'], 'NUM_LOT' => $numLot])) {
                        }
                        $cde['codeGestion'] = $cg_ligne['CODE_AFF'] ?? '';
                        $cde['LIBELLE_CDG'] = $cg_ligne['LIB_GES'] ?? '';
                    }
                } else {
                    $cde['codeGestionSaisie'] = 0;
                    $cde['codeGestionObligatoire'] = 0;
                }

                // Ligne en montant : réception en montant ou terme de paiement en montant, manuelle et sans numéro de ligne de commande
                if ($cde['RECEP_EN_MONTANT'] == 1 || ($cde['NUM_TERME'] != 0 && $cde['TP_QUANT'] == 0) || ($cde['NUM_LICDE'] == 0 || $cde['LIG_MAN'] == 1)) {
                    $cde['ligneEnMontant'] = 1;
                } else {
                    $cde['ligneEnMontant'] = 0;
                }

                if (!$cde['ligneEnMontant']) {
                    $cde['PU_REMISE'] = $montant / floatval($cde['QUANTITE']);
                }
                $cde['MONTANT'] = $montant;
                $cde['MT_TVA'] = $montant * floatval($cde['TAUX_TVA']) / 100;

                $cde['SELECT_LIGNE'] = $cde['SELECTIONNEE'];

                $cde['REFARTFOURN'] = $infoFacLig['REFARTFOU'];

                // soit un duplique depuis les valeurs trouvées dans FAC_LIG_TRAVAIL, soit on va chercher ces valeurs dans les input dans le cas de la duplication d'une ligne créée manuellement (donc pas encore dans FAC_LIG_TRAVAIL)

                $creationFacture->insertLigneFacLigTravail($post['facture'], $post['ligFact'], $cde['NO_LIGNE'], $cde);

                foreach ($listeCSFac as $cs) {
                    $infoCS = $repoChampSup->getInfoCS('FAC_LIG', $cs['NUM_FIX']);

                    if (Sql::boolSql($infoCS['NONDUPLI'])) {
                        $cde['CS' . $cs['NUM_FIX']] = '';
                    } else {
                        $cde['CS' . $cs['NUM_FIX']] = $cs['VALEUR'];
                    }

                    ChampSupp::insertChampSupp('FAC_LIG_TRAVAIL', ChampSupp::autoCompletCodeEnr($post['facture'], $cde['NO_LIGNE'], 'FAC_LIG'), $cs['NUM_FIX'], $cde['CS' . $cs['NUM_FIX']], $this->pdo);
                }
            }
        }

        foreach ($listeCde as $cde) {
            if ($cde['typeAction'] == 'ligneManuelle') {
                $creationFacture->insertNewFacLigTravail($post['facture'], $cde['NO_LIGNE'], $cde);
            }
            if (isset($cde['CODE_CDC'])) {
                $cde['LIBELLE_CDC'] = $Codecomp->find(['CODE_CDC' => $cde['CODE_CDC'], 'CODE_STE' => $steCDC])['LIBELLE'] ?? '';
            }
            if (isset($cde['CODE_SCA'])) {
                $cde['LIBELLE_SCA'] = $Sscptana->find(['CODE_SCA' => $cde['CODE_SCA'], 'CODE_STE' => $steSCA])['LIBELLE'] ?? '';
            }
        }

        // Paramétrage spécifique
        $specifique = new \Helpers\Additional\Specifique\Specifique();
        $namespaceSpecifique = $specifique->specifiqueFunction('\\Modules\\Outil\\Parametrage');
        if (class_exists($namespaceSpecifique)) {
            $params = array_merge($params, \Helpers\Additional\Specifique\Specifique::specifique('\\Modules\\Outil\\Parametrage', 'FactureAffectation', $this->pdo));
        }
        
        

        $menuContextuel = new AffectationMenuContextuel($this->pdo, $this->router, $this->getTranslationService());

        foreach ($listeCde as &$cde) {
            $cde['NUM_FACT'] = $post['facture'];
            $cde['menuContextuel'] = $menuContextuel->generate($cde, ($post['mode'] ?? ''));
        }

        return $this->renderer->render(
            $_SESSION['EasyDemat'] == 1 ?
                '@facture/affectationEasyDemat/ligneTableauAffectation':
                '@ajax-facture/ligne-affectation',
            [
                'listeCde' => $listeCde,
                'facture' => $facture ?? '',
                'saisieNonObligatoire' => $saisieNonObligatoire,
                'numLot' => $numLot,
                'last_NO_LIGNE' => $last_NO_LIGNE ?? '',
                'last_NO_LIGNE_tmp' => $last_NO_LIGNE_tmp ?? 0,
                'listeCS' => $listeCS,
                'action' => $post['mode'] ?? '',
                'listeTypeTva' => $listeTypeTva,
                
                'params' => $params,
                'numFact' => $post['facture'],
                'typeAction' => $post['typeAction'] ?? '',
                'droits' => $droits,
            ]
        );
    }

    /*****************************************************  *****************************************************/
    // VERIFICATION SI AFFICHAGE DU CODE GESTION SELON SECTION D'IMPUTATION
    public function setCGAction()
    {
        $post = $this->request->getParsedBody();
        $stesi = \Helpers\Outil\Roles::droit($this->pdo, 'SISECTOR', 'PARAMSTE') ? $post['CODE_STE'] : '';

        $sectimpu = new \Entity\Model\Sectimpu($this->pdo);
        $sectimpu = $sectimpu->find(['CODE_SI' => $post['CODE_SI'], 'CODE_STE' => $stesi]);

        $codeGestion['saisie'] = Sql::boolSql($sectimpu['SICODG'] ?? 0);
        $codeGestion['nonObligatoire'] = Sql::boolSql($sectimpu['IMPCODG'] ?? 0) == 1 ? 'false' : 'true';

        $codeGestion['cG_label'] = $sectimpu[2] ?? $post['CODE_SI'];

        if (isset($post['NO_LIGNE'])) {
            $repository = new CreationFacture($this->pdo);
            $repository->updateFacLigTravail($post['NUM_FACT'], $post['NO_LIGNE'], '', 'ID_CG', '');
        }

        return new Response(200, [], (string) \json_encode($codeGestion));
    }

    // AFFICHAGE DU DETAIL DE LA LIGNE DANS CHOIX DES COMMANDES
    public function detailChoixDesCommandesAction(): string
    {
        // Au premier affichage, affichage des 5 premières lignes
        $post = $this->request->getParsedBody();

        $br = new \Modules\Facture\Repository\CreationFacture($this->pdo);
        $brLignes = $br->getLignCDE($post['id']);

        $nombreEnregistrement = count($brLignes);

        if ($nombreEnregistrement > 5 && !isset($post['affichage'])) {
            $paginator = new Paginator();
            $infoPagination = $paginator->generate($brLignes, 5, $post);
            $post['affichage'] = 'notAll';
        }

        return $this->renderer->render('@ajax-facture/detail-choix-des-commandes', [
            'cas' => $brLignes,
            'nombreEnregistrement' => $nombreEnregistrement,
            'id' => $post['id'],
            'affichage' => $post['affichage'] ?? '',

        ]);
    }

    // GESTION FACTURE - CHOIX AVOIR : DETAIL DE L'ENTETE FACTURE + LISTE DES LIGNES DE LA FACTURE
    public function ligneFactureAction(): string
    {
        // Au premier affichage, affichage des 5 premières lignes
        $post = $this->request->getParsedBody();
        $factureId = $this->request->getAttribute('numFact');

        $factures = new \Modules\Facture\Repository\GestionFacture($this->pdo);
        $entete = $factures->getEntetFact($factureId);

        $lignes = $factures->listeLigneFacture($factureId);
        
        $nombreEnregistrement = count($lignes);

        if ($nombreEnregistrement > 5 && !isset($post['affichage'])) {
            $paginator = new Paginator();
            $paginator->generate($lignes, 5, $post);
            $post['affichage'] = 'notAll';
        }

        foreach ($lignes as &$facLigne) {
            $facLigne['codeCs'] = ChampSupp::autoCompletCodeEnr(
                $facLigne['NUM_FACT'],
                $facLigne['NUM_LIG'],
                'FAC_LIG'
            );
        }

        return $this->renderer->render('@ajax-facture/tableFactureDetail', [
            'lignes' => $lignes,
            'entete' => $entete,
            'nombreEnregistrement' => $nombreEnregistrement,
            'id' => $factureId,
            'affichage' => $post['affichage'] ?? '',
            'params' => [
                'IS_EXPE_ACTIVE' => $_SESSION['IS_EXPE_ACTIVE'],
                'IS_TP_ACTIVE' => $_SESSION['IS_TP_ACTIVE'],
                'IS_CG_ACTIVE' => $_SESSION['IS_CG_ACTIVE'],
            ],
            'easyDemat' => ($_SESSION['EasyDemat'] ?? ''),
            'codeEnrCs' => ChampSupp::autoCompletCodeEnr($factureId),
        ]);
    }

    // VISUALISATION FACTURE : DETAILS DE LA LIGNE SELECTIONNEE
    public function ligneDetailAction(): string
    {
        $id = $this->request->getAttribute('numFact');
        $numLigne = $this->request->getAttribute('ligne');

        $facture = new \Modules\Facture\Repository\GestionFacture($this->pdo);
        $ligne = $facture->detail1LigneFacture($id, $numLigne);

        $TypeTVA = new \Entity\Model\TypeTVA($this->pdo);
        $ligne['TypeTVA_LIBELLE'] = $TypeTVA->find($ligne['TYPE_TVA'])['LIBELLE'] ?? '';

        return $this->renderer->render('@ajax-facture/ligne-detail', [
            'ligne' => $ligne,
            'listeCS' => ChampSupp::listeIdCS('FAC_LIG', $this->pdo),
            'codeEnrCs' => ChampSupp::autoCompletCodeEnr($id, $numLigne, 'FAC_LIG'),

        ]);
    }

    // LISTE FACTURE PAR ENTÊTE : DETAIL ENTETE FACTURE + LISTE DES LIGNES DE LA FACTURE
    public function ligneListeEnteteAction(): string
    {
        // Au premier affichage, affichage des 5 premières lignes
        $post = $this->request->getParsedBody();

        $factures = new \Modules\Facture\Repository\GestionFacture($this->pdo);
        $entete = $factures->getEntetFact($post['id']);

        $listesFacture = new \Modules\Facture\Repository\ListesFacture($this->pdo);
        $lignes = $listesFacture->ligneListeEntete($post['id']);

        $nombreEnregistrement = count($lignes);

        if ($nombreEnregistrement > 5 && !isset($post['affichage'])) {
            $paginator = new Paginator();
            $infoPagination = $paginator->generate($lignes, 5, $post);
            $post['affichage'] = 'notAll';
        }

        return $this->renderer->render('@ajax-facture/ligne-liste-entete', [
            'lignes' => $lignes,
            'entete' => $entete,
            'nombreEnregistrement' => $nombreEnregistrement,
            'id' => $post['id'],
            'affichage' => $post['affichage'] ?? '',

            'easyDemat' => $_SESSION['EasyDemat'],
        ]);
    }

    // LISTE FACTURE PAR LIGNES : DETAIL DE LA LIGNE SELECTIONNEE + DETAIL ENTETE FACTURE
    public function ligneListeLigneAction(): string
    {
        $post = $this->request->getParsedBody();

        $factures = new \Modules\Facture\Repository\GestionFacture($this->pdo);
        $entete = $factures->getEntetFact($post['facture']);

        $listesFacture = new \Modules\Facture\Repository\ListesFacture($this->pdo);
        $ligne = $listesFacture->ligneListeLigne($post['facture'], $post['ligne']);

        return $this->renderer->render('@ajax-facture/ligne-liste-ligne', [
            'ligne' => $ligne,
            'entete' => $entete,
            'id' => $post['id'],
            'affichage' => $post['affichage'] ?? '',

            'easyDemat' => $_SESSION['EasyDemat'],
        ]);
    }

    // LISTE EVENEMENTS PAR FACTURE : LISTE DES EVENEMENTS DE LA FACTURE
    public function ligneListeEvenementsAction(): string
    {
        // Au premier affichage, affichage des 5 premières lignes
        $post = $this->request->getParsedBody();

        $factures = new \Modules\Facture\Repository\GestionFacture($this->pdo);
        $entete = $factures->getEntetFact($post['id']);

        $listesFacture = new \Modules\Facture\Repository\ListesFacture($this->pdo);
        $lignes = $listesFacture->ligneListeEvenements($post['id']);

        $menuContextuel = new SuiviEventMenuContextuel($this->pdo, $this->router, $this->getTranslationService());
        foreach ($lignes as &$e) {
            $e['menuContextuel'] = $menuContextuel->generate($entete, $e);
        }

        $nombreEnregistrement = count($lignes);
        if ($nombreEnregistrement > 5 && !isset($post['affichage'])) {
            $paginator = new Paginator();
            $infoPagination = $paginator->generate($lignes, 5, $post);
            $post['affichage'] = 'notAll';
        }

        return $this->renderer->render('@ajax-facture/ligne-liste-evenements', [
            'lignes' => $lignes,
            'entete' => $entete,
            'nombreEnregistrement' => $nombreEnregistrement,
            'id' => $post['id'],
            'affichage' => $post['affichage'] ?? '',

        ]);
    }

    // LORS D'UN ENVOI DE MAIL À PARTIR DU MODULE FACTURE, LES ÉLÉMENTS DU MAIL SONT CONSERVÉS DANS LA TABLE DES ÉVÈNEMENTS
    public static function mailEvenementFactureAction($post)
    {
        $xmlResult = new \Modules\Facture\WebService\MailEvenementFacture();
        $xmlResult = $xmlResult->mailEvenement($post);
        $reponse = new \SimpleXMLElement($xmlResult->responseData);

        return $reponse;
    }

    // MAJ d'une valeur sur une ligne dans FAC_LIG_TRAVAIL
    public function ajaxInsertValueAction()
    {
        $post = $this->request->getParsedBody();
        $spliter = Constante::spliter;

        $numFact    = $post['numFact'];
        $numLig     = $post['numLig'];
        $value      = $post['value'];
        $champs     = $post['CODE_CHAMPS'];

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

        if (substr($champs, 0, 16) == 'CS_' . $spliter) {
            $detailCS = $champSupp->generateChampSupp('FAC_LIG', '', substr($champs, 16));

            if ($detailCS['0']['FORMAT'] == 'D') {
                ChampSupp::convertDateToCS($value, $this->pdo);
            } elseif ($detailCS['0']['FORMAT'] == 'N') {
                $value = str_replace(' ', '', $value);
            } elseif ($detailCS['0']['FORMAT'] == 'L') {
                if ($value == 'true') {
                    $value = '1';
                } else {
                    $value = '0';
                }
            }

            $numFixe = substr($champs, 16);
            $champSupp->updateChampSupp('FAC_LIG_TRAVAIL', $champSupp::autoCompletCodeEnr($numFact, $numLig, 'FAC_LIG'), $numFixe, $value, $this->pdo);
        } else {
            if ($champs == 'CODE_CDC') {
                // SPECIFIQUE : initialisation des CS FAC_LIG en fonction du CODE_CDC
                $facLigCs = Specifique::specifique('\\Modules\\Facture\\Service\\AjaxFactureService', 'updateCsValue', $this->pdo, $value, $numFact);
                if ($facLigCs) {
                    foreach ($facLigCs as $cs) {
                        $champSupp->updateChampSupp('FAC_LIG_TRAVAIL', $champSupp::autoCompletCodeEnr($numFact, $numLig, 'FAC_LIG'), $cs['NUM_FIX'], $cs['VALEUR'], $this->pdo);
                    }
                }
            }
            $entity = new FacLigTravail($this->pdo);
            $architecture = $entity->getArchitecture($this->getTranslationService());
            $detailChamps = $architecture[$champs];

            if ($detailChamps['type'] == 'DATE') {
                $validator->isDate($value);
            } elseif ($detailChamps['type'] == 'float') {
                $validator->isFloat($value, $value, 13.5);
                // $value = str_replace(' ', '', $value);
            } elseif ($detailChamps['type'] == 'RADIO') {
                if ($value == 'true') {
                    $value = 1;
                } else {
                    $value = 0;
                }
            }

            if (! $validator->isValid()) {
                return new Response(200/* TODO : shoud be 400 */, [], $validator->getError());
            }

            $repository = new CreationFacture($this->pdo);
            $repository->updateFacLigTravail($numFact, $numLig, $value, $champs, $detailChamps['type']);
        }

        return new Response(200, []);
    }

    // CALCUL HT ET TVA TOTAL DEPUIS FAC_LIG_TRAVAIL
    public function calculTotalAction()
    {
        $post = $this->request->getParsedBody();
        $numFact     = $this->request->getAttribute('numFact');

        $creationFacture = new CreationFacture($this->pdo);
        $detailSelect = $creationFacture->detailSelectFactTravail($numFact);

        return new Response(200, [], (string) \json_encode([
            'HT' => $detailSelect['HT'] ?? 0,
            'TVA' => $detailSelect['TVA'] ?? 0,
        ]));
    }

    // MAJ groupée dans FAC_LIG_TRAVAIL
    public function ajaxModificationGroupeAction()
    {
        $post = $this->request->getParsedBody();
        $numFact     = $this->request->getAttribute('numFact');

        $creationFacture = new CreationFacture($this->pdo);
        $creationFacture->updateFacture($numFact, $post);

        return new Response(200, []);
    }
}
