<?php

namespace Modules\Additional\Specifique\Client56\Modules\Facture\Controller;

use Skeleton\Controller\Controller;
use GuzzleHttp\Psr7\Response;
use Helpers\Fichier\Fichier;
use Helpers\Trad\Trad;
use Helpers\Outil\Sql;
use Helpers\Validator\Validator;
use Helpers\ChampsSupplementaire\ChampSupp;
use Modules\Additional\Specifique\Client56\Modules\Facture\Repository\GestionFacture;
use Modules\Facture\WebService\ImpressionFacture;

class FactureController extends Controller
{
    public function init()
    {
        if (!\Helpers\Roles\Predispatch::connectRole()) {
            return $this->redirect($this->contenaire->get('base').'index.php');
        }
    }

    public function donneesComptablesAction() : string
    {
        
        $post    = $this->request->getParsedBody();
        $numFact = $this->request->getAttribute('numFact');
        
        $Dilispec = new  \Entity\Model\Dilispec($this->pdo);
        $Societe = new \Entity\Model\Societe($this->pdo);
        $factureRepository = new GestionFacture($this->pdo);
        $trad = $this->getTranslationService();

        $facture           = $factureRepository->detailFacture($numFact);
        $lignes            = $factureRepository->detailLigneFacture($numFact);

        $MODIF_ACTIF = !sql::boolSql($facture['AFF_VALID']);

        /* Récupération des NUM_FIX des CS Entete */
        $listeCsEntete = [
            'TYPE_FACTURE' => $Dilispec->find(['TYPEDICO' => 'PARAMCC', 'CODEDICO'=>'NCS_FAC_ENT_TYPEFACT'])['LIB01DICO'],
            'AFFACTUREUR' => $Dilispec->find(['TYPEDICO' => 'PARAMCC', 'CODEDICO'=>'NCS_FAC_ENT_TIERS'])['LIB01DICO'],
            'DEMANDEUR' => $Dilispec->find(['TYPEDICO' => 'PARAMCC', 'CODEDICO'=>'NCS_FAC_ENT_DEM'])['LIB01DICO'],
            'APPROUVEE' => $Dilispec->find(['TYPEDICO' => 'PARAMCC', 'CODEDICO'=>'NCS_FAC_ENT_APPROUVEE'])['LIB01DICO'],
        ];
        $codeEnr           = str_pad($numFact, 9, '0', STR_PAD_LEFT);

        /* Création du fichier temporaire */
        $GestionContainerFile = new \Modules\Outil\Outil\GestionContainerFile('', $this->JWTKEY);
        $GestionContainerFile->creationContainerFile([]);

        /* Récupération des NUM_FIX des CS Ligne */
        $listeCsLigne = [
            'COMPTE' => $Dilispec->find(['TYPEDICO' => 'PARAMCC', 'CODEDICO'=>'NCS_FAC_LIG_CPTECG_VAL'])['LIB01DICO'],
            'FONCTION' => $Dilispec->find(['TYPEDICO' => 'PARAMCC', 'CODEDICO'=>'NCS_FAC_LIG_FONCANA_VAL'])['LIB01DICO'],
            'ANNEE' => $Dilispec->find(['TYPEDICO' => 'PARAMCC', 'CODEDICO'=>'NCS_FAC_LIG_ANRECOLTE_VAL'])['LIB01DICO'],
            'PRODUIT' => $Dilispec->find(['TYPEDICO' => 'PARAMCC', 'CODEDICO'=>'NCS_FAC_LIG_PRODUIT_VAL'])['LIB01DICO'],
            'DOSSIER' => $Dilispec->find(['TYPEDICO' => 'PARAMCC', 'CODEDICO'=>'NCS_FAC_LIG_DOSSIERSIN_VAL'])['LIB01DICO'],
            'CODE_PARC' => $Dilispec->find(['TYPEDICO' => 'PARAMCC', 'CODEDICO'=>'NCS_FAC_LIG_CODEPARC_VAL'])['LIB01DICO'],
            'NATURE' => $Dilispec->find(['TYPEDICO' => 'PARAMCC', 'CODEDICO'=>'NCS_FAC_LIG_NATINTERV_VAL'])['LIB01DICO'],
            'CONTRAT' => $Dilispec->find(['TYPEDICO' => 'PARAMCC', 'CODEDICO'=>'NCS_FAC_LIG_NUMCONTRAT_VAL'])['LIB01DICO'],
            'TAUX_RECUP_TVA' => $Dilispec->find(['TYPEDICO' => 'PARAMCC', 'CODEDICO'=>'NCS_FAC_LIG_TXRECUPTVA_VAL'])['LIB01DICO'],
            'MODE_RECUP_TVA' => $Dilispec->find(['TYPEDICO' => 'PARAMCC', 'CODEDICO'=>'NCS_FAC_LIG_MODERECUPTVA'])['LIB01DICO'],
            'TYPE_FRAIS' => $Dilispec->find(['TYPEDICO' => 'PARAMCC', 'CODEDICO'=>'NCS_FAC_LIG_TYPEFRAIS_VAL'])['LIB01DICO'],
            'ACTIVITE_FAR' => $Dilispec->find(['TYPEDICO' => 'PARAMCC', 'CODEDICO'=>'NCS_FAC_LIG_ACTFACT_VAL'])['LIB01DICO'],
            'ACTIVITE' => $Dilispec->find(['TYPEDICO' => 'PARAMCC', 'CODEDICO'=>'NCS_FAC_LIG_ACTFAR_VAL'])['LIB01DICO'],
        ];

        $devise_ste = $Societe->find($facture['CODE_STE'])['DEVISE'];
        $listeType = [
            'F' => $trad->t('Facture'),
            'A' => $trad->t('Avoir'),
        ];
        
        \Helpers\Ariane\Ariane::generate(2, $trad->t('Données comptables'));

        if ($facture['TYPE'] == 'F') {
            $H2 = Trad::strBuild($trad->t("Détails de la facture N° @1@"), $numFact);
        } else {
            $H2 = Trad::strBuild($trad->t('Détails de l\'avoir N° @1@'), $numFact);
        }
        
        return $this->renderer->render('@Specifique56Facture/DonneesComptables/donneesComptables', [
            'menuActive'       => 'Facture',
            'menuLeft'         => 'GestionFacture',
            'post'             => $post,
            'numFact'          => $numFact,
            'H2'               => $H2,
            'MODIF_ACTIF'      => $MODIF_ACTIF,
            'facture'          => $facture,
            'lignes'           => $lignes,
            'codeEnr'          => $codeEnr,
            'listeCsEntete'    => $listeCsEntete,
            'listeCsLigne'     => $listeCsLigne,
            'devise_ste'       => $devise_ste,
            'listeType'        => $listeType,
        ]);
    }
    
