<?php
namespace Modules\Panier\Controller;

use Entity\Model\ArtFourn;
use Entity\Model\CataEnt;
use Entity\Model\Codgest;
use Entity\Model\Fourniss;
use Entity\Model\OxaUserPanierFour;
use Entity\Model\OxaUserPanierLigne;
use Entity\Model\Paravrac;
use Entity\Model\Sectimpu;
use Entity\Model\SousFamille;
use GuzzleHttp\Psr7\Response;
use Helpers\Ariane\Ariane;
use Helpers\CaracCompl\CaracCompl;
use Helpers\ChampsSupplementaire\ChampSupp;
use Helpers\Outil\Roles;
use Helpers\Outil\Sql;
use Helpers\Parametres\Constante;
use Modules\GlobalApplication\Outil\InitAxesImputations;
use Modules\Panier\Repository\ArticlePanier;
use Modules\Panier\Repository\PanierEntete;
use Modules\Panier\Repository\PanierLigne;
use Modules\Panier\Service\CalculTauxTvaService;
use Modules\Panier\Service\OutilPanierService;
use Modules\Panier\Service\PanierEnteteService;
use Modules\Panier\Service\PanierFrsService;
use Modules\Panier\Service\PanierLigneService;
use Modules\Panier\Service\RequeteArticle;
use Modules\RechercheArticles\Repository\Article;
use Modules\RechercheArticles\Service\ArticleService;
use Modules\RechercheArticles\Service\OutilArticleService;
use Modules\RechercheArticles\Validator\ArticleValidator;
use Skeleton\Controller\Controller;
use Modules\RechercheArticles\Repository\Recherche;

class ArticlePanierController extends Controller
{
    public function ficheAction() : string
    {
        $idLigne = $this->request->getAttribute('idLigne');
        $trad = $this->getTranslationService();

        $param = [
            'AFFTTC'  => Sql::paravrac($this->pdo, 'OXAPROC', 'AFFTTC') == 'O',
        ];

        /** Info de la fiche */
        $recherche = new recherche($this->pdo);
        $listeChamps = $recherche->getParamFicheArticle();

        $panierLigne = new PanierLigne($this->pdo);
        $article = $panierLigne->getFiche($idLigne);

        $panierEntete = new PanierEntete($this->pdo);
        $infoPanier = $panierEntete->getEntetePanier($_SESSION['id_panier'], $_SESSION['id_user']);

        if ($article['IDLIGNECAT']) {
            $article['CATCARACT'] = $panierLigne->getCaractInfoFromIdLigne($article['IDLIGNECAT']);
        }

        /* Tab stock de l'article */
        $caracArticle = explode('|', $article['CARACT_ART_HAP']);
        if ($caracArticle[2] == 'is_art_stk=1') {
            $articleRepo = new Article($this->pdo);
            $infoStock = $articleRepo->getInfoStock($article['COD_ART'], $article['CodeCtrLivraison']);
        }

        /** Tab fournisseur de l'article */
        $requeteArticle = new RequeteArticle(
            $this->pdo,
            $this->pdoOxaFT,
            $_SESSION["Session_Login"],
            $infoPanier['LIV_CTR'],
            $infoPanier['CENTRE_EMETTEUR']
        );
        $listeFrs = $requeteArticle->rechercheArtFrs(false, $article, '0');
        
        foreach ($listeFrs as &$frs) {
            $frs['FRAISPORT'] = $recherche->getInfoFrsArticle($frs['CODE_FOU']);

            if ($param['AFFTTC']) {
                $frs['PU'] = $frs['PU'] * (1 + ($frs['TAUX_TVA']/100));
            }
        }

        /** Article associés */
        $oxaUserPanierLigne = new OxaUserPanierLigne($this->pdo);
        $listeArtAssoc = $oxaUserPanierLigne->findAll([
            'id_user' => $_SESSION['id_user'],
            'id_panier'=> $_SESSION['id_panier'],
            'ID_LIGNE_ASSOC' => $idLigne
        ], [
            'REF_FOURN',
            'DES_ART',
            'DES_COMP',
            'qte',
            'PX_ART',
            'TAUX_TVA',
            'ASS_OBLIG',
            'COD_DEV',
            'id_lig'
        ]);

        foreach ($listeArtAssoc as &$art) {
            $art['PX_ART'] = floatval($art['PX_ART']) * (1 + floatval($art['TAUX_TVA'])/100);
        }

        /** Equivalence */
        if ($article['CLASSNUM'] != '0' && $article['CLASSNUM']) {
            $listeArtEquiv = $requeteArticle->getEquivalence($trad, $article['CLASSNUM']);

            foreach ($listeArtEquiv as &$equiv) {
                $coefArt = ((int)$article['COEFCONV'] == 0 ? 1 : $article['COEFCONV']);
                $coefEquiv = ((int)$equiv['COEFCONV'] == 0 ? 1 : $equiv['COEFCONV']);
                $equiv['qte'] = $article['qte'] * $coefArt / $coefEquiv;

                $equiv['frsPref'] = sql::toBool((new Fourniss($this->pdo))->find($equiv['COD_FOURN'], ['FOURPREF'])['FOURPREF']??0x46);
                if ($this->generateIdArticle($article) == $this->generateIdArticle($equiv)) {
                    $equiv['selected'] = true;
                }
            }
        }

        /** Imputation ? si on reprend */

        /** cs ? si on reprend ? */

        /**  document */
        $articleRepo = new Article($this->pdo);
        $listeDoc = $articleRepo->getListeDocArticle($article['COD_ART']);

        Ariane::generate(1, $trad->t('Article'));

        //@rechercheArticles/Article/Fiche.twig
        return $this->renderer->render('@Panier/General/fullTemplate', [
            'template'      => 'article',
            'panier'        => $infoPanier,
            'idLigne'       => $idLigne,
            'listeChamps'   => $listeChamps,
            'article'       => $article,
            'infoStock'     => $infoStock??null,
            'listeFrs'      => $listeFrs,
            'listeDoc'      => $listeDoc,
            'listeArtAssoc' => $listeArtAssoc,
            'listeArtEquiv' => $listeArtEquiv??[],
            /*'imputation'    => $imputation??[],*/
        ]);
    }

