<?php
namespace Modules\Commande\Controller;

use Entity\Model\Acart;
use Entity\Model\Acccadre;
use Entity\Model\CaEntet;
use Entity\Model\CaLigne;
use Entity\Model\CaPlCt;
use Entity\Model\Centre;
use Entity\Model\Codecomp;
use Entity\Model\Codgest;
use Entity\Model\Country;
use Entity\Model\DaEntet;
use Entity\Model\DaLigne;
use Entity\Model\DaPlann;
use Entity\Model\MCa;
use Entity\Model\Parametr;
use Entity\Model\Paravrac;
use Entity\Model\Sectimpu;
use Entity\Model\Societe;
use Entity\Model\SousFamille;
use Entity\Model\Sscptana;
use Entity\Model\TpEnt;
use Entity\Model\TVA;
use Modules\Commande\Service\LigneCommandeValidator;
use Modules\GlobalApplication\Outil\InitAxesImpCde;
use Modules\GlobalApplication\Repository\LicenceOxalys;
use Skeleton\Controller\Controller;
use Helpers\Outil\Sql;
use Helpers\Outil\Roles;
use Modules\Commande\Repository\ModificationDetailCommande;
use Helpers\Validator\Validator;
use GuzzleHttp\Psr7\Response;
use Helpers\CaracCompl\CaracCompl;
use Helpers\Trad\Trad;
use Helpers\ChampsSupplementaire\ChampSupp;
use Helpers\Outil\Date;
use Modules\Commande\Repository\CreationCommande;
use Modules\Commande\Service\CalculPlanningService;
use Modules\Commande\Service\CreationCommandeService;
use Modules\Commande\Service\GenerateLigneCdeService;
use Helpers\Parametres\Constante;
use Traits\Validator\Zoom;

class ModificationLigneCommandeController extends AbsModificationCommandeController
{

    /**
     * This action does not insert the CaLigne, it only generate its the html code
     */
    public function ajaxAjoutLigneCdeAction(
        TpEnt $tpEnt
    ): string {
        $idCommande = $this->request->getAttribute('idCommande');
        $post       = $this->request->getParsedBody();
        $infoCde = (new CaEntet($this->pdo))->find($idCommande);

        Date::dateToSql($post['DATEDEBCONT']);
        Date::dateToSql($post['DATEFINCONT']);

        $infoCde['RECEP_AUTO']            = sql::toBool($post['RECEP_AUTO']);
        $infoCde['DATEDEBCONT']           = $post['DATEDEBCONT'];
        $infoCde['DATEFINCONT']           = $post['DATEFINCONT']??'';
        $infoCde['CONTRAT_PERIOD']        = $post['CONTRAT_PERIOD']??'';
        $infoCde['FIN_DEB_PER']           = $post['FIN_DEB_PER']??'';
        $infoCde['CAEN_RECEPAUTO_JOUR']   = $post['CAEN_RECEPAUTO_JOUR']??'';
        $infoCde['CALI_RECEPAUTO_JOUR']   = $post['CAEN_RECEPAUTO_JOUR']??'';
        $infoCde['SAISIEREC']             = sql::toBool($post['SAISIEREC']);
        $infoCde['REMISE']                = $post['REM_GLOB']??'';
        date::dateToSql($post['DTE_LIV']);

        return $this->renderer->render(
            '@Commande/Creation/Ligne/ligne',
            $this->newCaLigneData($post['index'], $infoCde) +
                [
                    'hasTp' => (bool) $tpEnt->find(['NUM_CDE' => $idCommande, 'TYPEOBJ' => 'CA_ENTET'])
                ]
        );
    }
    
    public function ajaxModificationLigneAction(
        TpEnt $tpEnt
    ) : string {
        $idCommande = $this->request->getAttribute('idCommande');
        $post       = $this->request->getParsedBody();
        $idLigne    = $post['index'];
        
        $caPlCtEntity = new CaPlCt($this->pdo);
        $modifDetail = new ModificationDetailCommande($this->pdo);
        $ligne       = $modifDetail->allDetailLigne($idCommande, $idLigne);
        $planning    = $caPlCtEntity->findAll([
            'NO_CA' => $idCommande,
            'NO_PO_CA' => $idLigne
        ]);
        
        $caEntet = new CaEntet($this->pdo);
        $infoCde = $caEntet->find($idCommande);
        
        $creationCommandeService = new CreationCommandeService($this->pdo, $this->pdoOxaFT, $this->getTranslationService());
        $arrayBuild = $creationCommandeService->buildCreateLigne($infoCde);
        
        $tabTypeDate = $arrayBuild['tabTypeDate'];
        $tabPeriode = $arrayBuild['tabPeriode'];
        $tabPeriodicite = $arrayBuild['tabPeriodicite'];
        $tabJoursAppli = $arrayBuild['tabJoursAppli'];
        $param = $arrayBuild['param'];
        $droit = $arrayBuild['droit'];

        //$param['SITESTOCK_ACTIF'] = Sql::boolSql($ligne['LIMITPERSTOCK']);

        $creationCde = new CreationCommande($this->pdo);
        if ($ligne['SECTIMP']??'') {
            $codeGestActif = $creationCde->codeGestionActif(($ligne['SECTIMP']??''), ($ligne['CODE_STE']??null))['SICODG']??'';
            if (sql::boolSql($codeGestActif)) {
                $param['MODIF_CODGES'] = true;
            }
        }

        if (isset($post['CDE_EXP']) && $post['CDE_EXP'] == 'on') {
            $ligne['RECEP_AUTO']            = false;
            $ligne['DATEDEBCONT']           = '';
            $ligne['DATEFINCONT']           = '';
            $ligne['CONTRAT_PERIOD']        = '';
            $ligne['FIN_DEB_PER']           = '';
            $ligne['CAEN_RECEPAUTO_JOUR']   = '';
        }

        $cc = new CaracCompl($this->pdo, $ligne['CODE_ART'], $ligne['SSFAM']);
        $listeCC = $cc->getCCDocc('CA', $idCommande, $idLigne, '0');

        return $this->renderer->render('@Commande/Creation/Ligne/ligne', [
            'ligne'          => $ligne,
            'tabTypeDate'    => $tabTypeDate,
            'idCommande'     => $idCommande,
            'tabPeriode'     => $tabPeriode,
            'tabPeriodicite' => $tabPeriodicite,
            'tabJoursAppli'  => $tabJoursAppli,
            'param'          => $param,
            'droit'          => $droit,
            'open'           => true,
            'planning'       => $planning,
            'commande'       => $infoCde,
            'ModeModif'      => true,

            'initCC'         => false,
            'listeCC'        => $listeCC,

            'CC_typeDoc'     => 'CA',
            'CC_idDoc'       => $idCommande,
            'CC_idLigne'     => $idLigne,

            'isModification' => true,

            'CDE_EXP'        => Sql::boolSql($post['CDE_EXP']??false),
            'hasTp'          => (bool) $tpEnt->find(['NUM_CDE' => $idCommande, 'TYPEOBJ' => 'CA_ENTET'])
        ]);
    }
    