    public function ligneDetailDonneesComptablesAction() : string
    {
        $id = $this->request->getAttribute('numFact');
        $numLigne = $this->request->getAttribute('ligne');
        
        $facture = new GestionFacture($this->pdo);
        $ligne = $facture->detail1LigneFacture($id, $numLigne);

        /* CS Ligne */
        $ChampSupp = new ChampSupp($this->pdo);
        $CsLigne   = $ChampSupp->generateChampSupp('FAC_LIG');
        
        foreach ($CsLigne as $value) {
            if ($value['NOM'] == 'Activité FAR') {
                $listeCsLigne['ACTIVITE_FAR'] = $value['NUM_FIX'];
            } else {
                $listeCsLigne[$value['TYPE']] = $value['NUM_FIX'];
            }
        }
        
        return $this->renderer->render('@Specifique56Facture/DonneesComptables/detailLigne', [
            'ligne' => $ligne,
            'codeEnrLig' => str_pad($id, 9, '0', STR_PAD_LEFT).str_pad($numLigne, 3, '0', STR_PAD_LEFT),
            'listeCsLigne' => $listeCsLigne
        ]);
    }

    public function validationDonneesComptablesAction()
    {
        $post = $this->request->getParsedBody();
        $validator = $this->createValidator();
        $trad = $this->getTranslationService();

        $numFact = $post['numFact'];
        
        $FactEnt = new \Entity\Model\FactEnt($this->pdo);
        $facture = $FactEnt->find($numFact);
        
        $codEnr = str_pad($numFact, 9, '0', STR_PAD_LEFT);

        /*** RECUPERATION DES VALEURS DEPUIS FICHIER TEMPORAIRE ***/
        $GestionContainerFile = new \Modules\Outil\Outil\GestionContainerFile('', $this->JWTKEY);
        $valuesContainerFile = $GestionContainerFile->getContainerFile();
        
        /*** VALIDATION ***/
        /* Créateur de la facture */
        $modifFacEnt = 0;
        if ($facture['FAC_CBY'] == '') {
            $modifFacEnt = 1;
            $validator->utilisateurZoom(
                $valuesContainerFile['FAC_CBY'],
                $trad->t('Créateur de la facture'),
                $this->pdo,
                false,
                ['CODE_STE' =>  $facture['CODE_STE']]
            );
        }
        
        /* CS */
        $validator->validatorCS('FAC_ENTET', $numFact, $valuesContainerFile, $this->pdo, $facture['CODE_STE'], $facture['DATE_PER']);

        // Vérifier si présence de l'email pour le demandeur
        $Dilispec = new  \Entity\Model\Dilispec($this->pdo);
        $Hastutil = new \Entity\Model\Hastutil($this->pdo);
        $numFixDemandeur = trim($Dilispec->find(['TYPEDICO' => 'PARAMCC', 'CODEDICO'=>'NCS_FAC_ENT_DEM'])['LIB01DICO']);
        $keyCsDemandeur = 'CS_EXTENTIONdebut-----finFAC_ENTdebut-----fin'.$codEnr.'debut-----fin'.$numFixDemandeur;
        $demandeur = $Hastutil->find($valuesContainerFile[$keyCsDemandeur]);
        if (is_array($demandeur)) {
            $validator->isTrue($demandeur['EMAIL'] == '', '<br />'.$trad->t('Veuillez sélectionner un demandeur ayant un email.'));
        }
        /*** FIN DES CONTROLES ***/

        if ($validator->isValid()) {
            $majOK = 1;
            if ($modifFacEnt) {
                $majOK = $FactEnt->update(['FAC_CBY' => $valuesContainerFile['FAC_CBY']], ['NUM_FACT' => $numFact]);
            }

            if ($majOK) {
                $factureRepository = new GestionFacture($this->pdo);

                /* Comparaison des valeurs CS FAC_ENT pour n'enregistrer que les modifications */
                $listeIdCSEnt = ChampSupp::listeIdCS('FAC_ENT', $this->pdo);
                $listeCSDONEnt = ChampSupp::listeCSDON('FAC_ENT', $codEnr, $this->pdo);
                foreach ($listeIdCSEnt as $idCS) {
                    $numFix = $idCS['NUM_FIX'];
                    $keyCsExtension = 'CS_EXTENTIONdebut-----finFAC_ENTdebut-----fin'.$codEnr.'debut-----fin'.$numFix;
                    if (isset($valuesContainerFile[$keyCsExtension])) {
                        $csdonExit = 0;
                        foreach ($listeCSDONEnt as $csDon) {
                            if ($csDon['NUM_FIX'] == $numFix) {
                                if ($csDon['VALEUR']!=$valuesContainerFile[$keyCsExtension]) {
                                    $listeCSModifie[$keyCsExtension] = $valuesContainerFile[$keyCsExtension];
                                }
                                $csdonExit = 1;
                            }
                        }
                        if (!$csdonExit) {
                            $listeCSModifie[$keyCsExtension] = $valuesContainerFile[$keyCsExtension];
                        }
                    }
                }

                /* Comparaison des valeurs CS FAC_LIG pour n'enregistrer que les modifications */
                $listeLigne = $factureRepository->getNumLigneFacture($numFact);
                foreach ($listeLigne as $ligne) {
                    $listeIdCS = ChampSupp::listeIdCS('FAC_LIG', $this->pdo);

                    $codEnrLig = $codEnr.str_pad($ligne['NUM_LIG'], 3, '0', STR_PAD_LEFT);
                    $listeCSDON = ChampSupp::listeCSDON('FAC_LIG', $codEnrLig, $this->pdo);
                    foreach ($listeIdCS as $idCS) {
                        $numFix = $idCS['NUM_FIX'];
                        $keyCsExtension = 'CS_EXTENTIONdebut-----finFAC_LIGdebut-----fin'.$codEnrLig.'debut-----fin'.$numFix;
                        if (isset($valuesContainerFile[$keyCsExtension])) {
                            $csdonExit = 0;
                            foreach ($listeCSDON as $csDon) {
                                if ($csDon['NUM_FIX'] == $numFix) {
                                    if ($csDon['VALEUR']!=$valuesContainerFile[$keyCsExtension]) {
                                        $listeCSModifie[$keyCsExtension] = $valuesContainerFile[$keyCsExtension];
                                    }
                                    $csdonExit = 1;
                                }
                            }
                            if (!$csdonExit) {
                                $listeCSModifie[$keyCsExtension] = $valuesContainerFile[$keyCsExtension];
                            }
                        }
                    }
                }
                
                /* Enregistrement des CS modifiés*/
                if (isset($listeCSModifie)) {
                    ChampSupp::updateCS($listeCSModifie, $this->pdo);
                }
            
                $params = [
                    'statut' => 'redirect',
                    'path' => $this->router->generateUri('Specifique56.Index.menuIntermediaireFactureSpecifique', ['numFact' => $numFact]),
                ];

                // Suppression du fichier temporaire
                $GestionContainerFile->deleteContainerFile();
                return new Response(200, [
                
                ], (string) \json_encode($params));
            } else {
                $params = [
                    'statut' => 'E',
                    'alerte' => $trad->t("Erreur lors de l'exécution de l'opération.")
                ];
            }

            return $this->renderer->render('@popup-erreur/erreurAlerteEtAvertissement', [
                'params' => $params,
                'titrePopup'  => $trad->t("Erreur"),
            ]);
        } else {
            $params = [
                'alerte' => $validator->getError(),
                'titrePopup'  => $trad->t("Erreur sur l'entête de la DA"),
            ];
            return $this->renderer->render('@popup-erreur/erreurAlerteEtAvertissement', [
                'params' => $params,
            ]);
        }
    }

