<?php

/** 
 * Classe utilisé dans le cadre de la création de BS sous la forme de panier
 */
class BS
{

    private $nbArt;
 // nb articles stockés présents dans le BS en cours
    private $xml_array;
 // tableau contenant la structure XML a afficher
    private $data;
 // tableau contenant toutes les données des lignes d'un BS en cours
    private $entete;
 // tableau contenant toutes les données de l'entete du BS en cours
    /**
     * Constructeur
     */
    public function __construct()
    {}

    /**
     * Get and Set
     */
    
    /**
     * Fonction retournant le nombre d'article dans le BS en cours
     */
    public function &getNbArt()
    {
        $this->countArtInBS();
        return $this->nbArt;
    }

    /**
     * Fonction retournant le tableau $xml_array
     */
    public function &getXML_ARRAY()
    {
        return $this->xml_array;
    }

    public function &getData()
    {
        return $this->data;
    }

    /*
     * Section fonctions générales
     */
    
    /**
     * Fonction permettant de supprimer toutes les lignes et entetes de BS d'un utilisateur suite à un changement de site de stock
     * dans sa session ou à l'enregistrement du BS
     */
    public static function reinitBS()
    {
        BS::resetBsRecap('entete'); // suppression de l'entete du BS en cours de l'user
        BS::resetBsRecap('ligne'); // suppression des lignes de BS en cours de l'user
    }

    /**
     * Fonction enregistrant une ligne dans la table bs recap
     * Elle teste automatiquement si il s'agit d'un insert ou d'un update
     * 
     * @return boolean
     */
    public static function recordLigne($CODE_ART, $DESIGN, $QTE_SORTIE)
    {
        
        // Dans le cas de la mise à jour d'une quantité, on initialise uniquement la quantité
        if (BS::isLigneIntoBsRecap($CODE_ART))
            return BS::updateQTELigneIntoBsRecap($CODE_ART, $QTE_SORTIE);
        // Dans le cas d'une nouvelle ligne on initialise en plus les axes d'inputations en prenant ceux de l'entete
        else {
            $result = BS::selectBsRecapEntete();
            return BS::insertLigneIntoBsRecap($CODE_ART, $DESIGN, $QTE_SORTIE, $result['SI'], $result['CG'], $result['SCA'], $result['CDC']);
        }
    }

    /**
     * Fonction enregistrant une entete dans
     */
    public static function recordEntete($type, $value)
    {
        $r = BS::selectBsRecapEntete();
        
        if (is_array($r))
            BS::updateBsEntete($type, $value);
        else
            BS::insertIntoBsRecapEntete($type, $value);
    }

    /**
     * Fonction initialisation les axes d'imputation de l'entete d'un nouveau BS
     * à partir des valeurs des axes d'imputation de la session de l'utilisateur
     */
    public static function initInputEntete()
    {
        $result = BS::selectBsRecapEntete();
        if (! is_array($result)) {
            BS::insertIntoBsRecapEntete('CDC', $_SESSION['Session_CDC']);
            BS::updateBsEntete('SCA', $_SESSION['Session_SCA']);
            BS::updateBsEntete('SI', $_SESSION['SectionImputation_Session_user']);
        }
    }

    /**
     * Fonction retournant toutes les informations nécessaire à l'affichage du BS en cours de l'utilisateur
     */
    public function getAllInfoOnBS()
    {
        if ($this->data = SqlBs::rqSelectBsRecapLigne()->TrouveTous())
            // Initialisation des données des lignes de BS
            foreach ($this->data as &$r) { // On complète avec des informations supplémentaires provenant de OXASQLDB
                if ($complement = SqlBs::rqGetInfoCompl($r['CODE_ART'], $_SESSION['SiteStock'])->Trouve1()) {
                    $r['VAL_LOCAL'] = $complement['VAL_LOCAL'];
                    $r['UNITE_STK'] = $complement['UNITE_STK'];
                    $r['DEVISE'] = $complement['DEVISE'];
                    $r['QTE_PHYS'] = $complement['QTE_PHYS'];
                }
            }
        
        // Initialisation des données de l'entête de BS
        $this->entete = SqlBs::rqSelectBsRecapEntete()->Trouve1();
    }