    /**
     * @return mixed
     */
    public function updateLigneAction(
        TpEnt $tpEnt
    ) {
        // TODO : bug with Ligne/ligne.twig isModifiable is not carried on

        $idCommande = $this->request->getAttribute('idCommande');
        $origine = $this->request->getAttribute('origine');
        $post = $this->request->getParsedBody();

        $trad = $this->getTranslationService();
        
        $caEntet = new CaEntet($this->pdo);
        $cde = $caEntet->find($idCommande);
        $paravrac = new Paravrac($this->pdo);
        $cde['SAISIEREC'] = ($post['SAISIEREC']??false)? true:false;
        $cde['PAYCDEFO'] = $post['PAYCDEFO'];
        $cde['CTR_LIV'] = $post['CTR_LIV'];
        $article = [];

        $creationCde = new CreationCommande($this->pdo);

        /* Taux de TVA */
        $pays = new Country($this->pdo);
        $paysEntete = $pays->find($cde['PAYCDEFO']);
        $paysCtrLiv = $pays->find($cde['PAY_LIV']);

        $paramPaysInstall = sql::paravrac($this->pdo, 'PARAMGEN', 'PAYSINSTAL');
        $paysInstall = $pays->find($paramPaysInstall);

        $centre = new Centre($this->pdo);
        $centreEntete = $centre->find($cde['CTR_LIV']);

        $paramTVA = [
            'regle' => $paravrac->getGeneric('REGINIT_TVA'),
            'TVA'   => Sql::parametr($this->pdo, 'TX_TVA'),
        ];
        $detailDA = [];
        $recepAuto = false;

        if ($origine == 'ACD') {
            $price = $creationCde->getPriceAcd($post['ACD'], $cde['CODE_FOU'], $post['CODE_ART'], $post['QTE']);

            if ($price) {
                $price = $price['PU'];
                $price = number_format((float)$price, Constante::PUDECIMAL, '.', '');
                $remise = number_format(0, 2, '.', '');
                return new Response(200, [
                    
                ], (string) \json_encode([
                    'input_ligne_PU' => $price,
                    'input_ligne_REMISE' => $remise,
                    'value_TEMPINIT' => $price.'|'.$remise.'|'.date('d/m/Y').'|ACD',
                    'value_ID_CAT_ORI' => '',
                ]));
            } else {
                return new Response(200);
            }
        } elseif ($origine == 'SOUSFAMILLE') {
            $sousFamille = (new SousFamille($this->pdo))->find($post['SSFAM']);
            $imputations = (new InitAxesImpCde(
                $this->pdo,
                (new CaEntet($this->pdo))->find($idCommande)
            ))->getInitImputation([
                'CODE_ART' => '',
                'SousFamille' => $sousFamille,
            ]);

            $saisie = false;
            if (!Sql::toBool($sousFamille['NONRECEPT']) && Sql::toBool($cde['SAISIEREC'])) {
                $saisie = true;
            }

            /*
                Si taxe locale sur pays du FRS et que l’article est en mode taxe locale ou qu’il n’y a pas de code article mais une sous-famille avec taxe locale,
                on prend le taux de taxe locale du pays de livraison
            */
            if (Sql::toBool($paysEntete['AV_TAXLOC']) && (sql::toBool($sousFamille['AV_TAXLOC']))) {
                $tva = $centreEntete['TX_TAXLOC'];
            } else {
                if ($paramTVA['regle'] == 'T') {
                    $tva = $paysCtrLiv['TVA'];
                } else {
                    $tva = $paramTVA['TVA'];
                }

                $tva = (string)(new TVA($this->pdo))->find($tva, ['CODE_TVA'])['CODE_TVA'];
                if (str_starts_with($tva, '.')) {
                    $tva = '0'.$tva;
                }
            }

            $imputations['LIB_SI'] = (new Sectimpu($this->pdo))->find([
                'CODE_SI' => $imputations['SI']
                ] + (\Helpers\Outil\Roles::droit($this->pdo, 'SISECTOR', 'PARAMSTE')? ['CODE_STE' => $cde['CODE_STE']]:[]))['LIBELLE']??'';


            return new Response(200, [
                
            ], (string) \json_encode([
                'text_ligne_SECTIMP'    => $imputations['SI']? ($imputations['LIB_SI']. '('.$imputations['SI'].')'):'',
                'input_ligne_SECTIMP'   => $imputations['SI'],
                'text_ligne_CODGES'     => $imputations['CODGES'],
                'text_ligne_CODECOMP'   => $imputations['CDC'],
                'text_ligne_SSCPTEANA'  => $imputations['SCA'],

                'input_ligne_DATEDEBCONT'           => $saisie? $post['DATEDEBCONT']:'',
                'input_ligne_DATEFINCONT'           => $saisie? $post['DATEFINCONT']:'',
                'input_ligne_CONTRAT_PERIOD'        => $saisie? $post['CONTRAT_PERIOD']:'',
                'input_ligne_FIN_DEB_PER'           => $saisie? $post['FIN_DEB_PER']:'',
                'input_ligne_CAEN_RECEPAUTO_JOUR'   => $saisie? $post['CAEN_RECEPAUTO_JOUR']:'',

                'input_ligne_SAISIEREC' => $saisie,
                'input_ligne_RECEP_AUTO' => $saisie? Sql::boolSql($sousFamille['RECEP_AUTO']):false,
                'text_ligne_TVA' => $tva,
                //LAISSER input_ligne_CODE_ART A VIDE EN DERNIER IMPORTANT SINON JS KO
                'input_ligne_CODE_ART' => '',
            ]));
        } elseif ($origine == 'DA') {
            $daPlann = new DaPlann($this->pdo);
    
            if ($post['NO_PO']) {
                $detailDA = $creationCde->getListeDA(' de.NO_DA = :da and NO_PO = :noPo ', [':da' => $post['NO_DA'], ':noPo' => $post['NO_PO']], $cde['CODE_FOU'])[0]??[];
                $planning = $daPlann->findAll(['NO_DA' => $post['NO_DA'], 'NO_PO' => $post['NO_PO']]);
            } else {
                $DaEntet = new DaEntet($this->pdo);
                $detailDA = $DaEntet->find($post['NO_DA']);
                
                $planning = [];
            }

            foreach ($planning as &$ligPlan) {
                $ligPlan['QTE_COMM'] = $ligPlan['QTE_DEMAN'];
            }

            $cgParId = \Helpers\Outil\Roles::droit($this->pdo, 'CODE_GESTION_PAR_ID')? 1:0;
            $cgEntity = new Codgest($this->pdo);

            // TODO : verify find param
            if ($cgParId) {
                $infoCg = $cgEntity->find(['CODE_GES' => $post['CODGES']]);
            } else {
                $infoCg = $cgEntity->find(['CODE_AFF' => $post['CODGES']]);
            }

            $entete = [
                'CODE_STE' => $cde['CODE_STE'],
                'SECTIMP' => $post['SI'],
                'CODECOMP' => $post['CDC'],
                'SSCPTEANA' => $post['SCA'],
                
                'CODGES' => $infoCg['CODGES']??'',

                'ID_CG' => $infoCg['ID_CG']??'',
                'LIBGES' => $infoCg['LIBGES']??'',

                'TYP_DOC' => $cde['TYP_DOC'],
            ];

            $initAxesIlputation = new InitAxesImpCde($this->pdo, $entete);
            $creationCdeService = new GenerateLigneCdeService($this->pdo, $this->pdoOxaFT, $idCommande, $trad, $initAxesIlputation);
            if ($detailDA) {
                //$article['LIMITPERSTOCK'] = $detailDA['LIMITPERSTOCK'];
                $detailDA = $creationCdeService->calculeChampsCdeParDa('', $post['index'], $detailDA, [], false, $post['REMISE']);

                $detailDA['PU'] = floatval($detailDA['PU']);
                $detailDA['value_TEMPINIT'] = $detailDA['TEMPINIT'];
                $detailDA['value_ID_CAT_ORI'] = $detailDA['ID_CAT_ORI'];
                $siteStock = $detailDA['SITE_STK'];
                //$detailDA['LIMITPERSTOCK'] = $article['LIMITPERSTOCK'];
            }
            $arrayInitCsCde = ChampSupp::initCs('CA_LIGNE', 'CA_ENTET', ChampSupp::autoCompletCodeEnr($idCommande, '', 'CA_ENTET'), $this->pdo);
            $arrayInitCsDA = ChampSupp::initCs('CA_LIGNE', 'DA_LIGNE', ChampSupp::autoCompletCodeEnr($post['NO_DA'], $post['NO_PO'], 'DA_LIGNE'), $this->pdo);
            
            $arrayInitCs = array_merge($arrayInitCsCde, $arrayInitCsDA);
        } elseif ($origine == 'ARTICLE') {
            /* On récupère les info du frs */
            $article = $creationCde->getInfoArticle($post['CODE_ART'], $cde['CODE_FOU']);

            /* Si il y a un lien article / fournisseur, on remplace les elements de l'article par artfourne */
            $articleTmp = CreationCommandeService::articleFrsGrpFrs($article);

            $artFourn = $articleTmp['artFourn'];
            $ref      = $articleTmp['ref'];

            $ligne = [
                'CODE_ART'  => $post['CODE_ART'],
                'QTE'       => $post['QTE'],
                'COD_FAB'   => $article['CODEFAB'],
                'REF_FAB'   => $article['REFARTFAB'],
                'CODE_FOU'  => $cde['CODE_FOU'],
                'REF_FOUR'  => $ref,
            ];

            if ($artFourn) {
                $article['CTRL_QUA'] = $article['ARTFOURN_CTRL_QUA'];
            }

            /* Recherche du bst prix pour un article */
            $creationCdeService = new CreationCommandeService($this->pdo, $this->pdoOxaFT, $this->getTranslationService());
            $bestPrix = $creationCdeService->getbestPrix($cde, $ligne, true);

            /* Initialisation des imputations */
            $imputations = (new InitAxesImpCde(
                $this->pdo,
                (new CaEntet($this->pdo))->find($idCommande)
            ))->getInitImputation([
                'CODE_ART' => $post['CODE_ART'],
                'SousFamille' => [
                    'CODE_SFA' => $article['SSFAM'],
                    'CODE_FAM' => $article['CODE_FAM'],
                ],
            ]);

            $saisie = false;
            $periodeRecep = '';

            /* Initialisations des récéptions */
            if (sql::toBool($post['SAISIEREC'])) {
                $saisie = true;
                $recepAuto = Sql::toBool($post['RECEP_AUTO']);
            } elseif (!Sql::toBool($article['ARTICLE_NONRECPT']??'F') && Sql::toBool($cde['SAISIEREC'])) {
                $saisie = true;
                
                $recepAuto = Sql::toBool($article['RECEP_AUTO']);
                $periodeRecep = $article['PER_REC_AUTO'];
            }
            
            if (sql::toBool($paysEntete['AV_TAXLOC']) && sql::toBool($article['ARTICLE_AV_TAXLOC'])) {
                $tva = $centreEntete['TX_TAXLOC'];
            } else {
                if (Sql::toBool($paramTVA['regle'])) {
                    $tva = $paysCtrLiv['TVA'];
                } elseif (($paysEntete['CODE_PAYS'] == $paysInstall['CODE_PAYS']) || (sql::boolSql($paysEntete['PAYSCEE']) && sql::boolSql($paysInstall['PAYSCEE']))) {
                    $tva = $article['TXTVA'];
                } else {
                    $tva = $paramTVA['TVA'];
                }
            }

            $siteStock = '';
            if ($centreEntete['SITSTOCK'] != '' /*&& Sql::boolSql($article['LIMITPERSTOCK'])*/ && $creationCde->checkIfArticleIsStock($post['CODE_ART'], $centreEntete['SITSTOCK'])) {
                $siteStock = $centreEntete['SITSTOCK'];
            }
            date::dateToSql($post['DATEDEBCONT']);
            date::dateToSql($post['DATEFINCONT']);

            if (!(float) $bestPrix['TX_REMISE'] && $bestPrix['PROVENANCE'] != 'ACD') {
                $bestPrix['TX_REMISE'] = $post['REMISE'];
            }
            
            $tempinit = number_format($bestPrix['PU'], Constante::PUDECIMAL, '.', '').'|'.number_format($bestPrix['TX_REMISE'], 2, '.', '').'|'.date('d/m/Y').'|'.($bestPrix['PROVENANCE']?:'STD');

            /** @var array<mixed> $detailDA */
            $detailDA = [
                'NO_CDE'                    => $idCommande,
                'NO_PO'                     => $post['index'],
                'NO_DA'                     => $post['NO_DA'],
                'CODE_ART'                  => ($article['CODE_ART']??''),
                'DES_SOMM'                  => ($article['DESIGN']??''),
                'SSFAM'                     => ($article['SSFAM']??''),
                'PU'                        => $bestPrix['PU'],
                'REMISE'                    => $bestPrix['TX_REMISE'],
                'QTE_COMM'                  => '0',
                'UNITE'                     => ($article['UNIT']??''),
                'TVA'                       => $tva,
                'value_TEMPINIT'            => $tempinit,
                'value_ID_CAT_ORI'          => $bestPrix['ID_CAT']??'',
    
                'SECTIMP'                   => $imputations['SI'],
                'CODE_COMP'                 => $imputations['CDC'],
                'SSCPTEANA'                 => $imputations['SCA'],
                'ID_CG'                     => $imputations['ID_CG'],
                'CODGES'                    => $imputations['CODGES'],
                'LIBGES'                    => $imputations['LIBGES'],
    
                'SITE_STK'                  => $siteStock,
                'SAISIEREC'                 => $saisie,
                'RECEP_AUTO'                => $recepAuto,

                'TOLLIVAVA'                 => Sql::parametr($this->pdo, 'NBJOAVLIV'),
                'CODE_STE'                  => $cde['CODE_STE'],
                'ACCORCA'                   => $bestPrix['ACD'],
                
                'POIDS'                     => $artFourn['POIDS']??'',
                'LONGU'                     => $artFourn['LONGU']??'',
                'LARG'                      => $artFourn['LARG']??'',
                'HAUT'                      => $artFourn['HAUT']??'',
                'VOLUME'                    => $artFourn['VOLUME']??'',
                'PAY_ORI'                   => $artFourn['PAY_ORI']??'',
                'PAY_PRO'                   => $artFourn['PAY_PRO']??'',

                'DOUANE'                    => $article['DOUANE']??'',
                'POIDSNET'                  => $artFourn['POIDSNET']??'',
                'TYPDATE'                   => 'D',
    
                'REF_FOUR'                  => $ref??'',
                'COD_FAB'                   => ($article['CODEFAB']??''),
                'COD_GAM'                   => ($article['CODEGAM']??''),
                'REF_FAB'                   => ($article['REFARTFAB']??''),
                'CTRL_BR'                   => ($article['CTRL_QUA']??''),
                'NB_UNITE'                  => $article['NB_UNITE'],
            ];
            
            if ($siteStock) {
                $detailDA['RECEP_AUTO'] = false;
            }
            
            if (Sql::toBool($detailDA['RECEP_AUTO'])) {
                $detailDA['CONTRAT_PERIOD']            = $periodeRecep??($recepAuto? $post['CONTRAT_PERIOD']:'');
                $detailDA['DATEDEBCONT']               = $recepAuto? $post['DATEDEBCONT']:'00000000';
                $detailDA['DATEFINCONT']               = $recepAuto? $post['DATEFINCONT']:'00000000';
                $detailDA['FIN_DEB_PER']               = $recepAuto? $post['FIN_DEB_PER']:'';
                $detailDA['CALI_RECEPAUTO_JOUR']       = $recepAuto? $post['CAEN_RECEPAUTO_JOUR']:'';
            }

            $arrayInitCs = ChampSupp::initCs('CA_LIGNE', 'ARTICLES', $post['CODE_ART'], $this->pdo);
        }

        /** @var array<mixed> $detailDA */
        if ((isset($post['CDE_EXP']) && $post['CDE_EXP'])) {
            $detailDA['RECEP_AUTO']                = false;
            $detailDA['CONTRAT_PERIOD']            = '';
            $detailDA['DATEDEBCONT']               = '00000000';
            $detailDA['DATEFINCONT']               = '00000000';
            $detailDA['FIN_DEB_PER']               = '';
            $detailDA['CALI_RECEPAUTO_JOUR']       = '';
        }
        
        $creationCdeService = new CreationCommandeService($this->pdo, $this->pdoOxaFT, $this->getTranslationService());
        $arrayBuild = $creationCdeService->buildCreateLigne($cde);
        
        $tabTypeDate    = $arrayBuild['tabTypeDate'];
        $tabPeriode     = $arrayBuild['tabPeriode'];
        $tabPeriodicite = $arrayBuild['tabPeriodicite'];
        $tabJoursAppli  = $arrayBuild['tabJoursAppli'];
        $param          = $arrayBuild['param'];
        $droit          = $arrayBuild['droit'];

        
        if ($detailDA['SECTIMP']??'') {
            /** @var array<mixed> $detailDA */
            $codeGestActif = $creationCde->codeGestionActif(($detailDA['SECTIMP']??''), ($detailDA['CODE_STE']??null))['SICODG']??'';
            if (sql::boolSql($codeGestActif)) {
                $param['MODIF_CODGES'] = true;
            }
        }

        if ($siteStock??'') {
            $param['LOCK_SAISIEREC']    = true;
        // @phpstan-ignore-next-line
        } elseif (empty($param['LOCK_SAISIEREC']) || (isset($param['LOCK_SAISIEREC']) && $param['LOCK_SAISIEREC'])) {
            $param['LOCK_SAISIEREC']    = (Roles::droitsUtilisateur($this->pdo, 'HA_CA_MOFR')!='1' && sql::paravrac($this->pdo, 'PARAMGEN', 'CDERECEPTNONMODIF') == 'O');
        }

        /** @var array<mixed> $detailDA */
        $cc = new CaracCompl($this->pdo, ($detailDA['CODE_ART']??''), ($detailDA['SSFAM']??''));
        if ($origine == 'DA') {
            $listeCC = $cc->getCCDocc('DA', $post['NO_DA'], $post['NO_PO'], '0');
            $initCC = false;
        } else {
            $listeCC = $cc->getListeCCInit();
            $initCC = true;
        }

        if (!isset($detailDA['DTELIVCON'])) {
            Date::dateToSql($post['DTELIVCON']);
            $detailDA = $detailDA+['DTELIVCON' => $post['DTELIVCON']];

            $planning = [['QTE_COMM' => '', 'DTE_LIV' => $post['DTELIVCON']]];
        }

        return $this->renderer->render('@Commande/Creation/Ligne/ligne', [
            'param'          => $param,
            'droit'          => $droit,
            'ligne'          => $detailDA,
            'tabPeriode'     => $tabPeriode,
            'idCommande'     => $idCommande,
            'tabTypeDate'    => $tabTypeDate,
            'tabJoursAppli'  => $tabJoursAppli,
            'tabPeriodicite' => $tabPeriodicite,
            'open'           => true,
            'arrayInitCs'    => $arrayInitCs??[],
            'idLigneCS'      => ChampSupp::autoCompletCodeEnr($idCommande, $post['index'], 'CA_LIGNE'),
            'planning'       => $planning??[],
            'refresh'        => true,
            'commande'       => $cde,

            'initCC'         => $initCC,
            'listeCC'        => $listeCC,

            'CC_typeDoc'     => 'DA',
            'CC_idDoc'       => $post['NO_DA']??'',
            'CC_idLigne'     => $post['NO_PO']??'',

            'origine'        => $origine,

            'CDE_EXP'        => Sql::boolSql($post['CDE_EXP']??false),
            'hasTp'          => (bool) $tpEnt->find(['NUM_CDE' => $idCommande, 'TYPEOBJ' => 'CA_ENTET'])
        ]);
    }
    