    public function demandeCommandeRegulAction()
    {
        $post    = $this->request->getParsedBody();
        $numFact = $this->request->getAttribute('numFact');
        $trad = $this->getTranslationService();
        
        $codeEnr = str_pad($numFact, 9, '0', STR_PAD_LEFT);
        $CSDemandeur = ChampSupp::getCSValueSpecific(['COD_TAB' => 'FAC_ENT', 'COD_ENR' => $codeEnr, 'typedico' => 'PARAMCC', 'codedico'  =>'NCS_FAC_ENT_DEM'], $this->pdo);
        if (!$CSDemandeur) {
            $Dilispec = new  \Entity\Model\Dilispec($this->pdo);
            $CSDemandeur['NUM_FIX'] = $Dilispec->find(['TYPEDICO' => 'PARAMCC', 'CODEDICO'=>'NCS_FAC_ENT_DEM'])['LIB01DICO'];
        } elseif (is_array($CSDemandeur) && $CSDemandeur['VALEUR'] != '') {
            // Si présence d'un demandeur, redirection vers l'envoi facture
            return $this->redirect('Specifique56.Facture.envoiFacture', ['numFact' => $numFact, 'typeEnvoi' => 'commandeRegul']);
        }
        
        \Helpers\Ariane\Ariane::generate(2, $trad->t('Demande Commande Régularisation'));
        
        $H2 =  Trad::strBuild($trad->t('Demande de commande de régularisation pour la facture @1@'), $numFact);
        
        return $this->renderer->render('@Specifique56Facture/DemandeCommandeRegul/demandeCommandeRegul', [
            'menuActive'       => 'Facture',
            'menuLeft'         => 'GestionFacture',
            'post'             => $post,
            'numFact'          => $numFact,
            'H2'               => $H2,
            'codeEnr'          => $codeEnr,
            'CSDemandeur'      => $CSDemandeur,
        ]);
    }