    /**
     * Fonction créant la structure XML permettant l'affichage du détail du BS
     */
    public function buildXMLforDetailBS()
    {
        // Objet permettant de gérer la visibilité de l'axe d'imputation CG
        $axeImputation = new Imputation();
        
        // récupération des data du BS en cours
        $this->getAllInfoOnBS();
        
        // // Partie detail ligne
        
        // Montant total du BS
        $total = 0;
        
        for ($i = 0; $i < count($this->data); $i ++) {
            
            // Montant d'une ligne : qté * prix
            $montant_ligne = ($this->data[$i]['QTE_SORTIE'] * $this->data[$i]['VAL_LOCAL']);
            
            $indice_ligne = $i + 1;
            
            $this->xml_array['LIGNE'][] = array( // On utilisera un index pour identifier les lignes
                '!INDEX' => $indice_ligne,
                
                // Partie utilisée pour Detail BS et Imputation
                '!CODE' => $this->data[$i]['CODE'],
                '!CODE_ART' => $this->data[$i]['CODE_ART'],
                
                // Nom du champ caché à partir duquel on récupère le code article
                '!CHAMP_ART' => 'brw_BrwEtat_REF_ART_' . $indice_ligne,
                '!SITE' => $this->data[$i]['SITE'],
                '!DESIGN' => $this->data[$i]['DESIGN'],
                '!QTE_SORTIE' => $this->data[$i]['QTE_SORTIE'],
                
                // Nom du champ QTE SORTIE
                '!QTE_SORTIE_NAME' => "QTE_SORTIE_" . $indice_ligne,
                
                '!VAL_LOCAL' => $this->data[$i]['VAL_LOCAL'],
                '!UNITE_STK' => $this->data[$i]['UNITE_STK'],
                // On calcule ici le montant par ligne : quantité + prix article
                '!MONTANT_LIG' => $montant_ligne,
                '!DEVISE' => $this->data[$i]['DEVISE'],
                
                // Nom du champ QTE_PHYS
                '!CHAMP_QTE_PHYS' => "QTE_PHYS_" . $indice_ligne,
                '!QTE_PHYS' => $this->data[$i]['QTE_PHYS'],
                
                // Ajout d'un controle sur la quantité
                '!CONTROLE_QTE' => "Traite('BS_encours.php?ORIGINE=RECAP',this);",
                
                // Partie utilisée uniquement pour les imputations
                '!SI_VALUE' => $this->data[$i]['SI'],
                '!SI_NAME' => "SI_" . $indice_ligne,
                '!SI_ONCHANGE' => "Traite('BS_recap.php?action=changeSI',document.form_BS_recap.SI_" . $indice_ligne . ");",
                '!SI_BROWSE' => "javascript:Traite('BS_recap.php?action=popup',document.form_BS_recap.SI_" . $indice_ligne . ");",
                
                '!CG_VALUE' => $this->data[$i]['CG'],
                '!CG_NAME' => "CG_" . $indice_ligne,
                '!CG_ONCHANGE' => "Traite('BS_recap.php?action=changeCG',document.form_BS_recap.CG_" . $indice_ligne . ");",
                '!CG_BROWSE' => "javascript:Traite('BS_recap.php?action=popup',document.form_BS_recap.CG_" . $indice_ligne . ");",
                '!CG_VISIBLE' => $axeImputation->existCGforSI($_SESSION['Session_SocUsr'], $this->data[$i]['SI']),
                
                '!SCA_VALUE' => $this->data[$i]['SCA'],
                '!SCA_NAME' => "SCA_" . $indice_ligne,
                '!SCA_ONCHANGE' => "Traite('BS_recap.php?action=changeSCA',document.form_BS_recap.SCA_" . $indice_ligne . ");}",
                '!SCA_BROWSE' => "javascript:Traite('BS_recap.php?action=popup',document.form_BS_recap.SCA_" . $indice_ligne . ");",
                
                '!CDC_VALUE' => $this->data[$i]['CDC'],
                '!CDC_NAME' => "CDC_" . $indice_ligne,
                '!CDC_ONCHANGE' => "Traite('BS_recap.php?action=changeCDC',document.form_BS_recap.CDC_" . $indice_ligne . ");",
                '!CDC_BROWSE' => "javascript:Traite('BS_recap.php?action=popup',document.form_BS_recap.CDC_" . $indice_ligne . ");"
            );
            
            $total += $montant_ligne; // calcul du total
            $this->xml_array['PIED']['!DEVISE'] = $this->data[$i]['DEVISE']; // Devise affichée pour le total
        }
        
        // // Partie entete
        $this->xml_array['ENTETE']['!SITE'] = $_SESSION['SiteStock'];
        $info_site = & SqlSiteStock::rqGetSiteStockLabel($_SESSION['SiteStock'])->Trouve1();
        
        $this->xml_array['ENTETE']['!lib_site'] = $info_site['DESIGN'];
        
        $this->xml_array['ENTETE']['DEST'] = array(
            '!VALUE' => $this->entete['DEST'],
            '!ONCHANGE' => "Traite('BS_recap.php?action=changeDest',document.form_BS_recap.DEST_0);"
        );
        $this->xml_array['ENTETE']['ORIGINE'] = array(
            '!VALUE' => $this->entete['ORIGINE'],
            '!ONCHANGE' => "Traite('BS_recap.php?action=changeOrigine',document.form_BS_recap.ORIGINE_0);"
        );
        $this->xml_array['ENTETE']['SI'] = array(
            '!VALUE' => $this->entete['SI'],
            '!ONCHANGE' => "Traite('BS_recap.php?action=changeSI',document.form_BS_recap.SI_0);"
        );
        
        $this->xml_array['ENTETE']['CG'] = array(
            '!VALUE' => $this->entete['CG'],
            '!ONCHANGE' => "Traite('BS_recap.php?action=changeCG',document.form_BS_recap.CG_0);",
            '!VISIBLE' => $axeImputation->existCGforSI($_SESSION['Session_SocUsr'], $this->entete['SI'])
        );
        $this->xml_array['ENTETE']['SCA'] = array(
            '!VALUE' => $this->entete['SCA'], // $_SESSION['Session_SCA']
            '!ONCHANGE' => "Traite('BS_recap.php?action=changeSCA',document.form_BS_recap.SCA_0);"
        );
        $this->xml_array['ENTETE']['CDC'] = array(
            '!VALUE' => $this->entete['CDC'], // //$_SESSION['Session_CDC']
            '!ONCHANGE' => "Traite('BS_recap.php?action=changeCDC',document.form_BS_recap.CDC_0);"
        );
        
        // // Partie pied
        $this->xml_array['PIED']['!TOTAL'] = FormatageData::formatMontant($total, 2, ' ');
    }