    /**
     * @return mixed
     */
    public function ajaxCalculBestPrixAction()
    {
        $post = $this->request->getParsedBody();
        $idCommande = $this->request->getAttribute('idCommande');
        $caEntet = new CaEntet($this->pdo);
        $cde = $caEntet->find($idCommande);

        //ligne.NO_DA and param.LIMITACH_PX) and droit.HA_CA_MCPR == false
        $infoSoc = (new Societe($this->pdo))->find($cde['CODE_STE']);

        if ($post['NO_PO_DA'] == '' && Sql::boolSql($infoSoc['LIMITACH_PX']) && Roles::droitsUtilisateur($this->pdo, 'HA_CA_MCPR') == false) {
            return new Response(200, [], (string)json_encode([]));
        }

        $qte = str_replace(',', '.', $post['QTE_COMM']);
        $qte = str_replace(' ', '', $qte);

        $ligne = [
            'CODE_ART'  => $post['CODE_ART'],
            'QTE'       => $qte,
            'COD_FAB'   => $post['COD_FAB'],
            'REF_FAB'   => $post['REF_FAB'],
            'CODE_FOU'  => $cde['CODE_FOU'],
            'REF_FOUR'  => $post['REF_FOUR'],
        ];
        
        if ($ligne['CODE_ART'] || ($ligne['COD_FAB'] && $ligne['REF_FAB']) || ($ligne['CODE_FOU'] && $ligne['REF_FOUR'])) {
            $creationCdeService = new CreationCommandeService($this->pdo, $this->pdoOxaFT, $this->getTranslationService());
            $bestPrix = $creationCdeService->getbestPrix($cde, $ligne, true);
    
            $bestPrix['PU'] = number_format($bestPrix['PU'], Constante::PUDECIMAL, '.', '');
            $bestPrix['TX_REMISE'] = number_format($bestPrix['TX_REMISE'], Constante::montantDecimal, '.', '');
            
            return new Response(200, [
                    
            ], (string) \json_encode(array_merge($bestPrix, [
                'TEMPINIT' => $bestPrix['PU'].'|'.$bestPrix['TX_REMISE'].'|'.date('d/m/Y').'|'.$bestPrix['PROVENANCE'],
                'ID_CAT_ORI' => $bestPrix['ID_CAT'],
            ])));
        }

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

    public function validationLigneCommandeAction() :Response
    {
        $idCommande = $this->request->getAttribute('idCommande');
        $post       = $this->request->getParsedBody();
        
        $idLigne = $post['LIGNE_NO_PO_MODIF'];

        $caEntetEntity = new CaEntet($this->pdo);
        $caEntet = $caEntetEntity->find($idCommande);
        $codeSte = $caEntet['CODE_STE'];
        
        $modifLigne = new ModificationDetailCommande($this->pdo);
        $creationCommandeRepo = new CreationCommande($this->pdo);
        $creationCdeService = new CreationCommandeService($this->pdo, $this->pdoOxaFT, $this->getTranslationService());
        
        $editMode = $modifLigne->detailLigne($idCommande, $idLigne);

        $planning = [];
        $trad = $this->getTranslationService();

        $paramtr = (new Parametr($this->pdo));
        $paravrac = (new Paravrac($this->pdo));
        $configAxeImp = $paravrac->getCommandeAxeImpConfig($caEntet['CODE_STE']);

        //_____________________________
        // Validation

        $validator  = $this->createValidator();
        
        $hasSectImpModif = array_key_exists('ligne_SECTIMP', $post);
        $hasCodeCompModif = array_key_exists('ligne_CODECOMP', $post);
        $hasSousComptAnaModif = array_key_exists('ligne_SSCPTEANA', $post);

        if (!$editMode && $modifLigne->getNombreLigneCde($idCommande)>=999) {
            $validator->setError($trad->t('Votre commande à depassé le nombre maximum 999 de ligne pour cette commande.'));
            return new Response(
                400,
                [],
                $this->validationLigneCommandeError(
                    $validator,
                    $idLigne,
                    $idCommande,
                    $post['confirm'] == 1
                )
            );
        }
        
        if (!$editMode) {
            $validator->CAControleDA($post['ligne_NO_DA'], $trad->t('DA'), $codeSte);
        }
        $validator->CAControleArticle($post['ligne_CODE_ART'], $post['CODE_FOU'], $trad->t('Article'), true);

        $validator->CAControleQTE($post['ligne_QTE_COMM'], $trad->t('Quantité'), true, $post['ligne_UNITE']);
        $validator->CAControlePU($post['ligne_PU'], $trad->t('Prix unitaire'), true);
        $validator->isInteger($trad->t('Livraison avancée tolérée'), ($post['TOLLIVAVA']??''));

        $validator->isStringAvecEspace($trad->t('Désignation article'), $post['ligne_DES_SOMM'], 1, 120);
        
        $validator->zoom('Unites', $post['ligne_UNITE'], $trad->t('Unité'), $this->pdo, false);
        
        $validator->isStringAvecEspace($trad->t('Désignation complémentaire'), $post['ligne_DES_COMPL'], 0, 3000);
        $validator->isFloat($trad->t('Remise'), $post['ligne_REMISE'], Constante::formatMontant);
        $validator->zoom('TVA', $post['ligne_TVA'], $trad->t('TVA'), $this->pdo, true);
        
        $validator->zoom('SousFamille', $post['ligne_SSFAM'], $trad->t('Sous-famille'), $this->pdo, $post['ligne_CODE_ART']? true:false);
        $validator->zoom('SsItesto', $post['ligne_SITE_STK'], $trad->t('Site de stock'), $this->pdo, true);
        $validator->zoom('Acccadre', $post['ligne_ACCORCA'], $trad->t('Accord-cadre'), $this->pdo, true);
        $validator->zoom('cqualite', $post['ligne_CTRL_BR'], $trad->t('Contrôle qualité'), $this->pdo, true);
        
        $acartEntity = new Acart($this->pdo);
        $acart = $acartEntity->find(['CODE_ACD' => $post['ligne_ACCORCA'], 'CODE_ART' => $post['ligne_CODE_ART'], 'FOURNISS' => $post['CODE_FOU']]);

        if ($acart && $acart['QTEMAX'] > 0) {
            $validator->isTrue($acart['QTEMAX']<$post['ligne_QTE_COMM'], trad::strBuild($trad->t('L\'accord-cadre limite la quantité à @1@ pour cet article.'), $acart['QTEMAX']));
        }

        if ($hasSectImpModif) {
            $validator->zoom(
                'Sectimpu',
                $post['ligne_SECTIMP'],
                $trad->t('Section d\'imp.'),
                $this->pdo,
                $configAxeImp->SectImp->isBlankAllowed,
                ($configAxeImp->SectImp->isSecto ?
                    ['CODE_STE' => $caEntet['CODE_STE']] : [])
            );
            
            $sectionImp = (new Sectimpu($this->pdo))->find(
                ['CODE_SI' => $post['ligne_SECTIMP']]+($configAxeImp->SectImp->isSecto ?['CODE_STE' => $caEntet['CODE_STE']] : [])
            );

            if ($sectionImp != null) {
                $sectionImp['SICODG'] = Sql::toBool($sectionImp['SICODG']);
                $sectionImp['IMPCODG'] = Sql::toBool($sectionImp['IMPCODG']);
            }

            // Validate SectImpu date
            if ($sectionImp != null) {
                $validator->entityDateValidation(
                    CaLigne::class,
                    Sectimpu::class,
                    $trad,
                    $sectionImp['DATE_DEB'],
                    $sectionImp['DATE_FIN'],
                    $caEntet['DTE_PERIO']
                );
            }
    
            if ($sectionImp['SICODG'] ?? false) {
                $cgParId = Roles::droit($this->pdo, 'CODE_GESTION_PAR_ID')? 1:0;
                
                $arrayCG = [
                    'CODE_SI' => $post['ligne_SECTIMP'],
                    'NUM_LOT' => '1',
                    'CODE_STE' => $sectionImp['CODE_STE'],
                    'cgParId' => $cgParId
                ];
                $validator->codeGestionZoom($post['ligne_CODGES'], $trad->t('Code gestion'), $this->pdo, !$sectionImp['IMPCODG'], $arrayCG);
            
                $codeGest = (new Codgest($this->pdo))
                    ->find([
                        'CODE_STE' => $sectionImp['CODE_STE'],
                        'CODE_SI' => $post['ligne_SECTIMP'],
                    ] + ($cgParId ?
                        ['CODE_GES' =>  $post['ligne_CODGES']] :
                        ['CODE_AFF' => $post['ligne_CODGES']]
                    ));

                if ($codeGest != null) {
                    // Validate CodeGest
                    $validator->entityDateValidation(
                        CaLigne::class,
                        Codgest::class,
                        $trad,
                        $codeGest['DTEVALMIN'],
                        $codeGest['DTEVALMAX'],
                        $caEntet['DTE_PERIO']
                    );
                }
            }
        }
        
        if ($hasCodeCompModif) {
            $validator->zoom(
                'Codecomp',
                $post['ligne_CODECOMP'],
                $trad->t('Code compl.'),
                $this->pdo,
                $configAxeImp->CodeCompl->isBlankAllowed,
                ($configAxeImp->CodeCompl->isSecto ?
                    ['CODE_STE' => $caEntet['CODE_STE']] : [])
            );

            $codeComp = (new Codecomp($this->pdo))->find(
                ['CODE_CDC' => $post['ligne_CODECOMP']]+($configAxeImp->CodeCompl->isSecto ?['CODE_STE' => $caEntet['CODE_STE']] : [])
            );

            if ($codeComp != null) {
                $validator->entityDateValidation(
                    CaLigne::class,
                    Codecomp::class,
                    $trad,
                    $codeComp['DATE_DEB'],
                    $codeComp['DATE_FIN'],
                    $caEntet['DTE_PERIO']
                );
            }
        }
        
        if ($hasSousComptAnaModif) {
            $validator->zoom(
                'Sscptana',
                $post['ligne_SSCPTEANA']??'',
                $trad->t('SsCptAna'),
                $this->pdo,
                $configAxeImp->SousCompteAna->isBlankAllowed,
                ($configAxeImp->SousCompteAna->isSecto ?
                    ['CODE_STE' => $caEntet['CODE_STE']] : [])
            );

            $sousComptAna = (new Sscptana($this->pdo))->find(
                ['CODE_SCA' => $post['ligne_SSCPTEANA']]+($configAxeImp->SousCompteAna->isSecto ?['CODE_STE' => $caEntet['CODE_STE']] : [])
            );

            if ($sousComptAna != null) {
                $validator->entityDateValidation(
                    CaLigne::class,
                    Sscptana::class,
                    $trad,
                    $sousComptAna['DATE_MINI'],
                    $sousComptAna['DATE_MAXI'],
                    $caEntet['DTE_PERIO']
                );
            }
        }
        
        $validator->isCheck($post['ligne_SAISIEREC']);
        $validator->isCheck($post['ligne_RECEP_AUTO']);

        if ($post['ligne_RECEP_AUTO']) {
            $validator->isDate($post['ligne_DATEDEBCONT'], '', '', false, $trad->t('Début contrat'));
            $validator->isDate($post['ligne_DATEFINCONT'], '', '', false, $trad->t('Fin contrat'));
            $validator->isInteger($trad->t('Jour d\'application'), ($post['ligne_CAEN_RECEPAUTO_JOUR']??''), 1, 31, true);

            $validator->isObligatoire(($post['ligne_CONTRAT_PERIOD']??''), $trad->t('Périodicité du contrat'));
            $validator->isObligatoire(($post['ligne_FIN_DEB_PER']??''), $trad->t('Type de période'));
        } else {
            $post['ligne_DATEDEBCONT'] = '00000000';
            $post['ligne_DATEFINCONT'] = '00000000';

            $post['ligne_CONTRAT_PERIOD'] = '';
            $post['ligne_FIN_DEB_PER'] = '';
            $post['ligne_CAEN_RECEPAUTO_JOUR'] = '';
        }
        
        $validator->isFloat($trad->t('Longueur'), $post['ligne_LONGU'], 9.2);
        $validator->isFloat($trad->t('Largeur'), $post['ligne_LARG'], 9.2);
        $validator->isFloat($trad->t('Hauteur'), $post['ligne_HAUT'], 9.2);
        $validator->isFloat($trad->t('Volume'), $post['ligne_VOLUME'], 9.2);
        $validator->isFloat($trad->t('Poids brut'), $post['ligne_POIDS'], 9.2);
        $validator->isFloat($trad->t('Poids net'), $post['ligne_POIDSNET'], 9.2);
        
        $validator->zoom('Country', $post['ligne_PAY_ORIG'], $trad->t('Origine'), $this->pdo, true);
        $validator->zoom('Country', $post['ligne_PAY_PRO'], $trad->t('Provenance'), $this->pdo, true);
        $validator->zoom('Douanes', $post['ligne_DOUANE'], $trad->t('Douane'), $this->pdo, true);
        
        $validator->isStringAvecEspace($trad->t('Ref. fournisseur'), $post['ligne_REF_FOUR'], 0, 50);
        $validator->isStringAvecEspace($trad->t('Ref. fabricant'), $post['ligne_REF_FAB'], 0, 50);
        
        $validator->zoom('Fabricant', $post['ligne_COD_FAB'], $trad->t('Fabricant'), $this->pdo, true);
        $validator->zoom('Gamme', $post['ligne_COD_GAM'], $trad->t('Code gamme'), $this->pdo, true);
        
        $validator->isStringAvecEspace($trad->t('Titre avant cette ligne'), $post['ligne_AVLIGNE'], 0, 3000);
        
        $validator->isCheck($post['ligne_MASQ_QTE']);
        $validator->isCheck($post['ligne_MASQ_UNI']);
        $validator->isCheck($post['ligne_MASQ_PU']);
        $validator->isCheck($post['ligne_MASQ_DS']);
        $validator->isCheck($post['ligne_SSTOAPR']);
        
        $validator->validatorCS('CA_LIGNE', ChampSupp::autoCompletCodeEnr($idCommande, $idLigne, 'CA_LIGNE'), $post, $this->pdo);
        $validator->validatorCC($this->pdo, $post);
        
        $countPlanning = 0;
        $totalQTE = 0;
        
        if ($post['calculPlanning'] == '0' || !$post['ligne_RECEP_AUTO']) {
            $planning = [];
            
            $dateLivraison = [];
            foreach ($post as $key => $val) {
                if (strpos($key, 'PLANNING-DTE_LIV') === 0) {
                    $countPlanning++;
                }
            }

            $accEntity = new Acccadre($this->pdo);
            $infoAcd = $accEntity->find($post['ligne_ACCORCA']);
        
            foreach ($post as $key => $val) {
                if (strpos($key, 'PLANNING-DTE_LIV') === 0) {
                    $explodeKey = explode('-', $key);
                    $planningId = $explodeKey[2];

                    $validator->isFloat(
                        $trad->t('Quantité'),
                        $post['PLANNING-QTE_COMM-'.$planningId],
                        Constante::formatQTE
                    );
                    $validator->CAControleDateLivraison(
                        $post['PLANNING-DTE_LIV-'.$planningId],
                        Trad::strBuild(
                            $trad->t('Date de livraison du planning N°@1@'),
                            $planningId
                        ),
                        true,
                        $infoAcd
                    );
                    if ($post['ligne_DATEDEBCONT'] != '00000000' && $post['ligne_DATEFINCONT'] != '00000000') {
                        $validator->between($post['PLANNING-DTE_LIV-'.$explodeKey[2]], $post['ligne_DATEDEBCONT'], $post['ligne_DATEFINCONT'], $trad->t('Date de livraison'));
                    }

                    if (isset($dateLivraison[$post['PLANNING-DTE_LIV-'.$explodeKey[2]]])) {
                        $validator->setError(trad::strBuild($trad->t('La date @1@ est dupliquée sur le planning.'), Date::dateConverte($post['PLANNING-DTE_LIV-'.$explodeKey[2]])));
                    }

                    $dateLivraison[$post['PLANNING-DTE_LIV-'.$explodeKey[2]]] = $post['PLANNING-DTE_LIV-'.$explodeKey[2]];
                    $planning[] = [
                        'QTE_COMM' => $post['PLANNING-QTE_COMM-'.$explodeKey[2]],
                        'DTE_LIV' => $post['PLANNING-DTE_LIV-'.$explodeKey[2]],
                    ];

                    $totalQTE += floatval($post['PLANNING-QTE_COMM-'.$explodeKey[2]]);
                }
            }
        }

        if ($countPlanning == 1 && !$post['ligne_RECEP_AUTO']) {
            $validator->CAControleDateLivraison(
                $post['ligne_DTELIVCON'],
                $trad->t('Délai'),
                true
            );
        } elseif ($post['calculPlanning'] == '0') {
            Date::dateToSql($post['ligne_DTELIVCON']);
            $totalQTE = round($totalQTE, 3);
            $qteLigne = round((float)$post['ligne_QTE_COMM'], 3);

            $validator->isTrue($totalQTE!=$qteLigne, $trad->t('La somme des quantités du planning est différente de celle de la ligne.'));
        } else {
            $post['ligne_DTELIVCON'] = '00000000';
        }

        if (!$validator->isValid(true) || (($post['confirm']??0) != 1 && $validator->isNonBloquant())) {
            return new Response(
                400,
                [],
                $this->validationLigneCommandeError(
                    $validator,
                    $idLigne,
                    $idCommande,
                    ($post['confirm']??0) == 1
                )
            );
        }

        //_____________________________
        // Update DB

        $modelCa = (new MCa($this->pdo))->find($caEntet['MODELE']);
        if ($modelCa != null) {
            // Case : model lock SectImput edition
            if (Sql::toBool($modelCa['SIVER'])) {
                $post['ligne_SECTIMP'] = $modelCa['SI'];
            }
            // Case : model lock CodeComp edition
            if (Sql::toBool($modelCa['CDCVER'])) {
                $post['ligne_CODECOMP'] = $modelCa['CDC'];
            }
            // Case : model lock SousComptAna edition
            if (Sql::toBool($modelCa['SCAVER'])) {
                $post['ligne_SSCPTEANA'] = $modelCa['SCA'];
            }
        }

        $caLigneEntity = new CaLigne($this->pdo);
        $caPlCtEntity = new CaPlCt($this->pdo);
        $caracCompl = new CaracCompl($this->pdo, $post['ligne_CODE_ART'], $post['ligne_SSFAM']);

        $caLigne = [
            'CODE_ART' => $post['ligne_CODE_ART'],
            'DES_SOMM' => $post['ligne_DES_SOMM'],
            'SSFAM' => $post['ligne_SSFAM'],
            'PU' => str_replace(' ', '', $post['ligne_PU']),
            'TVA' => $post['ligne_TVA'],
            'REMISE' => $post['ligne_REMISE'],
            'QTE_COMM' => $post['ligne_QTE_COMM'],
            'UNITE' => $post['ligne_UNITE'],
            'RAL' => $post['ligne_QTE_COMM'],
            'DTELIVCON' => $post['ligne_DTELIVCON'],
            'NO_DA'  => $post['ligne_NO_DA'],
            'NO_PO_DA' => $post['ligne_NO_PO_DA'],

            'QTE_FACTU' => '0',
            'QTEFACVAL' => '0',
            'SOM_FACTU' => '0',
            'ET_CDELIG' => 'A',
            'SOMFACVAL' => '0',

            // TODO : put all common field to update and insert here
        ];

        if (isset($post['ligne_SECTIMP'])) {
            $caLigne +=  [
                'SECTIMP' => $post['ligne_SECTIMP'],
                'ID_CG' => $codeGest['CODE_GES'] ?? '',
                'CODGES' => $codeGest['CODE_AFF'] ?? '',
                'LIBGES' => $codeGest['LIB_GES'] ?? '',
            ];
        }
        if (isset($post['ligne_CODECOMP'])) {
            $caLigne['CODE_COMP'] = $post['ligne_CODECOMP'];
        }
        if (isset($post['ligne_SSCPTEANA'])) {
            $caLigne['SSCPTEANA'] = $post['ligne_SSCPTEANA'];
        }

        if ($editMode) {
            $oldCAlIGNE = $caLigneEntity->find(['NO_CDE'        => $idCommande, 'NO_PO' => $idLigne]);

            $caLigneEntity->update($caLigne + [
                'NM_DCOMP'      => Sql::updateMemo($this->pdo, $editMode['NM_DCOMP'], $post['ligne_DES_COMPL']),

                
                'SITE_STK'      => $post['ligne_SITE_STK'],
                'CTRL_BR'       => $post['ligne_CTRL_BR'],
                'numerique_SAISIEREC' => Sql::setBoolSql($post['ligne_SAISIEREC']),
                'TOLLIVAVA'             => $post['TOLLIVAVA']??Sql::parametr($this->pdo, 'NBJOAVLIV'),
                'CODE_STE'      => $codeSte,
                'TITREAV'       => Sql::updateMemo($this->pdo, $editMode['TITREAV'], $post['ligne_AVLIGNE']),
                'numerique_SSTOAPR' =>  Sql::setBoolSql($post['ligne_SSTOAPR']),
                'ACCORCA'       => $post['ligne_ACCORCA'],
                'POIDS'         => $post['ligne_POIDS'],
                'LONGU'         => $post['ligne_LONGU'],
                'LARG'          => $post['ligne_LARG'],
                'HAUT'          => $post['ligne_HAUT'],
                'VOLUME'        => $post['ligne_VOLUME'],
                'PAY_ORI'       => $post['ligne_PAY_ORIG'],
                'PAY_PRO'       => $post['ligne_PAY_PRO'],
                'DOUANE'        => $post['ligne_DOUANE'],
                'numerique_MASQ_QTE' =>  Sql::setBoolSql($post['ligne_MASQ_QTE']),
                'numerique_MASQ_UNI' =>  Sql::setBoolSql($post['ligne_MASQ_UNI']),
                'numerique_MASQ_PU'  =>  Sql::setBoolSql($post['ligne_MASQ_PU']),
                'numerique_MASQ_DS'  =>  Sql::setBoolSql($post['ligne_MASQ_DS']),
                'TYPDATE'       => $post['ligne_TYPDATE'],
                'POIDSNET'      => $post['ligne_POIDSNET'],
                'REF_FOUR'      => $post['ligne_REF_FOUR'],
                'COD_FAB'       => $post['ligne_COD_FAB'],
                'COD_GAM'       => $post['ligne_COD_GAM'],
                'REF_FAB'       => $post['ligne_REF_FAB'],
                'numerique_RECEP_AUTO'  => Sql::setBoolSql($post['ligne_RECEP_AUTO']),
                'DATEDEBCONT'   => $post['ligne_DATEDEBCONT'],
                'DATEFINCONT'   => $post['ligne_DATEFINCONT'],
                'CONTRAT_PERIOD' => $post['ligne_CONTRAT_PERIOD'],
                'FIN_DEB_PER'   => $post['ligne_FIN_DEB_PER'] ?? '',
                'CALI_RECEPAUTO_JOUR'   => $post['ligne_CAEN_RECEPAUTO_JOUR']
            ], ['NO_CDE'        => $idCommande, 'NO_PO' => $idLigne,]);

            $caracCompl->deleteCC('CA', $idCommande, $idLigne, '0');
            $caracCompl->insertCC('CA', $idCommande, $idLigne, '0', $post);

            $daEntity = new DaLigne($this->pdo);
            $da = $daEntity->find(['NO_DA' => $post['ligne_NO_DA'], 'NO_PO' => $post['ligne_NO_PO_DA']]);
            if ($da) {
                $creationCdeService->controleSoldeDA($da, $post['ligne_QTE_COMM'], $oldCAlIGNE['QTE_COMM']);
            }
        } else {
            $caLigneEntity->insert($caLigne + [
                'NO_CDE'                => $idCommande,
                'NO_PO'                 => $idLigne,
                
                'NM_DCOMP'              => Sql::updateMemo($this->pdo, '', $post['ligne_DES_COMPL']),

                'SITE_STK'              => $post['ligne_SITE_STK'],
                'CTRL_BR'               => $post['ligne_CTRL_BR'],
                'numerique_SAISIEREC'   => Sql::setBoolSql($post['ligne_SAISIEREC']),
                'TOLLIVAVA'             => $post['TOLLIVAVA']??Sql::parametr($this->pdo, 'NBJOAVLIV'),
                'CODE_STE'              => $codeSte,
                'TITREAV'               => Sql::updateMemo($this->pdo, '', $post['ligne_AVLIGNE']),
                'numerique_SSTOAPR'     =>  Sql::setBoolSql($post['ligne_SSTOAPR']),
                'ACCORCA'               => $post['ligne_ACCORCA'],
                'POIDS'                 => $post['ligne_POIDS'],
                'LONGU'                 => $post['ligne_LONGU'],
                'LARG'                  => $post['ligne_LARG'],
                'HAUT'                  => $post['ligne_HAUT'],
                'VOLUME'                => $post['ligne_VOLUME'],
                'PAY_ORI'               => $post['ligne_PAY_ORIG'],
                'PAY_PRO'               => $post['ligne_PAY_PRO'],
                'DOUANE'                => $post['ligne_DOUANE'],
                'numerique_MASQ_QTE'    =>  Sql::setBoolSql($post['ligne_MASQ_QTE']),
                'numerique_MASQ_UNI'    =>  Sql::setBoolSql($post['ligne_MASQ_UNI']),
                'numerique_MASQ_PU'     =>  Sql::setBoolSql($post['ligne_MASQ_PU']),
                'numerique_MASQ_DS'     =>  Sql::setBoolSql($post['ligne_MASQ_DS']),
                'TYPDATE'               => $post['ligne_TYPDATE'],
                'POIDSNET'              => $post['ligne_POIDSNET'],
                
                'REF_FOUR'              => $post['ligne_REF_FOUR'],
                'COD_FAB'               => $post['ligne_COD_FAB'],
                'COD_GAM'               => $post['ligne_COD_GAM'],
                'REF_FAB'               => $post['ligne_REF_FAB'],
                'numerique_RECEP_AUTO'  => Sql::setBoolSql($post['ligne_RECEP_AUTO']),
                'DATEDEBCONT'           => $post['ligne_DATEDEBCONT'],
                'DATEFINCONT'           => $post['ligne_DATEFINCONT'],
                'CONTRAT_PERIOD'        => $post['ligne_CONTRAT_PERIOD'],
                'FIN_DEB_PER'           => $post['ligne_FIN_DEB_PER'],
                'CALI_RECEPAUTO_JOUR'   => $post['ligne_CAEN_RECEPAUTO_JOUR'],
                'TEMPINIT'              => $post['value_TEMPINIT'],
                'ID_CAT_ORI'            => $post['value_ID_CAT_ORI'],
            ]);

            $caracCompl->insertCC('CA', $idCommande, $idLigne, '0', $post);

            
            $daEntity = new DaLigne($this->pdo);
            $da = $daEntity->find(['NO_DA' => $post['ligne_NO_DA'], 'NO_PO' => $post['ligne_NO_PO_DA']]);
            if ($da) {
                $creationCdeService->controleSoldeDA($da, $post['ligne_QTE_COMM']);
            }
        }

        $caPlCtEntity->delete(['NO_CA' => $idCommande, 'NO_PO_CA' => $idLigne]);

        if ($post['calculPlanning'] == '1' && $post['ligne_RECEP_AUTO']) {
            $calculPlanningService = new CalculPlanningService($post['ligne_QTE_COMM'], $post['ligne_CONTRAT_PERIOD'], $post['ligne_DATEDEBCONT'], $post['ligne_DATEFINCONT'], $post['ligne_FIN_DEB_PER'], $post['ligne_CAEN_RECEPAUTO_JOUR']);
            $calculPlanningService->calculPlanning();
            $planning = $calculPlanningService->getTableauEcheance();
        }

        foreach ($planning as $plann) {
            $caPlCtEntity->insert([
                'NO_CA' => $idCommande,
                'NO_PO_CA' => $idLigne,
                'DTE_LIV' => $plann['DTE_LIV'],
                'QTE_COMM' => $plann['QTE_COMM'],
                'CODE_STE' => $codeSte
            ]);
        }
        
        ChampSupp::updateCS($post, $this->pdo);

        $ligne = $modifLigne->allDetailLigne($idCommande, $idLigne);
        $commande['NO_CDE'] = $idCommande;

        /* mettre a jours le montant de la cde avec les valeurs des lignes */
        $totalCde = $creationCommandeRepo->getCalculMontantCde($idCommande);
        $caEntetEntity->update([
            'TOT_CDE'   => $totalCde['TOT_CDE'],
            'TOT_CDEHT' => $totalCde['TOT_CDEHT'],
            'TOT_TTC'   => $totalCde['TOT_TTC'],
        ], $idCommande);
        
        return new Response(200, [], $this->renderer->render('@Commande/Creation/Ligne/ligneNonModifiable', ['ligne' => $ligne, 'commande' => $commande]));
    }

    private function validationLigneCommandeError(
        Validator $validator,
        string $idLigne,
        string $idCommande,
        bool $isConfirm
    ) :string {
        $trad = $this->getTranslationService();
        return $this->renderer->render('@Commande/Creation/ErreurCreation', [
            'ErreurValid' => $validator->getError(),
            'ErreurNonBloquant' => $validator->getErrorNonBloquant(false),
            'titrePopup'  => $trad->t('Erreur sur la validation de la ligne :').' '.$idLigne,
            'idLigne' => $idLigne,
            'idCommande' => $idCommande,
            'idForm' => 'form_creationCde',
        ]);
    }
    
    public function annulationLigneCommandeAction() : string
    {
        $idCommande = $this->request->getAttribute('idCommande');
        $post       = $this->request->getParsedBody();
        
        $idLigne = $post['LIGNE_NO_PO_MODIF'];

        $modifLigne = new ModificationDetailCommande($this->pdo);
        $ligne = $modifLigne->allDetailLigne($idCommande, $idLigne);
        
        if ($ligne) {
            $commande['NO_CDE'] = $idCommande;
            return $this->renderer->render('@Commande/Creation/Ligne/ligneNonModifiable', [
                'ligne' => $ligne,
                'commande' => $commande
            ]);
        } else {
            return '';
        }
    }
    
    public function ajaxModificationOrdreAction() : string
    {
        $idCommande = $this->request->getAttribute('idCommande');
        $post       = $this->request->getParsedBody();

        $newPosition = $post['newPosition'];
        $oldPosition = $post['oldPosition'];
        
        $moveUp = false;
        if ($newPosition<$oldPosition) {
            $moveUp = true;
        }
        
        $this->pdo->beginTransaction();
        $modifLigne = new ModificationDetailCommande($this->pdo);
        $modifLigne->modificationOrdreCde($idCommande, $newPosition, $oldPosition, $moveUp);
        $modifLigne->modificationOrdrePlanningCde($idCommande, $newPosition, $oldPosition, $moveUp);
        $modifLigne->modificationOrdreCdeCS($idCommande, $newPosition, $oldPosition, $moveUp);
        $modifLigne->modificationOrdreCdeCC($idCommande, '0', $newPosition, $oldPosition, $moveUp);
        $this->pdo->commit();

        return '';
    }

    /**
     * @return mixed
     */
    public function deleteAction()
    {
        $idCommande = $this->request->getAttribute('idCommande');
        $idLigne = $this->request->getAttribute('idLigne');

        $caLigneEntity = new CaLigne($this->pdo);
        $findCaLigne = $caLigneEntity->find(['NO_CDE' => $idCommande, 'NO_PO' => $idLigne]);

        Sql::deleteMemos($this->pdo, $findCaLigne['NM_DCOMP']);
        Sql::deleteMemos($this->pdo, $findCaLigne['TITREAV']);

        $caLigneEntity->delete(['NO_CDE' => $idCommande, 'NO_PO' => $idLigne]);

        $caPlCtEntity = new CaPlCt($this->pdo);
        $caPlCtEntity->delete(['NO_CA' => $idCommande, 'NO_PO_CA' => $idLigne]);

        ChampSupp::deleteCS('CA_LIGNE', ChampSupp::autoCompletCodeEnr($idCommande, $idLigne, 'CA_LIGNE'), $this->pdo);

        $caracCompl = new CaracCompl($this->pdo, '', '');
        $caracCompl->deleteCC('CA', $idCommande, $idLigne);

        $daEntity = new DaLigne($this->pdo);
        $da = $daEntity->find(['NO_DA' => $findCaLigne['NO_DA'], 'NO_PO' => $findCaLigne['NO_PO_DA']]);
        if ($da) {
            $creationCdeService = new CreationCommandeService($this->pdo, $this->pdoOxaFT, $this->getTranslationService());
            $creationCdeService->controleSoldeDA($da, '0', $findCaLigne['QTE_COMM']);
        }

        /*$creationCommandeRepo = new CreationCommande($this->pdo);
        $totalCde = $creationCommandeRepo->getCalculMontantCde($idCommande);
        (new CaEntet($this->pdo))->update([
            'TOT_CDE'   => $totalCde['TOT_CDE'],
            'TOT_CDEHT' => $totalCde['TOT_CDEHT'],
            'TOT_TTC'   => $totalCde['TOT_TTC'],
        ], $idCommande);*/

        return new Response(200);
    }

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

        return $this->renderer->render('@Commande/Creation/Ligne/lignePlanning', [
            'ligne' => $post['noLigne'],
        ]);
    }

