<?php

namespace Modules\Facture\Controller;

use Entity\Model\FacLig;
use Entity\Model\Paravrac;
use GuzzleHttp\Psr7\Response;
use Skeleton\Controller\Controller;
use Helpers\ChampsSupplementaire\ChampSupp;
use Helpers\Trad\Trad;
use Helpers\Outil\Sql;
use Helpers\Outil\Date;
use Helpers\Parametres\Constante;

class ModificationFactureController extends Controller
{
    /**
     * @return Response|string
     * @throws \Exception
     */
    public function modificationFactureAction()
    {
        $post = $this->request->getParsedBody();
        $numFact = $this->request->getAttribute('numFact');
        
        
        $trad = $this->getTranslationService();
        
        $contenaire = [];
        $roles = [];
                
        $post = $this->request->getParsedBody();
        
        $facture = new \Entity\Model\FactEnt($this->pdo);
        $facture = $facture->find($numFact);
        if (!$facture) {
            return $this->redirect('Index.Index.error');
        }
        $facture['hasAffectations'] = !empty((new FacLig($this->pdo))->find(['NUM_FACT' => $numFact]));

        // Devise de la BDD
        $deviseBDD = $_SESSION['parametrage']['DEVISE_BASE'];

        // Devise de la société
        $societe = new \Entity\Model\Societe($this->pdo);
        $deviseSociete = $societe->find($facture['CODE_STE'])['DEVISE'];
        
        $Creationfacture = new \Modules\Facture\Repository\CreationFacture($this->pdo);
        $contenaire['MODE_NUM'] = $Creationfacture->getModeNumFact($facture['CODE_STE']);
        
        $fourniss = new \Entity\Model\Fourniss($this->pdo);
        $fournisseur = $fourniss->find($facture['CODE_FOUR']);
        $facture['COND_PAIE'] = $fournisseur['COND_PAIE'];
        
        if ($facture['NUM_CDE']) {
            $CaEntet = new \Entity\Model\CaEntet($this->pdo);
            $facture['COND_PAIE'] = $CaEntet->find($facture['NUM_CDE'])['COND_PAIE'];
        }

        $country = new \Entity\Model\Country($this->pdo);
        $paravrac = new Paravrac($this->pdo);
        
        
        // recuperation du taux de tva
        $pays_fourniss = $fournisseur['CODE_PAYS'];
        $pays_fourniss_cee = Sql::boolSql($country->find($pays_fourniss)['PAYSCEE']);
        
        $pays_install = $paravrac->getPaysInstall();
        $pays_install_cee = Sql::boolSql($country->find($pays_install)['PAYSCEE']);
        
        if ($pays_install!='' && ($pays_install==$pays_fourniss || ($pays_install_cee && $pays_fourniss_cee))) {
            $parametr = (new \Entity\Model\Parametr($this->pdo))->get();
            $taux_tva = $parametr->TX_TVA;
        }

        $roles['LIB_COMPT_OBLG'] = \Helpers\Outil\Roles::droit($this->pdo, 'LIB_COMPT_OBLG');
        $roles['DATE_FAFO'] = \Helpers\Outil\Roles::droit($this->pdo, 'FACDTEFOURNOB');
        $roles['DATE_ENR_MODIF'] = !\Helpers\Outil\Roles::droit($this->pdo, 'DENRFACTNONMODIF');
        $roles['DTAE_ECH_MODIF'] = !\Helpers\Outil\Roles::droit($this->pdo, 'DECHFACTNONMODIF');
        $roles['ORDONANCE'] = \Modules\Facture\Repository\CreationFacture::ordonanceActif($this->pdo);
        $roles['factFou'] = \Helpers\Outil\Roles::droit($this->pdo, 'REFFACFOU');
        $droits['HA_FA_DENR'] = \Helpers\Outil\Roles::droitsUtilisateur($this->pdo, 'HA_FA_DENR');
        
        $country = $country->find($facture['PY_REGLMT']);
        $listePays = new \Entity\Model\Pays($this->pdo);
        $Pays = $listePays->listChoice();
        $CodePays = array_combine(array_keys($Pays), array_keys($Pays));
        $CodePays['']='';
        
        $ordonanc = new \Entity\Model\Ordonanc($this->pdo);
        $ordonanc = $ordonanc->fetch();

        $codEnr = str_pad($numFact, 9, '0', STR_PAD_LEFT);
        
        $listeCS = ChampSupp::listeIdCS('FAC_ENT', $this->pdo, true);


        if ($facture['TYPE'] == 'F') {
            \Helpers\Ariane\Ariane::generate(1, $trad->t('Modification facture'));
        } else {
            \Helpers\Ariane\Ariane::generate(1, $trad->t('Modification avoir'));
        }
        
        return $this->renderer->render('@modification-facture/modification-facture', [
            'menuActive' => 'Facture',
            'menuLeft' => 'GestionFacture',
            'contenaire' => $contenaire,
            'roles' => $roles,
            'droits' => $droits,
            'dateJour'      => date("Ymd"),
            'dateDuJour' => \Helpers\Outil\Date::dateConverte(date("Ymd")),
            'post' => $post,
            'listeCS' => $listeCS,
            'action' => 'modification',
            'facture' => $facture,
            'country' => $country,
            'codePays' => $CodePays,
            'pays' => $Pays,
            'ordonanc' => $ordonanc,
            'fournisseur' => $fournisseur,
            'codEnr' => $codEnr,
            'deviseBDD' => $deviseBDD,
            'deviseSociete' => $deviseSociete,
            'TAUX_TVA' => $taux_tva ?? 0,
            'confirmationModification' => Trad::strBuild($trad->t("La facture n°@1@ a été modifiée."), $numFact),
            
        ]);
    }
    