    /**
     * @param array<mixed> $article
     * @return string
     */
    private function generateIdArticle($article) : string
    {
        $elementUnique = explode(',', 'COD_ART,COD_FAB,REF_FAB,COD_FOURN,REF_FOURN,COD_ACD');

        $unique_value = '';
        foreach ($elementUnique as $elem) {
            $unique_value .= $article[$elem] . '|';
        }

        return $unique_value;
    }

    /**
     * @return Response
     */
    public function ajaxChangeEquivalenceAction()
    {
        $idLigne = $this->request->getAttribute('idLigne');
        $rowCompteur = $this->request->getAttribute('rowCompteur');

        $requeteArticle = new RequeteArticle($this->pdo, $this->pdoOxaFT);
        $calculTauxTvaService = new CalculTauxTvaService($this->pdo);

        $articles = new ArticleService($this->pdo, $this->pdoOxaFT, 'CAT');
        $articles->setRowCompteur($rowCompteur);
        $listeChamps = [];
        $infoArticle = $articles->getArticle($this->getTranslationService(), $listeChamps, false);


        $infoArticle['PU'] = $infoArticle['PX_ART'];

        $panierLigne = new PanierLigne($this->pdo);
        $articlePanier = $panierLigne->getFiche($idLigne);

        $coefArt = ($articlePanier['COEFCONV'] == 0 ? 1 : $articlePanier['COEFCONV']);
        $coefEqui = ($infoArticle['COEFCONV'] == 0 ? 1 : $infoArticle['COEFCONV']);
        $qte = $articlePanier['qte'] * $coefArt / $coefEqui;

        $tva = $calculTauxTvaService->getTauxTva(
            $infoArticle['COD_ART'],
            $infoArticle['COD_SFAM'],
            $infoArticle['COD_FOURN'],
            $articlePanier['CodeCtrLivraison'],
            $infoArticle['TAUX_TVA']
        );
        $infoArticle['PX_ART'] = $requeteArticle->getPrixDegressifByQte($infoArticle, $qte);

        (new OxaUserPanierLigne($this->pdo))->update([
            'ID_CAT'    => $infoArticle['ID_CAT'],
            'COD_ART'   => $infoArticle['COD_ART'],
            'COD_FOURN' => $infoArticle['COD_FOURN'],
            'RS_FOURN'  => $infoArticle['RS_FOURN'],
            'REF_FOURN' => $infoArticle['REF_FOURN'],
            'COD_FAB'   => $infoArticle['COD_FAB'],
            'RS_FAB'    => $infoArticle['RS_FAB'],
            'COD_GAM'   => $infoArticle['COD_GAM'],
            'LIB_GAM'   => $infoArticle['LIB_GAM'],
            'REF_FAB'   => $infoArticle['REF_FAB'],
            'COD_SFAM'  => $infoArticle['COD_SFAM'],
            'LIB_SFAM'  => $infoArticle['LIB_SFAM'],
            'DES_ART'   => $infoArticle['DES_ART'],
            'DES_COMP'  => $infoArticle['DES_COMP'],
            'COD_UNIT'  => $infoArticle['COD_UNIT'],
            'PX_ART'    => $infoArticle['PX_ART'],
            'TAUX_TVA'  => $tva,
            'DELAI'     => $infoArticle['DELAI'],
            'CARACT'    => $infoArticle['CARACT'],
            'IMGART'    => $infoArticle['IMGART'],
            'TYPIMAGE'  => $infoArticle['TYPIMAGE'],
            'COD_ACD'   => $infoArticle['COD_ACD'],
            'COD_GRP'   => $infoArticle['COD_GRP'],
            'CONDITNT'  => $infoArticle['CONDITNT'],
            'TXTCOND'   => $infoArticle['TXTCOND'],
            'CLASSNUM'  => $infoArticle['CLASSNUM'],
            'COEFCONV'  => $infoArticle['COEFCONV'],

            'qte'       => $qte,
        ], $idLigne);
        

        (new PanierFrsService($this->pdo))->updateFrs($this->pdoOxaFT, $idLigne, $infoArticle);

        return new Response(200);
    }