    public function ajaxGeneratePlanningAction() : string
    {
        $post = $this->request->getParsedBody();

        Date::dateToSql($post['ligne_DATEDEBCONT']);
        Date::dateToSql($post['ligne_DATEFINCONT']);

        $calculPlanningService = new CalculPlanningService($post['ligne_QTE_COMM'], ($post['ligne_CONTRAT_PERIOD']??''), $post['ligne_DATEDEBCONT'], $post['ligne_DATEFINCONT'], ($post['ligne_FIN_DEB_PER']??''), ($post['ligne_CAEN_RECEPAUTO_JOUR']??''));
        $calculPlanningService->calculPlanning();
        $planning = $calculPlanningService->getTableauEcheance();

        return $this->renderer->render('@Commande/Creation/Ligne/planning', [
            'planning' => $planning,
            'lockPlanning' => true
        ]);
    }

    /**
     * initialise les valeurs pour la view ligneModifiable.twig
    * @return array<mixed>
    */
    public function buildCreateLigne(string $codeSte)
    {
        $trad = $this->getTranslationService();
        
        /* VALUE SELECT */
        $tabPeriodicite = [
            'M' => $trad->t('Mensuelle'),
            'T' => $trad->t('Trimestrielle'),
            'S' => $trad->t('Semestrielle'),
            'A' => $trad->t('Annuelle'),
        ];
        
        $tabPeriode = [
            'D' => $trad->t('Début de période'),
            'F' => $trad->t('Fin de période'),
        ];
        
        $tabTypeDate = [
            'D' => $trad->t('Date'),
            'S' => $trad->t('Semaine'),
            'M' => $trad->t('Mois'),
        ];
        
        for ($i=0; $i<32; $i++) {
            $tabJoursAppli[$i]=$i;
        }

        $paravrac = new Paravrac($this->pdo);
        $configImpu = $paravrac->getCommandeAxeImpConfig($codeSte);
        
        $param['SI_ACTIF']          = $configImpu->SectImp->isActive;
        $param['CDC_ACTIF']         = $configImpu->CodeCompl->isActive;
        $param['SCA_ACTIF']         = $configImpu->SousCompteAna->isActive;
        $param['SI_OBLI'] = ! $configImpu->SectImp->isBlankAllowed;
        $param['CDC_OBLI'] = ! $configImpu->CodeCompl->isBlankAllowed;
        $param['SCA_OBLI'] = ! $configImpu->SousCompteAna->isBlankAllowed;
        

        $param['TYPEACHAT_ACTIF']   = ! empty($paravrac->getValue('PARAMFOU', 'INITTAC'));
        $param['LOCK_SAISIEREC']    =
            Roles::droitsUtilisateur($this->pdo, 'HA_CA_MOFR')!='1'
            && $paravrac->getFlag('PARAMGEN', 'CDERECEPTNONMODIF');

        
        $param['CODE_GESTION_PAR_ID']    = Roles::droit($this->pdo, 'CODE_GESTION_PAR_ID')? 1:0;

        $societe = new Societe($this->pdo);
        $infoSoc = $societe->find($codeSte);

        $param['LIMITACH_PX'] = Sql::boolSql($infoSoc['LIMITACH_PX']);
        $param['LIMITACH_QTE'] = Sql::boolSql($infoSoc['LIMITACH_QTE']);

        $param['LIMITACH_ART'] = Sql::boolSql($infoSoc['LIMITACH_ART']);
        $param['LIMITACH_CAR'] = Sql::boolSql($infoSoc['LIMITACH_CAR']);
        $param['LIMITACH_DEL'] = Sql::boolSql($infoSoc['LIMITACH_DEL']);
        $param['LIMITACH_IMP'] = Sql::boolSql($infoSoc['LIMITACH_IMP']);
        $param['LIMITACH_CS'] = Sql::boolSql($infoSoc['LIMITACH_CS']);

        $param['SITESTOCK_ACTIF'] = (new LicenceOxalys($this->pdo))->stockActive();
        
        return [
            'tabPeriodicite' => $tabPeriodicite,
            'tabPeriode' => $tabPeriode,
            'tabTypeDate' => $tabTypeDate,
            'tabJoursAppli' => $tabJoursAppli,
            'param' => $param,
            'droit' => [
                'HA_CA_MCPR'    => Roles::droitsUtilisateur($this->pdo, 'HA_CA_MCPR', $_SESSION["Session_Login"]),
                'HA_CA_MOFR'    => Roles::droitsUtilisateur($this->pdo, 'HA_CA_MOFR', $_SESSION["Session_Login"]),
                'HA_CA_TOL'     => Roles::droitsUtilisateur($this->pdo, 'HA_CA_TOL', $_SESSION["Session_Login"]),
            ],
        ];
    }
}