    /*
     * Section : soumission du BS avec appel du WSDL
     *
     */
    public function recordBS($confirm)
    {
        // Récupération des information relatives au BS en cours pour l'entete et toutes les lignes
        $this->getAllInfoOnBS();
        
        // Pour la gestion des CG on a besoin de connaitre le numero du lot
        $lot = SqlCg::getNumLot()->Trouve1();
        
        // Depuis la 942 recherche du
        $ligne = '';
        for ($i = 0; $i < count($this->data); $i ++) {
            
            if (is_array($lot)) { // Si le numéro de lot existe
                
                if (Param::IsSISecto())
                    $reqSql = SqlCg::getUniqCGSecto($_SESSION['Session_SocUsr'], $this->data[$i]['SI'], $lot['NUM_LOT'], $this->data[$i]['CG']);
                else
                    $reqSql = SqlCg::getUniqCG($this->data[$i]['SI'], $lot['NUM_LOT'], $this->data[$i]['CG']);
                
                $record_cg_code = $reqSql->Trouve1();
            } else {
                $record_cg_code['CODE_AFF'] = '';
                $record_cg_code['CODE_GES'] = '';
                $record_cg_code['LIB_GES'] = '';
            }
            
            $ligne .= '<Ligne>';
            $ligne .= "<CodeArticle>{$this->data[$i]['CODE_ART']}</CodeArticle>";
            $ligne .= "<QteDemande>{$this->data[$i]['QTE_SORTIE']}</QteDemande>";
            $ligne .= "<SectImp>{$this->data[$i]['SI']}</SectImp>";
            
            $ligne .= "<CodeGest>{$record_cg_code['CODE_AFF']}</CodeGest>";
            $ligne .= "<IdCodeGest>{$record_cg_code['CODE_GES']}</IdCodeGest>";
            $ligne .= "<LibCodeGest>{$record_cg_code['LIB_GES']}</LibCodeGest>";
            
            $ligne .= "<CodeComp>{$this->data[$i]['CDC']}</CodeComp>";
            $ligne .= "<SCptAna>{$this->data[$i]['SCA']}</SCptAna>";
            $ligne .= '</Ligne>';
        }
        
        $envoi = "<BSIn LngUtilisation='{$_SESSION['Session_Langue']}'>";
        $envoi .= "<Utilisateur>{$_SESSION['Session_Login']}</Utilisateur>";
        $envoi .= "<Site>{$_SESSION['SiteStock']}</Site>";
        $envoi .= "<Societe>{$_SESSION['Session_SocUsr']}</Societe>";
        $envoi .= "<Destinataire>{$this->entete['DEST']}</Destinataire>";
        $envoi .= "<Origine>{$this->entete['ORIGINE']}</Origine>";
        $envoi .= "<Confirm>$confirm</Confirm>";
        $envoi .= $ligne;
        $envoi .= '</BSIn>';
        
        return Wsdl::wsdlCallGen('Oxaproc_BS.wsdl', 'OXAPRC_ENREGBS', $envoi);
    }