    public function addFraisAction():string
    {
        $idBlocfrsSave = $this->request->getAttribute('idBlocFrs');
        $trad = $this->getTranslationService();

        $idBlocfrs = str_replace(Constante::oxaPipe, '|', $idBlocfrsSave);

        $infoBloc = (new OxaUserPanierFour($this->pdo))->find([
            'id_user' => $_SESSION['id_user'],
            'id_panier' => $_SESSION['id_panier'],
            'CRITERE_REGROUP' => $idBlocfrs
        ]);

        $critere = explode('|', $idBlocfrs);

        $param = [
            'AFFTVA'                            => Sql::paravrac($this->pdo, 'OXAPROC', 'AFFTVA') == 'O',
            'TTC'                               => Sql::paravrac($this->pdo, 'OXAPROC', 'AFFTTC') == 'O',
            'INTERDIRE_PX_QTE_NEG'              => Sql::paravrac($this->pdo, 'OXAPROC', 'INTERDIRE_PX_QTE_NEG') == 'O',
            'MASQUER_BUDGET_SAISIE_LIGNE'       => Sql::paravrac($this->pdo, 'OXAPROC', 'MASQUER_BUDGET_SAISIE_LIGNE') == 'O',
        ];

        $listeFraisTmp = (new ArticlePanier($this->pdo))->getListeArticlesAnnexes();
        $listeFrais = array_column($listeFraisTmp, null, 'CODE_ART');
        $listeFraisSelect = array_column($listeFraisTmp, 'DESIGN', 'CODE_ART');

        $calculTauxTvaService = new CalculTauxTvaService($this->pdo);
        $tva = $calculTauxTvaService->getTauxTva('', '', $infoBloc['COD_FOURN']??'');

        
        $initArticle = [
            'COD_FOURN' => $infoBloc['COD_FOURN'],
            'COD_ART'   => array_key_first($listeFrais),
            'COD_UNIT'  => $listeFrais[array_key_first($listeFrais)]['UNIT'],
            'TAUX_TVA'  => $tva
        ];
        
        Ariane::generate(1, $trad->t('Frais annexes'));

        return $this->renderer->render('@Panier/Article/Frais', [
            'panier'            => (new PanierEntete($this->pdo))->getEntetePanier($_SESSION['id_panier'], $_SESSION['id_user']),
            'listeFraisSelect'  => $listeFraisSelect,
            'article'           => $initArticle,
            'listeFrais'        => json_encode($listeFrais),

            'param'             => $param,
            'devise'            => $critere[1]??'',

            'idBlocFrs'         => $idBlocfrsSave,
        ]);
    }