    public function validationDemandeCommandeRegulAction()
    {
        $post = $this->request->getParsedBody();
        $numFact = $this->request->getAttribute('numFact');
        $validator = $this->createValidator();
        $trad = $this->getTranslationService();
        
        $FactEnt = new \Entity\Model\FactEnt($this->pdo);
        $facture = $FactEnt->find($numFact);

        $codEnr = str_pad($numFact, 9, '0', STR_PAD_LEFT);
        
        /*** VALIDATION ***/
        $validator->validatorCS('FACT_ENTET', $numFact, $post, $this->pdo, $facture['CODE_STE'], $facture['DATE_PER']);

        // Vérifier si présence de l'email pour le demandeur
        $Dilispec = new  \Entity\Model\Dilispec($this->pdo);
        $Hastutil = new \Entity\Model\Hastutil($this->pdo);
        $numFixDemandeur = trim($Dilispec->find(['TYPEDICO' => 'PARAMCC', 'CODEDICO'=>'NCS_FAC_ENT_DEM'])['LIB01DICO']);
        $keyCsDemandeur = 'CS_EXTENTIONdebut-----finFAC_ENTdebut-----fin'.$codEnr.'debut-----fin'.$numFixDemandeur;
        $demandeur = $Hastutil->find($post[$keyCsDemandeur]);
        if (is_array($demandeur)) {
            $validator->isTrue($demandeur['EMAIL'] == '', '<br />'.$trad->t('Veuillez sélectionner un demandeur ayant un email.'));
        }
        /*** FIN DES CONTROLES ***/

        if ($validator->isValid()) {
            ChampSupp::updateCS($post, $this->pdo);

            $params = [
                'statut' => 'redirect',
                'path' => $this->router->generateUri('Specifique56.Facture.envoiFacture', ['numFact' => $numFact, 'typeEnvoi' => 'commandeRegul']),
            ];
            
            return new Response(200, [
            
            ], (string) \json_encode($params));
        } else {
            $params = [
                'alerte' => $validator->getError(),
                'titrePopup'  => $trad->t("Erreur sur l'entête de la DA"),
            ];
            return $this->renderer->render('@popup-erreur/erreurAlerteEtAvertissement', [
                'params' => $params,
            ]);
        }
    }

