<?php
/**
 * DBFORM - 'action' - Surcharge gen.
 *
 * Ce script permet de définir la classe 'action'.
 *
 * @package openads
 * @version SVN : $Id$
 */

require_once "../gen/obj/action.class.php";

class action extends action_gen {

    // Handler d'un objet de classe dossier
    var $dossier;

    // Liste des regles de dates
    var $date_rules = array(
        'regle_delai',
        'regle_delai_incompletude',
        'regle_date_limite',
        'regle_date_notification_delai',
        'regle_date_complet',
        'regle_date_validite',
        'regle_date_decision',
        'regle_date_chantier',
        'regle_date_achevement',
        'regle_date_conformite',
        'regle_date_rejet',
        'regle_date_dernier_depot',
        'regle_date_limite_incompletude',
        'regle_date_cloture_instruction',
        'regle_date_premiere_visite',
        'regle_date_derniere_visite',
        'regle_date_contradictoire',
        'regle_date_retour_contradictoire',
        'regle_date_ait',
        'regle_date_transmission_parquet',
        'regle_date_affichage',
    );

    function setValF($val = array()) {
        parent::setValF($val);
        foreach ($this->date_rules as $key => $rule){
            $this->valF[$rule] = $this->f->formatage_regles($this->valF[$rule]);
        }
    }

    function setType(&$form, $maj) {
        parent::setType($form, $maj);
        
        if ($maj == 0 || $maj == 1) {
            $form->setType("regle_donnees_techniques1", "regle_donnees_techniques");
            $form->setType("regle_donnees_techniques2", "regle_donnees_techniques");
            $form->setType("regle_donnees_techniques3", "regle_donnees_techniques");
            $form->setType("regle_donnees_techniques4", "regle_donnees_techniques");
            $form->setType("regle_donnees_techniques5", "regle_donnees_techniques");
            $form->setType("cible_regle_donnees_techniques1", "nodisplay");
            $form->setType("cible_regle_donnees_techniques2", "nodisplay");
            $form->setType("cible_regle_donnees_techniques3", "nodisplay");
            $form->setType("cible_regle_donnees_techniques4", "nodisplay");
            $form->setType("cible_regle_donnees_techniques5", "nodisplay");
        }
        if ($maj == 2 || $maj == 3) {
            $form->setType("regle_donnees_techniques1", "regle_donnees_techniques_static");
            $form->setType("regle_donnees_techniques2", "regle_donnees_techniques_static");
            $form->setType("regle_donnees_techniques3", "regle_donnees_techniques_static");
            $form->setType("regle_donnees_techniques4", "regle_donnees_techniques_static");
            $form->setType("regle_donnees_techniques5", "regle_donnees_techniques_static");
            $form->setType("cible_regle_donnees_techniques1", "nodisplay");
            $form->setType("cible_regle_donnees_techniques2", "nodisplay");
            $form->setType("cible_regle_donnees_techniques3", "nodisplay");
            $form->setType("cible_regle_donnees_techniques4", "nodisplay");
            $form->setType("cible_regle_donnees_techniques5", "nodisplay");
        }
    }
    