    /**
     * @return Response
     */
    public function addFraisvalidateAction()
    {
        $idBlocfrsSave = $this->request->getAttribute('idBlocFrs');
        $idBlocfrs = str_replace(Constante::oxaPipe, '|', $idBlocfrsSave);
        $post = $this->request->getParsedBody();
        $trad = $this->getTranslationService();
        $validator = $this->createValidator();

        $param = [
            'AFFTVA'                            => Sql::paravrac($this->pdo, 'OXAPROC', 'AFFTVA') == 'O',
            'TTC'                               => Sql::paravrac($this->pdo, 'OXAPROC', 'AFFTTC') == 'O',
            'INTERDIRE_PX_QTE_NEG'              => Sql::paravrac($this->pdo, 'OXAPROC', 'INTERDIRE_PX_QTE_NEG') == 'O'
        ];

        $validator->isStringAvecEspace($trad->t('Détail'), $post['DES_COMP'], 0, 3000);
        $validator->isFloat($trad->t('Quantité'), $post['QTE'], Constante::formatQTE, true, null, ($param['INTERDIRE_PX_QTE_NEG']? 0:null));
        $validator->isFloat($trad->t('Prix unitaire'), $post['PX_ART'], constante::formatPU, false, null, ($param['INTERDIRE_PX_QTE_NEG']? 0:null));

        if ($param['AFFTVA']) {
            $validator->zoom('TVA', $post['TAUX_TVA'], $trad->t('Taux Tva'), $this->pdo, true);
        } else {
            $post['TAUX_TVA'] = '0.00';
        }
        $validator->isFloat($trad->t('Budget total'), $post['budget_total'], Constante::formatMontant, false);

        $infoBloc = (new OxaUserPanierFour($this->pdo))->find([
            'id_user' => $_SESSION['id_user'],
            'id_panier' => $_SESSION['id_panier'],
            'CRITERE_REGROUP' => $idBlocfrs
        ]);

        if ($validator->isValid()) {
            $panierEntete = (new PanierEntete($this->pdo))->getEntetePanier($_SESSION['id_panier'], $_SESSION['id_user']);
            $ligneArticle = (new ArticlePanier($this->pdo))->getArticlesFraisAnnexes($post['COD_ART']);

            $rsFourn = '';
            $artFourn = '';
            if ($infoBloc['COD_FOURN']) {
                $rsFourn = (new Fourniss($this->pdo))->find($infoBloc['COD_FOURN'], ['RS'])['RS']??'';

                $artFourn = (new ArtFourn($this->pdo))->find([
                    'CODE_ART' => $post['COD_ART'],
                    'FOU' => $infoBloc['COD_FOURN']
                ], ['REFARTFOU'])['REFARTFOU']??'';
            }

            $specifique = new \Helpers\Additional\Specifique\Specifique();
            $namespaceSpecifique = $specifique->specifiqueFunction('\\Modules\\Panier\\Service\\SpecArticleService');
            if (class_exists($namespaceSpecifique)) {
                $dtLiv = \Helpers\Additional\Specifique\Specifique::specifique('\\Modules\\Panier\\Service\\SpecArticleService', 'initDteLivraison');
            } else {
                $dtLiv = $infoBloc['DATELIVR'];
            }

            $articleToAdd = [
                'type_de_ligne' => '2',
                'COD_FOURN'  => $infoBloc['COD_FOURN'],
                'RS_FOURN'   => $rsFourn,
                'PROVENANCE' => 'ARTFAN',
                'REF_FOURN'  => $artFourn,

                'DEVISE'    => explode('|', $idBlocfrs)[1]??'',

                'COD_ART'   => $post['COD_ART'],
                'DES_ART'   => $ligneArticle['DESIGN'],
                'DES_COMP'  => $post['DES_COMP'],
                'DELAI'     => 0,

                'COD_SFAM'  => $ligneArticle['SSFAM'],
                'COD_FAB'   => $ligneArticle['CODEFAB'],
                'COD_GAM'   => $ligneArticle['CODEGAM'],
                'REF_FAB'   => $ligneArticle['REFARTFAB'],

                'COD_UNIT'  => $post['COD_UNIT'],
                'PX_ART'    => $post['PX_ART'],
                'COD_DEV'   => explode('|', $idBlocfrs)[1]??'',

                'TAUX_TVA'  => $post['TAUX_TVA'],
                'DATE_LIVR' => $dtLiv,
            ];
            $panierLigneService = new PanierLigneService($this->pdo, $this->pdoOxaFT, 'panier');
            $idligne = $panierLigneService->addPanier($articleToAdd, $post['QTE'], ['budget_tot' => $post['budget_total']], false, false, $post, true);
            
            $champSupp = new ChampSupp($this->pdo);
            $listeCS = $champSupp->generateChampSupp('DA_LIGNE');
            foreach ($listeCS as $cs) {
                $post['CS_EXTENTION'.Constante::spliter.'DA_LIGNE'.Constante::spliter.''.Constante::spliter.$cs['NUM_FIX']] = '';
            }

            $typeDoc = sql::paravrac($this->pdo, 'OXAPROC', 'TYPDOCUMENT');

            $infoLigneCreate = (new OxaUserPanierLigne($this->pdo))->find($idligne, ['SI_CODE','CDC_CODE','SCA_CODE']);

            $csArtFourn = str_pad(($post['COD_ART']??''), 13, ' ', STR_PAD_RIGHT).str_pad(($infoBloc['COD_FOURN']??''), 12, ' ', STR_PAD_RIGHT);
            $listeCSinit = (new OutilArticleService($this->pdo))->generateInitCS(
                $panierEntete['LIV_CTR'],
                $_SESSION["Session_Login"],
                $typeDoc,
                ($infoLigneCreate['SI_CODE']??''),
                ($infoLigneCreate['CDC_CODE']??''),
                ($infoLigneCreate['SCA_CODE']??''),
                $csArtFourn,
                $ligneArticle['SSFAM'],
                $post['COD_ART']
            );

            foreach ($listeCSinit as $k => $val) {
                $post[$k] = $val;
            }

            ChampSupp::updateCsPanier($this->pdo, $idligne, $post);

            return new Response(443, [], (string) json_encode(['path' => $this->router->generateUri('Panier.Panier.index'), 'post' => []]));
        } else {
            return new Response(200, [], $this->renderer->render('@popup-erreur/ErreurCreation', [
                'ErreurValid' => $validator->getError(),
                'desactiveRow' => true,
            ]));
        }
    }