    public function envoiFactureAction() : string
    {
        $post    = $this->request->getParsedBody();
        $numFact = $this->request->getAttribute('numFact');
        $typeEnvoi = $this->request->getAttribute('typeEnvoi');
        
        $Hastutil = new \Entity\Model\Hastutil($this->pdo);
        $Fourniss = new \Entity\Model\Fourniss($this->pdo);
        $facture = new \Entity\Model\FactEnt($this->pdo);

        $facture = $facture->find($numFact);
        $Fourniss = $Fourniss->find($facture['CODE_FOUR']);
        $utilisateur = $Hastutil->find($_SESSION['Session_Login']);
        
        $codeEnr = str_pad($numFact, 9, '0', STR_PAD_LEFT);

        $trad = $this->getTranslationService();
            
        switch ($typeEnvoi) {
            case 'commandeRegul':
                $CSDemandeur = ChampSupp::getCSValueSpecific(['COD_TAB' => 'FAC_ENT', 'COD_ENR' => $codeEnr, 'typedico' => 'PARAMCC', 'codedico'  =>'NCS_FAC_ENT_DEM'], $this->pdo);
                $demandeur = $Hastutil->find($CSDemandeur['VALEUR']);
                
                $reponse['Destinataires'] =  $demandeur['EMAIL'];
                $reponse['Sujet'] = $trad->t("Demandes de COMMANDES de régularisation");

                $corps = Trad::strBuild($trad->t("Nous vous rappelons qu'aucun achat ne peut se faire chez @1@ sans demande d'achat approuvée par la hiérarchie."), $Fourniss['RS']);
                $corps .= "\n".$trad->t("Or, nous recevons la facture jointe qui n'a fait l'objet d'aucune commande de votre part.");
                $corps .= "\n".$trad->t("Merci de bien vouloir saisir la commande de régularisation  à l'aide des données ci-dessous, et nous en tenir informés rapidement.");
                $corps .= "\n\n".$_SESSION['URL_PAGE_ACCUEIL'];
                $corps .= "\n\n".$trad->t('Fournisseur') . $trad->colon() . $facture['CODE_FOUR']." ".$Fourniss['RS'];
                $corps .= "\n".$trad->t('Montant HT') . $trad->colon() . $facture['TOTAL_HT']." ".$facture['DEVISE'];
                $corps .= "\n\n".$trad->t('Merci par avance.');
                $corps .= "\n\n".$utilisateur['NOM'];
                $reponse['Corps'] = $corps;

                $CodeEvent = 'EDA';
                $commEvenement = 'eventVivescia|'.Trad::strBuild($trad->t("Envoi d'un email de demande de saisie de COMMANDES de régularisation à @1@ à l'adresse suivante :"), $CSDemandeur['VALEUR']);
                break;
            case 'envoiInfo':
                $reponse['Destinataires'] = '';
                $reponse['Sujet'] = Trad::strBuild($trad->t("Infos sur la facture n° @1@ du fournisseur @2@ :"), $facture['FACT_FOU'], $Fourniss['RS']);

                $corps = "\n".$trad->t("Ci-joint les informations sur la facture citée en sujet.");
                $corps .= "\n\n".$trad->t('Fournisseur') . $trad->colon() . $facture['CODE_FOUR']." ".$Fourniss['RS'];
                $corps .= "\n".$trad->t('Montant HT') . $trad->colon() . $facture['TOTAL_HT']." ".$facture['DEVISE'];
                $corps .= "\n\n".$utilisateur['NOM'];
                $reponse['Corps'] = $corps;
                break;
        }
        
        $impression = new ImpressionFacture();
        $impression = $impression->impressionEntete($numFact);
                   
        $xml = new \SimpleXMLElement($impression->responseData);
            
        if ($xml->Statut =="O") {
            $url = Fichier::URLDownload((string)$xml->FichierPDF[0]);
            $reponse['PJ_DEFAUT']  =
            [
                0 =>
                [
                    'urlPj' => $url,
                    'nomPj' => (string)$xml->FichierPDF[0],
                    'libellePj' => 'IMPRESSION_FACT'
                ]
            ];
        }
        
        if (trim($facture['FIC_LAD'])!='') {
            $reponse['PJ_DEFAUT'][1] =
            [
                'urlPj' => $_SESSION['chemin_pj'].$facture['FIC_LAD'],
                'nomPj' => $facture['FIC_LAD'],
                'libellePj' => 'IMG_FACT'
            ];
        }
        
        \Helpers\Ariane\Ariane::generate(2, $trad->t('Envoi infos facture'));

        $titre = Trad::strBuild($trad->t('Envoi infos Facture N° @1@'), $numFact);
        
        return $this->renderer->render('@ajax-mail/mail', [
            'menuActive'       => 'Facture',
            'menuLeft'         => 'GestionFacture',
            'post'             => $post,
            'numFact'          => $numFact,
            'codeSte'          => $facture['CODE_STE'],
            'erreur'           => '',
            'module'           => 'facture',
            'CodeEvent'        => $CodeEvent ?? '',
            'commEvenement'    => $commEvenement ?? '',
            'pathValidation'   => 'Ajax.MailController.validationMail',
            'pathConfirmation' => 'Ajax.Erreur.popupInformation',
            'uriRetour'        => $this->router->generateUri('Specifique56.Index.menuIntermediaireFactureSpecifique', ['numFact' => $numFact]),
            'reponse'          => $reponse,
            'titreModule'      => $trad->t('Factures et avoirs'),
            'titre'            => $titre,
        ]);
    }
}