    /*
     * Section : fonction SQL
     */
    
    /**
     * Fonction insérant une ligne dans la table recap BS
     * 
     * @param $CODE :
     *            Login de l'utilisateur connecté
     *            Partie articles =>
     * @param $CODE_ART :
     *            Code de l'article stocké
     * @param $SITE :
     *            Code du site de stockage de l'utilisateur
     * @param $DESIGN :
     *            Désignation courte de l'article
     * @param $QTE_SORTIE :
     *            Quantité sortie pour l'article donné
     *            Partie imputation =>
     * @param $SI :
     *            Section d'imputation
     * @param $CG :
     *            Code gestion
     * @param $SCA :
     *            Sous compte d'analyse
     * @param $CDC :
     *            Code complémentaire
     */
    public static function insertLigneIntoBsRecap($CODE_ART, $DESIGN, $QTE_SORTIE, $SI = '', $CG = '', $SCA = '', $CDC = '')
    {
        return SqlBs::rqInsertLigneIntoBsRecap($CODE_ART, $DESIGN, $QTE_SORTIE, $SI, $CG, $SCA, $CDC)->ExecuteSql();
    }

    /**
     * Fonction de mise à jour de la quantité sorite pour une ligne de BS
     * et ceci pour un utilisateur, un site et un code article donnés.
     * 
     * @param $CODE_ART :
     *            Code de l'article stocké
     * @param $QTE_SORTIE :
     *            Quantité sortie pour l'article donné
     */
    public static function updateQTELigneIntoBsRecap($CODE_ART, $QTE_SORTIE)
    {
        return SqlBs::rqUpdateQTELigneIntoBsRecap($CODE_ART, $QTE_SORTIE)->ExecuteSql();
    }

    /**
     * Fonction permettant de mettre à jour un axe d'imputation sur une ligne de BS
     * 
     * @param $TYPE_IMPUTATION :
     *            Type d'imputation SI, CDC, SCA ou CG => le nom de la colonne à updater est dynamique
     * @param $VALUE :
     *            Valeur de l'imputation
     * @param $CODE_ART :
     *            Code de l'article stocké
     */
    public static function updateImputLigneIntoBsRecap($TYPE_IMPUTATION, $VALUE, $CODE_ART)
    {
        return SqlBs::rqUpdateImpuLigneIntoBsRecap($TYPE_IMPUTATION, $VALUE, $CODE_ART)->ExecuteSql();
    }