    /**
     * @return string|Response
     */
    public function createEditAction()
    {
        $post = $this->request->getParsedBody();

        $idBlocfrsSave = $this->request->getAttribute('idBlocFrs');
        $idBlocfrs = str_replace(Constante::oxaPipe, '|', $idBlocfrsSave);
        $idLigne = $this->request->getAttribute('idLigne');

        $trad = $this->getTranslationService();

        $param = [
            'AFFTVA'                            => Sql::paravrac($this->pdo, 'OXAPROC', 'AFFTVA') == 'O',
            'TTC'                               => Sql::paravrac($this->pdo, 'OXAPROC', 'AFFTTC') == 'O',
            'INTERDIRE_PX_QTE_NEG'              => Sql::paravrac($this->pdo, 'OXAPROC', 'INTERDIRE_PX_QTE_NEG') == 'O',
            'MASQUER_BUDGET_SAISIE_LIGNE'       => Sql::paravrac($this->pdo, 'OXAPROC', 'MASQUER_BUDGET_SAISIE_LIGNE') == 'O',
            'DEFSFAMMAN'                        => Sql::paravrac($this->pdo, 'OXAPROC', 'DEFSFAMMAN'),
            'OX_MOD_TVA'                        => Roles::droitsUtilisateur($this->pdo, 'OX_MOD_TVA'),
            'SAISIE_PRIX_SI_NUL'                => sql::paravrac($this->pdo, 'OXAPROC', 'SAISIE_PRIX_SI_NUL') == 'O',

            'SILIGDA'                           => Sql::paravrac($this->pdo, 'INTRAVISIB', 'SILIGDA') == 'O',
            'CDCLIGDA'                          => Sql::paravrac($this->pdo, 'INTRAVISIB', 'CDCLIGDA') == 'O',
            'SCALIGDA'                          => Sql::paravrac($this->pdo, 'INTRAVISIB', 'SCALIGDA') == 'O',

            'SISECTO'                           => Sql::paravrac($this->pdo, 'PARAMSTE', 'SISECTOR') == 'O',
        ];

        
        $panierEntete = new PanierEntete($this->pdo);
        $infoPanierEntete = $panierEntete->getEntetePanier($_SESSION['id_panier'], $_SESSION['id_user']);
        $societe = $infoPanierEntete['CODE_STE']??$_SESSION["Session_SocUsr"];
        $changeSfam = false;
        
        if ((($post['action']??'') == 'changeSfam' && $post['COD_SFAM'] != '')) {
            $changeSfam = true;
            $article = $post;
            $testSfam = (new SousFamille($this->pdo))->find([
                'CODE_SFA' => $post['COD_SFAM'],
                'NVISIPROC' => 'F',
            ]);

            if (!$testSfam) {
                return new Response(443, [], $this->renderer->render('@popup-erreur/ErreurCreation', [
                    'ErreurValid' => $trad->t('Le code de sous-famille n\'est pas bon, veuillez le vérifier.'),
                    'desactiveRow' => true,
                ]));
            }

            $searchArt = [
                'CODE_ART' => '',
                'SSFAM' => $post['COD_SFAM']
            ];
            $isSfamPanier = (new RequeteArticle($this->pdo, $this->pdoOxaFT))->rechercherArtGen($searchArt);

            if (!$isSfamPanier) {
                return new Response(443, [], $this->renderer->render('@popup-erreur/ErreurCreation', [
                    'ErreurValid' => $trad->t('Vous n\'avez pas l\'autorisation de passer sur cette sous-famille.'),
                    'desactiveRow' => true,
                ]));
            }

            $unitSfamille = (new SousFamille($this->pdo))->find($post['COD_SFAM'], ['UNITEGEST']);
            $uniteModif = ($unitSfamille['UNITEGEST']??'') == '';
            $article['COD_UNIT']        = $unitSfamille['UNITEGEST'];

            $article['optionCOD_UNIT']      = $uniteModif? '':'readOnly';
        } elseif ($idLigne) {
            $article = (new OxaUserPanierLigne($this->pdo))->find($idLigne);

            $article['ID_CG'] = (new Codgest($this->pdo))->find([
                'CODE_SI' => $article['SI_CODE'],
                'CODE_AFF' => $article['CG_CODE']
            ], ['CODE_GES'])['CODE_GES']??'';


            $si = (new Sectimpu($this->pdo))->find(
                [
                'CODE_SI' => $article['SI_CODE']
                ]+($param['SISECTO']? [
                'CODE_STE' => $societe,
                ]:[]),
                ['SICODG']
            );
            $article['SICODG'] = sql::boolSql($si['SICODG']);
            $article['budget_total'] = $article['budget_tot'];
            $article['budgetUnitaire'] =
                ! empty($article['qte']) ? $article['budget_tot']/$article['qte'] : 0;

            $article['PX_ART_TTC'] = $article['PX_ART'] * (1 + ($article['TAUX_TVA'] / 100));

            $article['QTE'] = $article['qte'];

            if ($param['TTC']) {
                $article['montantTotalLigne'] = $article['PX_ART_TTC']*$article['qte'];
            } else {
                $article['montantTotalLigne'] = $article['PX_ART']*$article['qte'];
            }
            
            if ($article['type_de_ligne'] == '1') {
                $sfamEdit = true;
            }


            /**
             * On détermine si l'article est modifiable ou pas
             * Si l'article s'avère non modifiable alors les champs suivants seront en lecture seul
             * Désignation sommaire
             * Unité
             * Prix Unitaire
             * Référence Article
             */
            $articleModifiable = OutilPanierService::isModifiable(
                $this->pdo,
                $article['type_de_ligne'],
                $article['PROVENANCE'],
                $article['COD_ART'],
                $article['COD_FAB'],
                $article['COD_GAM'],
                $article['COD_ACD'],
                $article['COD_FOURN'],
                $article['REF_FOURN']
            );
            
            $uniteModif = $articleModifiable;
            if ($articleModifiable) {
                if ($article['type_de_ligne'] == 1 && $article['COD_ART'] == '' && $article['PROVENANCE'] != 'PO') {
                    $sfamPresent = (new RequeteArticle($this->pdo, $this->pdoOxaFT))->rechercherArtGen(['filter_SFAM' => 1]);
                    if ($sfamPresent) {
                        $uniteModif = true;
                    }
    
                    $unitSfamille = (new SousFamille($this->pdo))->find($article['COD_SFAM'], ['UNITEGEST']);
                    $uniteModif = ($unitSfamille['UNITEGEST']??'') == '';
                } elseif ($article['type_de_ligne'] == 1 && $article['COD_ART'] != '' && $article['PROVENANCE'] != 'PO') {
                    $uniteModif = true;
                } else {
                    $uniteModif = false;
                }
            }

            $tvaModifiable = Roles::droitsUtilisateur($this->pdo, 'OX_MOD_TVA');

            $modifPrixCata = false;
            if ($article['PROVENANCE'] == 'CAT' && $article['ID_CAT']) {
                $infoCata = (new CataEnt($this->pdo))->find($article['ID_CAT']);

                if (sql::boolSql($infoCata['MODIFTVA']??false) || $tvaModifiable) {
                    $tvaModifiable = true;
                } else {
                    $tvaModifiable = false;
                }
                
                if ($infoCata && sql::boolSql($infoCata['PRIXMODIFIABLE'])) {
                    $modifPrixCata = true;
                }
            }

            $modifPrix = $articleModifiable;
            if (Roles::droitsUtilisateur($this->pdo, 'OX_MODPCAT') && $modifPrixCata) {
                $modifPrix = true;
            } elseif ($article['type_de_ligne'] == 0 && $param['SAISIE_PRIX_SI_NUL']) {
                $modifPrix = false;

                $requeteArticle = new RequeteArticle(
                    $this->pdo,
                    $this->pdoOxaFT,
                    $_SESSION["Session_Login"],
                    $infoPanierEntete['LIV_CTR'],
                    $infoPanierEntete['CENTRE_EMETTEUR']
                );

                $resultCataproc = $requeteArticle->rechercheArt($article, false);
                if ($resultCataproc && $resultCataproc['PX_ART'] == 0) {
                    $modifPrix = true;
                } elseif ($resultCataproc) {
                    $modifPrix = false;
                }
            }

            $article['optionDES_ART']       = $articleModifiable? '':'readOnly';
            
            $article['optionREF_FOURN']     = $articleModifiable? '':'readOnly';
            
            $article['optionCOD_UNIT']      = $uniteModif? '':'readOnly';
            
            $article['optionTAUX_TVA']      = $tvaModifiable? '':'readOnly';
            $article['optionPX_ART']        = $modifPrix? '':'readOnly';

            Ariane::generate(1, $trad->t('Modification ligne panier'));
        } else {
            $sfamEdit = true;
            $infoBloc = (new OxaUserPanierFour($this->pdo))->find([
                'id_user' => $_SESSION['id_user'],
                'id_panier' => $_SESSION['id_panier'],
                'CRITERE_REGROUP' => $idBlocfrs
            ]);

            $critere = explode('|', $idBlocfrs);
            
            $calculTauxTvaService = new CalculTauxTvaService($this->pdo);
            $tva = $calculTauxTvaService->getTauxTva('', '', $infoBloc['COD_FOURN']??'');
            $article['TAUX_TVA']    = $tva;

            $article['COD_FOURN']   = $infoBloc['COD_FOURN'];
            $article['COD_DEV']     = $critere[1]??$infoPanierEntete['COD_DEV'];
            $article['COD_UNIT']    = sql::paravrac($this->pdo, 'PARAMGEN', 'UNITE_DEF');
            $article['COD_SFAM']    = Sql::paravrac($this->pdo, 'OXAPROC', 'DEFSFAMMAN');

            $article['optionTAUX_TVA'] = $param['OX_MOD_TVA']? '':'readOnly';

            $typeDoc = sql::paravrac($this->pdo, 'OXAPROC', 'TYPDOCUMENT');

            $initAxes = new InitAxesImputations($this->pdo, 'DA', '', [
                'SECTIMP'   => $infoPanierEntete['SI_CODE'],
                'CODECOMP'  => $infoPanierEntete['CDC_CODE'],
                'SSCPTEANA' => $infoPanierEntete['SCA_CODE'],
                'ID_CG'     => '',
                'CODGES'    => '',
                'LIBGES'    => '',
                'CODE_STE'  => $infoPanierEntete['CODE_STE'],
                'TYP_DOC'   => $typeDoc,
            ]);

            $imputation = $initAxes->getInitImputation('', '');

            $codeSI = ChampSupp::autoCompletCodeEnrImputations($this->pdo, 'SECTIMPU', $imputation['SI'], $societe);
            $codeCDC = ChampSupp::autoCompletCodeEnrImputations($this->pdo, 'CODECOMP', $imputation['CDC'], $societe);
            $codeSCA = ChampSupp::autoCompletCodeEnrImputations($this->pdo, 'SSCPTANA', $imputation['SCA'], $societe);

            $arrayInitCs = [];
            $arrayInitCs = (new OutilArticleService($this->pdo))->generateInitCS(
                $infoPanierEntete['LIV_CTR'],
                $_SESSION["Session_Login"],
                $typeDoc,
                $codeSI,
                $codeCDC,
                $codeSCA,
                '',
                $article['COD_SFAM'],
                '',
            );

            Ariane::generate(1, $trad->t('Création d\'une nouvelle ligne'));
        }

        $imposerDroit = sql::paravrac($this->pdo, 'OXAPROC', 'IMPOSER_DROIT_MOD_IMPUT') == 'O';

        return $this->renderer->render('@rechercheArticles/Article/createEdit', [
            'menuActive'                => 'eproc',
            'idBlocFrs'             => $idBlocfrsSave,
            'idLigne'               => $idLigne,

            'lockFrs'               => true,
            'codeSte'               => $societe,
            'listeFrsPanier'        => [],
            'param'                 => $param,
            'article'               => $article,
            'infoPanierEntete'      => $infoPanierEntete,

            'initCC'                => ($changeSfam == false && $idLigne)? false:true,
            'arrayInitCs'           => $arrayInitCs??[],
            'sfamEdit'              => $sfamEdit??false,

            'CC_idDoc'              => $_SESSION['id_panier'],
            'idUserPanier'          => $_SESSION['id_user'],

            'configImput'            => (new Paravrac($this->pdo))->getDemandeAxeImpConfig($societe),

            'cgParId'                => $cgParId = Roles::droit($this->pdo, 'CODE_GESTION_PAR_ID')? 1:0,
            'parametrage'            => [
                'OX_MOD_SI'                     => $imposerDroit ? roles::droitsUtilisateur($this->pdo, 'OX_MOD_SI'):true,
                'OX_MOD_CG'                     => $imposerDroit ? roles::droitsUtilisateur($this->pdo, 'OX_MOD_CG'):true,
                'OX_MOD_CDC'                    => $imposerDroit ? roles::droitsUtilisateur($this->pdo, 'OX_MOD_CDC'):true,
                'OX_MOD_SCA'                    => $imposerDroit ? roles::droitsUtilisateur($this->pdo, 'OX_MOD_SCA'):true,
            ]
        ]);
    }