    public function creationAffectationAction()
    {
        $post = $this->request->getParsedBody();
        $action = $this->request->getAttribute('action');
        
        
        $trad = $this->getTranslationService();

        $factEnt = new \Entity\Model\FactEnt($this->pdo);
        $CreationFacture = new \Modules\Facture\Repository\CreationFacture($this->pdo);
        $validator = $this->createValidator();
        
        if (\Helpers\Outil\Roles::droit($this->pdo, 'REFFACFOU')=='1') {
            $validator->size($post['FACT_FOU'], $trad->t("Référence fournisseur"), 1, 60); // => SPEC 4497
        }
        
        $post['TOTAL_HT'] = str_replace(' ', '', $post['TOTAL_HT']);
        $post['TOTAL_TTC'] = str_replace(' ', '', $post['TOTAL_TTC']);
        $post['MNT_TVA'] = str_replace(' ', '', $post['MNT_TVA']);

        $erreurNonBloquante = '';

        $validator->zoom('Societe', $post['societe'], $trad->t("Société"), $this->pdo);
        $validator->isStringAvecEspace($trad->t("Libellé"), $post['LIB_COMPT'], 0, 120);
        $validator->zoom('Fourniss', $post['CODE_FOUR'], $trad->t("Code fournisseur"), $this->pdo);
        $validator->numeroCommandeZoom($post['NUM_CDE'], $trad->t("Numéro de commande"), $this->pdo, true);
        $validator->numeroCommandeZoom($post['NUM_CDE'], $trad->t("Numéro de commande"), $this->pdo, true, ['CODE_STE' => $post['societe'], 'CODE_FOU' => $post['CODE_FOUR']]);
        $validator->zoom('Modepaie', $post['modepaie'], $trad->t("Mode de paiement"), $this->pdo);
        $validator->deviseZoom($post['DEVISE'], $trad->t("Devise"), $this->pdo);

        if (\Helpers\Outil\Roles::droit($this->pdo, 'FACDTEFOURNOB')) {
            $dateFafoValide = $validator->isDate($post['DATE_FAFO'], '', date("Ymd"), false, $trad->t("Date d'émission"));
        } else {
            $dateFafoValide = $validator->isDate($post['DATE_FAFO'], '', date("Ymd"), true, $trad->t("Date d'émission"));
        }
        if ($dateFafoValide) {
            if ($post['DATE_FAFO']!= '00000000' && !$CreationFacture->dateFafou($post['DATE_FAFO'], $this->pdo)) {
                $erreurNonBloquante .= '<br />'.$trad->t('La date d\'émission n\'est pas dans la période en cours.');
            }
        }

        $validator->isDate($post['DATE_ENR'], '', date("Ymd"), false, $trad->t("Date enregistrement"));
        $dateFormattedForResultatPeriode = $post['DATE_PER'];
        if ($validator->isDate($post['DATE_PER'], '', '', false, $trad->t("Date d'effet"))) {
            $resultPer = $CreationFacture->ouverturePeriode($post['DATE_PER']);
            $validator->isFalse(isset($resultPer['CODE_PER']), '<br />'.$trad->t("La période à laquelle correspond la date d'effet n'existe pas, contactez la personne responsable de la gestion des périodes."));
            if (\Helpers\Outil\Roles::droit($this->pdo, 'SPER_AVEC_OUV_FERM') && \Helpers\Outil\Roles::droit($this->pdo, 'CTRL_SSPERIODE_FAC')) {
                $validator->isDateOuverte($trad->t('sous-période'), $dateFormattedForResultatPeriode, $post['societe'], 'FAC', false);
            }
        }
        
        $factureEntete = $factEnt->find($post['NUM_FACT']);
        
        if (Date::dateConverte($factureEntete['DTAE_ECH']) != $post['DTAE_ECH']) {
            $validator->isDate($post['DTAE_ECH'], date('Ymd'), '', false, $trad->t("Date d'échéance"));
        } else {
            $validator->isDate($post['DTAE_ECH'], '', '', false, $trad->t("Date d'échéance"));
        }
        
        if ($post['TYPE']=='F') {
            // $validator->isTrue($post['TOTAL_HT']>$post['TOTAL_TTC'], $trad->t('Le montant HT ne peut pas être supérieur au montant TTC'));
        } elseif ($post['TYPE']=='A') {
            // $validator->isTrue($post['TOTAL_HT']<$post['TOTAL_TTC'], $trad->t('Le montant HT ne peut pas être inférieur au montant TTC'));
        }
 
        $validator->isFloat($trad->t("Montant HT"), $post['TOTAL_HT'], Constante::formatMontant, false);
        // @phpstan-ignore-next-line
        $validator->isTrue($post['TYPE']=='F' && $post['TOTAL_HT']<0, '<br />'.$trad->t("Le montant HT ne peut pas être négatif."));
        // @phpstan-ignore-next-line
        $validator->isTrue($post['TYPE']=='A' && $post['TOTAL_HT']>0, '<br />'.$trad->t("Le montant HT ne peut pas être positif."));
        // $validator->isTrue($post['TOTAL_HT']==0, '<br />'.$trad->t("Le total HT ne peut pas être égal à zéro."));
        $validator->isFloat($trad->t("Montant TTC"), $post['TOTAL_TTC'], Constante::formatMontant, false);
        // $validator->isTrue($post['TOTAL_TTC']==0, '<br />'.$trad->t("Le total TTC ne peut pas être égal à zéro."));
        $validator->isFloat($trad->t("Montant TVA"), $post['MNT_TVA'], Constante::formatMontant);
        if ($post['TX_DEVISE']!='') {
            $validator->isFloat($trad->t("Taux devise"), $post['TX_DEVISE'], "9.7");
        }
        $validator->isTrue($post['TX_DEVISE']<=0, '<br />'.$trad->t("La valeur de la devise doit être supérieure à 0."));
        if ($post['TX_DEVSTE']!='') {
            $validator->isFloat($trad->t("Taux devise"), $post['TX_DEVSTE'], "9.7");
        }
        
        $validator->validatorCS('FAC_ENT', str_pad($post['NUM_FACT'], 9, '0', STR_PAD_LEFT), $post, $this->pdo, $post['societe'], $post['DATE_PER']);
        
        $validator->isStringAvecEspace($trad->t("Raison sociale règlement"), $post['RS_REGLMT'], 0, 45);
        $validator->isStringAvecEspace($trad->t("Adresse règlement"), $post['AD_REGLMT'], 0, 90);
        $country = new \Entity\Model\Country($this->pdo);
        $country = $country->find($post['PY_REGLMT']);
        $validator->isStringAvecEspace($trad->t("Code postal règlement"), $post['CPREGLMT'], 0, $country['LONGCP']);
        $validator->isStringAvecEspace($trad->t("Ville règlement"), $post['VILREGLMT'], 0, 35);
        $validator->isStringAvecEspace($trad->t("Domiciliation bancaire"), $post['DOM_BANQ'], 0, 26);
        $validator->isStringAvecEspace($trad->t("Banque"), $post['CODE_BANQ'], 0, 5);
        $validator->isStringAvecEspace($trad->t("Guichet"), $post['CODE_GUIC'], 0, 5);
        $validator->isStringSansEspace($trad->t("N° Compte"), $post['NUM_COMPT'], 0, 11);
        $validator->isStringSansEspace($trad->t("Clé RIB"), $post['CLE_RIB'], 0, 2);
        $validator->isInteger($trad->t("Clé IBAN"), $post['IBANCLE'], 0, 2);

        $post['IBANCPT'] = strtoupper(str_replace('-', '', strtoupper(str_replace(' ', '', strtoupper($post['IBANCPT'])))));
        if ($post['IBANCLE']!='' && $post['IBANCPT']!='') {
            $validator->checkIban($trad->t("Compte IBAN"), ($post['IBANPAYS'].$post['IBANCLE'].$post['IBANCPT']));
        }
        $validator->checkBic($trad->t("Code BIC"), $post['CODEBIC'], 0, 11);
        
        $erreur = $validator->getError();
        
        $repo = new \Modules\Facture\Repository\CreationFacture($this->pdo);
        $paravrac = new Paravrac($this->pdo);
        if ($paravrac->getFlag('PARAMGEN', 'FACFOU_UNIQUE')
            && !empty($repo->getDuplicateRefFou($post))
        ) {
            $validator->setError($trad->t("Une facture existe déjà avec cette référence fournisseur."));
        }
        
        if ($erreur == '' && ($erreurNonBloquante == '' || $post['submitForce'])) {
            $res = \Modules\Facture\WebService\ModificationFacture::modificationEntete($post);
            $reponse = new \SimpleXMLElement($res->responseData);
            
            $statuts = $reponse->Statut;
            $numFact = $reponse->NO_FACT;

            if ($statuts =="O") {
                $statut = "O";
                if ($post['NUM_CDE']=='') {
                    $post['NUM_CDE']='all';
                }

                $refreshfacture = new \Entity\Model\FactEnt($this->pdo);
                $refreshfacture = $refreshfacture->find($numFact);
                
                $retour= [
                    'droit_validation' => \Helpers\Outil\Roles::droitsUtilisateur($this->pdo, 'HA_FA_VALI'),
                    'pathValidation' => $this->router->generateUri('Facture.popup.choixValidationFacture', ['numFact' => (string)$numFact, 'fournisseur' => $post['CODE_FOUR'], 'mode' => 'modificationEntete']),
                    'statut' => $statut,
                    'AFF_ENREG' => SQL::boolSql($refreshfacture['AFF_ENREG'])
                ];
                
                if ($post['TYPE']=='F') {
                    $retour['path'] = $this->router->generateUri('Facture.CreationFacture.choixCommande', ['action' => $action, 'numFact' => (string)$numFact, 'fournisseur' => $post['CODE_FOUR'], 'societe' => $post['societe'], 'numCde' => $post['NUM_CDE']]);
                } else {
                    $retour['path'] = $this->router->generateUri('Facture.CreationFacture.choixAvoir', ['action' => $action, 'numFact' => (string)$numFact, 'fournisseur' => $post['CODE_FOUR'], 'societe' => $post['societe'], 'numCde' => $post['NUM_CDE']]);
                }
                
                return new Response(200, [
                     
                ], (string) \json_encode($retour));
            } else {
                $params = [
                    'alerte' => $reponse->MsgErreur,
                    'titrePopup'  => $trad->t("Erreur sur l'entête de la facture"),
                ];
                return new Response(443, [
                    
                ], $this->renderer->render('@popup-erreur/erreurAlerteEtAvertissement', ['params' => $params]));
            }
        } else {
            $params = [
                'alerte' => $erreur,
                'avertissement' => $erreurNonBloquante,
                'action' => 'terminer',
                'titrePopup'  => $trad->t("Erreur sur l'entête de la facture"),
            ];
            return new Response(443, [
                    
            ], $this->renderer->render('@popup-erreur/erreurAlerteEtAvertissement', ['params' => $params]));
        }
        
        return $this->renderer->render('@facture/entete', [
            'post' => $post,
        ]);
    }
}