    /**
     * Fonction permettant de mettre à jour un axe d'imputation pour toutes les lignes des BS
     * 
     * @param $TYPE_IMPUTATION :
     *            Type d'imputation SI, CDC, SCA ou CG => le nom de la colonne à updater est dynamique
     * @param $VALUE :
     *            Valeur de l'imputation
     */
    public static function updateImputForAllLigneIntoBsRecap($TYPE_IMPUTATION, $VALUE)
    {
        return SqlBs::rqUpdateImpuForAllLigneIntoBsRecap($TYPE_IMPUTATION, $VALUE)->ExecuteSql();
    }

    /**
     * Fonction retournant la requete permettant d'inserer une ligne dans oxa_bs_recap_entete
     * 
     * @param $champ :
     *            champ
     * @param $value :
     *            valeur
     */
    public static function insertIntoBsRecapEntete($champ, $value)
    {
        return SqlBs::rqInsertIntoBsRecapEntete($champ, $value)->ExecuteSql();
    }

    /**
     * Fonction updatant une ligne dans oxa_bs_recap_entete
     * 
     * @param $DEST :
     *            Destinataire des articles sortis du stock
     * @param $ORIGINE :
     *            Origine des articles stockés
     */
    public static function updateIntoBsRecapEntete($DEST, $ORIGINE)
    {
        return SqlBs::rqUpdateIntoBsRecapEntete($DEST, $ORIGINE)->ExecuteSql();
    }

    /**
     * Fonction permettant de supprimer l'entete d'un BS dans oxa_bs_recap_entete
     */
    public static function deleteIntoBsRecapEntete()
    {
        return SqlBs::rqDeleteIntoBsRecapEntete()->ExecuteSql();
    }

    /**
     * Fonction supprimant une ligne dans oxa_bs_recap_ligne dont la quantite est 0
     * 
     * @param $CODE_ART :
     *            Code article
     */
    public static function deleteLigneIntoBsRecapLigne($CODE_ART)
    {
        return SqlBs::rqDeleteLigneIntoBsRecapLigne($CODE_ART)->ExecuteSql();
    }

    /**
     * Fonction retournant la requete permettant de supprimer les lignes et entete de BS
     * 
     * @param $table :
     *            table à reintialiser => ligne ou entete
     */
    public static function resetBsRecap($table)
    {
        return SqlBs::rqResetBsRecap($table)->ExecuteSql();
    }

    /**
     * Fonction permettant de savoir si une ligne existe déjà dans la table bc_recap pour
     * un user, un code article et un site donné
     * 
     * @param $CODE :
     *            code utilisateur
     * @param $CODE_ART :
     *            code article
     * @param $SITE :
     *            code du site de stockage
     * @return boolean : retourne vrai si un resultat est trouvé
     */
    public static function isLigneIntoBsRecap($CODE_ART)
    {
        $r = SqlBs::rqIsLigneIntoBsRecap($CODE_ART)->Trouve1();
        return is_array($r);
    }

    /**
     * Fonction permettant de retourner les informations relatives à une ligne dans le BS
     * 
     * @param $CODE_ART :
     *            Code de l'article recherché dans la table oxa_bs_recap_ligne
     */
    public static function &getInfoOnLigneBs($CODE_ART)
    {
        return SqlBs::rqIsLigneIntoBsRecap($CODE_ART)->Trouve1();
    }

    /**
     * Fonction permettant de compter le nombre d'article présents dans le BS en cours
     * 
     * @return : numeric => retourne le nombre d'article dans le BS en cours
     */
    function countArtInBS()
    {
        $r = SqlBs::rqSelectBsRecapLigne()->TrouveTous();
        $this->nbArt = count($r);
    }

    public static function &selectBsRecapEntete()
    {
        return SqlBs::rqSelectBsRecapEntete()->Trouve1();
    }

    public static function updateBsEntete($type, $value)
    {
        return SqlBs::rqUpdateImputBsRecapEntete($type, $value)->ExecuteSql();
    }

    public static function isDestExists($code_dest)
    {
        $result = SqlBs::rqGetDestinataire($code_dest, '', true)->Trouve1();
        return (is_array($result) && count($result) > 0);
    }
}