    function setLib(&$form, $maj) {
        parent::setLib($form, $maj);
        $form->setLib('regle_etat',__('Règle état'));
        $form->setLib('regle_delai',__('Règle delai (DATE)'));
        $form->setLib('regle_accord_tacite',__('Règle accord tacite (UNIQUE)'));
        $form->setLib('regle_avis',__('Règle avis'));
        $form->setLib('regle_date_limite',__('Règle date limite (DATE)'));
        $form->setLib('regle_date_notification_delai',__('Règle date de délai de notification (DATE)'));
        $form->setLib('regle_date_complet',__('Règle date complet (DATE)'));
        $form->setLib('regle_date_validite',__('Règle date de validite (DATE)'));
        $form->setLib('regle_date_decision',__('Règle date de décision (DATE)'));
        $form->setLib('regle_date_chantier',__('Règle date de chantier (DATE)'));
        $form->setLib('regle_date_achevement',__("Règle date d'achevement (DATE)"));
        $form->setLib('regle_date_conformite',__('Règle date de conformite (DATE)'));
        $form->setLib('regle_date_rejet',__('Règle date rejet (DATE)'));
        $form->setLib('regle_date_dernier_depot',__('règle date de dernier dépot (DATE)'));
        $form->setLib('regle_date_limite_incompletude',__("Règle date limite d'incomplétude (DATE)"));
        $form->setLib('regle_delai_incompletude',__("Règle delai d'incomplétude (DATE)"));
        $form->setLib('regle_autorite_competente',__('Règle autorité compétente (UNIQUE)'));
        $form->setLib('regle_date_cloture_instruction',__("Règle date de clôture de l'instruction (DATE)"));
        $form->setLib('regle_date_premiere_visite',__("Règle date de première visite (DATE)"));
        $form->setLib('regle_date_derniere_visite',__("Règle date de dernière visite (DATE)"));
        $form->setLib('regle_date_contradictoire',__("Règle date de contradictoire (DATE)"));
        $form->setLib('regle_date_retour_contradictoire',__("Règle date de retour de contradictoire (DATE)"));
        $form->setLib('regle_date_ait',__("Règle date AIT (DATE)"));
        $form->setLib('regle_date_transmission_parquet',__("Règle date de transmission au Parquet (DATE)"));

        $form->setLib('regle_donnees_techniques1',__('Règle donnée techniques / CERFA n°1'));
        $form->setLib('regle_donnees_techniques2',__('Règle donnée techniques / CERFA n°2'));
        $form->setLib('regle_donnees_techniques3',__('Règle donnée techniques / CERFA n°3'));
        $form->setLib('regle_donnees_techniques4',__('Règle donnée techniques / CERFA n°4'));
        $form->setLib('regle_donnees_techniques5',__('Règle donnée techniques / CERFA n°5'));

        $form->setLib('cible_regle_donnees_techniques1',__('Champ cible de la règle donnée technique n°1'));
        $form->setLib('cible_regle_donnees_techniques2',__('Champ cible de la règle donnée technique n°2'));
        $form->setLib('cible_regle_donnees_techniques3',__('Champ cible de la règle donnée technique n°3'));
        $form->setLib('cible_regle_donnees_techniques4',__('Champ cible de la règle donnée technique n°4'));
        $form->setLib('cible_regle_donnees_techniques5',__('Champ cible de la règle donnée technique n°5'));

        $form->setLib('regle_dossier_instruction_type',__("Règle type de dossier d'instruction (NUMERIQUE)"));
        $form->setLib('regle_date_affichage',__("Règle date d'affichage (DATE)"));
        $form->setLib('regle_pec_metier',__("Règle prise en compte métier (UNIQUE)"));
        $form->setLib('regle_a_qualifier',__("Règle à qualifier (BOOLEAN)"));
        $form->setLib('regle_incompletude',__("Règle incomplétude (BOOLEAN)"));
        $form->setLib('regle_incomplet_notifie',__("Règle incomplétude notifiée (BOOLEAN)"));
        $form->setLib('regle_etat_pendant_incompletude',__("Règle état du dossier pendant l'incomplétude (UNIQUE)"));
        $form->setLib('regle_evenement_suivant_tacite_incompletude',__("Règle événement suivant tacite de l'événement s'applique lors de
         l'incomplétude notifiée (BOOLEAN)"));
    }

    /**
     * @return void
     */
    function verifier($val = array(), &$dnu1 = null, $dnu2 = null) {
        parent::verifier($val);
        //
        $list_column = array();
        // Mot-clés à rechercher
        $search_field = "regle_";
        // Pour chaque champs du formulaire
        foreach ($this->champs as $champ) {
            // Si le mot-clés est présent dans l'identifiant du champ
            if (strpos($champ, $search_field) !== false) {
                // Ajoute le champ à la liste
                $list_column[] = $champ;
            }
        }

        // 
        $list_fields = array();
        // Pour chaque colonne
        foreach ($list_column as $value) {
            
            // Vérifie que le champs existe dans le formulaire et qu'il n'est 
            // pas vide
            if (isset($this->valF[$value]) 
                && $this->valF[$value] != ''
                && $this->valF[$value] != null) {
                //
                $list_fields[$value] = $this->valF[$value];
            }
        }

        // Si le tableau contenant les champs à tester n'est pas vide
        if (count($list_fields) > 0) {

            //
            foreach ($list_fields as $key => $value) {

                // Vérification de la possibilité des champs de la table dossier
                // correspondants aux règles d'être mis à null
                if($this->valF[$key] == "NULL" || $this->valF[$key] == "null") {
                    //
                    if($this->fieldCanBeNull(substr($key, 6)) === false) {
                        // Affiche l'erreur
                        $this->correct=false;
                        $error_message = __("Le champ %s des dossiers ne peut etre mis a NULL.");
                        $this->addToMessage(sprintf($error_message, "<b>".__(substr($key, 6))."</b>"));

                    }
                }

                // Vérifie que la règle est valide
                $this->rule_is_valid($value, $key);
            }
        }
        
        // Vérification de la présence du couple cible règle pour les DT
        for ($i = 1; $i < 6; $i++) { 
            if ($this->valF["regle_donnees_techniques".$i] === null XOR
                $this->valF["cible_regle_donnees_techniques".$i] === null) {
                
                $this->correct=false;
                $this->addToMessage(
                    sprintf(
                        __("Le champ <b>Règle données techniques / CERFA</b> %s ne peut comporter un champ rempli et un champ vide"),
                        $i
                    )
                );
            }
        }

        
    }

    /**
     * Vérification que les champs ciblés par les règles contenant NULL peuvent
     * l'être.
     * @param  string $field champ impacté par la règle
     * @return boolean       peut être null = true else false
     */
    function fieldCanBeNull($field) {
        // Instantiation de la classe dossier si pas déjà fait
        if(!isset($this->dossier) || empty($this->dossier)) {
            $this->dossier = $this->f->get_inst__om_dbform(array(
                "obj" => "dossier",
                "idx" => "]",
            ));
        }
        // Si le champ passé en param est dans la liste des champs obligatoires
        // de la table dossier return false
        if(array_search($field, $this->dossier->required_field) !== false) {
            return false;
        }
        return true;
    }

    /**
     * Vérifie la validité d'une règle d'action.
     * 
     * @param string $rule      Règle d'action.
     * @param string $rule_name Nom de la règle.
     */
    function rule_is_valid($rule, $rule_name) {    
        // Liste des régles de type 'champ de BDD'
        $cible_donnees_techniques_rules  = array(
            'cible_regle_donnees_techniques1',
            'cible_regle_donnees_techniques2',
            'cible_regle_donnees_techniques3',
            'cible_regle_donnees_techniques4',
            'cible_regle_donnees_techniques5',
        );

        // Liste des régles a Opérateur unique
        $unique_operand_rules = array(
            'regle_autorite_competente',
            'regle_etat',
            'regle_accord_tacite',
            'regle_pec_metier',
            'regle_etat_pendant_incompletude',
        );

        $common_rules = array(
            'regle_etat',
            'regle_accord_tacite',
            'regle_avis',
            'regle_autorite_competente',
            'regle_donnees_techniques1',
            'regle_donnees_techniques2',
            'regle_donnees_techniques3',
            'regle_donnees_techniques4',
            'regle_donnees_techniques5',
            'regle_pec_metier',
            'regle_etat_pendant_incompletude',
        );

        $boolean_rules = array_merge(
            $common_rules,
            array(
                'regle_a_qualifier',
                'regle_incompletude',
                'regle_incomplet_notifie',
                'regle_evenement_suivant_tacite_incompletude',
            )
        );

        $numeric_rules = array_merge(
            $common_rules,
            array(
                'regle_dossier_instruction_type',
            )
        );

        // Si la règle à vérifier concerne les données techniques, il faut
        // récupérer le type du champ des données techniques sélectionné.
        if (in_array($rule_name, $cible_donnees_techniques_rules, true) === true) {
            // Récupération du type de champ de la cible de la règle
            $type = $this->f->get_type_from_db(
                'donnees_techniques',
                $this->valF[$rule_name]
            );
            if (isset($type[$this->valF[$rule_name]]) === false
                || $type[$this->valF[$rule_name]] !== 'text') {
                $this->correct=false;
                $this->addToMessage(
                    sprintf(
                        __('Le champ %s ne peut être que de type texte.'),
                        '<b>'.__($rule_name).'</b>'
                    )
                );
            }
        }

        // Gestion du null
        $is_null_result = $this->f->rule_null_is_valid($rule, $rule_name);
        if ( is_array($is_null_result)  === true ){
            if ( $is_null_result[0] === false ){
                // Affiche l'erreur
                $this->correct=$is_null_result[0];
                $this->addToMessage($is_null_result[1]);
            }
            return null;
        }

        // Supprime tous les espaces de la chaîne de caractère
        $rule = str_replace(' ', '', $rule);
        // Coupe la chaîne au niveau de l'opérateur
        $operands = explode('+', $rule);
        // Nombre d'opérande
        $nb_operands = count($operands);

        // Si c'est une règle spécifique unique
        if (in_array($rule_name, $unique_operand_rules, true) === true) {
            // S'il y à plus d'une opérande
            if ($nb_operands > 1) {
                // Message d'erreur
                $this->correct=false;
                $this->addToMessage(
                    sprintf(__("Le champ %s ne peut pas avoir plus d'un opérande."),
                        '<b>'.__($rule_name).'</b>')
                );
                return null;
            }
        }

        // Pour chaque opérande
        foreach ($operands as $key => $operand) {
            // si on as une chaine +xmois ou +xjour(s) pour une regle de type date
            if (in_array($rule_name, $this->date_rules, true) === true) {
                $is_date_result = $this->f->rule_date_is_valid($operand, $rule_name);
                if ( is_array($is_date_result) === true ){
                    if ( $is_date_result[0] === false ){
                        // Affiche l'erreur
                        $this->correct=$is_date_result[0];
                        $this->addToMessage($is_date_result[1]);
                        return null;
                    }
                    // Supprime l'opérande
                    unset($operands[$key]);
                }
            }

            // Supprime les numériques pour les regles acceptant le numérique
            if (
                in_array($rule_name, $numeric_rules, true) === true
                && is_numeric($operand)
            ) {
                // Supprime l'opérande
                unset($operands[$key]);
            }

            // Supprime également les booléens pour les regles acceptant les booleans
            if (
                in_array($rule_name, $boolean_rules, true) === true
                && ($operand == 'f' || $operand == 't'
                || $operand == 'false' || $operand == 'true')
            ) {
                // Supprime l'opérande
                unset($operands[$key]);
            }
        }

        $rules = array(
            'regle_donnees_techniques1',
            'regle_donnees_techniques2',
            'regle_donnees_techniques3',
            'regle_donnees_techniques4',
            'regle_donnees_techniques5',
            'cible_regle_donnees_techniques1',
            'cible_regle_donnees_techniques2',
            'cible_regle_donnees_techniques3',
            'cible_regle_donnees_techniques4',
            'cible_regle_donnees_techniques5',
        );

        if (in_array($rule_name, $rules, true) === true) {

            // Vérification de l'existance des champs de règle dans les données
            // technique
            $check_field_dt_exist = $this->f->check_field_exist(
                $operands,
                'donnees_techniques'
            );

            $check_field_instr_exist = $this->f->check_field_exist(
                $operands,
                'instruction'
            );

            if ($check_field_dt_exist !== true and
                $check_field_instr_exist !== true) {
                    
                $check_field_exist = array_intersect(
                    $check_field_dt_exist,
                    $check_field_instr_exist
                );
                if (count($check_field_exist) === 0) {
                    $check_field_exist = true;
                }
            } else {
                $check_field_exist = true;
            }

        } else {
            // Vérifie les champs utilisés pour la règle
            $check_field_exist = $this->f->check_field_exist($operands, 'instruction');
        }

        if ($check_field_exist !== true) {

            // Liste des champs en erreur
            $string_error_fields = implode(', ', $check_field_exist);

            // Message d'erreur
            $error_msg = __("Le champ %s n'est pas utilisable pour le champ %s.");
            // Si plusieurs champs sont en erreur
            if (count($check_field_exist) > 1) {
                $error_msg = __("Les champs %s ne sont pas utilisables pour le champ %s.");
            }

            // Affiche l'erreur
            $this->correct=false;
            $this->addToMessage(
                sprintf(
                    $error_msg,
                    '<b>'.$string_error_fields.'</b>',
                    '<b>'.__($rule_name).'</b>'
                )
            );
        }
    }

    /**
     * 
     */
    function formSpecificContent($maj) {
        /**
         * Affichage des champs qu'il est possible d'utiliser dans les règles
         */
        // Archives du dossier
        echo '<h4>'.__("Valeurs du dossier avant l'evenement").'</h4>';
        echo '[archive_etat] [archive_delai] [archive_accord_tacite] 
        [archive_avis]';
        echo '<br/>';
        echo '[archive_date_dernier_depot] [archive_date_complet] 
        [archive_date_rejet] [archive_date_limite] 
        [archive_date_notification_delai] [archive_date_decision] 
        [archive_date_validite] [archive_date_achevement] 
        [archive_date_conformite] [archive_date_chantier] 
        [archive_etat_pendant_incompletude] [archive_date_limite_incompletude]
        [archive_delai_incompletude] [archive_autorite_competente] 
        [archive_date_cloture_instruction] [archive_date_premiere_visite]
        [archive_date_derniere_visite] [archive_date_contradictoire]
        [archive_date_retour_contradictoire] [archive_date_ait]
        [archive_date_transmission_parquet]
        [archive_incompletude] [archive_incomplet_notifie]
        [duree_validite][date_depot][date_depot_mairie]';
        // Champs de l'événement
        echo '<h4>'.__("Parametres de l'evenement").'</h4>';
        echo '[etat] [delai] [accord_tacite] [avis_decision] 
        [delai_notification] [date_evenement] [autorite_competente] [pec_metier]
        [complement_om_html] [complement2_om_html] [complement3_om_html]
        [complement4_om_html]';
        // Champs récupérés depuis l'événement d'instruction principal
        echo '<h4>'.__("Valeurs de l'evenement d'instruction principal").'</h4>';
        echo '[date_envoi_signature] [date_retour_signature] [date_envoi_rar] [date_retour_rar] [date_envoi_rar] [date_retour_rar] [date_envoi_controle_legalite] [date_retour_controle_legalite]';
        // Champs du type détaillé du dossier d'autorisation
        echo '<h4>'.__("Parametres du type detaille du dossier d'autorisation")
            .'</h4>';
        echo '[duree_validite_parametrage]';
        // Champs du type détaillé du dossier d'autorisation
        echo '<h4>'.__('Valeurs des données techniques')
            .'</h4>';
        echo '[ctx_nature_travaux_infra_om_html] [ctx_article_non_resp_om_html]';
        echo '<h4>'.__('Suppression de la valeur').'</h4>';
        echo '[null]';
        echo '<h4>'.__('Valeurs pour les booléens').'</h4>';
        echo '[f] ou [false] [t] ou [true]';
    }

}