    /**
     * @return Response
     */
    public function validateArticleAction()
    {
        $post = $this->request->getParsedBody();

        $idBlocfrsSave = $this->request->getAttribute('idBlocFrs');
        $idBlocfrs = str_replace(Constante::oxaPipe, '|', $idBlocfrsSave);
        $idLigne = $this->request->getAttribute('idLigne');

        $trad = $this->getTranslationService();

        $parametrage = OutilPanierService::parametragePanier($this->pdo, $trad);

        $panierEntete = new PanierEntete($this->pdo);
        $infoPanierEntete = $panierEntete->getEntetePanier($_SESSION['id_panier'], $_SESSION['id_user']);

        $validator = new ArticleValidator($this->pdo, $trad);

        if ($idLigne) {
            $validator->validateImputation($post, $infoPanierEntete);

            $infoLigne = (new OxaUserPanierLigne($this->pdo))->find($idLigne);

            if ($infoLigne['ID_CAT']??null) {
                $infoCata = (new CataEnt($this->pdo))->find($infoLigne['ID_CAT']);
                if ($infoCata && !sql::boolSql($infoCata['PRIXMODIFHAUSSE'])) {
                    $validator->isTrue(($infoLigne['PX_ART_INIT'] < $post['PX_ART']), $trad->t('Le prix unitaire ne peut pas être supérieur au prix catalogue.'));
                }
            }
        }

        $validator->articleLibre($post, $infoPanierEntete, ($infoLigne['type_de_ligne']??1) == 0);

        $validator->validatorCS('DA_LIGNE', '', $post, $this->pdo);
        $validator->validatorCC($this->pdo, $post);

        if ($validator->isValid()) {
            $infoBloc = (new OxaUserPanierFour($this->pdo))->find([
                'id_user' => $_SESSION['id_user'],
                'id_panier' => $_SESSION['id_panier'],
                'CRITERE_REGROUP' => $idBlocfrs
            ]);

            $oxaUserPanierLigne = (new OxaUserPanierLigne($this->pdo));
            if ($idLigne) {
                $article = $oxaUserPanierLigne->find($idLigne);
                
                $update = [
                    'DES_ART'       => $post['DES_ART'],
                    'DES_COMP'      => $post['DES_COMP'],
                    'COD_SFAM'      => $post['COD_SFAM'],
                    'COD_UNIT'      => $post['COD_UNIT'],
                    'qte'           => $post['QTE'],
                    'REF_FOURN'     => $post['REF_FOURN'],
                    'COD_ACD'       => $post['COD_ACD'],
                    'PX_ART'        => $post['PX_ART'],
                    'TAUX_TVA'      => $post['TAUX_TVA'],
                    'budget_tot'    => $post['budget_total'],
                ];

                if ($parametrage['SILIGDA']) {
                    $update['SI_CODE'] = $post['SI_CODE']??'';
                    $update['CG_CODE'] = $post['CG_CODE']??'';
                }

                if ($parametrage['CDCLIGDA']) {
                    $update['CDC_CODE'] = $post['CDC_CODE']??'';
                }

                if ($parametrage['SCALIGDA']) {
                    $update['SCA_CODE'] = $post['SCA_CODE']??'';
                }

                if ($article['COD_SFAM'] != $post['COD_SFAM']) {
                    $sousFamille = (new SousFamille($this->pdo))->find($post['COD_SFAM'], ['CODE_FAM']);
                    $typeDoc = sql::paravrac($this->pdo, 'OXAPROC', 'TYPDOCUMENT');

                    $initAxes = new InitAxesImputations($this->pdo, 'DA', '', [
                        'SECTIMP'       => $infoPanierEntete['SI_CODE'],
                        'CODECOMP'      => $infoPanierEntete['CDC_CODE'],
                        'SSCPTEANA'     => $infoPanierEntete['SCA_CODE'],
                        'ID_CG'         => '',
                        'CODGES'        => '',
                        'LIBGES'        => '',
                        'CODE_STE'      => $infoPanierEntete['CODE_STE'],
                        'TYP_DOC'       => $typeDoc,
                    ]);

                    $axesImputation = $initAxes->getInitImputation(
                        '',
                        $post['COD_SFAM'],
                        '',
                        []
                    );

                    $cg = $axesImputation['CODGES'];

                    $specifique = new \Helpers\Additional\Specifique\Specifique();
                    $namespaceSpecifique = $specifique->specifiqueFunction('\\Modules\\Panier\\Service\\SpecPanierLigneService');
                    if (class_exists($namespaceSpecifique)) {
                        $cg = \Helpers\Additional\Specifique\Specifique::specifique('\\Modules\\Panier\\Service\\SpecPanierLigneService', 'majCGBouygue', $this->pdo, $cg, ($axesImputation['SI']??''), $_SESSION['id_panier'], $post['COD_SFAM']);
                    }

                    $update = $update + [
                        'SI_CODE'   => $axesImputation['SI'],
                        'CDC_CODE'  => $axesImputation['CDC'],
                        'SCA_CODE'  => $axesImputation['SCA'],
                        'CG_CODE'   => $cg,
                    ];
                }

                $oxaUserPanierLigne->update($update, $idLigne);

                if ($article['qte'] != $post['QTE']) {
                    $panierLigneService = new PanierLigneService($this->pdo, $this->pdoOxaFT, 'panier');
                    $panierLigneService->updateArticleAssoc($idLigne, $post['QTE'], $article['qte']);

                    $panierLigneService->calculFraisDePort('qteChange');
                }

                $caracCompl = new CaracCompl($this->pdo, $article['COD_ART'], ($article['COD_SFAM']??''), ($article['CODE_FAM']??''));
                $caracCompl->deleteCC('PAN', $_SESSION['id_panier'], $idLigne, $_SESSION['id_user']);
                $caracCompl->insertCC('PAN', $_SESSION['id_panier'], $idLigne, $_SESSION['id_user'], $post);
            } else {
                $rsFourn = (new Fourniss($this->pdo))->find($infoBloc['COD_FOURN'], ['RS'])['RS']??'';

                $articleToAdd = [
                    'COD_FOURN'  => $infoBloc['COD_FOURN'],
                    'RS_FOURN'   => $rsFourn,
                    'PROVENANCE' => '',
                    'REF_FOURN'  => $post['REF_FOURN'],
    
                    'DEVISE'    => explode('|', $idBlocfrs)[1]??'',
    
                    'COD_ART'   => '',
                    'DES_ART'   => $post['DES_ART'],
                    'DES_COMP'  => $post['DES_COMP'],
                    'DELAI'     => 0,
    
                    'COD_SFAM'  => $post['COD_SFAM'],
    
                    'COD_UNIT'  => $post['COD_UNIT'],
                    'PX_ART'    => $post['PX_ART'],
                    'COD_DEV'   => explode('|', $idBlocfrs)[1]??'',
    
                    'TAUX_TVA'  => $post['TAUX_TVA'],

                    'COD_ACD'   => $post['COD_ACD'],

                    'type_de_ligne' => '1',
                ];

                $panierLigneService = new PanierLigneService($this->pdo, $this->pdoOxaFT, 'panier');
                $idLigne = $panierLigneService->addPanier($articleToAdd, $post['QTE'], ['budget_tot' => $post['budget_total']], false, false, $post, true);
            }

            ChampSupp::updateCsPanier($this->pdo, $idLigne, $post);
            
            $panierEnteteService = new PanierEnteteService($this->pdo);
            $panierEnteteService->getTotalPanier();

            return new Response(443, [], (string) json_encode(['path' => $this->router->generateUri('Panier.Panier.index'), 'post' => []]));
        } else {
            return new Response(200, [], $this->renderer->render('@popup-erreur/ErreurCreation', [
                'ErreurValid' => $validator->getError(),
                'desactiveRow' => true,
            ]));
        }
    }
}
