commit 9e9b6f96a195d15e6e013bed8a9bd267d4505ecd Author: jps Date: Thu Dec 18 09:44:42 2025 +0100 First commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..381f741 --- /dev/null +++ b/README.md @@ -0,0 +1,40 @@ +# ESI Crédit Direct + +Plugin WordPress pour la gestion du simulateur de crédit. + +## Mode Debug + +Le plugin inclut un mode debug qui permet d'utiliser les templates de développement (newSteps) au lieu des templates standards. + +### Activation du mode debug + +Pour activer le mode debug, modifiez le fichier `app/config.php` et changez la valeur de `_CRED_DEBUG_MODE_` à `true` : + +```php +/** + * Configuration du mode debug + * + * Mettre à true pour activer le mode debug et utiliser les templates de newSteps + * Mettre à false pour utiliser les templates standards + */ +define('_CRED_DEBUG_MODE_', true); +``` + +### Fonctionnement + +Lorsque le mode debug est activé, le plugin cherchera d'abord les templates dans le dossier `templates/front/newSteps/` au lieu du dossier `templates/front/`. Si un template n'existe pas dans le dossier newSteps, le plugin utilisera le template standard. + +### Utilisation dans le code + +Pour utiliser cette fonctionnalité dans votre code, utilisez la méthode statique `CRED::getTemplatePath()` : + +```php +$template_path = CRED::getTemplatePath('/templates/front/credit-step2-a.php'); +include(WP_PLUGIN_DIR . '/ESI_creditDirect' . $template_path); +``` + +Cette méthode retournera le chemin du template approprié en fonction du mode debug. + +## Autres fonctionnalités + +[À compléter avec d'autres informations sur le plugin] \ No newline at end of file diff --git a/actions/actions.php b/actions/actions.php new file mode 100644 index 0000000..6526c39 --- /dev/null +++ b/actions/actions.php @@ -0,0 +1,16 @@ +send_reminder_email(); + + } +} \ No newline at end of file diff --git a/actions/actions_autoloader.php b/actions/actions_autoloader.php new file mode 100644 index 0000000..9e7f9f1 --- /dev/null +++ b/actions/actions_autoloader.php @@ -0,0 +1,17 @@ +init(); + + + + + + diff --git a/app/config.php b/app/config.php new file mode 100644 index 0000000..335026d --- /dev/null +++ b/app/config.php @@ -0,0 +1,36 @@ +ID; +if($idUser == 1) { + echo '
';
+    print_r($_GET);
+    echo '
'; + die(); +} */ + +//try to load the model +$post = $_POST; +$one_step_form_send = false; +$one_step_credits = ['am','amr','cied','frais_notaire','cdp']; + + + +$model = new CRED_credit_step1(); + +if(isset($_POST['one_step_form'])) + $one_step_form_send = true; + +//exemple credit : 8d0f45319ba2ebcfc708a7e6a19922c6a478b655 + +if(!$one_step_form_send && !isset($_GET['credit-direct-token'])) { + $token = $model->save_step_0($post); +} else if(isset($_POST['credit_token'])) { + $token = $_POST['credit_token']; +} else if(isset($_GET['credit-direct-token'])) { + $token = $_GET['credit-direct-token']; +} else { + wp_redirect(home_url()); +} + + +$currentCredit = $model->getCredit($token); + +$exemple_info = $model->get_exemples_infos($currentCredit->type_credit); + +if(!empty($exemple_info)) { + $currentCredit->exemple_info = $exemple_info; +} + +if (!is_object($currentCredit)) { + wp_redirect(home_url()); +} + +/* echo '
';
+print_r($_POST);
+echo '
'; */ +/* die(); */ + +// Débogage +/* error_log('POST one_step_form: ' . (isset($_POST['one_step_form']) ? $_POST['one_step_form'] : 'non défini')); +error_log('one_step_credits: ' . print_r($one_step_credits, true)); */ + +if (file_exists(WP_PLUGIN_DIR . '/ESI_creditDirect/app/models/credit-step1.php') || file_exists(WP_PLUGIN_DIR . '/ESI_creditDirect/app/models/credit-one-step.php')) { + + + + $in_one_step = false; + $civilStatus = $model->getCivilStatus(); + $works = $model->getWorks(); + $existingCreditTypes = $model->getExistingCreditTypes(); + $contractTypes = $model->getContractTypes(); + + + + /* echo '
';
+    print_r($currentCredit);
+    echo '
'; */ + + if(in_array($currentCredit->type_credit, $one_step_credits)) + $in_one_step = true; + + + if($one_step_form_send) { + $model->save_one_step($post); + + /* echo '
';
+        print_r($_FILES);
+        echo '
'; */ + } + + //try to load the view + if (file_exists(WP_PLUGIN_DIR . '/ESI_creditDirect/templates/front/credit-step1.php')) { + + $agencies = $model->getAgencies(); + $map_credit_type = $model->getCreditTypes(); + $mapHouseCreditTypes = $model->getHouseCreditTypes(); + /*re-hydrate current credit*/ + $currentCredit = $model->getCredit($token); + $message = null; + + $type_credit_selected = ''; + + if(isset($currentCredit->sel_credit) && !empty($currentCredit->sel_credit)) { + $type_credit_selected = $currentCredit->sel_credit; + } + + if(isset($_POST['type_credit_selected']) && !empty($_POST['type_credit_selected']) || isset($_POST['sub_loan_type']) && !empty($_POST['sub_loan_type'])) + $type_credit_selected = isset($_POST['sub_loan_type']) ? $_POST['sub_loan_type'] : $_POST['type_credit_selected']; + + + $creditOptionsLabels = !empty($type_credit_selected) ? $model->getCreditLabel($type_credit_selected) : $map_credit_type[$currentCredit->type_credit]; + + //save the credit options labels in a cookie for 2 months + /* $model->save_step($currentCredit); */ + + $attachments = []; + $upload_errors = []; + /* + // Exemple d'utilisation de la fonction handleUploads + $allowed_types = [ + 'application/pdf', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', // docx + 'application/msword', // doc + 'image/jpeg', + 'image/png', + 'image/gif', + 'image/bmp', + 'image/webp' + ]; + $max_size = 2 * 1024 * 1024; // 2 Mo + $result = $model->handleUploads($_FILES, $allowed_types, $max_size, $token); + $attachments = $result['files']; + $upload_errors = $result['errors']; + $html_links = $result['html_links']; + */ + if(isset($_FILES)) { + if ($one_step_form_send) { // 4 = no file uploaded + $allowed_types = [ + 'application/pdf', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', // docx + 'application/msword', // doc + 'image/jpeg', + 'image/png', + 'image/gif', + 'image/bmp', + 'image/webp' + ]; + + //remove all the empty file from $_FILE + foreach($_FILES as $key => $value) { + if($value['error'] === 4) { + unset($_FILES[$key]); + } + } + + $max_size = 4 * 1024 * 1024; // 4 Mo + $result = $model->handleUploads($_FILES, $allowed_types, $max_size, $token); + + /* echo '
';
+                print_r($result);
+                echo '
'; + die(); */ + + $attachments = $result['files']; + $upload_errors = $result['errors']; + } + } + + $borrower = $model->getBorrower($currentCredit); + + /* echo '
';
+        print_r($borrower);
+        echo '
'; + die(); */ + + if($one_step_form_send) { + if (file_exists(WP_PLUGIN_DIR . '/ESI_creditDirect/templates/email/credit-one-step-mail.php')) { + $currentCredit = $model->getCredit($token); + + $coBorrower = $model->getCoBorrower($currentCredit); + + /* echo '
';
+                print_r($currentCredit);
+                echo '
'; + + echo '
';
+                print_r($borrower);
+                echo '
'; + die(); */ + + ob_start(); + include(WP_PLUGIN_DIR . '/ESI_creditDirect/templates/email/credit-one-step-mail.php'); + $message = ob_get_clean(); + + ob_start(); + include(WP_PLUGIN_DIR . '/ESI_creditDirect/templates/email/clients_emails/credit-one-step-mail-client.php'); + $message_client = ob_get_clean(); + + // Ajout des en-têtes pour une meilleure compatibilité Outlook + /* $headers = array( + 'Content-Type: text/html; charset=UTF-8', + 'X-Mailer: PHP/' . phpversion(), + 'MIME-Version: 1.0' + ); */ + + /* echo '
';
+                print_r($attachments);
+                echo '
'; + die(); */ + + // Envoi de l'email au client + $model->sendEmail('Demande de crédit', $message_client, $borrower, $currentCredit, [], true); + + // Envoi de l'email à l'administrateur + $model->sendEmail('Demande de crédit', $message, $borrower, $currentCredit, [], false); + + // Nettoyage des fichiers temporaires + /* foreach ($attachments as $file) { + if (file_exists($file)) @unlink($file); + } */ + include(WP_PLUGIN_DIR . '/ESI_creditDirect/templates/front/credit-step5.php'); + } + if (!empty($upload_errors)) { + foreach ($upload_errors as $err) { + echo '
' . htmlspecialchars((string) $err) . '
'; + } + } + } else { + if($in_one_step) { + include(WP_PLUGIN_DIR . '/ESI_creditDirect/templates/front/credit-one-step.php'); + } else { + include(WP_PLUGIN_DIR . '/ESI_creditDirect/templates/front/credit-step1.php'); + } + } + } +} + +get_footer(); \ No newline at end of file diff --git a/app/controllers/credit-step2.php b/app/controllers/credit-step2.php new file mode 100644 index 0000000..be1df59 --- /dev/null +++ b/app/controllers/credit-step2.php @@ -0,0 +1,159 @@ +checkOngoingCreditRequest(); + + if(!$ongoing_credit && empty($_POST) && !$is_from_back) { + wp_redirect(home_url()); + exit; + } + + // Vérifier le token soit en POST soit en GET + $token = isset($_POST['credit-direct-token']) ? $_POST['credit-direct-token'] : (isset($_GET['credit-direct-token']) ? $_GET['credit-direct-token'] : null); + + if(null === $token) { + $token = $model->get_ongoing_credit_token(); + } + + if (empty($token)) { + wp_redirect(home_url()); + exit; + } + + get_header(); + + //try to load the model + $post = $_POST; + if (empty($post)) { + $post = array('credit-direct-token' => $token); + } + + + + $currentCredit = $model->getCredit($token); + $borrower = $model->getBorrower($currentCredit); + $coBorrower = $model->getCoBorrower($currentCredit); + + $hasCoBorrower = $model->hasCoBorrower($currentCredit); + + $is_credit_auto = $model->is_credit_auto($currentCredit); + + $type_credit_selected = ''; + + if(isset($currentCredit->sel_credit) && !empty($currentCredit->sel_credit)) { + $type_credit_selected = $currentCredit->sel_credit; + } + + if(isset($_POST['type_credit_selected']) && !empty($_POST['type_credit_selected']) || isset($_POST['sub_loan_type']) && !empty($_POST['sub_loan_type'])) + $type_credit_selected = isset($_POST['sub_loan_type']) ? $_POST['sub_loan_type'] : $_POST['type_credit_selected']; + + if(empty($type_credit_selected)) { + $type_credit_selected = $currentCredit->type_credit; + } + + + + if (is_object($currentCredit)) { + // Sauvegarder l'étape 2 seulement si on vient du formulaire POST complet de step2 + if (!empty($_POST)) { + // Vérifier si c'est une soumission complète du formulaire step2 + // (présence de champs clés de step2) ou champ 'step' explicite + $is_step2_submission = isset($_POST['step']) && $_POST['step'] === '2'; + + if (!$is_step2_submission) { + // Vérifier la présence de champs clés de step2 pour détecter automatiquement + $step2_key_fields = ['civilstatus', 'job', 'salary', 'habitation_type']; + $has_step2_fields = false; + foreach ($step2_key_fields as $field) { + if (isset($_POST[$field]) && !empty($_POST[$field])) { + $has_step2_fields = true; + break; + } + } + $is_step2_submission = $has_step2_fields; + } + + if ($is_step2_submission) { + // Validation complète du formulaire step2 + $result = $model->save_step_1($post, true); // Avec validation + + // Vérifier s'il y a des erreurs de validation + if (is_array($result) && isset($result['success']) && !$result['success']) { + $validation_errors = $result['formatted_errors']; + } else { + $model->save_step($currentCredit); + } + } else { + // Simple transition de step1 : sauvegarder le borrower sans validation + $model->save_step_1($post, false); // Sans validation + $model->save_step($currentCredit); // Mettre à jour l'étape + } + } + + $contractTypes = $model->getContractTypes(); + $mapHouseCreditTypes = $model->getHouseCreditTypes(); + + // Utilisation du mode debug pour charger les templates + $template_a = CRED::getTemplatePath('/templates/front/credit-step2-a.php'); + $template_b = CRED::getTemplatePath('/templates/front/credit-step2-b.php'); + $template_c = CRED::getTemplatePath('/templates/front/credit-step2-c.php'); + + /* echo '
';
+        print_r($_COOKIE);
+        echo '
'; */ + + + //try to load the view + if (file_exists(WP_PLUGIN_DIR . '/ESI_creditDirect' . $template_a)) { + include(WP_PLUGIN_DIR . '/ESI_creditDirect' . $template_a); + } + if (file_exists(WP_PLUGIN_DIR . '/ESI_creditDirect' . $template_b)) { + include(WP_PLUGIN_DIR . '/ESI_creditDirect' . $template_b); + } + if (file_exists(WP_PLUGIN_DIR . '/ESI_creditDirect' . $template_c)) { + include(WP_PLUGIN_DIR . '/ESI_creditDirect' . $template_c); + } + } else { + // Si le crédit n'existe pas, rediriger vers la page d'accueil + wp_redirect(home_url()); + exit; + } +} + +get_footer(); \ No newline at end of file diff --git a/app/controllers/credit-step3.php b/app/controllers/credit-step3.php new file mode 100644 index 0000000..caebdb9 --- /dev/null +++ b/app/controllers/credit-step3.php @@ -0,0 +1,178 @@ +get_ongoing_credit_token(); +} + +if (empty($token)) { + wp_redirect(home_url()); + exit; +} + +$currentCredit = $model->getCredit($token); + +if(isset($_GET['debug'])) { + echo '
';
+    print_r($token);
+    print_r($currentCredit);
+    echo '
'; + //die(); +} + +/* echo '
';
+print_r($currentCredit);
+echo '
'; +die(); */ + +$is_credit_pat = $model->is_credit_pat($currentCredit); + +$type_credit_selected = ''; + +if(isset($currentCredit->sel_credit) && !empty($currentCredit->sel_credit)) { + $type_credit_selected = $currentCredit->sel_credit; +} + +if(isset($_POST['type_credit_selected']) && !empty($_POST['type_credit_selected']) || isset($_POST['sub_loan_type']) && !empty($_POST['sub_loan_type'])) + $type_credit_selected = isset($_POST['sub_loan_type']) ? $_POST['sub_loan_type'] : $_POST['type_credit_selected']; + +if(empty($type_credit_selected)) { + $type_credit_selected = $currentCredit->type_credit; +} + +get_header(); + +//try to load the model +$post = $_POST; +if (empty($post)) { + $post = array('credit-direct-token' => $token); +} + +if (file_exists(WP_PLUGIN_DIR . '/ESI_creditDirect/app/models/credit_step3.php')) { + + + if (is_object($currentCredit)) { + // Sauvegarder l'étape 2 seulement si on vient du formulaire POST + if (!empty($_POST)) { + $result = $model->save_step_2($post,$currentCredit); + + // Vérifier s'il y a des erreurs de validation + if (is_array($result) && isset($result['success']) && !$result['success']) { + $validation_errors = $result['formatted_errors']; + } + + // Gestion générique de l'upload de fichiers + $attachments = []; + $upload_errors = []; + /* + // Exemple d'utilisation de la fonction handleUploads + $allowed_types = [ + 'application/pdf', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', // docx + 'application/msword', // doc + 'image/jpeg', + 'image/png', + 'image/gif', + 'image/bmp', + 'image/webp' + ]; + $max_size = 2 * 1024 * 1024; // 2 Mo + $result = $model->handleUploads($_FILES, $allowed_types, $max_size, $token); + $attachments = $result['files']; + $upload_errors = $result['errors']; + $html_links = $result['html_links']; + */ + $allowed_types = [ + 'application/pdf', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', // docx + 'application/msword', // doc + 'image/jpeg', + 'image/png', + 'image/gif', + 'image/bmp', + 'image/webp' + ]; + $max_size = 4 * 1024 * 1024; // 4 Mo + + /* echo '
';
+            print_r($_FILES);
+            echo '
'; */ + + if(!empty($_FILES)) { + foreach ($_FILES as $field => $file) { + + // Traiter seulement les champs de fichiers qui ne sont pas vides + if(empty($file['name']) || empty($file['name'][0]) || $file['error'] === 4) { + continue; + } + + if (isset($file['error']) && $file['error'] !== 4) { // 4 = pas de fichier uploadé + $result = $model->handleUploads($file, $allowed_types, $max_size, $token); + $attachments = array_merge($attachments, $result['files']); + $upload_errors = array_merge($upload_errors, $result['errors']); + } + } + // Affichage des erreurs d'upload + if (!empty($upload_errors)) { + foreach ($upload_errors as $err) { + echo '
' . htmlspecialchars((string) $err) . '
'; + } + } + } + } + + //try to load the view + if (file_exists(WP_PLUGIN_DIR . '/ESI_creditDirect/templates/front/credit-step3.php')) { + $coBorrower = $model->getCoBorrower($currentCredit); + $borrower = $model->getBorrower($currentCredit); + include(WP_PLUGIN_DIR . '/ESI_creditDirect/templates/front/credit-step3.php'); + } + } else { + // Si le crédit n'existe pas, rediriger vers la page d'accueil + wp_redirect(home_url()); + exit; + } +} + +get_footer(); \ No newline at end of file diff --git a/app/controllers/credit-step4.php b/app/controllers/credit-step4.php new file mode 100644 index 0000000..185c983 --- /dev/null +++ b/app/controllers/credit-step4.php @@ -0,0 +1,90 @@ +get_ongoing_credit_token(); +} + +if (empty($token)) { + wp_redirect(home_url()); + exit; +} + +get_header(); + +//try to load the model +$post = $_POST; +if (empty($post)) { + $post = array('credit-direct-token' => $token); +} + +if (file_exists(WP_PLUGIN_DIR . '/ESI_creditDirect/app/models/credit_step4.php')) { + + + $currentCredit = $model->getCredit($token); + + $type_credit_selected = ''; + + $coBorrower = $model->getCoBorrower($currentCredit); + $borrower = $model->getBorrower($currentCredit); + + if(isset($currentCredit->sel_credit) && !empty($currentCredit->sel_credit)) { + $type_credit_selected = $currentCredit->sel_credit; + } + + if(isset($_POST['type_credit_selected']) && !empty($_POST['type_credit_selected']) || isset($_POST['sub_loan_type']) && !empty($_POST['sub_loan_type'])) + $type_credit_selected = isset($_POST['sub_loan_type']) ? $_POST['sub_loan_type'] : $_POST['type_credit_selected']; + + if(empty($type_credit_selected)) { + $type_credit_selected = $currentCredit->type_credit; + } + + if (is_object($currentCredit)) { + // Sauvegarder l'étape 3 seulement si on vient du formulaire POST + if (!empty($_POST)) { + + $model->save_step_3($post, $currentCredit); + } + + //try to load the view + if (file_exists(WP_PLUGIN_DIR . '/ESI_creditDirect/templates/front/credit-step4.php')) { + include(WP_PLUGIN_DIR . '/ESI_creditDirect/templates/front/credit-step4.php'); + } + } else { + // Si le crédit n'existe pas, rediriger vers la page d'accueil + wp_redirect(home_url()); + exit; + } +} + +get_footer(); \ No newline at end of file diff --git a/app/controllers/credit-step5.php b/app/controllers/credit-step5.php new file mode 100644 index 0000000..e35321e --- /dev/null +++ b/app/controllers/credit-step5.php @@ -0,0 +1,127 @@ +'; +print_r($token); +echo ''; */ + +if (empty($token)) { + wp_redirect(home_url()); + exit; +} + +get_header(); + +//try to load the model +$post = $_POST; +if (empty($post)) { + $post = array('credit-direct-token' => $token); +} + +if (file_exists(WP_PLUGIN_DIR . '/ESI_creditDirect/app/models/credit_step5.php')) { + + if(!class_exists('\models\CRED_credit')) { + include(WP_PLUGIN_DIR . '/ESI_creditDirect/app/models/credit.php'); + } + + if(!class_exists('\models\CRED_credit_step5')) { + include(WP_PLUGIN_DIR . '/ESI_creditDirect/app/models/credit_step5.php'); + } + + $model = new CRED_credit_step5(); + + $currentCredit = $model->getCredit($token); + + + if (is_object($currentCredit)) { + // Sauvegarder l'étape 4 seulement si on vient du formulaire POST + + + if (!empty($_POST)) { + $model->save_step_4($post, $currentCredit); + } + + $borrower = $model->getBorrower($currentCredit); + $coBorrower = $model->getCoBorrower($currentCredit); + $agencies = $model->getAgencies(); + $civilStatus = $model->getCivilStatus(); + $works = $model->getWorks(); + $existingCreditTypes = $model->getExistingCreditTypes(); + $map_credit_type = $model->getCreditTypes(); + $contractTypes = $model->getContractTypes(); + $mapHouseCreditTypes = $model->getHouseCreditTypes(); + + $type_credit_selected = ''; + + if(isset($currentCredit->sel_credit) && !empty($currentCredit->sel_credit)) { + $type_credit_selected = $currentCredit->sel_credit; + } + + if(isset($_POST['type_credit_selected']) && !empty($_POST['type_credit_selected']) || isset($_POST['sub_loan_type']) && !empty($_POST['sub_loan_type'])) + $type_credit_selected = isset($_POST['sub_loan_type']) ? $_POST['sub_loan_type'] : $_POST['type_credit_selected']; + + + $creditOptionsLabels = !empty($type_credit_selected) ? $model->getCreditLabel($type_credit_selected) : $map_credit_type[$currentCredit->type_credit]; + + $message = null; + + + if (file_exists(WP_PLUGIN_DIR . '/ESI_creditDirect/templates/email/credit-step4-mail.php')) { + ob_start(); + include(WP_PLUGIN_DIR . '/ESI_creditDirect/templates/email/credit-step4-mail.php'); + $message = ob_get_clean(); + + ob_start(); + include(WP_PLUGIN_DIR . '/ESI_creditDirect/templates/email/clients_emails/credit-step4-mail-client.php'); + $message_client = ob_get_clean(); + + + // Ajout des en-têtes pour une meilleure compatibilité Outlook + if(!isset($_GET['credit-direct-token'])) { + + $model->sendEmail('Demande de crédit', $message, $borrower, $currentCredit, [], false); + $model->sendEmail('Demande de crédit', $message_client, $borrower, $currentCredit, [], true); + } + } + + //try to load the view + if (file_exists(WP_PLUGIN_DIR . '/ESI_creditDirect/templates/front/credit-step5.php')) { + include(WP_PLUGIN_DIR . '/ESI_creditDirect/templates/front/credit-step5.php'); + } + + /* if (!is_null($message)) { + echo $message; + } */ + } else { + // Si le crédit n'existe pas, rediriger vers la page d'accueil + wp_redirect(home_url()); + exit; + } +} + +get_footer(); \ No newline at end of file diff --git a/app/controllers/credit_mailchimp.php b/app/controllers/credit_mailchimp.php new file mode 100644 index 0000000..7207184 --- /dev/null +++ b/app/controllers/credit_mailchimp.php @@ -0,0 +1,273 @@ + 'array', + 'sanitize_callback' => array($this, 'sanitize_options'), + 'default' => array( + 'api_key' => '', + 'server_prefix' => '', + 'primary_list_id' => '' + ) + ) + ); + + add_settings_section( + 'cred_mailchimp_main_section', + __('Paramètres de connexion', 'esi-creditdirect'), + function() { + echo '

' . esc_html__('Renseignez la clé API et le préfixe serveur (ex: us19) comme indiqué par Mailchimp.', 'esi-creditdirect') . '

'; + }, + 'credit-mailchimp' + ); + + add_settings_field( + 'cred_mailchimp_api_key', + __('Clé API', 'esi-creditdirect'), + array($this, 'field_api_key_cb'), + 'credit-mailchimp', + 'cred_mailchimp_main_section' + ); + + add_settings_field( + 'cred_mailchimp_server_prefix', + __('Préfixe serveur', 'esi-creditdirect'), + array($this, 'field_server_prefix_cb'), + 'credit-mailchimp', + 'cred_mailchimp_main_section' + ); + + add_settings_field( + 'cred_mailchimp_primary_list', + __('Liste principale (Audience)', 'esi-creditdirect'), + array($this, 'field_primary_list_cb'), + 'credit-mailchimp', + 'cred_mailchimp_main_section' + ); + } + + /** + * Affiche la page de réglages + */ + public function render_settings_page() { + $options = $this->get_options(); + include plugin_dir_path(__FILE__) . '../../templates/admin/mailchimp_settings.php'; + } + + /** + * Callback du champ API Key + */ + public function field_api_key_cb() { + $options = $this->get_options(); + $value = isset($options['api_key']) ? $options['api_key'] : ''; + echo ''; + } + + /** + * Callback du champ Server Prefix + */ + public function field_server_prefix_cb() { + $options = $this->get_options(); + $value = isset($options['server_prefix']) ? $options['server_prefix'] : ''; + echo ''; + } + + /** + * Callback du champ Liste principale (audience) + */ + public function field_primary_list_cb() { + $options = $this->get_options(); + $selected = isset($options['primary_list_id']) ? $options['primary_list_id'] : ''; + + $client = $this->get_client(); + if ($client === null) { + echo '' . esc_html__('Renseignez d\'abord la clé API et le préfixe serveur, puis enregistrez.', 'esi-creditdirect') . ''; + echo '
'; + echo ''; + return; + } + + $lists = array(); + try { + $resp = $client->lists->getAllLists(array('count' => 1000)); + if (is_array($resp) && isset($resp['lists']) && is_array($resp['lists'])) { + foreach ($resp['lists'] as $list) { + if (isset($list['id']) && isset($list['name'])) { + $lists[] = array( + 'id' => (string) $list['id'], + 'name' => (string) $list['name'] + ); + } + } + } + } catch (\Throwable $e) { + echo '

' . esc_html(sprintf(__('Erreur lors du chargement des audiences: %s', 'esi-creditdirect'), $e->getMessage())) . '

'; + } + + if (empty($lists)) { + echo '' . esc_html__('Aucune audience trouvée ou erreur. Vous pouvez saisir un ID manuellement.', 'esi-creditdirect') . ''; + echo '
'; + echo ''; + return; + } + + echo ''; + } + + /** + * Sanitize des options + */ + public function sanitize_options($options) { + $sanitized = array(); + $sanitized['api_key'] = isset($options['api_key']) ? sanitize_text_field($options['api_key']) : ''; + $sanitized['server_prefix'] = isset($options['server_prefix']) ? sanitize_text_field($options['server_prefix']) : ''; + $sanitized['primary_list_id'] = isset($options['primary_list_id']) ? sanitize_text_field($options['primary_list_id']) : ''; + return $sanitized; + } + + /** + * Récupère les options du plugin + */ + private function get_options() { + $defaults = array( + 'api_key' => '', + 'server_prefix' => '', + 'primary_list_id' => '' + ); + $options = get_option('cred_mailchimp_options', array()); + if (!is_array($options)) { + $options = array(); + } + return array_merge($defaults, $options); + } + + /** + * Retourne une instance configurée du client Mailchimp Marketing + * ou null si les informations de connexion sont incomplètes. + */ + public function get_client() { + $options = $this->get_options(); + $apiKey = isset($options['api_key']) ? trim($options['api_key']) : ''; + $server = isset($options['server_prefix']) ? trim($options['server_prefix']) : ''; + + if ($apiKey === '' || $server === '') { + return null; + } + + + if (!class_exists('\\MailchimpMarketing\\ApiClient')) { + return null; + } + + + + $client = new \MailchimpMarketing\ApiClient(); + $client->setConfig(array( + 'apiKey' => $apiKey, + 'server' => $server + )); + + return $client; + } + + /** + * AJAX: ping Mailchimp pour valider la connexion + */ + public function ajax_ping() { + check_ajax_referer('cred_mailchimp_ping', 'nonce'); + if (!current_user_can('manage_options')) { + wp_send_json_error(array('message' => __('Permissions insuffisantes', 'esi-creditdirect')), 403); + } + + $client = $this->get_client(); + if ($client === null) { + wp_send_json_error(array('message' => __('Configuration incomplète (clé API/préfixe serveur).', 'esi-creditdirect')), 400); + } + + try { + $resp = $client->ping->get(); + wp_send_json_success(array('response' => $resp)); + } catch (\Throwable $e) { + wp_send_json_error(array('message' => $e->getMessage()), 500); + } + } + + /** + * Abonne ou met à jour un contact à partir d'un objet crédit. + * @param object $credit Objet avec au minimum les propriétés email, prenom, nom + */ + public function subscribe_from_credit($credit) { + if (!$credit || !isset($credit->email)) { + return; + } + + $email = trim((string)$credit->email); + if ($email === '' || !is_email($email)) { + return; + } + + $options = get_option('cred_mailchimp_options', array()); + $listId = isset($options['primary_list_id']) ? trim((string)$options['primary_list_id']) : ''; + if ($listId === '') { + return; + } + + $client = $this->get_client(); + if ($client === null) { + return; + } + + $firstName = isset($credit->prenom) ? (string)$credit->prenom : ''; + $lastName = isset($credit->nom) ? (string)$credit->nom : ''; + + $subscriberHash = md5(strtolower($email)); + $body = array( + 'email_address' => $email, + 'status' => 'subscribed', + 'status_if_new' => 'subscribed', + 'merge_fields' => array( + 'FNAME' => $firstName, + 'LNAME' => $lastName + ) + ); + + try { + $client->lists->setListMember($listId, $subscriberHash, $body); + } catch (\Throwable $e) { + error_log('Mailchimp subscribe error (from credit): ' . $e->getMessage()); + } + } +} \ No newline at end of file diff --git a/app/controllers/credit_manager.php b/app/controllers/credit_manager.php new file mode 100644 index 0000000..fa05a1b --- /dev/null +++ b/app/controllers/credit_manager.php @@ -0,0 +1,1101 @@ + 'Prêt personnel / Tous motifs / Achats divers', + 'frais_notaire' => 'Financement frais de notaire', + 'but_immo' => 'Crédit travaux / Rénovation / Energie', + 'fin_neuve' => 'Financement véhicule NEUF', + 'fin_occ_m3a' => 'Financement véhicule d\'occasion MOINS de 3 ans', + 'fin_occ_p3a' => 'Financement véhicule d\'occasion PLUS de 3 ans', + 'mobil_carav' => 'Financement Mobil-home et caravane', + 'reno_energie' => 'Rénovation énergétique', + 'regrouping' => 'Regroupement de crédit / Rachat de crédit', + 'regroup_cred' => 'Regroupement de crédit / Rachat de crédit' + ]; + + protected $houseCreditTypes = [ + 'purchasehouse' => 'Achat bien immobilier', + 'construction' => 'Nouvelle construction', + 'regrouping_immo' => 'Regroupement de crédits', + 'refinancing' => 'Refinancement crédit(s) hypothécaire(s)', + 'purchaseabroad' => 'Achat d\'une 2éme résidence (à l\'étranger, en belgique)', + 'but_immo_hypo' => 'Travaux de rénovation', + 'achat_maison_de_rapport' => 'Achat maison de rapport', + 'credit_pont' => 'Crédit pont', + 'independants_et_entreprises_en_difficultes' => 'Indépendants et entreprises en difficultés', + 'regroupement_de_credit__rachats_de_credits' => 'Rachats de crédits', + 'financement_frais_de_notaire' => 'Financement frais de notaire', + 'fonds_roulement_independants' => 'Fonds de roulement' + ]; + + public function __construct() { + // Le hook admin_menu est maintenant géré par le factory + } + + public function init() { + + } + + /** + * Ajouter le menu d'administration simple + */ + public function add_admin_menu() { + add_menu_page( + 'Gestion des Crédits', // Titre de la page + 'Crédits', // Titre du menu + 'edit_posts', // Capacité requise + 'credit-manager', // Slug du menu + array($this, 'credit_manager_interfaces'), // Fonction de callback + 'dashicons-money-alt', // Icône + 8 // Position dans le menu + ); + + // Sous-menu: Import de crédits + add_submenu_page( + 'credit-manager', // Slug du menu parent + 'Import de crédits', // Titre de la page + 'Import de crédits', // Titre du sous-menu + 'edit_posts', // Capacité requise + 'credit-import', // Slug du sous-menu + array($this, 'credit_import_interface') // Callback + ); + } + + + public function credit_manager_interfaces() { + // Récupérer les crédits + $credits = $this->get_credits(); + + // Récupérer les sociétés de crédit pour le select + $societes_credit = $this->get_societes_credit(); + + // Passer les types de crédit au template + $creditTypes = $this->creditTypes; + $houseCreditTypes = $this->houseCreditTypes; + + // Calculer les compteurs par statut avec array_reduce + $status_counts = array_reduce($credits, function($counts, $credit) { + $status = isset($credit->status) ? (string)$credit->status : '0'; + + if (!isset($counts[$status])) { + $counts[$status] = 0; + } + $counts[$status]++; + + return $counts; + }, array()); + + // S'assurer que tous les statuts ont une valeur (même 0) + $status_counts = array_merge( + array('0' => 0, '1' => 0, '2' => 0, '-1' => 0), + $status_counts + ); + + // Total de tous les crédits + $total_credits = count($credits); + + // Inclure le template + include plugin_dir_path(__FILE__) . '../../templates/admin/credit_manager_table.php'; + } + + /** + * Interface d'import CSV (non-AJAX) + */ + public function credit_import_interface() { + if (!current_user_can('edit_posts')) { + wp_die('Permissions insuffisantes'); + } + + $import_summary = null; + $import_errors = array(); + + // Soumission du formulaire + if (!empty($_POST['credit_import_submit'])) { + // Vérifier le nonce + if (!isset($_POST['credit_import_nonce']) || !wp_verify_nonce($_POST['credit_import_nonce'], 'credit_import_action')) { + $import_errors[] = 'Sécurité: Nonce invalide'; + } else { + // Valider le fichier + if (!isset($_FILES['csv_file']) || !is_uploaded_file($_FILES['csv_file']['tmp_name'])) { + $import_errors[] = 'Aucun fichier CSV envoyé.'; + } else { + $status_input = isset($_POST['status']) ? intval($_POST['status']) : 1; // 1 par défaut + // Normaliser statut attendu par l'UI: 1=validé non signé, 2=validé signé, -1=refusé + $allowed_status = array(1, 2, -1); + if (!in_array($status_input, $allowed_status, true)) { + $status_input = 1; + } + + $file_tmp = $_FILES['csv_file']['tmp_name']; + $handle = fopen($file_tmp, 'r'); + if ($handle === false) { + $import_errors[] = 'Impossible d\'ouvrir le fichier CSV.'; + } else { + // Lire l'entête et ignorer + $header = fgetcsv($handle, 0, ';'); + + $row_num = 1; + $inserted = 0; + $skipped = 0; + + global $wpdb; + $table_name = 'cdf_Credits_listing'; + + // Vérifier la table + if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) { + $import_errors[] = 'Table de base de données non trouvée: ' . esc_html($table_name); + } else { + while (($row = fgetcsv($handle, 0, ';')) !== false) { + $row_num++; + // Sauter les lignes vides + if (count($row) === 0 || (count($row) === 1 && trim((string)$row[0]) === '')) { + continue; + } + + // Sécuriser les index attendus (jusqu'à 13 colonnes d'après le modèle) + for ($i = 0; $i <= 12; $i++) { + if (!isset($row[$i])) $row[$i] = ''; + } + + // Mapping CSV -> champs + $titre = trim((string)$row[0]); + $nomPrenom = trim((string)$row[1]); + $adresse = trim((string)$row[2]); + $localiteField = trim((string)$row[3]); // ex: "4333 SOUMAGNE" + $email = trim((string)$row[4]); + $telephone = trim((string)$row[5]); + $gsm = trim((string)$row[6]); + $societe_credit = trim((string)$row[7]); + $montantStr = trim((string)$row[8]); + $dateSignatureStr = trim((string)$row[9]); + $numero_dossier = trim((string)$row[10]); + $code = trim((string)$row[11]); + $remarque = trim((string)$row[12]); + + // Extraire nom/prénom (naïf: premier mot = nom, reste = prénom) + $nom = ''; + $prenom = ''; + if ($nomPrenom !== '') { + // Essayer "NOM Prénom" + $parts = preg_split('/\s+/', $nomPrenom); + if (count($parts) >= 2) { + $nom = trim((string)$parts[0]); + $prenom = trim(implode(' ', array_slice($parts, 1))); + } else { + $nom = $nomPrenom; + } + } + + // Extraire code postal et localité + $code_postal = 0; + $localite = $localiteField; + if ($localiteField !== '') { + if (preg_match('/^(\d{4,5})\s*(.+)$/u', $localiteField, $m)) { + $code_postal = intval($m[1]); + $localite = trim($m[2]); + } + } + + // Normaliser montant (ex: "4 000,00 €") + $montantClean = str_replace(array("\xC2\xA0", '€', ' '), '', $montantStr); + $montantClean = str_replace('.', '', $montantClean); // enlever séparateurs de milliers + $montantClean = str_replace(',', '.', $montantClean); // virgule -> point + $montant = is_numeric($montantClean) ? (float)$montantClean : 0.0; + + // Parser date de signature -> Y-m-d + $date_signature = ''; + $date_signature_candidates = array('d/m/Y', 'd-m-Y', 'Y-m-d', 'd.m.Y'); + foreach ($date_signature_candidates as $fmt) { + $dt = DateTime::createFromFormat($fmt, $dateSignatureStr); + if ($dt instanceof DateTime) { + $date_signature = $dt->format('Y-m-d'); + break; + } + } + if ($date_signature === '') { + // Si échec, laisser vide + $date_signature = ''; + } + + // Champs requis minimaux: nom, prenom ou email + if ($nom === '' && $prenom === '' && $email === '') { + $skipped++; + $import_errors[] = 'Ligne ' . $row_num . ' ignorée (nom/prénom/email manquants).'; + continue; + } + + $data = array( + 'credit_id' => 0, + 'emprunteur_id' => 0, + 'credit_code_select' => '', + 'code_credit' => '', + 'type_credit' => '', + 'nom' => $nom !== '' ? $nom : '', + 'prenom' => $prenom !== '' ? $prenom : '', + 'adresse' => $adresse !== '' ? $adresse : '', + 'localite' => $localite !== '' ? $localite : '', + 'code_postal' => $code_postal, + 'pays' => 0, + 'email' => $email !== '' ? $email : '', + 'telephone' => $telephone !== '' ? $telephone : '', + 'gsm' => $gsm !== '' ? $gsm : '', + 'societe_credit' => $societe_credit !== '' ? $societe_credit : '', + 'montant' => $montant, + 'date' => current_time('Y-m-d'), + 'date_signature' => $date_signature !== '' ? $date_signature : current_time('Y-m-d'), + 'numero_dossier' => $numero_dossier !== '' ? $numero_dossier : '', + 'code' => $code !== '' ? $code : '', + 'remarque' => $remarque !== '' ? $remarque : '', + 'status' => $status_input, + ); + + $formats = array('%d','%d','%s','%s','%s','%s','%s','%s','%s','%d','%d','%s','%s','%s','%s','%f','%s','%s','%s','%s','%s','%d'); + + $result = $wpdb->insert($table_name, $data, $formats); + if ($result === false) { + $skipped++; + $import_errors[] = 'Erreur d\'insertion ligne ' . $row_num . ' : ' . esc_html($wpdb->last_error); + } else { + $inserted++; + // Si l'import positionne directement le statut à 2, abonner l'email à la liste principale + if (intval($status_input) === 2 && $email !== '') { + $mailchimpController = $this->getCreditMailchimp(); + if ($mailchimpController && method_exists($mailchimpController, 'subscribe_from_credit')) { + $creditObj = (object) array( + 'id' => isset($data['credit_id']) && !empty($data['credit_id']) ? intval($data['credit_id']) : intval($wpdb->insert_id), + 'email' => $email, + 'prenom' => $prenom, + 'nom' => $nom + ); + try { + $mailchimpController->subscribe_from_credit($creditObj); + } catch (\Throwable $e) { + error_log('Mailchimp subscribe during import (row ' . $row_num . ') failed: ' . $e->getMessage()); + } + } + } + } + } + } + + if (is_resource($handle)) { + fclose($handle); + } + + $import_summary = array( + 'inserted' => $inserted, + 'skipped' => $skipped, + ); + } + } + } + } + + include plugin_dir_path(__FILE__) . '../../templates/admin/credit_import.php'; + } + + public function get_credits($filters = array()) { + global $wpdb; + + // Utiliser la table cdf_Credits_listing qui contient déjà toutes les informations + $table_name = 'cdf_Credits_listing'; + + // Vérifier si la table existe + if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) { + // Retourner des données de test si la table n'existe pas + error_log('Credit Manager: Table ' . $table_name . ' n\'existe pas, retour de données de test'); + return $this->get_test_credits(); + } + + // Construire la clause WHERE dynamiquement + $where_clauses = array(); + $where_values = array(); + + // Configuration des filtres par type avec leur opérateur et placeholder + $filter_config = array( + // Filtres de type string avec égalité + 'string_equal' => array( + 'fields' => array('localite', 'societe_credit', 'code_postal', 'type_credit', 'credit_code_select'), + 'operator' => '=', + 'placeholder' => '%s' + ), + // Filtres de type integer avec égalité + 'int_equal' => array( + 'fields' => array('status'), + 'operator' => '=', + 'placeholder' => '%d', + 'allow_zero' => true // Permet la valeur 0 pour status + ), + // Filtres de type habitation (checkbox multiples) + 'habitation_filter' => array( + 'habitation_locataire' => array('field' => 'habitation_type', 'value' => 'locataire'), + 'habitation_proprietaire' => array('field' => 'habitation_type', 'values' => array('proprietaire', 'proprietaire_sans_pret')) + ), + // Filtres de type float avec comparaison + 'float_range' => array( + 'montant_min' => array('field' => 'montant', 'operator' => '>=', 'placeholder' => '%f'), + 'montant_max' => array('field' => 'montant', 'operator' => '<=', 'placeholder' => '%f') + ), + // Filtres de type date avec comparaison + 'date_range' => array( + 'date_signature_debut' => array('field' => 'date_signature', 'operator' => '>=', 'placeholder' => '%s'), + 'date_signature_fin' => array('field' => 'date_signature', 'operator' => '<=', 'placeholder' => '%s') + ) + ); + + // Traiter les filtres string et int simples + foreach (array('string_equal', 'int_equal') as $type) { + $config = $filter_config[$type]; + foreach ($config['fields'] as $field) { + $allow_zero = isset($config['allow_zero']) && $config['allow_zero']; + + if ($allow_zero) { + // Pour status, vérifier avec isset car 0 est une valeur valide + if (isset($filters[$field]) && $filters[$field] !== '') { + $where_clauses[] = "{$field} {$config['operator']} {$config['placeholder']}"; + $where_values[] = ($type === 'int_equal') ? intval($filters[$field]) : $filters[$field]; + } + } else { + // Pour les autres champs, utiliser !empty + if (!empty($filters[$field])) { + $where_clauses[] = "{$field} {$config['operator']} {$config['placeholder']}"; + $where_values[] = ($type === 'int_equal') ? intval($filters[$field]) : $filters[$field]; + } + } + } + } + + // Traiter les filtres d'habitation (checkbox multiples) + if (!empty($filter_config['habitation_filter'])) { + $habitation_conditions = array(); + foreach ($filter_config['habitation_filter'] as $filter_key => $habitation_config) { + if (!empty($filters[$filter_key])) { + if (isset($habitation_config['value'])) { + // Filtre simple (locataire) + $habitation_conditions[] = "e.habitation_type = %s"; + $where_values[] = $habitation_config['value']; + } elseif (isset($habitation_config['values'])) { + // Filtre multiple (propriétaire avec/sans prêt) + $placeholders = array_fill(0, count($habitation_config['values']), '%s'); + $habitation_conditions[] = "e.habitation_type IN (" . implode(',', $placeholders) . ")"; + $where_values = array_merge($where_values, $habitation_config['values']); + } + } + } + if (!empty($habitation_conditions)) { + $where_clauses[] = "(" . implode(" OR ", $habitation_conditions) . ")"; + } + } + + // Traiter les filtres de fourchette (float et date) + foreach (array('float_range', 'date_range') as $range_type) { + foreach ($filter_config[$range_type] as $filter_key => $range_config) { + if (!empty($filters[$filter_key])) { + $where_clauses[] = "{$range_config['field']} {$range_config['operator']} {$range_config['placeholder']}"; + $where_values[] = ($range_type === 'float_range') + ? floatval($filters[$filter_key]) + : $filters[$filter_key]; + } + } + } + + // Construire la requête SQL avec jointure vers cdf_Emprunteur + $sql = "SELECT c.*, e.habitation_type FROM {$table_name} c + LEFT JOIN cdf_Emprunteur e ON c.emprunteur_id = e.idEmprunteur"; + + if (!empty($where_clauses)) { + $sql .= " WHERE " . implode(" AND ", $where_clauses); + } + + $sql .= " ORDER BY c.date DESC"; + + // Préparer et exécuter la requête + if (!empty($where_values)) { + $sql = $wpdb->prepare($sql, $where_values); + } + + // Debug: Log SQL query + error_log('Credit Manager SQL: ' . $sql); + error_log('Credit Manager Filters: ' . print_r($filters, true)); + + $results = $wpdb->get_results($sql); + + // Debug: Log results count + error_log('Credit Manager Results count: ' . count($results)); + + // Si pas de résultats ET pas de filtres appliqués, retourner des données de test + // Si des filtres sont appliqués et qu'il n'y a pas de résultats, retourner un tableau vide + if (empty($results)) { + if (empty($filters)) { + // Pas de filtres, table vide = données de test + error_log('Credit Manager: Aucun crédit dans la base, retour de données de test'); + return $this->get_test_credits(); + } else { + // Filtres appliqués, pas de résultats = tableau vide + error_log('Credit Manager: Aucun crédit ne correspond aux filtres'); + return array(); + } + } + + return $results; + } + + + /** + * Récupérer un crédit spécifique par ID + */ + public function get_credit_by_id($credit_id) { + global $wpdb; + + $table_name = 'cdf_Credits_listing'; + + // Vérifier si la table existe + if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) { + return null; + } + + $sql = $wpdb->prepare(" + SELECT + id, + type_credit, + nom, + prenom, + adresse, + localite, + email, + telephone, + gsm, + societe_credit, + montant, + date, + date_signature, + numero_dossier, + code, + remarque as remarques + FROM {$table_name} + WHERE id = %d + ", $credit_id); + + return $wpdb->get_row($sql); + } + + /** + * Récupérer les professions pour le select + */ + public function get_professions() { + global $wpdb; + + $table_name = 'cdf_Profession'; + + if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) { + return array(); + } + + $sql = "SELECT idprofession as id, nom_profession as nom FROM {$table_name} ORDER BY nom_profession"; + return $wpdb->get_results($sql); + } + + /** + * Récupérer les agences pour le select + */ + public function get_agences() { + global $wpdb; + + $table_name = 'cdf_Agences'; + + if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) { + return array(); + } + + $sql = "SELECT idAgences as id, Nom_agence as nom FROM {$table_name} ORDER BY Nom_agence"; + return $wpdb->get_results($sql); + } + + /** + * Récupérer les sociétés de crédit pour le select + */ + public function get_societes_credit() { + global $wpdb; + + $table_name = 'cdf_societes_credit'; + + if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) { + return array(); + } + + // Récupérer seulement les sociétés actives (status = 1) + $sql = "SELECT id, nom FROM {$table_name} WHERE status = 1 ORDER BY nom"; + return $wpdb->get_results($sql); + } + + /** + * Récupérer les localités distinctes + */ + public function get_distinct_localites() { + global $wpdb; + $table_name = 'cdf_Credits_listing'; + + if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) { + return array(); + } + + $sql = "SELECT DISTINCT localite FROM {$table_name} WHERE localite != '' ORDER BY localite"; + return $wpdb->get_col($sql); + } + + /** + * Récupérer les sociétés de crédit distinctes + */ + public function get_distinct_societes() { + global $wpdb; + $table_name = 'cdf_Credits_listing'; + + if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) { + return array(); + } + + $sql = "SELECT DISTINCT societe_credit FROM {$table_name} WHERE societe_credit != '' ORDER BY societe_credit"; + return $wpdb->get_col($sql); + } + + /** + * Récupérer les types de crédit distincts + */ + public function get_distinct_credit_types() { + global $wpdb; + $table_name = 'cdf_Credits_listing'; + + if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) { + return array(); + } + + $sql = "SELECT DISTINCT type_credit FROM {$table_name} WHERE type_credit != '' ORDER BY type_credit"; + return $wpdb->get_col($sql); + } + + /** + * Récupérer les types de crédit + */ + public function get_credit_types() { + return array( + 'credit_immobilier' => 'Crédit Immobilier', + 'credit_consommation' => 'Crédit Consommation', + 'credit_auto' => 'Crédit Automobile', + 'credit_personnel' => 'Crédit Personnel', + 'credit_travaux' => 'Crédit Travaux' + ); + } + + /** + * Données de test pour le développement + */ + private function get_test_credits() { + return array( + (object) array( + 'id' => 1, + 'type_credit' => 'CH', + 'nom' => 'Dupont', + 'prenom' => 'Jean', + 'adresse' => '123 Rue de la Paix', + 'localite' => 'Bruxelles', + 'email' => 'jean.dupont@example.com', + 'telephone' => '02/123.45.67', + 'gsm' => '0470/12.34.56', + 'societe_credit' => 'Banque 1', + 'montant' => 250000.00, + 'date' => '2024-01-15', + 'date_signature' => '2024-01-20', + 'numero_dossier' => 'CD-2024-001', + 'code' => 'ABC123', + 'remarques' => 'Premier crédit test' + ), + (object) array( + 'id' => 2, + 'type_credit' => 'PAT', + 'nom' => 'Martin', + 'prenom' => 'Marie', + 'adresse' => '456 Avenue des Champs', + 'localite' => 'Anvers', + 'email' => 'marie.martin@example.com', + 'telephone' => '03/987.65.43', + 'gsm' => '0471/98.76.54', + 'societe_credit' => 'Banque 2', + 'montant' => 15000.00, + 'date' => '2024-01-20', + 'date_signature' => '2024-01-25', + 'numero_dossier' => 'CD-2024-002', + 'code' => 'DEF456', + 'remarques' => 'Crédit pour voiture' + ) + ); + } + + /** + * ======================================== + * FONCTIONS CRUD POUR CREDIT MANAGER + * ======================================== + */ + + /** + * Créer un nouveau crédit + */ + public function ajax_create_credit() { + // Vérifier le nonce + if (!wp_verify_nonce($_POST['nonce'], 'credit_manager_action')) { + wp_die('Sécurité: Nonce invalide'); + } + + // Vérifier les permissions + if (!current_user_can('edit_posts')) { + wp_die('Permissions insuffisantes'); + } + + global $wpdb; + $table_name = 'cdf_Credits_listing'; + + // Récupérer et valider les données + $data = array( + 'type_credit' => $this->processTypeCredit($_POST['type_credit']), + 'nom' => sanitize_text_field($_POST['nom']), + 'prenom' => sanitize_text_field($_POST['prenom']), + 'adresse' => sanitize_textarea_field($_POST['adresse']), + 'localite' => sanitize_text_field($_POST['localite']), + 'email' => sanitize_email($_POST['email']), + 'telephone' => sanitize_text_field($_POST['telephone']), + 'gsm' => sanitize_text_field($_POST['gsm']), + 'type_habitation' => sanitize_text_field($_POST['type_habitation']), + 'societe_credit' => sanitize_text_field($_POST['societe_credit']), + 'montant' => floatval($_POST['montant']), + 'date' => sanitize_text_field($_POST['date']), + 'date_signature' => sanitize_text_field($_POST['signature']), + 'numero_dossier' => sanitize_text_field($_POST['numero_dossier']), + 'code' => sanitize_text_field($_POST['code']), + 'remarque' => sanitize_textarea_field($_POST['remarques']) + ); + + // Validation des champs obligatoires + if (empty($data['nom']) || empty($data['prenom']) || empty($data['email'])) { + wp_send_json_error('Les champs nom, prénom et email sont obligatoires'); + } + + // Vérifier si la table existe + if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) { + wp_send_json_error('Table de base de données non trouvée'); + } + + // Insérer le nouveau crédit + $result = $wpdb->insert($table_name, $data); + + if ($result === false) { + wp_send_json_error('Erreur lors de la création du crédit'); + } + + $credit_id = $wpdb->insert_id; + $new_credit = $this->get_credit_by_id($credit_id); + + wp_send_json_success(array( + 'message' => 'Crédit créé avec succès', + 'credit' => $new_credit + )); + } + + /** + * Lire un crédit spécifique + */ + public function ajax_get_credit() { + // Vérifier le nonce + if (!wp_verify_nonce($_POST['nonce'], 'credit_manager_action')) { + wp_die('Sécurité: Nonce invalide'); + } + + // Vérifier les permissions + if (!current_user_can('edit_posts')) { + wp_die('Permissions insuffisantes'); + } + + $credit_id = intval($_POST['credit_id']); + + if ($credit_id <= 0) { + wp_send_json_error('ID de crédit invalide'); + } + + $credit = $this->get_credit_by_id($credit_id); + + if (!$credit) { + wp_send_json_error('Crédit non trouvé'); + } + + wp_send_json_success(array( + 'credit' => $credit + )); + } + + /** + * Mettre à jour un crédit existant + */ + public function ajax_update_credit() { + // Vérifier le nonce + if (!wp_verify_nonce($_POST['nonce'], 'credit_manager_action')) { + wp_die('Sécurité: Nonce invalide'); + } + + // Vérifier les permissions + if (!current_user_can('edit_posts')) { + wp_die('Permissions insuffisantes'); + } + + global $wpdb; + $table_name = 'cdf_Credits_listing'; + $credit_id = intval($_POST['credit_id']); + + if ($credit_id <= 0) { + wp_send_json_error('ID de crédit invalide'); + } + + // Vérifier si le crédit existe + $existing_credit = $this->get_credit_by_id($credit_id); + if (!$existing_credit) { + wp_send_json_error('Crédit non trouvé'); + } + + // Récupérer et valider les données + $data = array( + 'type_credit' => $this->processTypeCredit($_POST['type_credit']), + 'nom' => sanitize_text_field($_POST['nom']), + 'prenom' => sanitize_text_field($_POST['prenom']), + 'adresse' => sanitize_textarea_field($_POST['adresse']), + 'localite' => sanitize_text_field($_POST['localite']), + 'email' => sanitize_email($_POST['email']), + 'telephone' => sanitize_text_field($_POST['telephone']), + 'gsm' => sanitize_text_field($_POST['gsm']), + 'type_habitation' => sanitize_text_field($_POST['type_habitation']), + 'societe_credit' => sanitize_text_field($_POST['societe_credit']), + 'montant' => floatval($_POST['montant']), + 'date' => sanitize_text_field($_POST['date']), + 'date_signature' => sanitize_text_field($_POST['signature']), + 'numero_dossier' => sanitize_text_field($_POST['numero_dossier']), + 'code' => sanitize_text_field($_POST['code']), + 'remarque' => sanitize_textarea_field($_POST['remarques']) + ); + + // Validation des champs obligatoires + if (empty($data['nom']) || empty($data['prenom']) || empty($data['email'])) { + wp_send_json_error('Les champs nom, prénom et email sont obligatoires'); + } + + // Mettre à jour le crédit + $result = $wpdb->update( + $table_name, + $data, + array('id' => $credit_id), + array('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%f', '%s', '%s', '%s', '%s', '%s'), + array('%d') + ); + + if ($result === false) { + wp_send_json_error('Erreur lors de la mise à jour du crédit'); + } + + $updated_credit = $this->get_credit_by_id($credit_id); + + wp_send_json_success(array( + 'message' => 'Crédit mis à jour avec succès', + 'credit' => $updated_credit + )); + } + + /** + * Supprimer un crédit + */ + public function ajax_delete_credit() { + // Vérifier le nonce + if (!wp_verify_nonce($_POST['nonce'], 'credit_manager_action')) { + wp_die('Sécurité: Nonce invalide'); + } + + // Vérifier les permissions + if (!current_user_can('edit_posts')) { + wp_die('Permissions insuffisantes'); + } + + global $wpdb; + $table_name = 'cdf_Credits_listing'; + $credit_id = intval($_POST['credit_id']); + + if ($credit_id <= 0) { + wp_send_json_error('ID de crédit invalide'); + } + + // Vérifier si le crédit existe + $existing_credit = $this->get_credit_by_id($credit_id); + if (!$existing_credit) { + wp_send_json_error('Crédit non trouvé'); + } + + // Supprimer le crédit + $result = $wpdb->delete( + $table_name, + array('id' => $credit_id), + array('%d') + ); + + if ($result === false) { + wp_send_json_error('Erreur lors de la suppression du crédit'); + } + + wp_send_json_success(array( + 'message' => 'Crédit supprimé avec succès', + 'credit_id' => $credit_id + )); + } + + /** + * Lister tous les crédits avec pagination et filtres + */ + public function ajax_list_credits() { + // Debug: Log des données POST reçues + error_log('Credit Manager AJAX - POST data: ' . print_r($_POST, true)); + + // Vérifier que le nonce est présent + if (!isset($_POST['nonce']) || empty($_POST['nonce'])) { + error_log('Credit Manager AJAX - Nonce manquant dans POST'); + wp_send_json_error('Nonce manquant'); + return; + } + + // Vérifier le nonce + if (!wp_verify_nonce($_POST['nonce'], 'credit_manager_action')) { + error_log('Credit Manager AJAX - Nonce invalide: ' . $_POST['nonce']); + wp_send_json_error('Sécurité: Nonce invalide'); + return; + } + + // Vérifier les permissions + if (!current_user_can('edit_posts')) { + error_log('Credit Manager AJAX - Permissions insuffisantes'); + wp_send_json_error('Permissions insuffisantes'); + return; + } + + // Récupérer les filtres + $filters = array(); + if (!empty($_POST['localite'])) { + $filters['localite'] = sanitize_text_field($_POST['localite']); + } + if (!empty($_POST['societe_credit'])) { + $filters['societe_credit'] = sanitize_text_field($_POST['societe_credit']); + } + if (!empty($_POST['code_postal'])) { + $filters['code_postal'] = sanitize_text_field($_POST['code_postal']); + } + if (isset($_POST['status']) && $_POST['status'] !== '') { + $filters['status'] = intval($_POST['status']); + } + if (!empty($_POST['type_credit'])) { + $filters['type_credit'] = sanitize_text_field($_POST['type_credit']); + } + if (!empty($_POST['credit_code_select'])) { + $filters['credit_code_select'] = sanitize_text_field($_POST['credit_code_select']); + } + if (!empty($_POST['montant_min'])) { + $filters['montant_min'] = floatval($_POST['montant_min']); + } + if (!empty($_POST['montant_max'])) { + $filters['montant_max'] = floatval($_POST['montant_max']); + } + if (!empty($_POST['date_signature_debut'])) { + $filters['date_signature_debut'] = sanitize_text_field($_POST['date_signature_debut']); + } + if (!empty($_POST['date_signature_fin'])) { + $filters['date_signature_fin'] = sanitize_text_field($_POST['date_signature_fin']); + } + + // Utiliser la méthode get_credits avec les filtres + $credits = $this->get_credits($filters); + + // Récupérer TOUS les crédits pour les compteurs (sans filtre) + $all_credits = $this->get_credits(array()); + + // Calculer les compteurs par statut avec array_reduce + $status_counts = array_reduce($all_credits, function($counts, $credit) { + $status = isset($credit->status) ? (string)$credit->status : '0'; + + if (!isset($counts[$status])) { + $counts[$status] = 0; + } + $counts[$status]++; + + return $counts; + }, array()); + + // S'assurer que tous les statuts ont une valeur (même 0) + $status_counts = array_merge( + array('0' => 0, '1' => 0, '2' => 0, '-1' => 0), + $status_counts + ); + + wp_send_json_success(array( + 'credits' => $credits, + 'total' => count($credits), + 'status_counts' => $status_counts, + 'total_all' => count($all_credits) + )); + } + + /** + * Récupérer les options de filtres + */ + public function ajax_get_filter_options() { + // Vérifier le nonce + if (!wp_verify_nonce($_POST['nonce'], 'credit_manager_action')) { + wp_die('Sécurité: Nonce invalide'); + } + + // Vérifier les permissions + if (!current_user_can('edit_posts')) { + wp_die('Permissions insuffisantes'); + } + + wp_send_json_success(array( + 'localites' => $this->get_distinct_localites(), + 'societes' => $this->get_distinct_societes(), + 'types_credit' => $this->get_distinct_credit_types() + )); + } + + /** + * change credit status + */ + public function ajax_change_credit_status() { + // Vérifier le nonce + if (!wp_verify_nonce($_POST['nonce'], 'credit_manager_action')) { + wp_die('Sécurité: Nonce invalide'); + } + + global $wpdb; + $table_name = 'cdf_Credits_listing'; + $credit_id = isset($_POST['credit_id']) ? absint($_POST['credit_id']) : 0; + $new_status = isset($_POST['new_status']) ? intval($_POST['new_status']) : 0; + + if ($credit_id <= 0) { + wp_send_json_error('ID de crédit invalide'); + } + + // Vérifier si le crédit existe + $existing_credit = $this->get_credit_by_id($credit_id); + + if (!$existing_credit) { + wp_send_json_error('Crédit non trouvé'); + } + + // Changer le statut du crédit + error_log('Credit Manager: change_status id=' . $credit_id . ' new_status=' . $new_status); + + $result = $wpdb->update( + $table_name, + array('status' => $new_status), + array('id' => $credit_id), + array('%d'), + array('%d') + ); + + if ($result === false) { + wp_send_json_error('Erreur lors du changement de statut du crédit'); + } + + // Si statut = 2 (accepté classé), tenter d'ajouter l'email à la liste Mailchimp principale + if (intval($new_status) === 2 && !empty($existing_credit->email)) { + $mailchimpController = $this->getCreditMailchimp(); + if ($mailchimpController && method_exists($mailchimpController, 'subscribe_from_credit')) { + $mailchimpController->subscribe_from_credit($existing_credit); + } + } + + wp_send_json_success(array( + 'message' => 'Statut du crédit changé avec succès', + 'credit_id' => $credit_id, + 'status' => $new_status + )); + } + + /** + * Mettre à jour le statut du crédit (accepté non signé, accepté classé, refusé) + */ + public function ajax_update_credit_status() { + // Vérifier le nonce + if (!wp_verify_nonce($_POST['nonce'], 'credit_manager_action')) { + wp_die('Sécurité: Nonce invalide'); + } + + // Vérifier les permissions + if (!current_user_can('edit_posts')) { + wp_die('Permissions insuffisantes'); + } + + global $wpdb; + $table_name = 'cdf_Credits_listing'; + $credit_id = isset($_POST['credit_id']) ? absint($_POST['credit_id']) : 0; + $status = isset($_POST['status']) ? sanitize_text_field($_POST['status']) : ''; + + if ($credit_id <= 0) { + wp_send_json_error('ID de crédit invalide'); + } + + // Vérifier si le crédit existe + $existing_credit = $this->get_credit_by_id($credit_id); + if (!$existing_credit) { + wp_send_json_error('Crédit non trouvé'); + } + + // Mapper les statuts aux valeurs numériques + $status_map = array( + 'accepte_non_signe' => 1, + 'accepte_classe' => 2, + 'refuse' => -1 + ); + + if (!isset($status_map[$status])) { + wp_send_json_error('Statut invalide'); + } + + $status_value = $status_map[$status]; + + // Mettre à jour le statut + error_log('Credit Manager: update_status id=' . $credit_id . ' status=' . $status . ' value=' . $status_value); + + $result = $wpdb->update( + $table_name, + array('status' => $status_value), + array('id' => $credit_id), + array('%d'), + array('%d') + ); + + if ($result === false) { + wp_send_json_error('Erreur lors de la mise à jour du statut'); + } + + // Si statut = 2 (accepté classé), tenter d'ajouter l'email à la liste Mailchimp principale + if (intval($status_value) === 2 && !empty($existing_credit->email)) { + $mailchimpController = $this->getCreditMailchimp(); + if ($mailchimpController && method_exists($mailchimpController, 'subscribe_from_credit')) { + $mailchimpController->subscribe_from_credit($existing_credit); + } + } + + wp_send_json_success(array( + 'message' => 'Statut mis à jour avec succès', + 'credit_id' => $credit_id, + 'status' => $status, + 'status_value' => $status_value + )); + } + + /** + * Si la configuration Mailchimp est présente, abonner le contact à l'audience principale. + * @param object $credit Objet crédit contenant au moins email, prenom, nom + */ + // méthode supprimée: la logique d'abonnement est dans CRED_credit_mailchimp +} \ No newline at end of file diff --git a/app/controllers/credit_sendy.php b/app/controllers/credit_sendy.php new file mode 100644 index 0000000..3697976 --- /dev/null +++ b/app/controllers/credit_sendy.php @@ -0,0 +1,495 @@ + 'array', + 'sanitize_callback' => array($this, 'sanitize_options'), + 'default' => array( + 'api_url' => '', + 'api_key' => '', + 'brand_id' => '', + 'list_id' => '' + ) + ) + ); + + add_settings_section( + 'cred_sendy_main_section', + __('Paramètres de connexion', 'esi-creditdirect'), + function() { + echo '

' . esc_html__('Renseignez l\'URL de votre installation Sendy et la clé API comme indiqué dans votre compte Sendy.', 'esi-creditdirect') . '

'; + }, + 'credit-sendy' + ); + + add_settings_field( + 'cred_sendy_api_url', + __('URL Sendy', 'esi-creditdirect'), + array($this, 'field_api_url_cb'), + 'credit-sendy', + 'cred_sendy_main_section' + ); + + add_settings_field( + 'cred_sendy_api_key', + __('Clé API', 'esi-creditdirect'), + array($this, 'field_api_key_cb'), + 'credit-sendy', + 'cred_sendy_main_section' + ); + + add_settings_field( + 'cred_sendy_brand_id', + __('ID du Brand', 'esi-creditdirect'), + array($this, 'field_brand_id_cb'), + 'credit-sendy', + 'cred_sendy_main_section' + ); + + add_settings_field( + 'cred_sendy_list_id', + __('ID de la liste', 'esi-creditdirect'), + array($this, 'field_list_id_cb'), + 'credit-sendy', + 'cred_sendy_main_section' + ); + } + + /** + * Affiche la page de réglages + */ + public function render_settings_page() { + $options = $this->get_options(); + include plugin_dir_path(__FILE__) . '../../templates/admin/sendy_settings.php'; + } + + /** + * Callback du champ API URL + */ + public function field_api_url_cb() { + $options = $this->get_options(); + $value = isset($options['api_url']) ? $options['api_url'] : ''; + echo ''; + echo '

' . esc_html__('URL complète de votre installation Sendy (ex: https://sendy.example.com)', 'esi-creditdirect') . '

'; + } + + /** + * Callback du champ API Key + */ + public function field_api_key_cb() { + $options = $this->get_options(); + $value = isset($options['api_key']) ? $options['api_key'] : ''; + echo ''; + echo '

' . esc_html__('Clé API disponible dans votre compte Sendy (Settings > API)', 'esi-creditdirect') . '

'; + } + + /** + * Callback du champ Brand ID + */ + public function field_brand_id_cb() { + $options = $this->get_options(); + $selected = isset($options['brand_id']) ? $options['brand_id'] : ''; + + $client = $this->get_client(); + if ($client === null) { + echo '' . esc_html__('Renseignez d\'abord l\'URL et la clé API, puis enregistrez.', 'esi-creditdirect') . ''; + echo '
'; + echo ''; + return; + } + + $brands = array(); + try { + $brands = $this->get_brands(); + } catch (\Throwable $e) { + echo '

' . esc_html(sprintf(__('Erreur lors du chargement des brands: %s', 'esi-creditdirect'), $e->getMessage())) . '

'; + } + + if (empty($brands)) { + echo '' . esc_html__('Aucun brand trouvé ou erreur. Vous pouvez saisir un ID manuellement.', 'esi-creditdirect') . ''; + echo '
'; + echo ''; + return; + } + + echo ''; + echo '

' . esc_html__('Sélectionnez un brand pour filtrer les listes disponibles (optionnel)', 'esi-creditdirect') . '

'; + } + + /** + * Callback du champ Liste ID + */ + public function field_list_id_cb() { + $options = $this->get_options(); + $selected = isset($options['list_id']) ? $options['list_id'] : ''; + + $client = $this->get_client(); + if ($client === null) { + echo '' . esc_html__('Renseignez d\'abord l\'URL et la clé API, puis enregistrez.', 'esi-creditdirect') . ''; + echo '
'; + echo ''; + return; + } + + $lists = array(); + try { + $lists = $this->get_lists(); + } catch (\Throwable $e) { + echo '

' . esc_html(sprintf(__('Erreur lors du chargement des listes: %s', 'esi-creditdirect'), $e->getMessage())) . '

'; + } + + if (empty($lists)) { + echo '' . esc_html__('Aucune liste trouvée ou erreur. Vous pouvez saisir un ID manuellement.', 'esi-creditdirect') . ''; + echo '
'; + echo ''; + return; + } + + echo ''; + } + + /** + * Sanitize des options + */ + public function sanitize_options($options) { + $sanitized = array(); + $sanitized['api_url'] = isset($options['api_url']) ? esc_url_raw($options['api_url']) : ''; + $sanitized['api_key'] = isset($options['api_key']) ? sanitize_text_field($options['api_key']) : ''; + $sanitized['brand_id'] = isset($options['brand_id']) ? sanitize_text_field($options['brand_id']) : ''; + $sanitized['list_id'] = isset($options['list_id']) ? sanitize_text_field($options['list_id']) : ''; + return $sanitized; + } + + /** + * Récupère les options du plugin + */ + private function get_options() { + $defaults = array( + 'api_url' => '', + 'api_key' => '', + 'brand_id' => '', + 'list_id' => '' + ); + $options = get_option('cred_sendy_options', array()); + if (!is_array($options)) { + $options = array(); + } + return array_merge($defaults, $options); + } + + /** + * Retourne les informations de connexion Sendy + * ou null si les informations de connexion sont incomplètes. + */ + public function get_client() { + $options = $this->get_options(); + $apiUrl = isset($options['api_url']) ? trim($options['api_url']) : ''; + $apiKey = isset($options['api_key']) ? trim($options['api_key']) : ''; + + if ($apiUrl === '' || $apiKey === '') { + return null; + } + + // Retourne un tableau avec les infos de connexion + return array( + 'api_url' => rtrim($apiUrl, '/'), + 'api_key' => $apiKey + ); + } + + /** + * Récupère la liste des brands Sendy + * @return array Tableau de brands avec id et name + */ + private function get_brands() { + $client = $this->get_client(); + if ($client === null) { + return array(); + } + + $apiUrl = $client['api_url']; + $apiKey = $client['api_key']; + + // Sendy API endpoint pour récupérer les brands + $url = $apiUrl . '/api/brands/get-brands.php'; + + $response = wp_remote_post($url, array( + 'body' => array( + 'api_key' => $apiKey + ), + 'timeout' => 15 + )); + + if (is_wp_error($response)) { + throw new \Exception($response->get_error_message()); + } + + $body = wp_remote_retrieve_body($response); + $data = json_decode($body, true); + + if (!$data || !is_array($data)) { + return array(); + } + + $brands = array(); + foreach ($data as $id => $name) { + $brands[] = array( + 'id' => (string) $id, + 'name' => (string) $name + ); + } + + return $brands; + } + + /** + * Récupère la liste des listes Sendy pour un brand donné + * @param string $brandId ID du brand + * @return array Tableau de listes avec id et name + */ + private function get_lists_for_brand($brandId) { + $client = $this->get_client(); + if ($client === null) { + return array(); + } + + $apiUrl = $client['api_url']; + $apiKey = $client['api_key']; + + // Sendy API endpoint pour récupérer les listes + $url = $apiUrl . '/api/lists/get-lists.php'; + + $response = wp_remote_post($url, array( + 'body' => array( + 'api_key' => $apiKey, + 'brand_id' => $brandId, + 'include_hidden' => 'no' + ), + 'timeout' => 15 + )); + + if (is_wp_error($response)) { + throw new \Exception($response->get_error_message()); + } + + $body = wp_remote_retrieve_body($response); + $data = json_decode($body, true); + + if (!$data || !is_array($data)) { + return array(); + } + + $lists = array(); + foreach ($data as $id => $name) { + $lists[] = array( + 'id' => (string) $id, + 'name' => (string) $name + ); + } + + return $lists; + } + + /** + * Récupère toutes les listes Sendy de tous les brands ou d'un brand spécifique + * @return array Tableau de listes avec id, name et brand_name + */ + private function get_lists() { + $client = $this->get_client(); + if ($client === null) { + return array(); + } + + try { + $options = $this->get_options(); + $selectedBrandId = isset($options['brand_id']) ? trim($options['brand_id']) : ''; + + // Si un brand_id est sélectionné, ne récupérer que les listes de ce brand + if ($selectedBrandId !== '') { + $brands = $this->get_brands(); + $selectedBrand = null; + foreach ($brands as $brand) { + if ($brand['id'] === $selectedBrandId) { + $selectedBrand = $brand; + break; + } + } + + if ($selectedBrand) { + $lists = $this->get_lists_for_brand($selectedBrandId); + $allLists = array(); + foreach ($lists as $list) { + $allLists[] = array( + 'id' => $list['id'], + 'name' => $list['name'], + 'brand_name' => $selectedBrand['name'] + ); + } + return $allLists; + } + } + + // Sinon, récupérer toutes les listes de tous les brands + $brands = $this->get_brands(); + if (empty($brands)) { + return array(); + } + + $allLists = array(); + foreach ($brands as $brand) { + $lists = $this->get_lists_for_brand($brand['id']); + foreach ($lists as $list) { + $allLists[] = array( + 'id' => $list['id'], + 'name' => $list['name'], + 'brand_name' => $brand['name'] + ); + } + } + + return $allLists; + } catch (\Throwable $e) { + throw $e; + } + } + + /** + * AJAX: ping Sendy pour valider la connexion + */ + public function ajax_ping() { + check_ajax_referer('cred_sendy_ping', 'nonce'); + if (!current_user_can('manage_options')) { + wp_send_json_error(array('message' => __('Permissions insuffisantes', 'esi-creditdirect')), 403); + } + + $client = $this->get_client(); + if ($client === null) { + wp_send_json_error(array('message' => __('Configuration incomplète (URL/clé API).', 'esi-creditdirect')), 400); + } + + try { + // Test de connexion en récupérant les brands + $brands = $this->get_brands(); + $lists = $this->get_lists(); + wp_send_json_success(array( + 'message' => __('Connexion réussie', 'esi-creditdirect'), + 'brands_count' => count($brands), + 'lists_count' => count($lists) + )); + } catch (\Throwable $e) { + wp_send_json_error(array('message' => $e->getMessage()), 500); + } + } + + /** + * Abonne ou met à jour un contact à partir d'un objet crédit. + * @param object $credit Objet avec au minimum les propriétés email, prenom, nom + */ + public function subscribe_from_credit($credit) { + if (!$credit || !isset($credit->email)) { + return; + } + + $email = trim((string)$credit->email); + if ($email === '' || !is_email($email)) { + return; + } + + $options = $this->get_options(); + $listId = isset($options['list_id']) ? trim((string)$options['list_id']) : ''; + if ($listId === '') { + return; + } + + $client = $this->get_client(); + if ($client === null) { + return; + } + + $firstName = isset($credit->prenom) ? (string)$credit->prenom : ''; + $lastName = isset($credit->nom) ? (string)$credit->nom : ''; + + $apiUrl = $client['api_url']; + $apiKey = $client['api_key']; + + // Sendy API endpoint pour s'abonner + $url = $apiUrl . '/subscribe'; + + $body = array( + 'api_key' => $apiKey, + 'email' => $email, + 'list' => $listId, + 'boolean' => 'true' + ); + + // Ajouter le nom si disponible + if ($firstName !== '' || $lastName !== '') { + $name = trim($firstName . ' ' . $lastName); + if ($name !== '') { + $body['name'] = $name; + } + } + + try { + $response = wp_remote_post($url, array( + 'body' => $body, + 'timeout' => 15 + )); + + if (is_wp_error($response)) { + throw new \Exception($response->get_error_message()); + } + + $responseBody = wp_remote_retrieve_body($response); + // Sendy retourne généralement "true" ou "1" en cas de succès + if ($responseBody !== 'true' && $responseBody !== '1') { + error_log('Sendy subscribe error (from credit): ' . $responseBody); + } + } catch (\Throwable $e) { + error_log('Sendy subscribe error (from credit): ' . $e->getMessage()); + } + } +} diff --git a/app/controllers/old/credit-step1.php b/app/controllers/old/credit-step1.php new file mode 100644 index 0000000..e94c855 --- /dev/null +++ b/app/controllers/old/credit-step1.php @@ -0,0 +1,271 @@ +validateForDisplay($turnstileToken, $_SERVER['REMOTE_ADDR'] ?? null); + + if (!$turnstileResult['valid']) { + $turnstile_error = $turnstileResult['message']; + } +} + +// Ne traiter le formulaire que si Turnstile est valide (ou non configuré) +if (!isset($turnstile_error) && !$one_step_form_send && !isset($_GET['credit-direct-token'])) { + $token = $model->save_step_0($post); +} else if(isset($_POST['credit_token'])) { + $token = $_POST['credit_token']; +} else if(isset($_GET['credit-direct-token'])) { + $token = $_GET['credit-direct-token']; +} else { + wp_redirect(home_url()); +} + + +$currentCredit = $model->getCredit($token); + +if (!is_object($currentCredit)) { + wp_redirect(home_url()); +} + +/* echo '
';
+print_r($_POST);
+echo '
'; */ +/* die(); */ + +// Débogage +/* error_log('POST one_step_form: ' . (isset($_POST['one_step_form']) ? $_POST['one_step_form'] : 'non défini')); +error_log('one_step_credits: ' . print_r($one_step_credits, true)); */ + +if (file_exists(WP_PLUGIN_DIR . '/ESI_creditDirect/app/models/credit-step1.php') || file_exists(WP_PLUGIN_DIR . '/ESI_creditDirect/app/models/credit-one-step.php')) { + + + + $in_one_step = false; + $civilStatus = $model->getCivilStatus(); + $works = $model->getWorks(); + $existingCreditTypes = $model->getExistingCreditTypes(); + $contractTypes = $model->getContractTypes(); + + + + /* echo '
';
+    print_r($currentCredit);
+    echo '
'; */ + + if(in_array($currentCredit->type_credit, $one_step_credits)) + $in_one_step = true; + + + if($one_step_form_send) { + $model->save_one_step($post); + + /* echo '
';
+        print_r($_FILES);
+        echo '
'; */ + } + + //try to load the view + if (file_exists(WP_PLUGIN_DIR . '/ESI_creditDirect/templates/front/credit-step1.php')) { + + $agencies = $model->getAgencies(); + $map_credit_type = $model->getCreditTypes(); + $mapHouseCreditTypes = $model->getHouseCreditTypes(); + /*re-hydrate current credit*/ + $currentCredit = $model->getCredit($token); + $message = null; + + $type_credit_selected = ''; + + if(isset($currentCredit->sel_credit) && !empty($currentCredit->sel_credit)) { + $type_credit_selected = $currentCredit->sel_credit; + } + + if(isset($_POST['type_credit_selected']) && !empty($_POST['type_credit_selected']) || isset($_POST['sub_loan_type']) && !empty($_POST['sub_loan_type'])) + $type_credit_selected = isset($_POST['sub_loan_type']) ? $_POST['sub_loan_type'] : $_POST['type_credit_selected']; + + + $creditOptionsLabels = !empty($type_credit_selected) ? $model->getCreditLabel($type_credit_selected) : $map_credit_type[$currentCredit->type_credit]; + + //save the credit options labels in a cookie for 2 months + /* $model->save_step($currentCredit); */ + + $attachments = []; + $upload_errors = []; + /* + // Exemple d'utilisation de la fonction handleUploads + $allowed_types = [ + 'application/pdf', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', // docx + 'application/msword', // doc + 'image/jpeg', + 'image/png', + 'image/gif', + 'image/bmp', + 'image/webp' + ]; + $max_size = 2 * 1024 * 1024; // 2 Mo + $result = $model->handleUploads($_FILES, $allowed_types, $max_size, $token); + $attachments = $result['files']; + $upload_errors = $result['errors']; + $html_links = $result['html_links']; + */ + if(isset($_FILES)) { + if ($one_step_form_send) { // 4 = no file uploaded + $allowed_types = [ + 'application/pdf', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', // docx + 'application/msword', // doc + 'image/jpeg', + 'image/png', + 'image/gif', + 'image/bmp', + 'image/webp' + ]; + + //remove all the empty file from $_FILE + foreach($_FILES as $key => $value) { + if($value['error'] === 4) { + unset($_FILES[$key]); + } + } + + $max_size = 4 * 1024 * 1024; // 4 Mo + $result = $model->handleUploads($_FILES, $allowed_types, $max_size, $token); + + /* echo '
';
+                print_r($result);
+                echo '
'; + die(); */ + + $attachments = $result['files']; + $upload_errors = $result['errors']; + } + } + + $borrower = $model->getBorrower($currentCredit); + + /* echo '
';
+        print_r($borrower);
+        echo '
'; + die(); */ + + if($one_step_form_send) { + if (file_exists(WP_PLUGIN_DIR . '/ESI_creditDirect/templates/email/credit-one-step-mail.php')) { + $currentCredit = $model->getCredit($token); + + $coBorrower = $model->getCoBorrower($currentCredit); + + /* echo '
';
+                print_r($currentCredit);
+                echo '
'; + + echo '
';
+                print_r($borrower);
+                echo '
'; + die(); */ + + ob_start(); + include(WP_PLUGIN_DIR . '/ESI_creditDirect/templates/email/credit-one-step-mail.php'); + $message = ob_get_clean(); + + ob_start(); + include(WP_PLUGIN_DIR . '/ESI_creditDirect/templates/email/clients_emails/credit-one-step-mail-client.php'); + $message_client = ob_get_clean(); + + // Ajout des en-têtes pour une meilleure compatibilité Outlook + /* $headers = array( + 'Content-Type: text/html; charset=UTF-8', + 'X-Mailer: PHP/' . phpversion(), + 'MIME-Version: 1.0' + ); */ + + /* echo '
';
+                print_r($attachments);
+                echo '
'; + die(); */ + + // Exception : ne pas envoyer de mail si l'utilisateur connecté a l'ID 1 + if (!is_user_logged_in() || get_current_user_id() != 1) { + // Envoi de l'email au client + $model->sendEmail('Demande de crédit', $message_client, $borrower, $currentCredit, [], true); + + // Envoi de l'email à l'administrateur + $model->sendEmail('Demande de crédit', $message, $borrower, $currentCredit, [], false); + } + + // Nettoyage des fichiers temporaires + /* foreach ($attachments as $file) { + if (file_exists($file)) @unlink($file); + } */ + include(WP_PLUGIN_DIR . '/ESI_creditDirect/templates/front/credit-step5.php'); + } + if (!empty($upload_errors)) { + foreach ($upload_errors as $err) { + echo '
' . htmlspecialchars($err) . '
'; + } + } + } else { + if($in_one_step) { + include(WP_PLUGIN_DIR . '/ESI_creditDirect/templates/front/credit-one-step.php'); + } else { + include(WP_PLUGIN_DIR . '/ESI_creditDirect/templates/front/credit-step1.php'); + } + } + } +} + +get_footer(); \ No newline at end of file diff --git a/app/controllers/old/credit-step2.php b/app/controllers/old/credit-step2.php new file mode 100644 index 0000000..3365775 --- /dev/null +++ b/app/controllers/old/credit-step2.php @@ -0,0 +1,153 @@ +checkOngoingCreditRequest(); + + if(!$ongoing_credit && empty($_POST) && !$is_from_back) { + wp_redirect(home_url()); + exit; + } + + // Vérifier le token soit en POST soit en GET + $token = isset($_POST['credit-direct-token']) ? $_POST['credit-direct-token'] : (isset($_GET['credit-direct-token']) ? $_GET['credit-direct-token'] : null); + + if(null === $token) { + $token = $model->get_ongoing_credit_token(); + } + + if (empty($token)) { + wp_redirect(home_url()); + exit; + } + + get_header(); + + //try to load the model + $post = $_POST; + if (empty($post)) { + $post = array('credit-direct-token' => $token); + } + + + + $currentCredit = $model->getCredit($token); + $borrower = $model->getBorrower($currentCredit); + $coBorrower = $model->getCoBorrower($currentCredit); + + $hasCoBorrower = $model->hasCoBorrower($currentCredit); + + $is_credit_auto = $model->is_credit_auto($currentCredit); + + $type_credit_selected = ''; + + if(isset($currentCredit->sel_credit) && !empty($currentCredit->sel_credit)) { + $type_credit_selected = $currentCredit->sel_credit; + } + + if(isset($_POST['type_credit_selected']) && !empty($_POST['type_credit_selected']) || isset($_POST['sub_loan_type']) && !empty($_POST['sub_loan_type'])) + $type_credit_selected = isset($_POST['sub_loan_type']) ? $_POST['sub_loan_type'] : $_POST['type_credit_selected']; + + if(empty($type_credit_selected)) { + $type_credit_selected = $currentCredit->type_credit; + } + + + + if (is_object($currentCredit)) { + // Sauvegarder l'étape 1 seulement si on vient du formulaire POST + if (!empty($_POST)) { + // Validation Turnstile si configuré + if (\libraries\TurnstileValidator::isConfigured()) { + $turnstileToken = isset($_POST['cf-turnstile-response']) ? $_POST['cf-turnstile-response'] : ''; + $turnstileValidator = new \libraries\TurnstileValidator(); + $turnstileResult = $turnstileValidator->validateForDisplay($turnstileToken, $_SERVER['REMOTE_ADDR'] ?? null); + + if (!$turnstileResult['valid']) { + $turnstile_error = $turnstileResult['message']; + } + } + + // Ne traiter le formulaire que si Turnstile est valide (ou non configuré) + if (!isset($turnstile_error)) { + $result = $model->save_step_1($post); + + // Vérifier s'il y a des erreurs de validation + if (is_array($result) && isset($result['success']) && !$result['success']) { + $validation_errors = $result['formatted_errors']; + } else { + $model->save_step($currentCredit); + } + } + } + + $contractTypes = $model->getContractTypes(); + $mapHouseCreditTypes = $model->getHouseCreditTypes(); + + // Utilisation du mode debug pour charger les templates + $template_a = CRED::getTemplatePath('/templates/front/credit-step2-a.php'); + $template_b = CRED::getTemplatePath('/templates/front/credit-step2-b.php'); + $template_c = CRED::getTemplatePath('/templates/front/credit-step2-c.php'); + + /* echo '
';
+        print_r($_COOKIE);
+        echo '
'; */ + + + //try to load the view + if (file_exists(WP_PLUGIN_DIR . '/ESI_creditDirect' . $template_a)) { + include(WP_PLUGIN_DIR . '/ESI_creditDirect' . $template_a); + } + if (file_exists(WP_PLUGIN_DIR . '/ESI_creditDirect' . $template_b)) { + include(WP_PLUGIN_DIR . '/ESI_creditDirect' . $template_b); + } + if (file_exists(WP_PLUGIN_DIR . '/ESI_creditDirect' . $template_c)) { + include(WP_PLUGIN_DIR . '/ESI_creditDirect' . $template_c); + } + } else { + // Si le crédit n'existe pas, rediriger vers la page d'accueil + wp_redirect(home_url()); + exit; + } +} + +get_footer(); \ No newline at end of file diff --git a/app/controllers/old/credit-step3.php b/app/controllers/old/credit-step3.php new file mode 100644 index 0000000..0263e41 --- /dev/null +++ b/app/controllers/old/credit-step3.php @@ -0,0 +1,193 @@ +get_ongoing_credit_token(); +} + +if (empty($token)) { + wp_redirect(home_url()); + exit; +} + +$currentCredit = $model->getCredit($token); + +if(isset($_GET['debug'])) { + echo '
';
+    print_r($token);
+    print_r($currentCredit);
+    echo '
'; + //die(); +} + +/* echo '
';
+print_r($currentCredit);
+echo '
'; +die(); */ + +$is_credit_pat = $model->is_credit_pat($currentCredit); + +$type_credit_selected = ''; + +if(isset($currentCredit->sel_credit) && !empty($currentCredit->sel_credit)) { + $type_credit_selected = $currentCredit->sel_credit; +} + +if(isset($_POST['type_credit_selected']) && !empty($_POST['type_credit_selected']) || isset($_POST['sub_loan_type']) && !empty($_POST['sub_loan_type'])) + $type_credit_selected = isset($_POST['sub_loan_type']) ? $_POST['sub_loan_type'] : $_POST['type_credit_selected']; + +if(empty($type_credit_selected)) { + $type_credit_selected = $currentCredit->type_credit; +} + +get_header(); + +//try to load the model +$post = $_POST; +if (empty($post)) { + $post = array('credit-direct-token' => $token); +} + +if (file_exists(WP_PLUGIN_DIR . '/ESI_creditDirect/app/models/credit_step3.php')) { + + + if (is_object($currentCredit)) { + // Sauvegarder l'étape 2 seulement si on vient du formulaire POST + if (!empty($_POST)) { + // Validation Turnstile si configuré + if (\libraries\TurnstileValidator::isConfigured()) { + $turnstileToken = isset($_POST['cf-turnstile-response']) ? $_POST['cf-turnstile-response'] : ''; + $turnstileValidator = new \libraries\TurnstileValidator(); + $turnstileResult = $turnstileValidator->validateForDisplay($turnstileToken, $_SERVER['REMOTE_ADDR'] ?? null); + + if (!$turnstileResult['valid']) { + $turnstile_error = $turnstileResult['message']; + } + } + + // Ne traiter le formulaire que si Turnstile est valide (ou non configuré) + if (!isset($turnstile_error)) { + $result = $model->save_step_2($post,$currentCredit); + + // Vérifier s'il y a des erreurs de validation + if (is_array($result) && isset($result['success']) && !$result['success']) { + $validation_errors = $result['formatted_errors']; + } + } + + // Gestion générique de l'upload de fichiers + $attachments = []; + $upload_errors = []; + /* + // Exemple d'utilisation de la fonction handleUploads + $allowed_types = [ + 'application/pdf', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', // docx + 'application/msword', // doc + 'image/jpeg', + 'image/png', + 'image/gif', + 'image/bmp', + 'image/webp' + ]; + $max_size = 2 * 1024 * 1024; // 2 Mo + $result = $model->handleUploads($_FILES, $allowed_types, $max_size, $token); + $attachments = $result['files']; + $upload_errors = $result['errors']; + $html_links = $result['html_links']; + */ + $allowed_types = [ + 'application/pdf', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', // docx + 'application/msword', // doc + 'image/jpeg', + 'image/png', + 'image/gif', + 'image/bmp', + 'image/webp' + ]; + $max_size = 4 * 1024 * 1024; // 4 Mo + + /* echo '
';
+            print_r($_FILES);
+            echo '
'; */ + + if(!empty($_FILES)) { + foreach ($_FILES as $field => $file) { + + // Traiter seulement les champs de fichiers qui ne sont pas vides + if(empty($file['name']) || empty($file['name'][0]) || $file['error'] === 4) { + continue; + } + + if (isset($file['error']) && $file['error'] !== 4) { // 4 = pas de fichier uploadé + $result = $model->handleUploads($file, $allowed_types, $max_size, $token); + $attachments = array_merge($attachments, $result['files']); + $upload_errors = array_merge($upload_errors, $result['errors']); + } + } + // Affichage des erreurs d'upload + if (!empty($upload_errors)) { + foreach ($upload_errors as $err) { + echo '
' . htmlspecialchars($err) . '
'; + } + } + } + } + + //try to load the view + if (file_exists(WP_PLUGIN_DIR . '/ESI_creditDirect/templates/front/credit-step3.php')) { + $coBorrower = $model->getCoBorrower($currentCredit); + $borrower = $model->getBorrower($currentCredit); + include(WP_PLUGIN_DIR . '/ESI_creditDirect/templates/front/credit-step3.php'); + } + } else { + // Si le crédit n'existe pas, rediriger vers la page d'accueil + wp_redirect(home_url()); + exit; + } +} + +get_footer(); \ No newline at end of file diff --git a/app/controllers/old/credit-step4.php b/app/controllers/old/credit-step4.php new file mode 100644 index 0000000..239cda2 --- /dev/null +++ b/app/controllers/old/credit-step4.php @@ -0,0 +1,107 @@ +get_ongoing_credit_token(); +} + +if (empty($token)) { + wp_redirect(home_url()); + exit; +} + +get_header(); + +//try to load the model +$post = $_POST; +if (empty($post)) { + $post = array('credit-direct-token' => $token); +} + +if (file_exists(WP_PLUGIN_DIR . '/ESI_creditDirect/app/models/credit_step4.php')) { + + + $currentCredit = $model->getCredit($token); + + $type_credit_selected = ''; + + $coBorrower = $model->getCoBorrower($currentCredit); + $borrower = $model->getBorrower($currentCredit); + + if(isset($currentCredit->sel_credit) && !empty($currentCredit->sel_credit)) { + $type_credit_selected = $currentCredit->sel_credit; + } + + if(isset($_POST['type_credit_selected']) && !empty($_POST['type_credit_selected']) || isset($_POST['sub_loan_type']) && !empty($_POST['sub_loan_type'])) + $type_credit_selected = isset($_POST['sub_loan_type']) ? $_POST['sub_loan_type'] : $_POST['type_credit_selected']; + + if(empty($type_credit_selected)) { + $type_credit_selected = $currentCredit->type_credit; + } + + if (is_object($currentCredit)) { + // Sauvegarder l'étape 3 seulement si on vient du formulaire POST + if (!empty($_POST)) { + // Validation Turnstile si configuré + if (\libraries\TurnstileValidator::isConfigured()) { + $turnstileToken = isset($_POST['cf-turnstile-response']) ? $_POST['cf-turnstile-response'] : ''; + $turnstileValidator = new \libraries\TurnstileValidator(); + $turnstileResult = $turnstileValidator->validateForDisplay($turnstileToken, $_SERVER['REMOTE_ADDR'] ?? null); + + if (!$turnstileResult['valid']) { + $turnstile_error = $turnstileResult['message']; + } + } + + // Ne traiter le formulaire que si Turnstile est valide (ou non configuré) + if (!isset($turnstile_error)) { + $model->save_step_3($post, $currentCredit); + } + } + + //try to load the view + if (file_exists(WP_PLUGIN_DIR . '/ESI_creditDirect/templates/front/credit-step4.php')) { + include(WP_PLUGIN_DIR . '/ESI_creditDirect/templates/front/credit-step4.php'); + } + } else { + // Si le crédit n'existe pas, rediriger vers la page d'accueil + wp_redirect(home_url()); + exit; + } +} + +get_footer(); \ No newline at end of file diff --git a/app/controllers/old/credit-step5.php b/app/controllers/old/credit-step5.php new file mode 100644 index 0000000..36d92d6 --- /dev/null +++ b/app/controllers/old/credit-step5.php @@ -0,0 +1,128 @@ +'; +print_r($token); +echo ''; */ + +if (empty($token)) { + wp_redirect(home_url()); + exit; +} + +get_header(); + +//try to load the model +$post = $_POST; +if (empty($post)) { + $post = array('credit-direct-token' => $token); +} + +if (file_exists(WP_PLUGIN_DIR . '/ESI_creditDirect/app/models/credit_step5.php')) { + + if(!class_exists('\models\CRED_credit')) { + include(WP_PLUGIN_DIR . '/ESI_creditDirect/app/models/credit.php'); + } + + if(!class_exists('\models\CRED_credit_step5')) { + include(WP_PLUGIN_DIR . '/ESI_creditDirect/app/models/credit_step5.php'); + } + + $model = new CRED_credit_step5(); + + $currentCredit = $model->getCredit($token); + + + if (is_object($currentCredit)) { + // Sauvegarder l'étape 4 seulement si on vient du formulaire POST + + + if (!empty($_POST)) { + $model->save_step_4($post, $currentCredit); + } + + $borrower = $model->getBorrower($currentCredit); + $coBorrower = $model->getCoBorrower($currentCredit); + $agencies = $model->getAgencies(); + $civilStatus = $model->getCivilStatus(); + $works = $model->getWorks(); + $existingCreditTypes = $model->getExistingCreditTypes(); + $map_credit_type = $model->getCreditTypes(); + $contractTypes = $model->getContractTypes(); + $mapHouseCreditTypes = $model->getHouseCreditTypes(); + + $type_credit_selected = ''; + + if(isset($currentCredit->sel_credit) && !empty($currentCredit->sel_credit)) { + $type_credit_selected = $currentCredit->sel_credit; + } + + if(isset($_POST['type_credit_selected']) && !empty($_POST['type_credit_selected']) || isset($_POST['sub_loan_type']) && !empty($_POST['sub_loan_type'])) + $type_credit_selected = isset($_POST['sub_loan_type']) ? $_POST['sub_loan_type'] : $_POST['type_credit_selected']; + + + $creditOptionsLabels = !empty($type_credit_selected) ? $model->getCreditLabel($type_credit_selected) : $map_credit_type[$currentCredit->type_credit]; + + $message = null; + + + if (file_exists(WP_PLUGIN_DIR . '/ESI_creditDirect/templates/email/credit-step4-mail.php')) { + ob_start(); + include(WP_PLUGIN_DIR . '/ESI_creditDirect/templates/email/credit-step4-mail.php'); + $message = ob_get_clean(); + + ob_start(); + include(WP_PLUGIN_DIR . '/ESI_creditDirect/templates/email/clients_emails/credit-step4-mail-client.php'); + $message_client = ob_get_clean(); + + + // Ajout des en-têtes pour une meilleure compatibilité Outlook + + // Exception : ne pas envoyer de mail si l'utilisateur connecté a l'ID 1 + if (!is_user_logged_in() || get_current_user_id() != 1) { + $model->sendEmail('Demande de crédit', $message, $borrower, $currentCredit, [], false); + $model->sendEmail('Demande de crédit', $message_client, $borrower, $currentCredit, [], true); + } + } + + //try to load the view + if (file_exists(WP_PLUGIN_DIR . '/ESI_creditDirect/templates/front/credit-step5.php')) { + include(WP_PLUGIN_DIR . '/ESI_creditDirect/templates/front/credit-step5.php'); + } + + /* if (!is_null($message)) { + echo $message; + } */ + } else { + // Si le crédit n'existe pas, rediriger vers la page d'accueil + wp_redirect(home_url()); + exit; + } +} + +get_footer(); \ No newline at end of file diff --git a/app/controllers/old/credit_mailchimp.php b/app/controllers/old/credit_mailchimp.php new file mode 100644 index 0000000..7207184 --- /dev/null +++ b/app/controllers/old/credit_mailchimp.php @@ -0,0 +1,273 @@ + 'array', + 'sanitize_callback' => array($this, 'sanitize_options'), + 'default' => array( + 'api_key' => '', + 'server_prefix' => '', + 'primary_list_id' => '' + ) + ) + ); + + add_settings_section( + 'cred_mailchimp_main_section', + __('Paramètres de connexion', 'esi-creditdirect'), + function() { + echo '

' . esc_html__('Renseignez la clé API et le préfixe serveur (ex: us19) comme indiqué par Mailchimp.', 'esi-creditdirect') . '

'; + }, + 'credit-mailchimp' + ); + + add_settings_field( + 'cred_mailchimp_api_key', + __('Clé API', 'esi-creditdirect'), + array($this, 'field_api_key_cb'), + 'credit-mailchimp', + 'cred_mailchimp_main_section' + ); + + add_settings_field( + 'cred_mailchimp_server_prefix', + __('Préfixe serveur', 'esi-creditdirect'), + array($this, 'field_server_prefix_cb'), + 'credit-mailchimp', + 'cred_mailchimp_main_section' + ); + + add_settings_field( + 'cred_mailchimp_primary_list', + __('Liste principale (Audience)', 'esi-creditdirect'), + array($this, 'field_primary_list_cb'), + 'credit-mailchimp', + 'cred_mailchimp_main_section' + ); + } + + /** + * Affiche la page de réglages + */ + public function render_settings_page() { + $options = $this->get_options(); + include plugin_dir_path(__FILE__) . '../../templates/admin/mailchimp_settings.php'; + } + + /** + * Callback du champ API Key + */ + public function field_api_key_cb() { + $options = $this->get_options(); + $value = isset($options['api_key']) ? $options['api_key'] : ''; + echo ''; + } + + /** + * Callback du champ Server Prefix + */ + public function field_server_prefix_cb() { + $options = $this->get_options(); + $value = isset($options['server_prefix']) ? $options['server_prefix'] : ''; + echo ''; + } + + /** + * Callback du champ Liste principale (audience) + */ + public function field_primary_list_cb() { + $options = $this->get_options(); + $selected = isset($options['primary_list_id']) ? $options['primary_list_id'] : ''; + + $client = $this->get_client(); + if ($client === null) { + echo '' . esc_html__('Renseignez d\'abord la clé API et le préfixe serveur, puis enregistrez.', 'esi-creditdirect') . ''; + echo '
'; + echo ''; + return; + } + + $lists = array(); + try { + $resp = $client->lists->getAllLists(array('count' => 1000)); + if (is_array($resp) && isset($resp['lists']) && is_array($resp['lists'])) { + foreach ($resp['lists'] as $list) { + if (isset($list['id']) && isset($list['name'])) { + $lists[] = array( + 'id' => (string) $list['id'], + 'name' => (string) $list['name'] + ); + } + } + } + } catch (\Throwable $e) { + echo '

' . esc_html(sprintf(__('Erreur lors du chargement des audiences: %s', 'esi-creditdirect'), $e->getMessage())) . '

'; + } + + if (empty($lists)) { + echo '' . esc_html__('Aucune audience trouvée ou erreur. Vous pouvez saisir un ID manuellement.', 'esi-creditdirect') . ''; + echo '
'; + echo ''; + return; + } + + echo ''; + } + + /** + * Sanitize des options + */ + public function sanitize_options($options) { + $sanitized = array(); + $sanitized['api_key'] = isset($options['api_key']) ? sanitize_text_field($options['api_key']) : ''; + $sanitized['server_prefix'] = isset($options['server_prefix']) ? sanitize_text_field($options['server_prefix']) : ''; + $sanitized['primary_list_id'] = isset($options['primary_list_id']) ? sanitize_text_field($options['primary_list_id']) : ''; + return $sanitized; + } + + /** + * Récupère les options du plugin + */ + private function get_options() { + $defaults = array( + 'api_key' => '', + 'server_prefix' => '', + 'primary_list_id' => '' + ); + $options = get_option('cred_mailchimp_options', array()); + if (!is_array($options)) { + $options = array(); + } + return array_merge($defaults, $options); + } + + /** + * Retourne une instance configurée du client Mailchimp Marketing + * ou null si les informations de connexion sont incomplètes. + */ + public function get_client() { + $options = $this->get_options(); + $apiKey = isset($options['api_key']) ? trim($options['api_key']) : ''; + $server = isset($options['server_prefix']) ? trim($options['server_prefix']) : ''; + + if ($apiKey === '' || $server === '') { + return null; + } + + + if (!class_exists('\\MailchimpMarketing\\ApiClient')) { + return null; + } + + + + $client = new \MailchimpMarketing\ApiClient(); + $client->setConfig(array( + 'apiKey' => $apiKey, + 'server' => $server + )); + + return $client; + } + + /** + * AJAX: ping Mailchimp pour valider la connexion + */ + public function ajax_ping() { + check_ajax_referer('cred_mailchimp_ping', 'nonce'); + if (!current_user_can('manage_options')) { + wp_send_json_error(array('message' => __('Permissions insuffisantes', 'esi-creditdirect')), 403); + } + + $client = $this->get_client(); + if ($client === null) { + wp_send_json_error(array('message' => __('Configuration incomplète (clé API/préfixe serveur).', 'esi-creditdirect')), 400); + } + + try { + $resp = $client->ping->get(); + wp_send_json_success(array('response' => $resp)); + } catch (\Throwable $e) { + wp_send_json_error(array('message' => $e->getMessage()), 500); + } + } + + /** + * Abonne ou met à jour un contact à partir d'un objet crédit. + * @param object $credit Objet avec au minimum les propriétés email, prenom, nom + */ + public function subscribe_from_credit($credit) { + if (!$credit || !isset($credit->email)) { + return; + } + + $email = trim((string)$credit->email); + if ($email === '' || !is_email($email)) { + return; + } + + $options = get_option('cred_mailchimp_options', array()); + $listId = isset($options['primary_list_id']) ? trim((string)$options['primary_list_id']) : ''; + if ($listId === '') { + return; + } + + $client = $this->get_client(); + if ($client === null) { + return; + } + + $firstName = isset($credit->prenom) ? (string)$credit->prenom : ''; + $lastName = isset($credit->nom) ? (string)$credit->nom : ''; + + $subscriberHash = md5(strtolower($email)); + $body = array( + 'email_address' => $email, + 'status' => 'subscribed', + 'status_if_new' => 'subscribed', + 'merge_fields' => array( + 'FNAME' => $firstName, + 'LNAME' => $lastName + ) + ); + + try { + $client->lists->setListMember($listId, $subscriberHash, $body); + } catch (\Throwable $e) { + error_log('Mailchimp subscribe error (from credit): ' . $e->getMessage()); + } + } +} \ No newline at end of file diff --git a/app/controllers/old/credit_manager.php b/app/controllers/old/credit_manager.php new file mode 100644 index 0000000..2c74d08 --- /dev/null +++ b/app/controllers/old/credit_manager.php @@ -0,0 +1,1337 @@ + 'Prêt personnel / Tous motifs / Achats divers', + 'frais_notaire' => 'Financement frais de notaire', + 'but_immo' => 'Crédit travaux / Rénovation / Energie', + 'fin_neuve' => 'Financement véhicule NEUF', + 'fin_occ_m3a' => 'Financement véhicule d\'occasion MOINS de 3 ans', + 'fin_occ_p3a' => 'Financement véhicule d\'occasion PLUS de 3 ans', + 'mobil_carav' => 'Financement Mobil-home et caravane', + 'reno_energie' => 'Rénovation énergétique', + 'regrouping' => 'Regroupement de crédit / Rachat de crédit', + 'regroup_cred' => 'Regroupement de crédit / Rachat de crédit' + ]; + + protected $houseCreditTypes = [ + 'purchasehouse' => 'Achat bien immobilier', + 'construction' => 'Nouvelle construction', + 'regrouping_immo' => 'Regroupement de crédits', + 'refinancing' => 'Refinancement crédit(s) hypothécaire(s)', + 'purchaseabroad' => 'Achat d\'une 2éme résidence (à l\'étranger, en belgique)', + 'but_immo_hypo' => 'Travaux de rénovation', + 'achat_maison_de_rapport' => 'Achat maison de rapport', + 'credit_pont' => 'Crédit pont', + 'independants_et_entreprises_en_difficultes' => 'Indépendants et entreprises en difficultés', + 'regroupement_de_credit__rachats_de_credits' => 'Rachats de crédits', + 'financement_frais_de_notaire' => 'Financement frais de notaire', + 'fonds_roulement_independants' => 'Fonds de roulement' + ]; + + public function __construct() { + // Le hook admin_menu est maintenant géré par le factory + } + + public function init() { + + } + + /** + * Ajouter le menu d'administration simple + */ + public function add_admin_menu() { + add_menu_page( + 'Gestion des Crédits', // Titre de la page + 'Crédits', // Titre du menu + 'edit_posts', // Capacité requise + 'credit-manager', // Slug du menu + array($this, 'credit_manager_interfaces'), // Fonction de callback + 'dashicons-money-alt', // Icône + 8 // Position dans le menu + ); + + // Sous-menu: Import de crédits + add_submenu_page( + 'credit-manager', // Slug du menu parent + 'Import de crédits', // Titre de la page + 'Import de crédits', // Titre du sous-menu + 'edit_posts', // Capacité requise + 'credit-import', // Slug du sous-menu + array($this, 'credit_import_interface') // Callback + ); + } + + + public function credit_manager_interfaces() { + // Récupérer les crédits + $credits = $this->get_credits(); + + // Récupérer les sociétés de crédit pour le select + $societes_credit = $this->get_societes_credit(); + + // Passer les types de crédit au template + $creditTypes = $this->creditTypes; + $houseCreditTypes = $this->houseCreditTypes; + + // Calculer les compteurs par statut avec array_reduce + $status_counts = array_reduce($credits, function($counts, $credit) { + $status = isset($credit->status) ? (string)$credit->status : '0'; + + if (!isset($counts[$status])) { + $counts[$status] = 0; + } + $counts[$status]++; + + return $counts; + }, array()); + + // S'assurer que tous les statuts ont une valeur (même 0) + $status_counts = array_merge( + array('0' => 0, '1' => 0, '2' => 0, '-1' => 0), + $status_counts + ); + + // Total de tous les crédits + $total_credits = count($credits); + + // Inclure le template + include plugin_dir_path(__FILE__) . '../../templates/admin/credit_manager_table.php'; + } + + /** + * Interface d'import CSV (non-AJAX) - Fonction d'aiguillage + */ + public function credit_import_interface() { + if (!current_user_can('edit_posts')) { + wp_die('Permissions insuffisantes'); + } + + $import_summary = null; + $import_errors = array(); + + // Soumission du formulaire + if (!empty($_POST['credit_import_submit'])) { + // Vérifier le nonce + if (!isset($_POST['credit_import_nonce']) || !wp_verify_nonce($_POST['credit_import_nonce'], 'credit_import_action')) { + $import_errors[] = 'Sécurité: Nonce invalide'; + } else { + // Valider le fichier + if (!isset($_FILES['csv_file']) || !is_uploaded_file($_FILES['csv_file']['tmp_name'])) { + $import_errors[] = 'Aucun fichier CSV envoyé.'; + } else { + $file_tmp = $_FILES['csv_file']['tmp_name']; + $handle = fopen($file_tmp, 'r'); + if ($handle === false) { + $import_errors[] = 'Impossible d\'ouvrir le fichier CSV.'; + } else { + // Lire l'entête pour déterminer le nombre de colonnes + $header = fgetcsv($handle, 0, ';'); + $column_count = count($header); + + // Fermer et rouvrir le fichier pour réinitialiser le pointeur + fclose($handle); + + // Aiguiller vers la fonction appropriée selon le nombre de colonnes + if ($column_count >= 18) { + // Format PH VERVIERS (20 colonnes) + list($import_summary, $import_errors) = $this->import_ph_credits($file_tmp, $_POST); + } else { + // Format standard (13 colonnes) + list($import_summary, $import_errors) = $this->import_standard_credits($file_tmp, $_POST); + } + } + } + } + } + + include plugin_dir_path(__FILE__) . '../../templates/admin/credit_import.php'; + } + + /** + * Import standard (13 colonnes) + */ + private function import_standard_credits($file_tmp, $post_data) { + $import_errors = array(); + $import_summary = null; + + $status_input = isset($post_data['status']) ? intval($post_data['status']) : 1; // 1 par défaut + $statut_client = isset($post_data['client_status']) ? sanitize_text_field($post_data['client_status']) : ''; + if($statut_client !== '' && $statut_client !== 'habitation_locataire' && $statut_client !== 'habitation_proprietaire') { + $import_errors[] = 'Statut du client invalide.'; + return array($import_summary, $import_errors); + } + // Normaliser statut attendu par l'UI: 1=validé non signé, 2=validé signé, -1=refusé + $allowed_status = array(1, 2, -1); + if (!in_array($status_input, $allowed_status, true)) { + $status_input = 1; + } + + $handle = fopen($file_tmp, 'r'); + if ($handle === false) { + $import_errors[] = 'Impossible d\'ouvrir le fichier CSV.'; + return array($import_summary, $import_errors); + } + + // Lire l'entête et ignorer + $header = fgetcsv($handle, 0, ';'); + + $row_num = 1; + $inserted = 0; + $skipped = 0; + + global $wpdb; + $table_name = 'cdf_Credits_listing'; + + // Vérifier la table + if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) { + $import_errors[] = 'Table de base de données non trouvée: ' . esc_html($table_name); + fclose($handle); + return array($import_summary, $import_errors); + } + + while (($row = fgetcsv($handle, 0, ';')) !== false) { + $row_num++; + // Sauter les lignes vides + if (count($row) === 0 || (count($row) === 1 && trim((string)$row[0]) === '')) { + continue; + } + + // Sécuriser les index attendus (jusqu'à 13 colonnes d'après le modèle) + for ($i = 0; $i <= 12; $i++) { + if (!isset($row[$i])) $row[$i] = ''; + } + + // Mapping CSV -> champs + $titre = trim((string)$row[0]); + $nomPrenom = trim((string)$row[1]); + $adresse = trim((string)$row[2]); + $localiteField = trim((string)$row[3]); // ex: "4333 SOUMAGNE" + $email = trim((string)$row[4]); + $telephone = trim((string)$row[5]); + $gsm = trim((string)$row[6]); + $societe_credit = trim((string)$row[7]); + $montantStr = trim((string)$row[8]); + $dateSignatureStr = trim((string)$row[9]); + $numero_dossier = trim((string)$row[10]); + $code = trim((string)$row[11]); + $remarque = trim((string)$row[12]); + + // Extraire nom/prénom (naïf: premier mot = nom, reste = prénom) + $nom = ''; + $prenom = ''; + if ($nomPrenom !== '') { + // Essayer "NOM Prénom" + $parts = preg_split('/\s+/', $nomPrenom); + if (count($parts) >= 2) { + $nom = trim((string)$parts[0]); + $prenom = trim(implode(' ', array_slice($parts, 1))); + } else { + $nom = $nomPrenom; + } + } + + // Extraire code postal et localité + $code_postal = 0; + $localite = $localiteField; + if ($localiteField !== '') { + if (preg_match('/^(\d{4,5})\s*(.+)$/u', $localiteField, $m)) { + $code_postal = intval($m[1]); + $localite = trim($m[2]); + } + } + + // Normaliser montant (ex: "4 000,00 €") + $montantClean = str_replace(array("\xC2\xA0", '€', ' '), '', $montantStr); + $montantClean = str_replace('.', '', $montantClean); // enlever séparateurs de milliers + $montantClean = str_replace(',', '.', $montantClean); // virgule -> point + $montant = is_numeric($montantClean) ? (float)$montantClean : 0.0; + + // Parser date de signature -> Y-m-d + $date_signature = ''; + $date_signature_candidates = array('d/m/Y', 'd-m-Y', 'Y-m-d', 'd.m.Y'); + foreach ($date_signature_candidates as $fmt) { + $dt = DateTime::createFromFormat($fmt, $dateSignatureStr); + if ($dt instanceof DateTime) { + $date_signature = $dt->format('Y-m-d'); + break; + } + } + if ($date_signature === '') { + // Si échec, laisser vide + $date_signature = ''; + } + + // Champs requis minimaux: nom, prenom ou email + if ($nom === '' && $prenom === '' && $email === '') { + $skipped++; + $import_errors[] = 'Ligne ' . $row_num . ' ignorée (nom/prénom/email manquants).'; + continue; + } + + $data = array( + 'credit_id' => 0, + 'emprunteur_id' => 0, + 'credit_code_select' => '', + 'code_credit' => '', + 'type_credit' => '', + 'nom' => $nom !== '' ? $nom : '', + 'prenom' => $prenom !== '' ? $prenom : '', + 'adresse' => $adresse !== '' ? $adresse : '', + 'localite' => $localite !== '' ? $localite : '', + 'code_postal' => $code_postal, + 'pays' => 0, + 'email' => $email !== '' ? $email : '', + 'telephone' => $telephone !== '' ? $telephone : '', + 'gsm' => $gsm !== '' ? $gsm : '', + 'societe_credit' => $societe_credit !== '' ? $societe_credit : '', + 'montant' => $montant, + 'duree' => 0, + 'date' => current_time('Y-m-d'), + 'date_signature' => $date_signature !== '' ? $date_signature : current_time('Y-m-d'), + 'numero_dossier' => $numero_dossier !== '' ? $numero_dossier : '', + 'code' => $code !== '' ? $code : '', + 'remarque' => $remarque !== '' ? $remarque : '', + 'status' => $status_input, + 'type_habitation' => $statut_client !== '' ? $statut_client : '', + 'date_acte' => '0000-00-00', + 'but_credit' => '', + 'taux_credit' => 0.0, + 'type_taux' => '', + 'valeur_bien' => 0.0, + 'notaire' => '' + ); + + $formats = array('%d','%d','%s','%s','%s','%s','%s','%s','%s','%d','%d','%s','%s','%s','%s','%f','%d','%s','%s','%s','%s','%d','%s','%s','%f','%s','%f','%s'); + + $result = $wpdb->insert($table_name, $data, $formats); + if ($result === false) { + $skipped++; + $import_errors[] = 'Erreur d\'insertion ligne ' . $row_num . ' : ' . esc_html($wpdb->last_error); + } else { + $inserted++; + // Si l'import positionne directement le statut à 2, abonner l'email à la liste principale + if (intval($status_input) === 2 && $email !== '') { + $mailchimpController = $this->getCreditMailchimp(); + if ($mailchimpController && method_exists($mailchimpController, 'subscribe_from_credit')) { + $creditObj = (object) array( + 'id' => isset($data['credit_id']) && !empty($data['credit_id']) ? intval($data['credit_id']) : intval($wpdb->insert_id), + 'email' => $email, + 'prenom' => $prenom, + 'nom' => $nom + ); + try { + $mailchimpController->subscribe_from_credit($creditObj); + } catch (\Throwable $e) { + error_log('Mailchimp subscribe during import (row ' . $row_num . ') failed: ' . $e->getMessage()); + } + } + } + } + } + + if (is_resource($handle)) { + fclose($handle); + } + + $import_summary = array( + 'inserted' => $inserted, + 'skipped' => $skipped, + ); + + return array($import_summary, $import_errors); + } + + /** + * Import format PH VERVIERS (20 colonnes) + */ + private function import_ph_credits($file_tmp, $post_data) { + $import_errors = array(); + $import_summary = null; + + $status_input = isset($post_data['status']) ? intval($post_data['status']) : 1; // 1 par défaut + $statut_client = isset($post_data['client_status']) ? sanitize_text_field($post_data['client_status']) : ''; + if($statut_client !== '' && $statut_client !== 'habitation_locataire' && $statut_client !== 'habitation_proprietaire') { + $import_errors[] = 'Statut du client invalide.'; + return array($import_summary, $import_errors); + } + // Normaliser statut attendu par l'UI: 1=validé non signé, 2=validé signé, -1=refusé + $allowed_status = array(1, 2, -1); + if (!in_array($status_input, $allowed_status, true)) { + $status_input = 1; + } + + $handle = fopen($file_tmp, 'r'); + if ($handle === false) { + $import_errors[] = 'Impossible d\'ouvrir le fichier CSV.'; + return array($import_summary, $import_errors); + } + + // Lire l'entête et ignorer + $header = fgetcsv($handle, 0, ';'); + + $row_num = 1; + $inserted = 0; + $skipped = 0; + + global $wpdb; + $table_name = 'cdf_Credits_listing'; + + // Vérifier la table + if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) { + $import_errors[] = 'Table de base de données non trouvée: ' . esc_html($table_name); + fclose($handle); + return array($import_summary, $import_errors); + } + + while (($row = fgetcsv($handle, 0, ';')) !== false) { + $row_num++; + // Sauter les lignes vides + if (count($row) === 0 || (count($row) === 1 && trim((string)$row[0]) === '')) { + continue; + } + + // Sécuriser les index attendus (jusqu'à 20 colonnes pour le format PH) + for ($i = 0; $i <= 19; $i++) { + if (!isset($row[$i])) $row[$i] = ''; + } + + // Mapping CSV -> champs (format PH VERVIERS) + $titre = trim((string)$row[0]); + $nomPrenom = trim((string)$row[1]); + $adresse = trim((string)$row[2]); + $localiteField = trim((string)$row[3]); // ex: "4800 VERVIERS" + $email = trim((string)$row[4]); + // $row[5] = Classeur (ignoré) + $gsm = trim((string)$row[6]); // Premier GSM + // $row[7] = Deuxième GSM (ignoré, doublon) + $societe_credit = trim((string)$row[8]); + $numero_dossier = trim((string)$row[9]); + $montantStr = trim((string)$row[10]); + $dureeStr = trim((string)$row[11]); + $dateActeStr = trim((string)$row[12]); + $but_credit = trim((string)$row[13]); + $tauxStr = trim((string)$row[14]); + $type_taux = trim((string)$row[15]); + $valeur_bienStr = trim((string)$row[16]); + $notaire = trim((string)$row[17]); + $code = trim((string)$row[18]); + $remarque = trim((string)$row[19]); + + // Extraire nom/prénom (format: "NOM - Prénom" ou "NOM Prénom") + $nom = ''; + $prenom = ''; + if ($nomPrenom !== '') { + // Gérer le format "NOM - Prénom" ou "NOM Prénom" + if (strpos($nomPrenom, ' - ') !== false) { + $parts = explode(' - ', $nomPrenom, 2); + $nom = trim((string)$parts[0]); + $prenom = trim((string)$parts[1]); + } else { + $parts = preg_split('/\s+/', $nomPrenom); + if (count($parts) >= 2) { + $nom = trim((string)$parts[0]); + $prenom = trim(implode(' ', array_slice($parts, 1))); + } else { + $nom = $nomPrenom; + } + } + } + + // Extraire code postal et localité + $code_postal = 0; + $localite = $localiteField; + if ($localiteField !== '') { + if (preg_match('/^(\d{4,5})\s*(.+)$/u', $localiteField, $m)) { + $code_postal = intval($m[1]); + $localite = trim($m[2]); + } + } + + // Normaliser montant (ex: "135.000 €") + $montantClean = str_replace(array("\xC2\xA0", '€', ' '), '', $montantStr); + $montantClean = str_replace('.', '', $montantClean); // enlever séparateurs de milliers + $montantClean = str_replace(',', '.', $montantClean); // virgule -> point + $montant = is_numeric($montantClean) ? (float)$montantClean : 0.0; + + // Normaliser durée + $duree = is_numeric($dureeStr) ? intval($dureeStr) : 0; + + // Parser date acte -> Y-m-d + $date_acte = ''; + $date_acte_candidates = array('d/m/Y', 'd-m-Y', 'Y-m-d', 'd.m.Y'); + foreach ($date_acte_candidates as $fmt) { + $dt = DateTime::createFromFormat($fmt, $dateActeStr); + if ($dt instanceof DateTime) { + $date_acte = $dt->format('Y-m-d'); + break; + } + } + if ($date_acte === '') { + $date_acte = '0000-00-00'; + } + + // Normaliser taux (ex: "2,90%" ou "1,95%") + $tauxClean = str_replace('%', '', $tauxStr); + $tauxClean = str_replace(',', '.', $tauxClean); + $taux_credit = is_numeric($tauxClean) ? (float)$tauxClean : 0.0; + + // Normaliser valeur bien (ex: "140.000 €") + $valeur_bienClean = str_replace(array("\xC2\xA0", '€', ' ', ','), '', $valeur_bienStr); + $valeur_bienClean = str_replace('.', '', $valeur_bienClean); // enlever séparateurs de milliers + $valeur_bien = is_numeric($valeur_bienClean) ? (float)$valeur_bienClean : 0.0; + + // Champs requis minimaux: nom, prenom ou email + if ($nom === '' && $prenom === '' && $email === '') { + $skipped++; + $import_errors[] = 'Ligne ' . $row_num . ' ignorée (nom/prénom/email manquants).'; + continue; + } + + $data = array( + 'credit_id' => 0, + 'emprunteur_id' => 0, + 'credit_code_select' => '', + 'code_credit' => '', + 'type_credit' => '', + 'nom' => $nom !== '' ? $nom : '', + 'prenom' => $prenom !== '' ? $prenom : '', + 'adresse' => $adresse !== '' ? $adresse : '', + 'localite' => $localite !== '' ? $localite : '', + 'code_postal' => $code_postal, + 'pays' => 0, + 'email' => $email !== '' ? $email : '', + 'telephone' => '', + 'gsm' => $gsm !== '' ? $gsm : '', + 'societe_credit' => $societe_credit !== '' ? $societe_credit : '', + 'montant' => $montant, + 'duree' => $duree, + 'date' => current_time('Y-m-d'), + 'date_signature' => $date_acte !== '0000-00-00' ? $date_acte : current_time('Y-m-d'), + 'numero_dossier' => $numero_dossier !== '' ? $numero_dossier : '', + 'code' => $code !== '' ? $code : '', + 'remarque' => $remarque !== '' ? $remarque : '', + 'status' => $status_input, + 'type_habitation' => $statut_client !== '' ? $statut_client : '', + 'date_acte' => $date_acte !== '' ? $date_acte : '0000-00-00', + 'but_credit' => $but_credit !== '' ? $but_credit : '', + 'taux_credit' => $taux_credit, + 'type_taux' => $type_taux !== '' ? $type_taux : '', + 'valeur_bien' => $valeur_bien, + 'notaire' => $notaire !== '' ? $notaire : '' + ); + + $formats = array('%d','%d','%s','%s','%s','%s','%s','%s','%s','%d','%d','%s','%s','%s','%s','%f','%d','%s','%s','%s','%s','%d','%s','%s','%f','%s','%f','%s'); + + $result = $wpdb->insert($table_name, $data, $formats); + if ($result === false) { + $skipped++; + $import_errors[] = 'Erreur d\'insertion ligne ' . $row_num . ' : ' . esc_html($wpdb->last_error); + } else { + $inserted++; + // Si l'import positionne directement le statut à 2, abonner l'email à la liste principale + if (intval($status_input) === 2 && $email !== '') { + $mailchimpController = $this->getCreditMailchimp(); + if ($mailchimpController && method_exists($mailchimpController, 'subscribe_from_credit')) { + $creditObj = (object) array( + 'id' => isset($data['credit_id']) && !empty($data['credit_id']) ? intval($data['credit_id']) : intval($wpdb->insert_id), + 'email' => $email, + 'prenom' => $prenom, + 'nom' => $nom + ); + try { + $mailchimpController->subscribe_from_credit($creditObj); + } catch (\Throwable $e) { + error_log('Mailchimp subscribe during import (row ' . $row_num . ') failed: ' . $e->getMessage()); + } + } + } + } + } + + if (is_resource($handle)) { + fclose($handle); + } + + $import_summary = array( + 'inserted' => $inserted, + 'skipped' => $skipped, + ); + + return array($import_summary, $import_errors); + } + + public function get_credits($filters = array()) { + global $wpdb; + + // Utiliser la table cdf_Credits_listing qui contient déjà toutes les informations + $table_name = 'cdf_Credits_listing'; + + // Vérifier si la table existe + if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) { + // Retourner des données de test si la table n'existe pas + error_log('Credit Manager: Table ' . $table_name . ' n\'existe pas, retour de données de test'); + return $this->get_test_credits(); + } + + // Construire la clause WHERE dynamiquement + $where_clauses = array(); + $where_values = array(); + + // Configuration des filtres par type avec leur opérateur et placeholder + $filter_config = array( + // Filtres de type string avec égalité + 'string_equal' => array( + 'fields' => array('localite', 'societe_credit', 'code_postal', 'type_credit', 'credit_code_select'), + 'operator' => '=', + 'placeholder' => '%s' + ), + // Filtres de type integer avec égalité + 'int_equal' => array( + 'fields' => array('status'), + 'operator' => '=', + 'placeholder' => '%d', + 'allow_zero' => true // Permet la valeur 0 pour status + ), + // Filtres de type float avec comparaison + 'float_range' => array( + 'montant_min' => array('field' => 'montant', 'operator' => '>=', 'placeholder' => '%f'), + 'montant_max' => array('field' => 'montant', 'operator' => '<=', 'placeholder' => '%f') + ), + // Filtres de type date avec comparaison + 'date_range' => array( + 'date_signature_debut' => array('field' => 'date_signature', 'operator' => '>=', 'placeholder' => '%s'), + 'date_signature_fin' => array('field' => 'date_signature', 'operator' => '<=', 'placeholder' => '%s') + ) + ); + + // Traiter les filtres string et int simples + foreach (array('string_equal', 'int_equal') as $type) { + $config = $filter_config[$type]; + foreach ($config['fields'] as $field) { + $allow_zero = isset($config['allow_zero']) && $config['allow_zero']; + + if ($allow_zero) { + // Pour status, vérifier avec isset car 0 est une valeur valide + if (isset($filters[$field]) && $filters[$field] !== '') { + $where_clauses[] = "{$field} {$config['operator']} {$config['placeholder']}"; + $where_values[] = ($type === 'int_equal') ? intval($filters[$field]) : $filters[$field]; + } + } else { + // Pour les autres champs, utiliser !empty + if (!empty($filters[$field])) { + $where_clauses[] = "{$field} {$config['operator']} {$config['placeholder']}"; + $where_values[] = ($type === 'int_equal') ? intval($filters[$field]) : $filters[$field]; + } + } + } + } + + // Traiter les filtres de fourchette (float et date) + foreach (array('float_range', 'date_range') as $range_type) { + foreach ($filter_config[$range_type] as $filter_key => $range_config) { + if (!empty($filters[$filter_key])) { + $where_clauses[] = "{$range_config['field']} {$range_config['operator']} {$range_config['placeholder']}"; + $where_values[] = ($range_type === 'float_range') + ? floatval($filters[$filter_key]) + : $filters[$filter_key]; + } + } + } + + // Construire la requête SQL + $sql = "SELECT * FROM {$table_name}"; + + if (!empty($where_clauses)) { + $sql .= " WHERE " . implode(" AND ", $where_clauses); + } + + $sql .= " ORDER BY date DESC"; + + // Préparer et exécuter la requête + if (!empty($where_values)) { + $sql = $wpdb->prepare($sql, $where_values); + } + + // Debug: Log SQL query + error_log('Credit Manager SQL: ' . $sql); + error_log('Credit Manager Filters: ' . print_r($filters, true)); + + $results = $wpdb->get_results($sql); + + // Debug: Log results count + error_log('Credit Manager Results count: ' . count($results)); + + // Si pas de résultats ET pas de filtres appliqués, retourner des données de test + // Si des filtres sont appliqués et qu'il n'y a pas de résultats, retourner un tableau vide + if (empty($results)) { + if (empty($filters)) { + // Pas de filtres, table vide = données de test + error_log('Credit Manager: Aucun crédit dans la base, retour de données de test'); + return $this->get_test_credits(); + } else { + // Filtres appliqués, pas de résultats = tableau vide + error_log('Credit Manager: Aucun crédit ne correspond aux filtres'); + return array(); + } + } + + return $results; + } + + + /** + * Récupérer un crédit spécifique par ID + */ + public function get_credit_by_id($credit_id) { + global $wpdb; + + $table_name = 'cdf_Credits_listing'; + + // Vérifier si la table existe + if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) { + return null; + } + + $sql = $wpdb->prepare(" + SELECT + id, + type_credit, + nom, + prenom, + adresse, + localite, + email, + telephone, + gsm, + societe_credit, + montant, + date, + date_signature, + numero_dossier, + code, + remarque as remarques + FROM {$table_name} + WHERE id = %d + ", $credit_id); + + return $wpdb->get_row($sql); + } + + /** + * Récupérer les professions pour le select + */ + public function get_professions() { + global $wpdb; + + $table_name = 'cdf_Profession'; + + if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) { + return array(); + } + + $sql = "SELECT idprofession as id, nom_profession as nom FROM {$table_name} ORDER BY nom_profession"; + return $wpdb->get_results($sql); + } + + /** + * Récupérer les agences pour le select + */ + public function get_agences() { + global $wpdb; + + $table_name = 'cdf_Agences'; + + if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) { + return array(); + } + + $sql = "SELECT idAgences as id, Nom_agence as nom FROM {$table_name} ORDER BY Nom_agence"; + return $wpdb->get_results($sql); + } + + /** + * Récupérer les sociétés de crédit pour le select + */ + public function get_societes_credit() { + global $wpdb; + + $table_name = 'cdf_societes_credit'; + + if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) { + return array(); + } + + // Récupérer seulement les sociétés actives (status = 1) + $sql = "SELECT id, nom FROM {$table_name} WHERE status = 1 ORDER BY nom"; + return $wpdb->get_results($sql); + } + + /** + * Récupérer les localités distinctes + */ + public function get_distinct_localites() { + global $wpdb; + $table_name = 'cdf_Credits_listing'; + + if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) { + return array(); + } + + $sql = "SELECT DISTINCT localite FROM {$table_name} WHERE localite != '' ORDER BY localite"; + return $wpdb->get_col($sql); + } + + /** + * Récupérer les sociétés de crédit distinctes + */ + public function get_distinct_societes() { + global $wpdb; + $table_name = 'cdf_Credits_listing'; + + if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) { + return array(); + } + + $sql = "SELECT DISTINCT societe_credit FROM {$table_name} WHERE societe_credit != '' ORDER BY societe_credit"; + return $wpdb->get_col($sql); + } + + /** + * Récupérer les types de crédit distincts + */ + public function get_distinct_credit_types() { + global $wpdb; + $table_name = 'cdf_Credits_listing'; + + if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) { + return array(); + } + + $sql = "SELECT DISTINCT type_credit FROM {$table_name} WHERE type_credit != '' ORDER BY type_credit"; + return $wpdb->get_col($sql); + } + + /** + * Récupérer les types de crédit + */ + public function get_credit_types() { + return array( + 'credit_immobilier' => 'Crédit Immobilier', + 'credit_consommation' => 'Crédit Consommation', + 'credit_auto' => 'Crédit Automobile', + 'credit_personnel' => 'Crédit Personnel', + 'credit_travaux' => 'Crédit Travaux' + ); + } + + /** + * Données de test pour le développement + */ + private function get_test_credits() { + return array( + (object) array( + 'id' => 1, + 'type_credit' => 'CH', + 'nom' => 'Dupont', + 'prenom' => 'Jean', + 'adresse' => '123 Rue de la Paix', + 'localite' => 'Bruxelles', + 'email' => 'jean.dupont@example.com', + 'telephone' => '02/123.45.67', + 'gsm' => '0470/12.34.56', + 'societe_credit' => 'Banque 1', + 'montant' => 250000.00, + 'date' => '2024-01-15', + 'date_signature' => '2024-01-20', + 'numero_dossier' => 'CD-2024-001', + 'code' => 'ABC123', + 'remarques' => 'Premier crédit test' + ), + (object) array( + 'id' => 2, + 'type_credit' => 'PAT', + 'nom' => 'Martin', + 'prenom' => 'Marie', + 'adresse' => '456 Avenue des Champs', + 'localite' => 'Anvers', + 'email' => 'marie.martin@example.com', + 'telephone' => '03/987.65.43', + 'gsm' => '0471/98.76.54', + 'societe_credit' => 'Banque 2', + 'montant' => 15000.00, + 'date' => '2024-01-20', + 'date_signature' => '2024-01-25', + 'numero_dossier' => 'CD-2024-002', + 'code' => 'DEF456', + 'remarques' => 'Crédit pour voiture' + ) + ); + } + + /** + * ======================================== + * FONCTIONS CRUD POUR CREDIT MANAGER + * ======================================== + */ + + /** + * Créer un nouveau crédit + */ + public function ajax_create_credit() { + // Vérifier le nonce + if (!wp_verify_nonce($_POST['nonce'], 'credit_manager_action')) { + wp_die('Sécurité: Nonce invalide'); + } + + // Vérifier les permissions + if (!current_user_can('edit_posts')) { + wp_die('Permissions insuffisantes'); + } + + global $wpdb; + $table_name = 'cdf_Credits_listing'; + + // Récupérer et valider les données + $data = array( + 'type_credit' => sanitize_text_field($_POST['type_credit']), + 'nom' => sanitize_text_field($_POST['nom']), + 'prenom' => sanitize_text_field($_POST['prenom']), + 'adresse' => sanitize_textarea_field($_POST['adresse']), + 'localite' => sanitize_text_field($_POST['localite']), + 'email' => sanitize_email($_POST['email']), + 'telephone' => sanitize_text_field($_POST['telephone']), + 'gsm' => sanitize_text_field($_POST['gsm']), + 'societe_credit' => sanitize_text_field($_POST['societe_credit']), + 'montant' => floatval($_POST['montant']), + 'date' => sanitize_text_field($_POST['date']), + 'date_signature' => sanitize_text_field($_POST['signature']), + 'numero_dossier' => sanitize_text_field($_POST['numero_dossier']), + 'code' => sanitize_text_field($_POST['code']), + 'remarque' => sanitize_textarea_field($_POST['remarques']) + ); + + // Validation des champs obligatoires + if (empty($data['nom']) || empty($data['prenom']) || empty($data['email'])) { + wp_send_json_error('Les champs nom, prénom et email sont obligatoires'); + } + + // Vérifier si la table existe + if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) { + wp_send_json_error('Table de base de données non trouvée'); + } + + // Insérer le nouveau crédit + $result = $wpdb->insert($table_name, $data); + + if ($result === false) { + wp_send_json_error('Erreur lors de la création du crédit'); + } + + $credit_id = $wpdb->insert_id; + $new_credit = $this->get_credit_by_id($credit_id); + + wp_send_json_success(array( + 'message' => 'Crédit créé avec succès', + 'credit' => $new_credit + )); + } + + /** + * Lire un crédit spécifique + */ + public function ajax_get_credit() { + // Vérifier le nonce + if (!wp_verify_nonce($_POST['nonce'], 'credit_manager_action')) { + wp_die('Sécurité: Nonce invalide'); + } + + // Vérifier les permissions + if (!current_user_can('edit_posts')) { + wp_die('Permissions insuffisantes'); + } + + $credit_id = intval($_POST['credit_id']); + + if ($credit_id <= 0) { + wp_send_json_error('ID de crédit invalide'); + } + + $credit = $this->get_credit_by_id($credit_id); + + if (!$credit) { + wp_send_json_error('Crédit non trouvé'); + } + + wp_send_json_success(array( + 'credit' => $credit + )); + } + + /** + * Mettre à jour un crédit existant + */ + public function ajax_update_credit() { + // Vérifier le nonce + if (!wp_verify_nonce($_POST['nonce'], 'credit_manager_action')) { + wp_die('Sécurité: Nonce invalide'); + } + + // Vérifier les permissions + if (!current_user_can('edit_posts')) { + wp_die('Permissions insuffisantes'); + } + + global $wpdb; + $table_name = 'cdf_Credits_listing'; + $credit_id = intval($_POST['credit_id']); + + if ($credit_id <= 0) { + wp_send_json_error('ID de crédit invalide'); + } + + // Vérifier si le crédit existe + $existing_credit = $this->get_credit_by_id($credit_id); + if (!$existing_credit) { + wp_send_json_error('Crédit non trouvé'); + } + + // Récupérer et valider les données + $data = array( + 'type_credit' => sanitize_text_field($_POST['type_credit']), + 'nom' => sanitize_text_field($_POST['nom']), + 'prenom' => sanitize_text_field($_POST['prenom']), + 'adresse' => sanitize_textarea_field($_POST['adresse']), + 'localite' => sanitize_text_field($_POST['localite']), + 'email' => sanitize_email($_POST['email']), + 'telephone' => sanitize_text_field($_POST['telephone']), + 'gsm' => sanitize_text_field($_POST['gsm']), + 'societe_credit' => sanitize_text_field($_POST['societe_credit']), + 'montant' => floatval($_POST['montant']), + 'date' => sanitize_text_field($_POST['date']), + 'date_signature' => sanitize_text_field($_POST['signature']), + 'numero_dossier' => sanitize_text_field($_POST['numero_dossier']), + 'code' => sanitize_text_field($_POST['code']), + 'remarque' => sanitize_textarea_field($_POST['remarques']) + ); + + // Validation des champs obligatoires + if (empty($data['nom']) || empty($data['prenom']) || empty($data['email'])) { + wp_send_json_error('Les champs nom, prénom et email sont obligatoires'); + } + + // Mettre à jour le crédit + $result = $wpdb->update( + $table_name, + $data, + array('id' => $credit_id), + array('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%f', '%s', '%s', '%s', '%s', '%s'), + array('%d') + ); + + if ($result === false) { + wp_send_json_error('Erreur lors de la mise à jour du crédit'); + } + + $updated_credit = $this->get_credit_by_id($credit_id); + + wp_send_json_success(array( + 'message' => 'Crédit mis à jour avec succès', + 'credit' => $updated_credit + )); + } + + /** + * Supprimer un crédit + */ + public function ajax_delete_credit() { + // Vérifier le nonce + if (!wp_verify_nonce($_POST['nonce'], 'credit_manager_action')) { + wp_die('Sécurité: Nonce invalide'); + } + + // Vérifier les permissions + if (!current_user_can('edit_posts')) { + wp_die('Permissions insuffisantes'); + } + + global $wpdb; + $table_name = 'cdf_Credits_listing'; + $credit_id = intval($_POST['credit_id']); + + if ($credit_id <= 0) { + wp_send_json_error('ID de crédit invalide'); + } + + // Vérifier si le crédit existe + $existing_credit = $this->get_credit_by_id($credit_id); + if (!$existing_credit) { + wp_send_json_error('Crédit non trouvé'); + } + + // Supprimer le crédit + $result = $wpdb->delete( + $table_name, + array('id' => $credit_id), + array('%d') + ); + + if ($result === false) { + wp_send_json_error('Erreur lors de la suppression du crédit'); + } + + wp_send_json_success(array( + 'message' => 'Crédit supprimé avec succès', + 'credit_id' => $credit_id + )); + } + + /** + * Lister tous les crédits avec pagination et filtres + */ + public function ajax_list_credits() { + // Debug: Log des données POST reçues + error_log('Credit Manager AJAX - POST data: ' . print_r($_POST, true)); + + // Vérifier que le nonce est présent + if (!isset($_POST['nonce']) || empty($_POST['nonce'])) { + error_log('Credit Manager AJAX - Nonce manquant dans POST'); + wp_send_json_error('Nonce manquant'); + return; + } + + // Vérifier le nonce + if (!wp_verify_nonce($_POST['nonce'], 'credit_manager_action')) { + error_log('Credit Manager AJAX - Nonce invalide: ' . $_POST['nonce']); + wp_send_json_error('Sécurité: Nonce invalide'); + return; + } + + // Vérifier les permissions + if (!current_user_can('edit_posts')) { + error_log('Credit Manager AJAX - Permissions insuffisantes'); + wp_send_json_error('Permissions insuffisantes'); + return; + } + + // Récupérer les filtres + $filters = array(); + if (!empty($_POST['localite'])) { + $filters['localite'] = sanitize_text_field($_POST['localite']); + } + if (!empty($_POST['societe_credit'])) { + $filters['societe_credit'] = sanitize_text_field($_POST['societe_credit']); + } + if (!empty($_POST['code_postal'])) { + $filters['code_postal'] = sanitize_text_field($_POST['code_postal']); + } + if (isset($_POST['status']) && $_POST['status'] !== '') { + $filters['status'] = intval($_POST['status']); + } + if (!empty($_POST['type_credit'])) { + $filters['type_credit'] = sanitize_text_field($_POST['type_credit']); + } + if (!empty($_POST['credit_code_select'])) { + $filters['credit_code_select'] = sanitize_text_field($_POST['credit_code_select']); + } + if (!empty($_POST['montant_min'])) { + $filters['montant_min'] = floatval($_POST['montant_min']); + } + if (!empty($_POST['montant_max'])) { + $filters['montant_max'] = floatval($_POST['montant_max']); + } + if (!empty($_POST['date_signature_debut'])) { + $filters['date_signature_debut'] = sanitize_text_field($_POST['date_signature_debut']); + } + if (!empty($_POST['date_signature_fin'])) { + $filters['date_signature_fin'] = sanitize_text_field($_POST['date_signature_fin']); + } + + // Utiliser la méthode get_credits avec les filtres + $credits = $this->get_credits($filters); + + // Récupérer TOUS les crédits pour les compteurs (sans filtre) + $all_credits = $this->get_credits(array()); + + // Calculer les compteurs par statut avec array_reduce + $status_counts = array_reduce($all_credits, function($counts, $credit) { + $status = isset($credit->status) ? (string)$credit->status : '0'; + + if (!isset($counts[$status])) { + $counts[$status] = 0; + } + $counts[$status]++; + + return $counts; + }, array()); + + // S'assurer que tous les statuts ont une valeur (même 0) + $status_counts = array_merge( + array('0' => 0, '1' => 0, '2' => 0, '-1' => 0), + $status_counts + ); + + wp_send_json_success(array( + 'credits' => $credits, + 'total' => count($credits), + 'status_counts' => $status_counts, + 'total_all' => count($all_credits) + )); + } + + /** + * Récupérer les options de filtres + */ + public function ajax_get_filter_options() { + // Vérifier le nonce + if (!wp_verify_nonce($_POST['nonce'], 'credit_manager_action')) { + wp_die('Sécurité: Nonce invalide'); + } + + // Vérifier les permissions + if (!current_user_can('edit_posts')) { + wp_die('Permissions insuffisantes'); + } + + wp_send_json_success(array( + 'localites' => $this->get_distinct_localites(), + 'societes' => $this->get_distinct_societes(), + 'types_credit' => $this->get_distinct_credit_types() + )); + } + + /** + * change credit status + */ + public function ajax_change_credit_status() { + // Vérifier le nonce + if (!wp_verify_nonce($_POST['nonce'], 'credit_manager_action')) { + wp_die('Sécurité: Nonce invalide'); + } + + global $wpdb; + $table_name = 'cdf_Credits_listing'; + $credit_id = isset($_POST['credit_id']) ? absint($_POST['credit_id']) : 0; + $new_status = isset($_POST['new_status']) ? intval($_POST['new_status']) : 0; + + if ($credit_id <= 0) { + wp_send_json_error('ID de crédit invalide'); + } + + // Vérifier si le crédit existe + $existing_credit = $this->get_credit_by_id($credit_id); + + if (!$existing_credit) { + wp_send_json_error('Crédit non trouvé'); + } + + // Changer le statut du crédit + error_log('Credit Manager: change_status id=' . $credit_id . ' new_status=' . $new_status); + + $result = $wpdb->update( + $table_name, + array('status' => $new_status), + array('id' => $credit_id), + array('%d'), + array('%d') + ); + + if ($result === false) { + wp_send_json_error('Erreur lors du changement de statut du crédit'); + } + + // Si statut = 2 (accepté classé), tenter d'ajouter l'email à la liste Mailchimp principale + if (intval($new_status) === 2 && !empty($existing_credit->email)) { + $mailchimpController = $this->getCreditMailchimp(); + if ($mailchimpController && method_exists($mailchimpController, 'subscribe_from_credit')) { + $mailchimpController->subscribe_from_credit($existing_credit); + } + } + + wp_send_json_success(array( + 'message' => 'Statut du crédit changé avec succès', + 'credit_id' => $credit_id, + 'status' => $new_status + )); + } + + /** + * Mettre à jour le statut du crédit (accepté non signé, accepté classé, refusé) + */ + public function ajax_update_credit_status() { + // Vérifier le nonce + if (!wp_verify_nonce($_POST['nonce'], 'credit_manager_action')) { + wp_die('Sécurité: Nonce invalide'); + } + + // Vérifier les permissions + if (!current_user_can('edit_posts')) { + wp_die('Permissions insuffisantes'); + } + + global $wpdb; + $table_name = 'cdf_Credits_listing'; + $credit_id = isset($_POST['credit_id']) ? absint($_POST['credit_id']) : 0; + $status = isset($_POST['status']) ? sanitize_text_field($_POST['status']) : ''; + + if ($credit_id <= 0) { + wp_send_json_error('ID de crédit invalide'); + } + + // Vérifier si le crédit existe + $existing_credit = $this->get_credit_by_id($credit_id); + if (!$existing_credit) { + wp_send_json_error('Crédit non trouvé'); + } + + // Mapper les statuts aux valeurs numériques + $status_map = array( + 'accepte_non_signe' => 1, + 'accepte_classe' => 2, + 'refuse' => -1 + ); + + if (!isset($status_map[$status])) { + wp_send_json_error('Statut invalide'); + } + + $status_value = $status_map[$status]; + + // Mettre à jour le statut + error_log('Credit Manager: update_status id=' . $credit_id . ' status=' . $status . ' value=' . $status_value); + + $result = $wpdb->update( + $table_name, + array('status' => $status_value), + array('id' => $credit_id), + array('%d'), + array('%d') + ); + + if ($result === false) { + wp_send_json_error('Erreur lors de la mise à jour du statut'); + } + + // Si statut = 2 (accepté classé), tenter d'ajouter l'email à la liste Mailchimp principale + if (intval($status_value) === 2 && !empty($existing_credit->email)) { + $mailchimpController = $this->getCreditMailchimp(); + if ($mailchimpController && method_exists($mailchimpController, 'subscribe_from_credit')) { + $mailchimpController->subscribe_from_credit($existing_credit); + } + } + + wp_send_json_success(array( + 'message' => 'Statut mis à jour avec succès', + 'credit_id' => $credit_id, + 'status' => $status, + 'status_value' => $status_value + )); + } + + /** + * Si la configuration Mailchimp est présente, abonner le contact à l'audience principale. + * @param object $credit Objet crédit contenant au moins email, prenom, nom + */ + // méthode supprimée: la logique d'abonnement est dans CRED_credit_mailchimp +} \ No newline at end of file diff --git a/app/controllers/old/shortcodes.php b/app/controllers/old/shortcodes.php new file mode 100644 index 0000000..9442e5a --- /dev/null +++ b/app/controllers/old/shortcodes.php @@ -0,0 +1,202 @@ + 'create', // 'create' ou 'edit' + 'credit_id' => 0 + ), $atts); + + // Inclure le template du modal + ob_start(); + include plugin_dir_path(__FILE__) . '../../templates/modules/credit-manager-edit-form.php'; + return ob_get_clean(); + } + + /** + * Shortcode pour afficher le tableau de gestion des crédits + * Usage: [credit_manager_table] + */ + public function credit_manager_table_shortcode($atts) { + $atts = shortcode_atts(array( + 'show_actions' => 'true', + 'limit' => 50 + ), $atts); + + // Récupérer les crédits + $credits = $this->get_credits($atts['limit']); + + // Inclure le template du tableau + ob_start(); + include plugin_dir_path(__FILE__) . '../../templates/admin/credit_manager_table.php'; + return ob_get_clean(); + } + + /** + * Récupérer la liste des crédits + */ + private function get_credits($limit = 50) { + global $wpdb; + + // TODO: Remplacer par la vraie table des crédits + $table_name = $wpdb->prefix . 'credit_direct_credits'; + + $sql = $wpdb->prepare(" + SELECT * FROM {$table_name} + ORDER BY date DESC + LIMIT %d + ", $limit); + + return $wpdb->get_results($sql); + } + + /** + * Traitement AJAX pour créer un crédit + */ + public function ajax_create_credit() { + check_ajax_referer('credit_manager_action', 'nonce'); + + $data = array( + 'title' => sanitize_text_field($_POST['title']), + 'nom' => sanitize_text_field($_POST['nom']), + 'prenom' => sanitize_text_field($_POST['prenom']), + 'adresse' => sanitize_textarea_field($_POST['adresse']), + 'localite' => sanitize_text_field($_POST['localite']), + 'email' => sanitize_email($_POST['email']), + 'telephone' => sanitize_text_field($_POST['telephone']), + 'gsm' => sanitize_text_field($_POST['gsm']), + 'societe_credit' => sanitize_text_field($_POST['societe_credit']), + 'montant' => floatval($_POST['montant']), + 'date' => sanitize_text_field($_POST['date']), + 'signature' => sanitize_text_field($_POST['signature']), + 'numero_dossier' => sanitize_text_field($_POST['numero_dossier']), + 'code' => sanitize_text_field($_POST['code']), + 'remarques' => sanitize_textarea_field($_POST['remarques']), + 'created_at' => current_time('mysql') + ); + + global $wpdb; + $table_name = $wpdb->prefix . 'credit_direct_credits'; + + $result = $wpdb->insert($table_name, $data); + + if ($result) { + wp_send_json_success(array( + 'message' => 'Crédit créé avec succès', + 'credit_id' => $wpdb->insert_id + )); + } else { + wp_send_json_error(array( + 'message' => 'Erreur lors de la création du crédit' + )); + } + } + + /** + * Traitement AJAX pour mettre à jour un crédit + */ + public function ajax_update_credit() { + check_ajax_referer('credit_manager_action', 'nonce'); + + $credit_id = intval($_POST['credit_id']); + + if (!$credit_id) { + wp_send_json_error(array('message' => 'ID de crédit invalide')); + } + + $data = array( + 'title' => sanitize_text_field($_POST['title']), + 'nom' => sanitize_text_field($_POST['nom']), + 'prenom' => sanitize_text_field($_POST['prenom']), + 'adresse' => sanitize_textarea_field($_POST['adresse']), + 'localite' => sanitize_text_field($_POST['localite']), + 'email' => sanitize_email($_POST['email']), + 'telephone' => sanitize_text_field($_POST['telephone']), + 'gsm' => sanitize_text_field($_POST['gsm']), + 'societe_credit' => sanitize_text_field($_POST['societe_credit']), + 'montant' => floatval($_POST['montant']), + 'date' => sanitize_text_field($_POST['date']), + 'signature' => sanitize_text_field($_POST['signature']), + 'numero_dossier' => sanitize_text_field($_POST['numero_dossier']), + 'code' => sanitize_text_field($_POST['code']), + 'remarques' => sanitize_textarea_field($_POST['remarques']), + 'updated_at' => current_time('mysql') + ); + + global $wpdb; + $table_name = $wpdb->prefix . 'credit_direct_credits'; + + $result = $wpdb->update( + $table_name, + $data, + array('id' => $credit_id), + array('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%f', '%s', '%s', '%s', '%s', '%s', '%s'), + array('%d') + ); + + if ($result !== false) { + wp_send_json_success(array('message' => 'Crédit mis à jour avec succès')); + } else { + wp_send_json_error(array('message' => 'Erreur lors de la mise à jour du crédit')); + } + } + + /** + * Traitement AJAX pour récupérer un crédit + */ + public function ajax_get_credit() { + check_ajax_referer('credit_manager_action', 'nonce'); + + $credit_id = intval($_POST['credit_id']); + + if (!$credit_id) { + wp_send_json_error(array('message' => 'ID de crédit invalide')); + } + + global $wpdb; + $table_name = $wpdb->prefix . 'credit_direct_credits'; + + $credit = $wpdb->get_row($wpdb->prepare( + "SELECT * FROM {$table_name} WHERE id = %d", + $credit_id + )); + + if ($credit) { + wp_send_json_success($credit); + } else { + wp_send_json_error(array('message' => 'Crédit non trouvé')); + } + } +} + +// Initialiser la classe +new ESI_CreditDirect_Shortcodes(); + +// Enregistrer les actions AJAX +add_action('wp_ajax_create_credit', array('ESI_CreditDirect_Shortcodes', 'ajax_create_credit')); +add_action('wp_ajax_update_credit', array('ESI_CreditDirect_Shortcodes', 'ajax_update_credit')); +add_action('wp_ajax_get_credit', array('ESI_CreditDirect_Shortcodes', 'ajax_get_credit')); diff --git a/app/controllers/old/societes_credit_manager.php b/app/controllers/old/societes_credit_manager.php new file mode 100644 index 0000000..804cebc --- /dev/null +++ b/app/controllers/old/societes_credit_manager.php @@ -0,0 +1,353 @@ +get_societes_credit(); + + // Inclure le template + include plugin_dir_path(__FILE__) . '../../templates/admin/societes_credit_table.php'; + } + + /** + * Récupérer toutes les sociétés de crédit + */ + public function get_societes_credit($limit = 100) { + global $wpdb; + + $table_name = 'cdf_societes_credit'; + + // Vérifier si la table existe + if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) { + return $this->get_test_societes(); + } + + $sql = "SELECT id, nom, status FROM {$table_name} ORDER BY nom ASC"; + $results = $wpdb->get_results($sql); + + // Si pas de résultats, retourner des données de test + if (empty($results)) { + return $this->get_test_societes(); + } + + return $results; + } + + /** + * Récupérer une société spécifique par ID + */ + public function get_societe_by_id($societe_id) { + global $wpdb; + + $table_name = 'cdf_societes_credit'; + + // Vérifier si la table existe + if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) { + return null; + } + + $sql = $wpdb->prepare(" + SELECT id, nom, status + FROM {$table_name} + WHERE id = %d + ", $societe_id); + + return $wpdb->get_row($sql); + } + + /** + * Données de test pour le développement + */ + private function get_test_societes() { + return array( + (object) array( + 'id' => 1, + 'nom' => 'Banque Exemple 1', + 'status' => 1 + ), + (object) array( + 'id' => 2, + 'nom' => 'Banque Exemple 2', + 'status' => 1 + ), + (object) array( + 'id' => 3, + 'nom' => 'Banque Désactivée', + 'status' => 0 + ) + ); + } + + /** + * ======================================== + * FONCTIONS CRUD POUR SOCIETES DE CREDIT + * ======================================== + */ + + /** + * Créer une nouvelle société de crédit + */ + public function ajax_create_societe() { + // Vérifier le nonce + if (!wp_verify_nonce($_POST['nonce'], 'societes_credit_action')) { + wp_die('Sécurité: Nonce invalide'); + } + + // Vérifier les permissions + if (!current_user_can('edit_posts')) { + wp_die('Permissions insuffisantes'); + } + + global $wpdb; + $table_name = 'cdf_societes_credit'; + + // Récupérer et valider les données + $data = array( + 'nom' => sanitize_text_field($_POST['nom']), + 'status' => isset($_POST['status']) && $_POST['status'] === 'true' ? 1 : 0 + ); + + // Validation des champs obligatoires + if (empty($data['nom'])) { + wp_send_json_error('Le nom est obligatoire'); + } + + // Vérifier si la table existe + if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) { + wp_send_json_error('Table de base de données non trouvée'); + } + + // Vérifier si le nom existe déjà + $existing = $wpdb->get_var($wpdb->prepare( + "SELECT COUNT(*) FROM {$table_name} WHERE nom = %s", + $data['nom'] + )); + + if ($existing > 0) { + wp_send_json_error('Une société avec ce nom existe déjà'); + } + + // Insérer la nouvelle société + $result = $wpdb->insert($table_name, $data); + + if ($result === false) { + wp_send_json_error('Erreur lors de la création de la société'); + } + + $societe_id = $wpdb->insert_id; + $new_societe = $this->get_societe_by_id($societe_id); + + wp_send_json_success(array( + 'message' => 'Société créée avec succès', + 'societe' => $new_societe + )); + } + + /** + * Lire une société spécifique + */ + public function ajax_get_societe() { + // Vérifier le nonce + if (!wp_verify_nonce($_POST['nonce'], 'societes_credit_action')) { + wp_die('Sécurité: Nonce invalide'); + } + + // Vérifier les permissions + if (!current_user_can('edit_posts')) { + wp_die('Permissions insuffisantes'); + } + + $societe_id = intval($_POST['societe_id']); + + if ($societe_id <= 0) { + wp_send_json_error('ID de société invalide'); + } + + $societe = $this->get_societe_by_id($societe_id); + + if (!$societe) { + wp_send_json_error('Société non trouvée'); + } + + wp_send_json_success(array( + 'societe' => $societe + )); + } + + /** + * Mettre à jour une société existante + */ + public function ajax_update_societe() { + // Vérifier le nonce + if (!wp_verify_nonce($_POST['nonce'], 'societes_credit_action')) { + wp_die('Sécurité: Nonce invalide'); + } + + // Vérifier les permissions + if (!current_user_can('edit_posts')) { + wp_die('Permissions insuffisantes'); + } + + global $wpdb; + $table_name = 'cdf_societes_credit'; + $societe_id = intval($_POST['societe_id']); + + if ($societe_id <= 0) { + wp_send_json_error('ID de société invalide'); + } + + // Vérifier si la société existe + $existing_societe = $this->get_societe_by_id($societe_id); + if (!$existing_societe) { + wp_send_json_error('Société non trouvée'); + } + + // Récupérer et valider les données + $data = array( + 'nom' => sanitize_text_field($_POST['nom']), + 'status' => isset($_POST['status']) && $_POST['status'] === 'true' ? 1 : 0 + ); + + // Validation des champs obligatoires + if (empty($data['nom'])) { + wp_send_json_error('Le nom est obligatoire'); + } + + // Vérifier si le nom existe déjà (sauf pour cette société) + $existing = $wpdb->get_var($wpdb->prepare( + "SELECT COUNT(*) FROM {$table_name} WHERE nom = %s AND id != %d", + $data['nom'], + $societe_id + )); + + if ($existing > 0) { + wp_send_json_error('Une autre société avec ce nom existe déjà'); + } + + // Mettre à jour la société + $result = $wpdb->update( + $table_name, + $data, + array('id' => $societe_id), + array('%s', '%d'), + array('%d') + ); + + if ($result === false) { + wp_send_json_error('Erreur lors de la mise à jour de la société'); + } + + $updated_societe = $this->get_societe_by_id($societe_id); + + wp_send_json_success(array( + 'message' => 'Société mise à jour avec succès', + 'societe' => $updated_societe + )); + } + + /** + * Supprimer une société + */ + public function ajax_delete_societe() { + // Vérifier le nonce + if (!wp_verify_nonce($_POST['nonce'], 'societes_credit_action')) { + wp_die('Sécurité: Nonce invalide'); + } + + // Vérifier les permissions + if (!current_user_can('edit_posts')) { + wp_die('Permissions insuffisantes'); + } + + global $wpdb; + $table_name = 'cdf_societes_credit'; + $societe_id = intval($_POST['societe_id']); + + if ($societe_id <= 0) { + wp_send_json_error('ID de société invalide'); + } + + // Vérifier si la société existe + $existing_societe = $this->get_societe_by_id($societe_id); + if (!$existing_societe) { + wp_send_json_error('Société non trouvée'); + } + + // Supprimer la société + $result = $wpdb->delete( + $table_name, + array('id' => $societe_id), + array('%d') + ); + + if ($result === false) { + wp_send_json_error('Erreur lors de la suppression de la société'); + } + + wp_send_json_success(array( + 'message' => 'Société supprimée avec succès', + 'societe_id' => $societe_id + )); + } + + /** + * Lister toutes les sociétés avec pagination + */ + public function ajax_list_societes() { + // Vérifier le nonce + if (!wp_verify_nonce($_POST['nonce'], 'societes_credit_action')) { + wp_die('Sécurité: Nonce invalide'); + } + + // Vérifier les permissions + if (!current_user_can('edit_posts')) { + wp_die('Permissions insuffisantes'); + } + + global $wpdb; + $table_name = 'cdf_societes_credit'; + + // Vérifier si la table existe + if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) { + wp_send_json_error('Table de base de données non trouvée'); + } + + // Compter le total + $total = $wpdb->get_var("SELECT COUNT(*) FROM {$table_name}"); + + // Récupérer toutes les sociétés + $sql = "SELECT id, nom, status FROM {$table_name} ORDER BY nom ASC"; + $societes = $wpdb->get_results($sql); + + wp_send_json_success(array( + 'societes' => $societes, + 'total' => intval($total) + )); + } +} + diff --git a/app/controllers/societes_credit_manager.php b/app/controllers/societes_credit_manager.php new file mode 100644 index 0000000..a474404 --- /dev/null +++ b/app/controllers/societes_credit_manager.php @@ -0,0 +1,392 @@ +get_societes_credit(); + + // Inclure le template + include plugin_dir_path(__FILE__) . '../../templates/admin/societes_credit_table.php'; + } + + /** + * Récupérer toutes les sociétés de crédit + */ + public function get_societes_credit($limit = 100) { + global $wpdb; + + $table_name = 'cdf_societes_credit'; + + // Vérifier si la table existe + if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) { + return $this->get_test_societes(); + } + + $sql = "SELECT id, nom, status, type_credit FROM {$table_name} ORDER BY nom ASC"; + $results = $wpdb->get_results($sql); + + // Si pas de résultats, retourner des données de test + if (empty($results)) { + return $this->get_test_societes(); + } + + return $results; + } + + /** + * Récupérer une société spécifique par ID + */ + public function get_societe_by_id($societe_id) { + global $wpdb; + + $table_name = 'cdf_societes_credit'; + + // Vérifier si la table existe + if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) { + return null; + } + + $sql = $wpdb->prepare(" + SELECT id, nom, status, type_credit + FROM {$table_name} + WHERE id = %d + ", $societe_id); + + return $wpdb->get_row($sql); + } + + /** + * Données de test pour le développement + */ + private function get_test_societes() { + return array( + (object) array( + 'id' => 1, + 'nom' => 'Banque Exemple 1', + 'status' => 1 + ), + (object) array( + 'id' => 2, + 'nom' => 'Banque Exemple 2', + 'status' => 1 + ), + (object) array( + 'id' => 3, + 'nom' => 'Banque Désactivée', + 'status' => 0 + ) + ); + } + + /** + * ======================================== + * FONCTIONS CRUD POUR SOCIETES DE CREDIT + * ======================================== + */ + + /** + * Créer une nouvelle société de crédit + */ + public function ajax_create_societe() { + // Vérifier le nonce + if (!wp_verify_nonce($_POST['nonce'], 'societes_credit_action')) { + wp_die('Sécurité: Nonce invalide'); + } + + // Vérifier les permissions + if (!current_user_can('edit_posts')) { + wp_die('Permissions insuffisantes'); + } + + global $wpdb; + $table_name = 'cdf_societes_credit'; + + // Récupérer et valider les données + $type_credit_raw = isset($_POST['type_credit']) ? $_POST['type_credit'] : []; + error_log('Type credit raw: ' . print_r($type_credit_raw, true)); + + $data = array( + 'nom' => sanitize_text_field($_POST['nom']), + 'status' => isset($_POST['status']) && $_POST['status'] === 'true' ? 1 : 0, + 'type_credit' => implode(',', $this->processTypeCredit($type_credit_raw)) + ); + + error_log('Type credit processed: ' . $data['type_credit']); + + // Validation des champs obligatoires + if (empty($data['nom'])) { + wp_send_json_error('Le nom est obligatoire'); + } + + // Vérifier si la table existe + if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) { + wp_send_json_error('Table de base de données non trouvée'); + } + + // Vérifier si le nom existe déjà + $existing = $wpdb->get_var($wpdb->prepare( + "SELECT COUNT(*) FROM {$table_name} WHERE nom = %s", + $data['nom'] + )); + + if ($existing > 0) { + wp_send_json_error('Une société avec ce nom existe déjà'); + } + + // Insérer la nouvelle société + $result = $wpdb->insert($table_name, $data); + + if ($result === false) { + wp_send_json_error('Erreur lors de la création de la société'); + } + + $societe_id = $wpdb->insert_id; + $new_societe = $this->get_societe_by_id($societe_id); + + wp_send_json_success(array( + 'message' => 'Société créée avec succès', + 'societe' => $new_societe + )); + } + + /** + * Lire une société spécifique + */ + public function ajax_get_societe() { + // Vérifier le nonce + if (!wp_verify_nonce($_POST['nonce'], 'societes_credit_action')) { + wp_die('Sécurité: Nonce invalide'); + } + + // Vérifier les permissions + if (!current_user_can('edit_posts')) { + wp_die('Permissions insuffisantes'); + } + + $societe_id = intval($_POST['societe_id']); + + if ($societe_id <= 0) { + wp_send_json_error('ID de société invalide'); + } + + $societe = $this->get_societe_by_id($societe_id); + + if (!$societe) { + wp_send_json_error('Société non trouvée'); + } + + wp_send_json_success(array( + 'societe' => $societe + )); + } + + /** + * Mettre à jour une société existante + */ + public function ajax_update_societe() { + // Vérifier le nonce + if (!wp_verify_nonce($_POST['nonce'], 'societes_credit_action')) { + wp_die('Sécurité: Nonce invalide'); + } + + // Vérifier les permissions + if (!current_user_can('edit_posts')) { + wp_die('Permissions insuffisantes'); + } + + global $wpdb; + $table_name = 'cdf_societes_credit'; + $societe_id = intval($_POST['societe_id']); + + if ($societe_id <= 0) { + wp_send_json_error('ID de société invalide'); + } + + // Vérifier si la société existe + $existing_societe = $this->get_societe_by_id($societe_id); + if (!$existing_societe) { + wp_send_json_error('Société non trouvée'); + } + + // Récupérer et valider les données + $type_credit_raw = isset($_POST['type_credit']) ? $_POST['type_credit'] : []; + error_log('Type credit raw: ' . print_r($type_credit_raw, true)); + + $data = array( + 'nom' => sanitize_text_field($_POST['nom']), + 'status' => isset($_POST['status']) && $_POST['status'] === 'true' ? 1 : 0, + 'type_credit' => implode(',', $this->processTypeCredit($type_credit_raw)) + ); + + error_log('Type credit processed: ' . $data['type_credit']); + + // Validation des champs obligatoires + if (empty($data['nom'])) { + wp_send_json_error('Le nom est obligatoire'); + } + + // Vérifier si le nom existe déjà (sauf pour cette société) + $existing = $wpdb->get_var($wpdb->prepare( + "SELECT COUNT(*) FROM {$table_name} WHERE nom = %s AND id != %d", + $data['nom'], + $societe_id + )); + + if ($existing > 0) { + wp_send_json_error('Une autre société avec ce nom existe déjà'); + } + + // Mettre à jour la société + $result = $wpdb->update( + $table_name, + $data, + array('id' => $societe_id), + array('%s', '%d'), + array('%d') + ); + + if ($result === false) { + wp_send_json_error('Erreur lors de la mise à jour de la société'); + } + + $updated_societe = $this->get_societe_by_id($societe_id); + + wp_send_json_success(array( + 'message' => 'Société mise à jour avec succès', + 'societe' => $updated_societe + )); + } + + /** + * Supprimer une société + */ + public function ajax_delete_societe() { + // Vérifier le nonce + if (!wp_verify_nonce($_POST['nonce'], 'societes_credit_action')) { + wp_die('Sécurité: Nonce invalide'); + } + + // Vérifier les permissions + if (!current_user_can('edit_posts')) { + wp_die('Permissions insuffisantes'); + } + + global $wpdb; + $table_name = 'cdf_societes_credit'; + $societe_id = intval($_POST['societe_id']); + + if ($societe_id <= 0) { + wp_send_json_error('ID de société invalide'); + } + + // Vérifier si la société existe + $existing_societe = $this->get_societe_by_id($societe_id); + if (!$existing_societe) { + wp_send_json_error('Société non trouvée'); + } + + // Supprimer la société + $result = $wpdb->delete( + $table_name, + array('id' => $societe_id), + array('%d') + ); + + if ($result === false) { + wp_send_json_error('Erreur lors de la suppression de la société'); + } + + wp_send_json_success(array( + 'message' => 'Société supprimée avec succès', + 'societe_id' => $societe_id + )); + } + + /** + * Lister toutes les sociétés avec pagination + */ + public function ajax_list_societes() { + // Vérifier le nonce + if (!wp_verify_nonce($_POST['nonce'], 'societes_credit_action')) { + wp_die('Sécurité: Nonce invalide'); + } + + // Vérifier les permissions + if (!current_user_can('edit_posts')) { + wp_die('Permissions insuffisantes'); + } + + global $wpdb; + $table_name = 'cdf_societes_credit'; + + // Vérifier si la table existe + if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) { + wp_send_json_error('Table de base de données non trouvée'); + } + + // Compter le total + $total = $wpdb->get_var("SELECT COUNT(*) FROM {$table_name}"); + + // Récupérer toutes les sociétés + $sql = "SELECT id, nom, status, type_credit FROM {$table_name} ORDER BY nom ASC"; + $societes = $wpdb->get_results($sql); + + wp_send_json_success(array( + 'societes' => $societes, + 'total' => intval($total) + )); + } +} + diff --git a/app/init-buildings.php b/app/init-buildings.php new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/app/init-buildings.php @@ -0,0 +1 @@ + diff --git a/app/libraries/FormValidator.php b/app/libraries/FormValidator.php new file mode 100644 index 0000000..1402c73 --- /dev/null +++ b/app/libraries/FormValidator.php @@ -0,0 +1,1075 @@ +data = $data; + $this->creditModel = $creditModel; + } + + /** + * Valide un champ requis + * @param string $field Le nom du champ + * @param string $message Message d'erreur personnalisé + * @return FormValidator + */ + public function required($field, $message = null) + { + if (empty($this->data[$field]) || trim($this->data[$field]) === '') { + $this->addError($field, $message ?: "Le champ {$field} est requis."); + } + return $this; + } + + /** + * Valide un email + * @param string $field Le nom du champ + * @param string $message Message d'erreur personnalisé + * @return FormValidator + */ + public function email($field, $message = null) + { + if (!empty($this->data[$field]) && !filter_var($this->data[$field], FILTER_VALIDATE_EMAIL)) { + $this->addError($field, $message ?: "Le champ {$field} doit être un email valide."); + } + return $this; + } + + /** + * Valide un numéro de téléphone belge + * @param string $field Le nom du champ + * @param string $message Message d'erreur personnalisé + * @return FormValidator + */ + public function phone($field, $message = null) + { + if (!empty($this->data[$field])) { + $phone = preg_replace('/[^0-9+]/', '', $this->data[$field]); + if (!preg_match('/^(\+32|0)[0-9]{8,9}$/', $phone)) { + $this->addError($field, $message ?: "Le champ {$field} doit être un numéro de téléphone belge valide."); + } + } + return $this; + } + + /** + * Valide un code postal belge + * @param string $field Le nom du champ + * @param string $message Message d'erreur personnalisé + * @return FormValidator + */ + public function zipCode($field, $message = null) + { + if (!empty($this->data[$field])) { + if (!preg_match('/^[0-9]{4}$/', $this->data[$field])) { + $this->addError($field, $message ?: "Le champ {$field} doit être un code postal belge valide (4 chiffres)."); + } + } + return $this; + } + + /** + * Valide un numéro de registre national belge + * @param string $field Le nom du champ + * @param string $message Message d'erreur personnalisé + * @return FormValidator + */ + public function nationalNumber($field, $message = null) + { + if (!empty($this->data[$field])) { + $number = preg_replace('/[^0-9]/', '', $this->data[$field]); + if (strlen($number) !== 11) { + $this->addError($field, $message ?: "Le champ {$field} doit contenir 11 chiffres."); + return $this; + } + + // Validation de la clé de contrôle du registre national + if (!$this->validateNationalNumberChecksum($number)) { + $this->addError($field, $message ?: "Le champ {$field} n'est pas un numéro de registre national valide."); + } + } + return $this; + } + + /** + * Valide un numéro de compte bancaire belge (IBAN) + * @param string $field Le nom du champ + * @param string $message Message d'erreur personnalisé + * @return FormValidator + */ + public function bankAccount($field, $message = null) + { + if (!empty($this->data[$field])) { + $account = preg_replace('/[^0-9]/', '', $this->data[$field]); + if (strlen($account) < 10 || strlen($account) > 16) { + $this->addError($field, $message ?: "Le champ {$field} doit contenir entre 10 et 16 chiffres."); + } + } + return $this; + } + + /** + * Valide une date au format JJ/MM/AAAA + * @param string $field Le nom du champ + * @param string $message Message d'erreur personnalisé + * @return FormValidator + */ + public function date($field, $message = null) + { + if (!empty($this->data[$field])) { + $date = \DateTime::createFromFormat('d/m/Y', $this->data[$field]); + if (!$date || $date->format('d/m/Y') !== $this->data[$field]) { + $this->addError($field, $message ?: "Le champ {$field} doit être une date valide au format JJ/MM/AAAA."); + } + } + return $this; + } + + /** + * Valide qu'une date est dans le passé + * @param string $field Le nom du champ + * @param string $message Message d'erreur personnalisé + * @return FormValidator + */ + public function datePast($field, $message = null) + { + if (!empty($this->data[$field])) { + $date = \DateTime::createFromFormat('d/m/Y', $this->data[$field]); + if ($date && $date > new \DateTime()) { + $this->addError($field, $message ?: "Le champ {$field} doit être une date dans le passé."); + } + } + return $this; + } + + /** + * Valide qu'une date est dans le futur + * @param string $field Le nom du champ + * @param string $message Message d'erreur personnalisé + * @return FormValidator + */ + public function dateFuture($field, $message = null) + { + if (!empty($this->data[$field])) { + $date = \DateTime::createFromFormat('d/m/Y', $this->data[$field]); + if ($date && $date < new \DateTime()) { + $this->addError($field, $message ?: "Le champ {$field} doit être une date dans le futur."); + } + } + return $this; + } + + /** + * Valide un montant (nombre positif) + * @param string $field Le nom du champ + * @param float $min Montant minimum + * @param float $max Montant maximum + * @param string $message Message d'erreur personnalisé + * @return FormValidator + */ + public function amount($field, $min = 0, $max = null, $message = null) + { + if (!empty($this->data[$field])) { + $amount = floatval($this->data[$field]); + if ($amount < $min) { + $this->addError($field, $message ?: "Le champ {$field} doit être supérieur ou égal à {$min}."); + } + if ($max !== null && $amount > $max) { + $this->addError($field, $message ?: "Le champ {$field} doit être inférieur ou égal à {$max}."); + } + } + return $this; + } + + /** + * Valide un nombre d'enfants + * @param string $field Le nom du champ + * @param string $message Message d'erreur personnalisé + * @return FormValidator + */ + public function childrenCount($field, $message = null) + { + if (!empty($this->data[$field])) { + $count = intval($this->data[$field]); + if ($count < 0 || $count > 24) { + $this->addError($field, $message ?: "Le champ {$field} doit être entre 0 et 24."); + } + } + return $this; + } + + /** + * Valide qu'un champ est dans une liste de valeurs + * @param string $field Le nom du champ + * @param array $allowedValues Valeurs autorisées + * @param string $message Message d'erreur personnalisé + * @return FormValidator + */ + public function in($field, $allowedValues, $message = null) + { + if (!empty($this->data[$field]) && !in_array($this->data[$field], $allowedValues)) { + $this->addError($field, $message ?: "Le champ {$field} doit être une des valeurs autorisées."); + } + return $this; + } + + /** + * Valide la longueur d'une chaîne + * @param string $field Le nom du champ + * @param int $min Longueur minimum + * @param int $max Longueur maximum + * @param string $message Message d'erreur personnalisé + * @return FormValidator + */ + public function length($field, $min, $max, $message = null) + { + if (!empty($this->data[$field])) { + $length = strlen($this->data[$field]); + if ($length < $min || $length > $max) { + $this->addError($field, $message ?: "Le champ {$field} doit contenir entre {$min} et {$max} caractères."); + } + } + return $this; + } + + /** + * Valide un numéro de carte d'identité belge + * @param string $field Le nom du champ + * @param string $message Message d'erreur personnalisé + * @return FormValidator + */ + public function identityCard($field, $message = null) + { + if (!empty($this->data[$field])) { + $card = preg_replace('/[^0-9]/', '', $this->data[$field]); + if (strlen($card) < 8 || strlen($card) > 12) { + $this->addError($field, $message ?: "Le champ {$field} doit contenir entre 8 et 12 chiffres."); + } + } + return $this; + } + + /** + * Valide un taux (pourcentage) au format "int%" ou juste un entier positif + * @param string $field Le nom du champ + * @param string $message Message d'erreur personnalisé + * @return FormValidator + */ + public function rate($field, $message = null) + { + if (!empty($this->data[$field])) { + $value = trim($this->data[$field]); + + // Vérifier si c'est au format "X%" ou juste "X" + if (preg_match('/^(\d+)%?$/', $value, $matches)) { + $rate = intval($matches[1]); + if ($rate < 0 || $rate > 100) { + $this->addError($field, $message ?: "Le champ {$field} doit être un taux entre 0 et 100."); + } + } else { + $this->addError($field, $message ?: "Le champ {$field} doit être un taux au format 'X%' ou juste 'X'."); + } + } + return $this; + } + + /** + * Valide qu'un montant est dans les limites définies pour le type de crédit + * @param string $amountField Le nom du champ montant + * @param string $creditTypeField Le nom du champ type de crédit + * @param string $message Message d'erreur personnalisé + * @return FormValidator + */ + public function creditAmountWithinLimits($amountField, $creditTypeField, $message = null) + { + if (!empty($this->data[$amountField]) && !empty($this->data[$creditTypeField])) { + $amount = floatval($this->data[$amountField]); + $creditType = $this->data[$creditTypeField]; + + // Récupérer les limites depuis le modèle + if (isset($this->creditModel) && method_exists($this->creditModel, 'get_credit_limits')) { + $limits = $this->creditModel->get_credit_limits($creditType); + + if ($amount < $limits['limite_basse']) { + $this->addError($amountField, $message ?: "Le montant demandé ({$amount}€) est inférieur à la limite minimale de {$limits['limite_basse']}€ pour ce type de crédit."); + } elseif ($amount > $limits['limite_haute']) { + $this->addError($amountField, $message ?: "Le montant demandé ({$amount}€) dépasse la limite maximale de {$limits['limite_haute']}€ pour ce type de crédit."); + } + } + } + return $this; + } + + /** + * Détermine automatiquement le type de champ et applique les bonnes validations + * @param string $field Le nom du champ + * @param mixed $value La valeur du champ + * @param bool $required Si le champ est requis + * @return FormValidator + */ + public function autoValidate($field, $value, $required = false) + { + $this->data[$field] = $value; + + // Validation des champs requis + if ($required) { + $this->required($field); + } + + // Détermination automatique du type de champ + $fieldType = $this->detectFieldType($field, $value); + + // Application des validations selon le type détecté + switch ($fieldType) { + case 'email': + $this->email($field); + break; + case 'phone': + $this->phone($field); + break; + case 'date': + $this->date($field); + break; + case 'date_past': + $this->date($field)->datePast($field); + break; + case 'date_future': + $this->date($field)->dateFuture($field); + break; + case 'zip_code': + $this->zipCode($field); + break; + case 'national_number': + $this->nationalNumber($field); + break; + case 'bank_account': + $this->bankAccount($field); + break; + case 'identity_card': + $this->identityCard($field); + break; + case 'amount': + $this->amount($field); + break; + case 'rate': + $this->rate($field); + break; + case 'children_count': + $this->childrenCount($field); + break; + case 'text': + $this->length($field, 1, 255); + break; + } + + return $this; + } + + /** + * Détecte automatiquement le type de champ basé sur son nom et sa valeur + * @param string $field Le nom du champ + * @param mixed $value La valeur du champ + * @return string Le type de champ détecté + */ + private function detectFieldType($field, $value) + { + $field = strtolower($field); + + // Détection par nom de champ + if (strpos($field, 'email') !== false) { + return 'email'; + } + + if (strpos($field, 'phone') !== false || strpos($field, 'telephone') !== false) { + return 'phone'; + } + + if (strpos($field, 'zip') !== false || strpos($field, 'code_postal') !== false) { + return 'zip_code'; + } + + if (strpos($field, 'nationalregistrationnumber') !== false || strpos($field, 'num_registre_national') !== false) { + return 'national_number'; + } + + if (strpos($field, 'bankaccountnumber') !== false || strpos($field, 'num_compte_bancaire') !== false) { + return 'bank_account'; + } + + if (strpos($field, 'cardnumber') !== false || strpos($field, 'num_carte_identite') !== false) { + return 'identity_card'; + } + + if (strpos($field, 'salary') !== false || strpos($field, 'salaire') !== false || + strpos($field, 'loyer') !== false || strpos($field, 'montant') !== false || + strpos($field, 'capital') !== false || strpos($field, 'mensualite') !== false || + strpos($field, 'cout_total') !== false) { + return 'amount'; + } + + if (strpos($field, 'taux') !== false || strpos($field, 'rate') !== false) { + return 'rate'; + } + + if (strpos($field, 'children') !== false || strpos($field, 'enfant') !== false) { + return 'children_count'; + } + + // Détection par nom de champ contenant "date" + if (strpos($field, 'date') !== false) { + if (strpos($field, 'validity') !== false || strpos($field, 'validite') !== false) { + return 'date_future'; + } + if (strpos($field, 'birth') !== false || strpos($field, 'naissance') !== false) { + return 'date_past'; + } + return 'date'; + } + + // Détection par valeur si c'est une date + if (!empty($value) && $this->isDateFormat($value)) { + return 'date'; + } + + // Détection par valeur si c'est un email + if (!empty($value) && filter_var($value, FILTER_VALIDATE_EMAIL)) { + return 'email'; + } + + // Détection par valeur si c'est un montant + if (!empty($value) && is_numeric($value) && floatval($value) > 0) { + return 'amount'; + } + + return 'text'; + } + + /** + * Vérifie si une valeur est au format date JJ/MM/AAAA + * @param string $value La valeur à vérifier + * @return bool + */ + private function isDateFormat($value) + { + if (empty($value)) return false; + + // Vérifier le format JJ/MM/AAAA + if (preg_match('/^\d{2}\/\d{2}\/\d{4}$/', $value)) { + $date = \DateTime::createFromFormat('d/m/Y', $value); + return $date && $date->format('d/m/Y') === $value; + } + + return false; + } + + /** + * Valide les données de l'emprunteur principal + * @param array $data Les données du formulaire + * @return array Erreurs de validation + */ + public function validateBorrower($data) + { + $this->data = $data; + $this->errors = []; + + // Informations de base + $this->required('firstname', 'Le prénom est requis.') + ->required('lastname', 'Le nom est requis.') + ->required('email', 'L\'email est requis.') + ->email('email', 'L\'email doit être valide.') + ->required('phone', 'Le téléphone est requis.') + ->phone('phone', 'Le téléphone doit être un numéro belge valide.') + ->required('zip', 'Le code postal est requis.') + ->zipCode('zip', 'Le code postal doit être valide.') + ->required('country', 'Le pays est requis.'); + + // Données personnelles (étape 3) + if (isset($data['birthdate'])) { + $this->required('birthdate', 'La date de naissance est requise.') + ->date('birthdate', 'La date de naissance doit être au format JJ/MM/AAAA.') + ->datePast('birthdate', 'La date de naissance doit être dans le passé.'); + } + + if (isset($data['birthplace'])) { + $this->required('birthplace', 'Le lieu de naissance est requis.'); + } + + if (isset($data['nationality'])) { + $this->required('nationality', 'La nationalité est requise.'); + } + + if (isset($data['cardnumber'])) { + $this->required('cardnumber', 'Le numéro de carte d\'identité est requis.') + ->identityCard('cardnumber', 'Le numéro de carte d\'identité doit être valide.'); + } + + if (isset($data['cnvaliditydate'])) { + $this->required('cnvaliditydate', 'La date de validité de la carte est requise.') + ->date('cnvaliditydate', 'La date de validité doit être au format JJ/MM/AAAA.') + ->dateFuture('cnvaliditydate', 'La date de validité doit être dans le futur.'); + } + + if (isset($data['nationalregistrationnumber'])) { + $this->required('nationalregistrationnumber', 'Le numéro de registre national est requis.') + ->nationalNumber('nationalregistrationnumber', 'Le numéro de registre national doit être valide.'); + } + + if (isset($data['bankaccountnumber'])) { + $this->required('bankaccountnumber', 'Le numéro de compte bancaire est requis.') + ->bankAccount('bankaccountnumber', 'Le numéro de compte bancaire doit être valide.'); + } + + if (isset($data['dependentchildren'])) { + $this->childrenCount('dependentchildren', 'Le nombre d\'enfants doit être entre 0 et 24.'); + } + + // Informations professionnelles + if (isset($data['civilstatus'])) { + $this->required('civilstatus', 'L\'état civil est requis.'); + } + + if (isset($data['job'])) { + $this->required('job', 'La profession est requise.'); + } + + if (isset($data['salary'])) { + $this->required('salary', 'Le salaire est requis.') + ->amount('salary', 0, null, 'Le salaire doit être un montant positif.'); + } + + if (isset($data['annual_taxable_income'])) { + $this->amount('annual_taxable_income', 0, null, 'Le revenu imposable doit être un montant positif.'); + } + + // Autres revenus + if (isset($data['oiamouthmealvoucher'])) { + $this->amount('oiamouthmealvoucher', 0, null, 'Le montant des chèques repas doit être positif.'); + } + + if (isset($data['oiamouthrentalincome'])) { + $this->amount('oiamouthrentalincome', 0, null, 'Le montant des revenus locatifs doit être positif.'); + } + + if (isset($data['oiamouthunemployment'])) { + $this->amount('oiamouthunemployment', 0, null, 'Le montant du chômage doit être positif.'); + } + + if (isset($data['oiamouthother'])) { + $this->amount('oiamouthother', 0, null, 'Le montant des autres revenus doit être positif.'); + } + + // Logement + if (isset($data['habitation_type'])) { + $allowedTypes = ['proprietaire', 'proprietaire_sans_pret', 'locataire', 'cohabitant']; + $this->in('habitation_type', $allowedTypes, 'Le type d\'habitation doit être valide.'); + } + + if (isset($data['habitation_loyer'])) { + $this->amount('habitation_loyer', 0, null, 'Le montant du loyer doit être positif.'); + } + + return $this->errors; + } + + /** + * Valide les données du co-emprunteur + * @param array $data Les données du formulaire + * @return array Erreurs de validation + */ + public function validateCoBorrower($data) + { + $this->data = $data; + $this->errors = []; + + // Préfixe 'co' pour les champs du co-emprunteur + $coFields = [ + 'cobirthdate' => 'birthdate', + 'cobirthplace' => 'birthplace', + 'conationality' => 'nationality', + 'cocardnumber' => 'cardnumber', + 'cocnvaliditydate' => 'cnvaliditydate', + 'conationalregistrationnumber' => 'nationalregistrationnumber', + 'cobankaccountnumber' => 'bankaccountnumber', + 'codependentchildren' => 'dependentchildren' + ]; + + foreach ($coFields as $coField => $baseField) { + if (isset($data[$coField]) && !empty($data[$coField])) { + $this->data[$baseField] = $data[$coField]; + + switch ($baseField) { + case 'birthdate': + $this->date($baseField, 'La date de naissance du co-emprunteur doit être au format JJ/MM/AAAA.') + ->datePast($baseField, 'La date de naissance du co-emprunteur doit être dans le passé.'); + break; + case 'birthplace': + $this->required($baseField, 'Le lieu de naissance du co-emprunteur est requis.'); + break; + case 'nationality': + $this->required($baseField, 'La nationalité du co-emprunteur est requise.'); + break; + case 'cardnumber': + $this->identityCard($baseField, 'Le numéro de carte d\'identité du co-emprunteur doit être valide.'); + break; + case 'cnvaliditydate': + $this->date($baseField, 'La date de validité de la carte du co-emprunteur doit être au format JJ/MM/AAAA.') + ->dateFuture($baseField, 'La date de validité de la carte du co-emprunteur doit être dans le futur.'); + break; + case 'nationalregistrationnumber': + $this->nationalNumber($baseField, 'Le numéro de registre national du co-emprunteur doit être valide.'); + break; + case 'bankaccountnumber': + $this->bankAccount($baseField, 'Le numéro de compte bancaire du co-emprunteur doit être valide.'); + break; + case 'dependentchildren': + $this->childrenCount($baseField, 'Le nombre d\'enfants du co-emprunteur doit être entre 0 et 24.'); + break; + } + } + } + + return $this->errors; + } + + /** + * Valide les crédits en cours + * @param array $data Les données du formulaire + * @return array Erreurs de validation + */ + public function validateCurrentLoans($data) + { + $this->data = $data; + $this->errors = []; + + if (isset($data['currentloans']) && is_array($data['currentloans'])) { + foreach ($data['currentloans'] as $index => $loan) { + $prefix = "currentloans[{$index}]"; + + if (isset($loan['loantype'])) { + $this->required($prefix . '[loantype]', "Le type de créance du crédit {$index} est requis."); + } + + if (isset($loan['bankname'])) { + $this->required($prefix . '[bankname]', "Le nom de la banque du crédit {$index} est requis.") + ->length($prefix . '[bankname]', 2, 100, "Le nom de la banque du crédit {$index} doit contenir entre 2 et 100 caractères."); + } + + if (isset($loan['borrowedcapital'])) { + $this->required($prefix . '[borrowedcapital]', "Le capital emprunté du crédit {$index} est requis.") + ->amount($prefix . '[borrowedcapital]', 0, null, "Le capital emprunté du crédit {$index} doit être positif."); + } + + if (isset($loan['durationmonth'])) { + $this->required($prefix . '[durationmonth]', "La durée du crédit {$index} est requise.") + ->amount($prefix . '[durationmonth]', 1, 600, "La durée du crédit {$index} doit être entre 1 et 600 mois."); + } + + if (isset($loan['monthlypayment'])) { + $this->required($prefix . '[monthlypayment]', "La mensualité du crédit {$index} est requise.") + ->amount($prefix . '[monthlypayment]', 0, null, "La mensualité du crédit {$index} doit être positive."); + } + + if (isset($loan['firstduedate'])) { + $this->required($prefix . '[firstduedate]', "La date de première échéance du crédit {$index} est requise.") + ->date($prefix . '[firstduedate]', "La date de première échéance du crédit {$index} doit être au format JJ/MM/AAAA."); + } + + if (isset($loan['remainingbalance'])) { + $this->required($prefix . '[remainingbalance]', "Le solde restant du crédit {$index} est requis.") + ->amount($prefix . '[remainingbalance]', 0, null, "Le solde restant du crédit {$index} doit être positif."); + } + } + } + + return $this->errors; + } + + /** + * Valide automatiquement tous les champs d'un formulaire + * @param array $data Les données du formulaire + * @param array $requiredFields Liste des champs requis + * @return array Erreurs de validation + */ + public function autoValidateAll($data, $requiredFields = []) + { + $this->data = $data; + $this->errors = []; + + foreach ($data as $field => $value) { + // Ignorer les champs spéciaux + if (in_array($field, ['credit-direct-token', 'type_credit_selected', 'sub_loan_type'])) { + continue; + } + + // Déterminer si le champ est requis + $isRequired = in_array($field, $requiredFields); + + // Validation automatique + $this->autoValidate($field, $value, $isRequired); + } + + return $this->errors; + } + + /** + * Valide les données de l'étape 2 (revenus et charges) + * @param array $data Les données du formulaire + * @return array Erreurs de validation + */ + public function validateStep2($data) + { + $this->data = $data; + $this->errors = []; + + // Champs requis pour l'étape 2 UNIQUEMENT + $step2RequiredFields = [ + 'firstname', 'lastname', 'email', 'phone', + 'civilstatus', 'job', 'salary', 'habitation_type' + ]; + + // Validation explicite des champs requis de l'étape 2 + foreach ($step2RequiredFields as $field) { + if (isset($data[$field])) { + $this->required($field); + } + } + + // Validation des champs spécifiques de l'étape 2 + if (isset($data['email'])) { + $this->email('email', 'L\'email doit être valide.'); + } + + if (isset($data['phone'])) { + $this->phone('phone', 'Le téléphone doit être un numéro belge valide.'); + } + + // Type de contrat et revenus + if (isset($data['contract_type']) && !empty($data['contract_type'])) { + $allowedContracts = ['cdi', 'cdd', 'fon', 'int', 'oth', 'ssc']; + $this->in('contract_type', $allowedContracts, 'Le type de contrat doit être valide.'); + } + + if (isset($data['independent_since'])) { + $this->date('independent_since', 'La date de début d\'activité indépendante doit être au format JJ/MM/AAAA.'); + } + + if (isset($data['salary'])) { + $this->amount('salary', 0, null, 'Le salaire doit être un montant positif.'); + } + + if (isset($data['annual_taxable_income'])) { + $this->amount('annual_taxable_income', 0, null, 'Le revenu imposable doit être un montant positif.'); + } + + // Autres revenus + if (isset($data['hasotherincome']) && $data['hasotherincome'] === '1') { + if (isset($data['oiamouthmealvoucher'])) { + $this->amount('oiamouthmealvoucher', 0, null, 'Le montant des chèques repas doit être positif.'); + } + + if (isset($data['oiamouthrentalincome'])) { + $this->amount('oiamouthrentalincome', 0, null, 'Le montant des revenus locatifs doit être positif.'); + } + + if (isset($data['oiamouthunemployment'])) { + $this->amount('oiamouthunemployment', 0, null, 'Le montant du chômage doit être positif.'); + } + + if (isset($data['oiamouthother'])) { + $this->amount('oiamouthother', 0, null, 'Le montant des autres revenus doit être positif.'); + } + } + + // Fichage + if (isset($data['isFiched']) && $data['isFiched'] === '1') { + $this->required('fichage_status', 'Le statut du fichage est requis.'); + } + + // Logement + if (isset($data['habitation_type'])) { + $allowedTypes = ['proprietaire', 'proprietaire_sans_pret', 'locataire', 'cohabitant']; + $this->in('habitation_type', $allowedTypes, 'Le type d\'habitation doit être valide.'); + } + + if (isset($data['habitation_loyer'])) { + $this->amount('habitation_loyer', 0, null, 'Le montant du loyer doit être positif.'); + } + + // Crédits en cours + if (isset($data['hascurrentloan']) && $data['hascurrentloan'] === '1') { + $this->validateCurrentLoans($data); + } + + return $this->errors; + } + + /** + * Valide les données de l'étape 3 (informations personnelles) + * @param array $data Les données du formulaire + * @return array Erreurs de validation + */ + public function validateStep3($data) + { + $this->data = $data; + $this->errors = []; + + // Champs requis pour l'étape 3 UNIQUEMENT - Emprunteur principal + $step3RequiredFields = [ + 'birthdate', 'birthplace', 'nationality', + 'cardnumber', 'cnvaliditydate', + 'nationalregistrationnumber', 'bankaccountnumber', + 'dependentchildren' + ]; + + // Validation explicite des champs requis de l'étape 3 pour l'emprunteur principal + foreach ($step3RequiredFields as $field) { + if (isset($data[$field])) { + $this->required($field); + } + } + + // Validation spécifique des champs de l'étape 3 - Emprunteur principal + if (isset($data['birthdate'])) { + $this->date('birthdate', 'La date de naissance doit être au format JJ/MM/AAAA.') + ->datePast('birthdate', 'La date de naissance doit être dans le passé.'); + } + + if (isset($data['cnvaliditydate'])) { + $this->date('cnvaliditydate', 'La date de validité de la carte doit être au format JJ/MM/AAAA.') + ->dateFuture('cnvaliditydate', 'La date de validité de la carte doit être dans le futur.'); + } + + if (isset($data['nationalregistrationnumber'])) { + $this->nationalNumber('nationalregistrationnumber', 'Le numéro de registre national doit être valide.'); + } + + if (isset($data['bankaccountnumber'])) { + $this->bankAccount('bankaccountnumber', 'Le numéro de compte bancaire doit être valide.'); + } + + if (isset($data['cardnumber'])) { + $this->identityCard('cardnumber', 'Le numéro de carte d\'identité doit être valide.'); + } + + if (isset($data['dependentchildren'])) { + $this->childrenCount('dependentchildren', 'Le nombre d\'enfants doit être entre 0 et 24.'); + } + + if (isset($data['montant_allocation_familiale'])) { + $this->amount('montant_allocation_familiale', 0, null, 'Le montant des allocations familiales doit être positif.'); + } + + // Validation du co-emprunteur UNIQUEMENT si hascoborrower est défini et égal à '1' + if (isset($data['hascoborrower']) && $data['hascoborrower'] === '1') { + // Validation des champs du co-emprunteur (tous optionnels mais si présents, doivent être valides) + if (isset($data['cobirthdate'])) { + $this->date('cobirthdate', 'La date de naissance du co-emprunteur doit être au format JJ/MM/AAAA.') + ->datePast('cobirthdate', 'La date de naissance du co-emprunteur doit être dans le passé.'); + } + + if (isset($data['cocnvaliditydate'])) { + $this->date('cocnvaliditydate', 'La date de validité de la carte du co-emprunteur doit être au format JJ/MM/AAAA.') + ->dateFuture('cocnvaliditydate', 'La date de validité de la carte du co-emprunteur doit être dans le futur.'); + } + + if (isset($data['conationalregistrationnumber'])) { + $this->nationalNumber('conationalregistrationnumber', 'Le numéro de registre national du co-emprunteur doit être valide.'); + } + + if (isset($data['cobankaccountnumber'])) { + $this->bankAccount('cobankaccountnumber', 'Le numéro de compte bancaire du co-emprunteur doit être valide.'); + } + + if (isset($data['cocardnumber'])) { + $this->identityCard('cocardnumber', 'Le numéro de carte d\'identité du co-emprunteur doit être valide.'); + } + + if (isset($data['codependentchildren'])) { + $this->childrenCount('codependentchildren', 'Le nombre d\'enfants du co-emprunteur doit être entre 0 et 24.'); + } + + if (isset($data['comontant_allocation_familiale'])) { + $this->amount('comontant_allocation_familiale', 0, null, 'Le montant des allocations familiales du co-emprunteur doit être positif.'); + } + } + + return $this->errors; + } + + /** + * Valide la clé de contrôle du numéro de registre national belge + * @param string $number Le numéro à valider + * @return bool + */ + private function validateNationalNumberChecksum($number) + { + if (strlen($number) !== 11) { + return false; + } + + $base = substr($number, 0, 9); + $check = substr($number, 9, 2); + + $remainder = intval($base) % 97; + $expectedCheck = 97 - $remainder; + + return intval($check) === $expectedCheck; + } + + /** + * Ajoute une erreur + * @param string $field Le nom du champ + * @param string $message Le message d'erreur + */ + private function addError($field, $message) + { + $this->errors[$field] = $message; + } + + /** + * Retourne les erreurs + * @return array + */ + public function getErrors() + { + return $this->errors; + } + + /** + * Vérifie s'il y a des erreurs + * @return bool + */ + public function hasErrors() + { + return !empty($this->errors); + } + + /** + * Retourne les erreurs formatées pour l'affichage + * @return string + */ + public function getFormattedErrors() + { + if (empty($this->errors)) { + return ''; + } + + $html = '

Erreurs de validation :

'; + + return $html; + } + + /** + * Analyse les champs d'un formulaire et retourne leurs types détectés + * @param array $data Les données du formulaire + * @return array Types de champs détectés + */ + public function analyzeFields($data) + { + $fieldTypes = []; + + foreach ($data as $field => $value) { + if (in_array($field, ['credit-direct-token', 'type_credit_selected', 'sub_loan_type'])) { + continue; + } + + $fieldType = $this->detectFieldType($field, $value); + $fieldTypes[$field] = [ + 'type' => $fieldType, + 'value' => $value, + 'detection_method' => $this->getDetectionMethod($field, $value, $fieldType) + ]; + } + + return $fieldTypes; + } + + /** + * Retourne la méthode de détection utilisée pour un champ + * @param string $field Le nom du champ + * @param mixed $value La valeur du champ + * @param string $detectedType Le type détecté + * @return string + */ + private function getDetectionMethod($field, $value, $detectedType) + { + $field = strtolower($field); + + // Vérifier si c'est par nom de champ + if (strpos($field, 'email') !== false && $detectedType === 'email') { + return 'nom_champ'; + } + + if (strpos($field, 'phone') !== false && $detectedType === 'phone') { + return 'nom_champ'; + } + + if (strpos($field, 'date') !== false && in_array($detectedType, ['date', 'date_past', 'date_future'])) { + return 'nom_champ'; + } + + // Vérifier si c'est par valeur + if ($detectedType === 'email' && filter_var($value, FILTER_VALIDATE_EMAIL)) { + return 'valeur'; + } + + if ($detectedType === 'date' && $this->isDateFormat($value)) { + return 'valeur'; + } + + if ($detectedType === 'amount' && is_numeric($value)) { + return 'valeur'; + } + + return 'nom_champ'; + } + + /** + * Génère un rapport d'analyse des champs + * @param array $data Les données du formulaire + * @return string Rapport HTML + */ + public function generateFieldAnalysisReport($data) + { + $fieldTypes = $this->analyzeFields($data); + + $html = '
'; + $html .= '

Analyse des types de champs

'; + $html .= ''; + $html .= ''; + $html .= ''; + + foreach ($fieldTypes as $field => $info) { + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + } + + $html .= '
ChampValeurType détectéMéthode de détection
' . htmlspecialchars($field) . '' . htmlspecialchars($info['value']) . '' . htmlspecialchars($info['type']) . '' . htmlspecialchars($info['detection_method']) . '
'; + $html .= '
'; + + return $html; + } +} diff --git a/app/libraries/TurnstileValidator.php b/app/libraries/TurnstileValidator.php new file mode 100644 index 0000000..777b943 --- /dev/null +++ b/app/libraries/TurnstileValidator.php @@ -0,0 +1,184 @@ +secretKey = $secretKey ?: _CRED_TURNSTILE_SECRET_KEY_; + $this->timeout = $timeout; + } + + /** + * Valide un token Turnstile + * + * @param string $token Le token à valider + * @param string $remoteip L'adresse IP du client (optionnel) + * @param string $idempotencyKey Clé d'idempotence pour éviter les doublons (optionnel) + * @return array Résultat de la validation + */ + public function validate($token, $remoteip = null, $idempotencyKey = null) + { + // Validation des paramètres d'entrée + if (empty($token) || !is_string($token)) { + return [ + 'success' => false, + 'error' => 'Token manquant ou invalide', + 'error_codes' => ['missing-input-response'] + ]; + } + + if (strlen($token) > 2048) { + return [ + 'success' => false, + 'error' => 'Token trop long', + 'error_codes' => ['invalid-input-response'] + ]; + } + + // Préparation de la requête + $url = 'https://challenges.cloudflare.com/turnstile/v0/siteverify'; + + $postData = [ + 'secret' => $this->secretKey, + 'response' => $token + ]; + + if (!empty($remoteip)) { + $postData['remoteip'] = $remoteip; + } + + if (!empty($idempotencyKey)) { + $postData['idempotency_key'] = $idempotencyKey; + } + + // Configuration cURL + $ch = curl_init($url); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData)); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_TIMEOUT_MS, $this->timeout); + curl_setopt($ch, CURLOPT_HTTPHEADER, [ + 'Content-Type: application/x-www-form-urlencoded' + ]); + + // Exécution de la requête + $response = curl_exec($ch); + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + $curlError = curl_error($ch); + curl_close($ch); + + // Gestion des erreurs cURL + if ($response === false) { + error_log('Turnstile validation cURL error: ' . $curlError); + return [ + 'success' => false, + 'error' => 'Erreur de connexion au service Turnstile', + 'error_codes' => ['internal-error'] + ]; + } + + // Vérification du code HTTP + if ($httpCode !== 200) { + error_log('Turnstile validation HTTP error: ' . $httpCode); + return [ + 'success' => false, + 'error' => 'Erreur du service Turnstile (HTTP ' . $httpCode . ')', + 'error_codes' => ['internal-error'] + ]; + } + + // Décodage de la réponse JSON + $result = json_decode($response, true); + if (json_last_error() !== JSON_ERROR_NONE) { + error_log('Turnstile validation JSON decode error: ' . json_last_error_msg()); + return [ + 'success' => false, + 'error' => 'Erreur de parsing de la réponse Turnstile', + 'error_codes' => ['internal-error'] + ]; + } + + // Validation du succès + if (!isset($result['success'])) { + error_log('Turnstile validation missing success field in response'); + return [ + 'success' => false, + 'error' => 'Réponse invalide du service Turnstile', + 'error_codes' => ['internal-error'] + ]; + } + + return $result; + } + + /** + * Valide un token avec gestion d'erreurs formatée pour l'affichage + * + * @param string $token Le token à valider + * @param string $remoteip L'adresse IP du client (optionnel) + * @return array Résultat formaté pour l'affichage + */ + public function validateForDisplay($token, $remoteip = null) + { + $result = $this->validate($token, $remoteip); + + if ($result['success']) { + return [ + 'valid' => true, + 'message' => '', + 'data' => $result + ]; + } + + // Mapping des erreurs pour l'affichage utilisateur + $errorMessages = [ + 'missing-input-secret' => 'Configuration Turnstile invalide.', + 'invalid-input-secret' => 'Configuration Turnstile invalide.', + 'missing-input-response' => 'Vérification de sécurité manquante. Veuillez cocher la case "Je ne suis pas un robot".', + 'invalid-input-response' => 'Vérification de sécurité invalide. Veuillez réessayer.', + 'bad-request' => 'Requête de vérification invalide.', + 'timeout-or-duplicate' => 'Vérification de sécurité expirée. Veuillez réessayer.', + 'internal-error' => 'Erreur temporaire du service de sécurité. Veuillez réessayer dans quelques instants.' + ]; + + $errorCodes = isset($result['error-codes']) ? $result['error-codes'] : ['internal-error']; + $errorCode = reset($errorCodes); // Premier code d'erreur + + $message = isset($errorMessages[$errorCode]) ? $errorMessages[$errorCode] : 'Erreur de vérification de sécurité inconnue.'; + + return [ + 'valid' => false, + 'message' => $message, + 'error_codes' => $errorCodes, + 'data' => $result + ]; + } + + /** + * Vérifie si Turnstile est correctement configuré + * + * @return bool True si configuré, false sinon + */ + public static function isConfigured() + { + return defined('_CRED_TURNSTILE_SECRET_KEY_') && + _CRED_TURNSTILE_SECRET_KEY_ !== '' && + _CRED_TURNSTILE_SECRET_KEY_ !== 'YOUR_SECRET_KEY_HERE' && + defined('_CRED_TURNSTILE_SITE_KEY_') && + _CRED_TURNSTILE_SITE_KEY_ !== '' && + _CRED_TURNSTILE_SITE_KEY_ !== 'YOUR_SITE_KEY_HERE'; + } +} diff --git a/app/libraries/base.php b/app/libraries/base.php new file mode 100644 index 0000000..2f97ddd --- /dev/null +++ b/app/libraries/base.php @@ -0,0 +1,49 @@ + + + checkOngoingCreditRequest(); + + /* echo '
';
+        print_r($credit_request);
+        echo '
'; */ + + if ($credit_request) { + $last_update = \Carbon\Carbon::parse($credit_request['last_update_date']); + $now = \Carbon\Carbon::now(); + $interval = $now->diffInDays($last_update); + + if ($interval <= 60) { // 2 mois maximum + /* include(_CRED_MODULES_PATH_ . 'credit-reminder-btn.php'); */ + return true; + } else { + setcookie('credit_data', '', time() - 3600, '/'); + return false; + } + } + } + + public function display_credit_reminder_modal() { + if($this->display_credit_reminder()) { + include(_CRED_MODULES_PATH_ . 'credit-reminder-modal.php'); + } + } + + public function display_credit_reminder_btn() { + if($this->display_credit_reminder()) { + include(_CRED_MODULES_PATH_ . 'credit-reminder-btn.php'); + } + } + + /** + * Envoie des rappels par email pour les crédits en attente. + * Cette méthode doit être appelée dans un contexte WordPress où la fonction wp_mail est disponible. + */ + public function send_reminder_email() { + global $wpdb; + + $now = Carbon::now(); + + $model = new \models\CRED_credit(); + $credit_types = $model->getCreditTypes(); + + $one_day = 1; // Carbon gère la différence en jours directement + $results = $wpdb->get_results(" + SELECT c.idCredit, c.type_credit, c.create_date, c.last_step, c.reminder_sent, c.last_reminder, c.token, e.email, e.nom, e.prenom + FROM cdf_Credit c + JOIN cdf_Emprunteur e ON e.FK_demande_creditdirect = c.idCredit + WHERE e.email IS NOT NULL AND e.email <> '' + AND c.create_date >= DATE_SUB(NOW(), INTERVAL 3 MONTH) + AND ( + (c.type_credit = 'am' AND c.last_step = 1) + OR + (c.type_credit <> 'am' AND c.last_step < 4) + ) + AND c.type_credit NOT IN ('am','amr','cied','frais_notaire','cdp') + "); + + /* echo '
';
+        print_r($results);
+        echo '
'; + die(); */ + + // getMain() est défini dans CRED_base et retourne l'instance de CRED_Main + $main = $this->getMain(); + $template_path = $main::template('credit-reminder-mail.php', 'email', true); + $mail_ar = []; + + + foreach ($results as $row) { + /* echo '
';
+            print_r($row);
+            echo '
'; */ + $send = false; + $reminder_to_send = null; + $create_date = Carbon::parse($row->create_date); + $last_reminder = $row->last_reminder ? Carbon::parse($row->last_reminder) : null; + + // Premier rappel : +3 heures + $target1 = $create_date->copy()->addHours(3); + + $limit_target1 = $create_date->copy()->addDays(1); + // Deuxième rappel : +7 jours + $target2 = $create_date->copy()->addDays(7); + $limit_target2 = $create_date->copy()->addDays(8); + // Troisième rappel : +1 mois + $target3 = $create_date->copy()->addMonth(); + + if ((is_null($row->reminder_sent) || $row->reminder_sent == 0)) { + + // Tolérance : 1h + if ($now->greaterThanOrEqualTo($target1) && $now->lessThan($limit_target1) && ($last_reminder === null || $last_reminder->diffInHours($now) >= 1)) { + $send = true; + $reminder_to_send = 1; + } + } elseif ($row->reminder_sent == 1) { + // Tolérance : 1 jour + if ($now->greaterThanOrEqualTo($target2) && $now->lessThan($limit_target2) && ($last_reminder === null || $last_reminder->diffInDays($now) >= 1)) { + $send = true; + $reminder_to_send = 2; + } + } elseif ($row->reminder_sent == 2) { + // Tolérance : 1 jour + if ($now->greaterThanOrEqualTo($target3) && ($last_reminder === null || $last_reminder->diffInDays($now) >= 1)) { + $send = true; + $reminder_to_send = 3; + } + } + + if ($send) { + // Préparer l'email HTML via le template + + if(empty($row->email)) + continue; + + if(in_array($row->email, $mail_ar)) + continue; + + $mail_ar[] = $row->email; + + $vars = array( + 'main' => $main, + 'prenom' => $row->prenom, + 'nom' => $row->nom, + 'type_credit' => $credit_types[$row->type_credit], + 'reminder_num' => $reminder_to_send, + 'step' => $row->last_step, + 'token' => $row->token + ); + $message = $main->renderTemplate($template_path, $vars); + + /* echo 'message : ' . $message; + die(); */ + + $to = $row->email; + $subject = 'Rappel concernant votre demande de crédit'; + $headers = array('Content-Type: text/html; charset=UTF-8'); + + // Envoyer l'email + /* $to = 'jps@esi-informatique.com'; */ + wp_mail($to, $subject, $message, $headers); + + // Mettre à jour la base + $wpdb->update( + 'cdf_Credit', + array( + 'reminder_sent' => $reminder_to_send, + 'last_reminder' => $now->toDateTimeString() + ), + array('idCredit' => $row->idCredit) + ); + } + } + } +} + +// Initialiser le rappel +CRED_Credit_Reminder::instance(); \ No newline at end of file diff --git a/app/libraries/factory.php b/app/libraries/factory.php new file mode 100644 index 0000000..0105811 --- /dev/null +++ b/app/libraries/factory.php @@ -0,0 +1,522 @@ +main === null) + $this->main = $this->getMain(); + + if($this->forms === null) + $this->forms = $this->getForms(); + + if($this->simulateur === null) + $this->simulateur = $this->getSimulateur(); + + if($this->creditReminder === null) + $this->creditReminder = $this->getCreditReminder(); + + if($this->creditManager === null) + $this->creditManager = $this->getCreditManager(); + + if($this->societesCreditManager === null) + $this->societesCreditManager = $this->getSocietesCreditManager(); + + if($this->creditMailchimp === null) + $this->creditMailchimp = $this->getCreditMailchimp(); + + if($this->creditSendy === null) + $this->creditSendy = $this->getCreditSendy(); + } + + public function load_actions() { + $this->action('template_redirect', array($this, 'load_frontend_assets')); + + $this->action('init', array($this, 'init_hook')); + + $this->action('init', array($this, 'load_shortcodes')); + + $this->action('wp_ajax_ajax_regenerate_simulator', array($this->simulateur, 'ajax_regenerate_simulator')); + $this->action('wp_ajax_nopriv_ajax_regenerate_simulator', array($this->simulateur, 'ajax_regenerate_simulator')); + + // Hook pour le menu d'administration du Credit Manager + $this->action('admin_menu', array($this, 'register_admin_menu')); + + // Hook pour enregistrer les réglages Mailchimp (Settings API) + $this->action('admin_init', array($this->creditMailchimp, 'register_settings')); + + // Hook pour enregistrer les réglages Sendy (Settings API) + $this->action('admin_init', array($this->creditSendy, 'register_settings')); + + // Hook pour charger les assets du Credit Manager et Societes Credit Manager + $this->action('admin_enqueue_scripts', array($this, 'enqueue_credit_manager_assets')); + $this->action('admin_enqueue_scripts', array($this, 'enqueue_societes_credit_assets')); + // Hook pour charger les assets de la page Mailchimp (admin) + $this->action('admin_enqueue_scripts', array($this, 'enqueue_mailchimp_assets')); + // Hook pour charger les assets de la page Sendy (admin) + $this->action('admin_enqueue_scripts', array($this, 'enqueue_sendy_assets')); + + // Hooks AJAX pour le Credit Manager + $this->action('wp_ajax_credit_manager_create', array($this->creditManager, 'ajax_create_credit')); + $this->action('wp_ajax_credit_manager_get', array($this->creditManager, 'ajax_get_credit')); + $this->action('wp_ajax_credit_manager_update', array($this->creditManager, 'ajax_update_credit')); + $this->action('wp_ajax_credit_manager_delete', array($this->creditManager, 'ajax_delete_credit')); + $this->action('wp_ajax_credit_manager_list', array($this->creditManager, 'ajax_list_credits')); + $this->action('wp_ajax_credit_manager_get_filter_options', array($this->creditManager, 'ajax_get_filter_options')); + $this->action('wp_ajax_credit_manager_change_status', array($this->creditManager, 'ajax_change_credit_status')); + $this->action('wp_ajax_credit_manager_update_status', array($this->creditManager, 'ajax_update_credit_status')); + + // Hooks AJAX pour le Societes Credit Manager + $this->action('wp_ajax_societes_credit_create', array($this->societesCreditManager, 'ajax_create_societe')); + $this->action('wp_ajax_societes_credit_get', array($this->societesCreditManager, 'ajax_get_societe')); + $this->action('wp_ajax_societes_credit_update', array($this->societesCreditManager, 'ajax_update_societe')); + $this->action('wp_ajax_societes_credit_delete', array($this->societesCreditManager, 'ajax_delete_societe')); + $this->action('wp_ajax_societes_credit_list', array($this->societesCreditManager, 'ajax_list_societes')); + + // Hook AJAX pour tester la connexion Mailchimp + $this->action('wp_ajax_cred_mailchimp_ping', array($this->creditMailchimp, 'ajax_ping')); + + // Hook AJAX pour tester la connexion Sendy + $this->action('wp_ajax_cred_sendy_ping', array($this->creditSendy, 'ajax_ping')); + } + + public function load_filters() { + $this->filter('page_template',array($this->main,'CRED_page_template')); + } + + public function load_shortcodes() { + + $this->shortcode('loan_simulator', array($this->simulateur,'simulateur_shortcode')); + + } + + public function action($hook, $function, $priority = 10, $accepted_args = 1) { + // Check Parameters + if(!trim($hook) or !$function) return false; + + // Add it to WordPress actions + return add_action($hook, $function, $priority, $accepted_args); + } + + public function filter($tag, $function, $priority = 10, $accepted_args = 1) { + // Check Parameters + if(!trim($tag) or !$function) return false; + + // Add it to WordPress filters + return add_filter($tag, $function, $priority, $accepted_args); + } + + public function load_frontend_assets() { + + global $wpdb; + global $post; + + if (null === $post) + return; + + $includes_page = ['credit-step1', 'credit-step2', 'credit-step3', 'credit-step4', 'credit-step5', 'simulateur', 'simulateur-pret', 'accueil', 'page-daccueil', 'simulateur-pret-hypothecaire', 'pret-a-temperament-pret-personnel']; + //includes posts + $included_posts = ['simulation-pret-hypothecaire']; + $ids_parents = [495,497,824,5359]; + $allooded_children = false; + + if(null != $post && $post->post_pareent > 0) { + if(in_array($post->post_parent, $ids_parents)) { + $allooded_children = true; + } + } + + $independent = $wpdb->get_results('SELECT * FROM cdf_Profession WHERE nom_profession IN ("Indépendant")'); + + //if page parent is not in the array, return + /* if(!in_array($post->post_parent, $ids_parents)) return; */ + + $noEmployer = []; + $info_pat = self::$instance->main->get_acf_audit_option('infos_pat_statut_maries_sans_separation_ds_biens'); + $noEmployerQuery = $wpdb->get_results( + 'SELECT * FROM cdf_Profession WHERE nom_profession IN ( + "Chômeur", + "Invalide", + "Pensionné", + "Prépensionné", + "Sans profession" + )' + ); + + foreach ($noEmployerQuery as $a) { + $noEmployer[] = intval($a->idprofession); + } + + // Include css files + + //if(is page parent in the array, include css files) + + + if(!is_admin()) { + + + } + + + if(is_page($includes_page) || in_array($post->post_parent, $ids_parents) || is_single($included_posts)) { + + wp_enqueue_style( 'bootstrap', $this->main->asset('css/bootstrap.min.css'), array(), '4.6.2' ); + wp_enqueue_style('cd-frontend-style', $this->main->asset('css/cd_main.css')); + wp_enqueue_style('izimodal', $this->main->asset('css/iziModal.min.css')); + + + /* wp_enqueue_script("bootstrap", $this->main->asset("/js/libraries/bootstrap.bundle.min.js"),array('jquery'),false,true);*/ + wp_enqueue_script("bootstrap-form", $this->main->asset("/js/libraries/jquery.bootstrap.wizard.min.js"),array('jquery'),false,true); + wp_enqueue_script("izimodal", $this->main->asset("/js/libraries/iziModal.min.js"),array('jquery'),false,true); + wp_enqueue_script("inputmask", $this->main->asset("/js/libraries/jquery.inputmask.min.js"),array('jquery'),false,true); + + //include custom scripts + /* wp_enqueue_script("cred_custom_js", $this->main->asset('js/cred_js.php'),array('jquery'),false,true); */ + //includes libraries scripts + + wp_enqueue_script( 'jquery-ui-slider' ); + wp_enqueue_script("validate", $this->main->asset("/js/libraries/jquery.validate.min.js"),array('jquery'),false,true); + wp_enqueue_script("additional-methods", $this->main->asset("/js/libraries/additional-methods.min.js"),array('jquery'),false,true); + + wp_enqueue_script( 'jquery-ui-accordion' ); + wp_enqueue_script("jquery_repeater", $this->main->asset("/js/libraries/jquery.repeater.min.js"),array('jquery'),false,true); + + //include main script + wp_enqueue_script("cred_main_js", $this->main->asset('js/cd_main.js'),array('jquery'),'1.0.1',true); + wp_enqueue_script("cred_form_js", $this->main->asset('js/form_main.js'),array('jquery'),'1.0.0',true); + + // Cloudflare Turnstile script + /* if (\libraries\TurnstileValidator::isConfigured()) { + wp_enqueue_script("cloudflare-turnstile", "https://challenges.cloudflare.com/turnstile/v0/api.js", array(), null, true); + } */ + + + wp_localize_script( 'cred_main_js', 'cd_js', + array( + 'ajaxUrl' => admin_url( 'admin-ajax.php' ), + 'groups' => CRED_Main::get_groups_vars(), + 'site_url' => site_url(), + 'nonce' => wp_create_nonce( "cd_47ax_412m" ), + 'independent' => intval($independent[0]->idprofession), + 'noEmployer' => $noEmployer, + 'info_pat' => $info_pat + ) + ); + + // Enregistrement du script du simulateur + wp_enqueue_script('cd-simulator', $this->main->asset('js/cd_simulator.js'), array('jquery'), '1.0.0', true); + + // Localisation du script + wp_localize_script('cd-simulator', 'cred_simulator', array( + 'ajax_url' => admin_url('admin-ajax.php'), + 'nonce' => wp_create_nonce('cred_simulator_nonce') + )); + + // Charger les assets pour la gestion des bâtiments (credit-one-step) + if(is_page('credit-step1')) { + wp_enqueue_style('cd-buildings-style', $this->main->asset('css/buildings.css'), array(), '1.0.0'); + wp_enqueue_script('cd-buildings-manager', $this->main->asset('js/buildings-manager.js'), array('jquery'), '1.0.0', true); + } + + } + + } + + public function load_backend_assets() { + + if(is_admin()) { + wp_dequeue_style('bootstrap'); + + wp_dequeue_script('bootstrap'); + wp_dequeue_script('bootstrap'); + wp_dequeue_script('validate'); + wp_dequeue_script('additional-methods'); + wp_dequeue_script('bootstrap-form'); + wp_dequeue_script('jquery_repeater'); + wp_dequeue_script('cred_main_js'); + wp_dequeue_script('cred_form_js'); + + // Enqueue des assets du credit manager pour l'administration + $this->action('admin_enqueue_scripts', array($this, 'enqueue_credit_manager_assets')); + $this->action('admin_enqueue_scripts', array($this, 'enqueue_societes_credit_assets')); + } + + + } + + /** + * Enqueue des assets du credit manager - limité à la page credit-manager + */ + public function enqueue_credit_manager_assets($hook) { + // Charger seulement sur la page credit-manager (hook ou via le paramètre page) + $should_enqueue = ($hook === 'toplevel_page_credit-manager'); + if (!$should_enqueue && isset($_GET['page']) && $_GET['page'] === 'credit-manager') { + $should_enqueue = true; + } + if (!$should_enqueue) { + return; + } + + // Font Awesome 7 (Kit personnel) + wp_enqueue_style( + 'font-awesome-kit', + 'https://kit.fontawesome.com/a029b5a0f4.css', + array(), + '7.0.0' + ); + + // Enqueue des assets communs (DataTables + CSS personnalisé) + $this->enqueue_common_credit_admin_assets(); + + // DataTables Buttons CSS + wp_enqueue_style( + 'datatables-buttons-css', + 'https://cdn.datatables.net/buttons/2.4.2/css/buttons.dataTables.min.css', + array('datatables-css'), + '2.4.2' + ); + + // JSZip (requis pour Excel) + wp_enqueue_script( + 'jszip', + 'https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js', + array(), + '3.10.1', + true + ); + + // DataTables Buttons + wp_enqueue_script( + 'datatables-buttons', + 'https://cdn.datatables.net/buttons/2.4.2/js/dataTables.buttons.min.js', + array('datatables-js'), + '2.4.2', + true + ); + + // Buttons HTML5 export + wp_enqueue_script( + 'datatables-buttons-html5', + 'https://cdn.datatables.net/buttons/2.4.2/js/buttons.html5.min.js', + array('datatables-buttons', 'jszip'), + '2.4.2', + true + ); + + // JavaScript personnalisé + wp_enqueue_script( + 'credit-manager-js', + $this->main->asset('js/credit-manager.js'), + array('datatables-js', 'datatables-buttons', 'datatables-buttons-html5', 'select2-js'), + '1.0.0', + true + ); + + // Localiser les variables JavaScript + wp_localize_script('credit-manager-js', 'creditManagerAjax', array( + 'ajaxurl' => admin_url('admin-ajax.php'), + 'nonce' => wp_create_nonce('credit_manager_action') + )); + } + + public function enqueue_mailchimp_assets($hook) { + $should_enqueue = ($hook === 'credit-manager_page_credit-mailchimp'); + if (!$should_enqueue && isset($_GET['page']) && $_GET['page'] === 'credit-mailchimp') { + $should_enqueue = true; + } + if (!$should_enqueue) { + return; + } + + // Charger uniquement le JS commun sans DataTables ni CSS lourds + wp_enqueue_script( + 'credit-manager-js', + $this->main->asset('js/credit-manager.js'), + array('jquery', 'select2-js'), + '1.0.0', + true + ); + + // Localiser uniquement ce qui est nécessaire pour le test Mailchimp + wp_localize_script('credit-manager-js', 'creditManagerAjax', array( + 'ajaxurl' => admin_url('admin-ajax.php'), + 'mailchimpPingNonce' => wp_create_nonce('cred_mailchimp_ping') + )); + } + + public function enqueue_sendy_assets($hook) { + $should_enqueue = ($hook === 'credit-manager_page_credit-sendy'); + if (!$should_enqueue && isset($_GET['page']) && $_GET['page'] === 'credit-sendy') { + $should_enqueue = true; + } + if (!$should_enqueue) { + return; + } + + // Charger uniquement le JS commun sans DataTables ni CSS lourds + wp_enqueue_script( + 'credit-manager-js', + $this->main->asset('js/credit-manager.js'), + array('jquery', 'select2-js'), + '1.0.0', + true + ); + + // Localiser uniquement ce qui est nécessaire pour le test Sendy + wp_localize_script('credit-manager-js', 'creditManagerAjax', array( + 'ajaxurl' => admin_url('admin-ajax.php'), + 'sendyPingNonce' => wp_create_nonce('cred_sendy_ping') + )); + } + + public function shortcode($shortcode, $function) { + // Check Parameters + if(!trim($shortcode) or !$function) return false; + + // Add it to WordPress shortcodes + return add_shortcode($shortcode, $function); + } + + public function init_hook() { + + //create table + /* CRED_Main::create_db_tables(); */ + + /* CRED_Main::create_uploadr_page(); + + CRED_Main::start_session(); */ + + //register post type + CRED_Main::cred_register_post_type('agences','Agence Physique','Agence','Agences','dashicons-building','f'); + + //register agence taxonomy + CRED_Main::cred_register_post_taxonomy('agences_email','agences','Emails agence','Email','Emails','','m'); + + //load shortcode + $this->load_shortcodes(); + + //load frontend styles and scripts + /* $this->load_frontend_assets(); */ + + //load backend styles and scripts + $this->load_backend_assets(); + } + + /** + * Enregistrer le menu d'administration du Credit Manager + */ + public function register_admin_menu() { + $creditManager = $this->creditManager; + if ($creditManager) { + $creditManager->add_admin_menu(); + } + + $societesCreditManager = $this->societesCreditManager; + if ($societesCreditManager) { + $societesCreditManager->add_admin_menu(); + } + + $creditMailchimp = $this->creditMailchimp; + if ($creditMailchimp) { + $creditMailchimp->add_admin_menu(); + } + + $creditSendy = $this->creditSendy; + if ($creditSendy) { + $creditSendy->add_admin_menu(); + } + } + + /** + * Enqueue des assets du societes credit manager - limité à la page societes-credit-manager + */ + public function enqueue_societes_credit_assets($hook) { + // Charger seulement sur la page societes-credit-manager (sous-menu de credit-manager) + $should_enqueue = ($hook === 'credit-manager_page_societes-credit-manager'); + if (!$should_enqueue && isset($_GET['page']) && $_GET['page'] === 'societes-credit-manager') { + $should_enqueue = true; + } + if (!$should_enqueue) { + return; + } + + // Enqueue des assets communs (DataTables + CSS personnalisé) + $this->enqueue_common_credit_admin_assets(); + + // Script spécifique à la page Sociétés de Crédit + wp_enqueue_script( + 'societes-credit-manager-js', + $this->main->asset('js/societes-credit-manager.js'), + array('datatables-js', 'select2-js'), + '1.0.0', + true + ); + + // Variables JS pour AJAX (nonce aligné avec les contrôleurs) + wp_localize_script('societes-credit-manager-js', 'societesCreditAjax', array( + 'ajaxurl' => admin_url('admin-ajax.php'), + 'nonce' => wp_create_nonce('societes_credit_action') + )); + } + + /** + * Enqueue des assets communs aux pages d'administration liées au Credit Manager + * - DataTables CSS/JS + * - CSS commun du Credit Manager + */ + private function enqueue_common_credit_admin_assets() { + // Select2 CSS (CDN) + wp_enqueue_style( + 'select2-css', + 'https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css', + array(), + '4.1.0-rc.0' + ); + + // Select2 JS (CDN) + wp_enqueue_script( + 'select2-js', + 'https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js', + array('jquery'), + '4.1.0-rc.0', + true + ); + + // DataTables CSS + wp_enqueue_style( + 'datatables-css', + $this->main->node_modules('datatables.net-dt/css/dataTables.dataTables.min.css'), + array(), + '1.13.7' + ); + + // DataTables JS + wp_enqueue_script( + 'datatables-js', + $this->main->node_modules('datatables.net/js/dataTables.min.js'), + array('jquery'), + '1.13.7', + true + ); + + // CSS commun du Credit Manager + wp_enqueue_style( + 'credit-manager-css', + $this->main->asset('css/credit-manager.css'), + array('datatables-css'), + '1.0.0' + ); + } + +} \ No newline at end of file diff --git a/app/libraries/forms.php b/app/libraries/forms.php new file mode 100644 index 0000000..5633a2c --- /dev/null +++ b/app/libraries/forms.php @@ -0,0 +1,5 @@ + $value) { + $$key = $value; + } + } + } + + ob_start(); + include $url; + + return ob_get_clean(); + } + + /** + * Returns URL of WordPress items such as site, admin, plugins, ANA plugin etc. + * @param string $type + * @return string + */ + public static function URL($type = 'site') + { + // Make it lowercase + $type = strtolower($type); + $url = ""; + + // Frontend + if(in_array($type, array('frontend','site'))) $url = site_url().'/'; + // Backend + elseif(in_array($type, array('backend','admin'))) $url = admin_url(); + // WordPress Content directory URL + elseif($type === 'content') $url = content_url().'/'; + // WordPress plugins directory URL + elseif($type === 'plugin') $url = plugins_url().'/'; + // WordPress include directory URL + elseif($type === 'include') $url = includes_url(); + // Webnus MEC plugin URL + elseif($type === 'cred') + { + // If plugin installed regularly on plugins directory + if(!defined('CRED_IN_THEME')) $url = plugins_url() .'/'._CRED_DIRNAME_.'/'; + // If plugin embeded into one theme + else $url = get_template_directory_uri().'/plugins/'._CRED_DIRNAME_.'/'; + } + + return $url; + } + + /** + * Returns absolute path of file + * @param string $type + * @return string + */ + public static function full_path() { + + $path = WP_PLUGIN_DIR .'/'._CRED_DIRNAME_.'/'; + + return $path; + } + + /** + * Return an acf option based on the field name + * @return string, object or array depending on the field type + * */ + public static function get_acf_audit_option($field_name) { + + if(empty($field_name) && !isset($field_name)) return false; + + $field = get_field($field_name, 'option'); + + if(!$field) + return false; + + return $field; + } + + + + public static function get_groups_vars() { + + $vars_groups = array( + 'pret_personnel__tous_motifs__achats_divers' => self::get_acf_audit_option('pret_personnel__tous_motifs__achats_divers'), + 'financement_frais_de_notaire' => self::get_acf_audit_option('financement_frais_de_notaire'), + 'credit_travaux__renovation__energie' => self::get_acf_audit_option('credit_travaux__renovation__energie'), + 'financement_vehicule_neuf' => self::get_acf_audit_option('financement_vehicule_neuf'), + 'financement_vehicule_doccasion_moins_de_3_ans' => self::get_acf_audit_option('financement_vehicule_d’occasion_moins_de_3_ans'), + 'financement_vehicule_doccasion_plus_de_3_ans' => self::get_acf_audit_option('financement_vehicule_d’occasion_plus_de_3_ans'), + 'financement_mobilhome_et_caravane_de_moins_de_3_ans' => self::get_acf_audit_option('financement_mobilhome_et_caravane_de_moins_de_3_ans'), + 'credit_hypothecaire_classique' => self::get_acf_audit_option('credit_hypothecaire_classique'), + 'credit_hypothecaire_social' => self::get_acf_audit_option('credit_hypothecaire_social'), + 'achat_maison_de_rapport' => self::get_acf_audit_option('achat_maison_de_rapport'), + 'credit_pont' => self::get_acf_audit_option('credit_pont'), + 'independants_et_entreprises_en_difficultes' => self::get_acf_audit_option('independants_et_entreprises_en_difficultes'), + 'regroupement_de_credit__rachats_de_credits' => self::get_acf_audit_option('regroupement_de_credit__rachats_de_credits'), + 'fonds_roulement_independants' => self::get_acf_audit_option('fonds_roulement_independants'), + ); + + return $vars_groups; + } + + public static function create_db_tables() { + + global $wpdb; + + require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); + + $charset_collate = $wpdb->get_charset_collate(); + + /** + * CREATE TABLE `$wpdb->dbname`.`cdf_Agences` ( + `idAgences` INT NOT NULL AUTO_INCREMENT, + `Nom_agence` VARCHAR(45) NULL, + `description_agence` VARCHAR(255) NULL, + PRIMARY KEY (`idAgences`)) + ENGINE = InnoDB; + CREATE TABLE `$wpdb->dbname`.`cdf_Emails` ( + `idEmails` INT NOT NULL AUTO_INCREMENT, + `email` VARCHAR(45) NOT NULL, + PRIMARY KEY (`idEmails`)) + ENGINE = InnoDB; + CREATE TABLE `$wpdb->dbname`.`cdf_Agences_emails` ( + `FK_agence` INT NULL, + `FK_email` INT NULL, + `type_email` VARCHAR(45) NOT NULL, + CONSTRAINT `FK_agence` + FOREIGN KEY (`FK_agence`) + REFERENCES `cdf_Agences` (`idAgences`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `FK_email` + FOREIGN KEY (`FK_email`) + REFERENCES `cdf_Emails` (`idEmails`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) + ENGINE = InnoDB; + */ + + $sql = " + CREATE TABLE `$wpdb->dbname`.`cdf_Profession` ( + `idprofession` INT NOT NULL AUTO_INCREMENT, + `nom_profession` VARCHAR(45) NULL, + PRIMARY KEY (`idprofession`)) + ENGINE = InnoDB; + CREATE TABLE `$wpdb->dbname`.`cdf_Options_credit_auto` ( + `idOptions_credit_auto` INT NOT NULL AUTO_INCREMENT, + `marque` VARCHAR(45) NULL, + `date_immatriculation` DATE NULL, + `nom_vendeur` VARCHAR(45) NULL, + `adresse_vendeur` VARCHAR(45) NULL, + `prix_vehicule` FLOAT NULL, + `montant_accompte` FLOAT NULL, + `montant_reprise` FLOAT NULL, + `montant_emprunt` FLOAT NULL, + `duree` INT NULL, + PRIMARY KEY (`idOptions_credit_auto`)) + ENGINE = InnoDB; + CREATE TABLE `$wpdb->dbname`.`cdf_Options_credit_hypotecaire` ( + `idOptions_credit_hypotecaire` INT NOT NULL AUTO_INCREMENT, + `type_credit` VARCHAR(45) NULL, + `prix_achat` FLOAT NULL, + `prix_construction_tvac` FLOAT NULL, + `frais_notaire_pays` FLOAT NULL, + `valeur_batiment` FLOAT NULL, + `fonds_propre` FLOAT NULL, + `compromis_signe` INT NULL, + `montant_revenu_cadastral` FLOAT NULL, + `montant_a_emprunter` FLOAT NULL, + `duree` INT NULL, + PRIMARY KEY (`idOptions_credit_hypotecaire`)) + ENGINE = InnoDB; + CREATE TABLE `$wpdb->dbname`.`cdf_Credit` ( + `idCredit` INT NOT NULL AUTO_INCREMENT, + `type_credit` VARCHAR(45) NULL, + `capital` VARCHAR(45) NULL, + `duree` VARCHAR(45) NULL, + `cout_total` VARCHAR(45) NULL, + `mensualite` VARCHAR(45) NULL, + `taux_nominal_annuel` VARCHAR(45) NULL, + `rgpd` VARCHAR(45) NULL, + `create_date` DATETIME NULL DEFAULT NULL, + `last_update_date` DATETIME NULL DEFAULT NULL, + `last_step` TINYINT NOT NULL DEFAULT '1', + `token` VARCHAR(45) NULL, + `FK_credit_auto` INT NULL, + `FK_credit_hypothecaire` INT NULL, + PRIMARY KEY (`idCredit`), + INDEX `FK_credit_auto_idx` (`FK_credit_auto` ASC), + INDEX `FK_credit_hypothecaire_idx` (`FK_credit_hypothecaire` ASC), + CONSTRAINT `FK_credit_auto` + FOREIGN KEY (`FK_credit_auto`) + REFERENCES `cdf_Options_credit_auto` (`idOptions_credit_auto`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `FK_credit_hypothecaire` + FOREIGN KEY (`FK_credit_hypothecaire`) + REFERENCES `cdf_Options_credit_hypotecaire` (`idOptions_credit_hypotecaire`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) + ENGINE = InnoDB; + CREATE TABLE `$wpdb->dbname`.`cdf_Etat_civil` ( + `idetat_civil` INT NOT NULL AUTO_INCREMENT, + `nom_etat_civil` VARCHAR(45) NULL, + PRIMARY KEY (`idetat_civil`)) + ENGINE = InnoDB; + CREATE TABLE `$wpdb->dbname`.`cdf_Emprunteur` ( + `idemprunteur` INT NOT NULL AUTO_INCREMENT, + `nom` VARCHAR(45) NULL, + `num_registre_national` VARCHAR(45) NULL, + `prenom` VARCHAR(45) NULL, + `telephone` VARCHAR(45) NULL, + `email` VARCHAR(45) NULL, + `date_naissance` DATE NULL, + `lieu_naissance` VARCHAR(45) NULL, + `nationalité` VARCHAR(45) NULL, + `num_carte_identite` VARCHAR(45) NULL, + `carte_identite_validite` DATE NULL, + `num_compte_bancaire` VARCHAR(45) NULL, + `adresse` VARCHAR(45) NULL, + `code_postal` INT NULL, + `localite` VARCHAR(45) NULL, + `pays` VARCHAR(45) NULL, + `date_emmenagement` DATE NULL, + `enfant_charge` INT NULL, + `contract_type` VARCHAR(45) NULL, + `nom_employeur` VARCHAR(45) NULL, + `numero_entreprise` VARCHAR(45) NULL, + `adresse_employeur` VARCHAR(45) NULL, + `code_postal_employeur` VARCHAR(45) NULL, + `localite_employeur` VARCHAR(45) NULL, + `pays_employeur` VARCHAR(45) NULL, + `date_engagement` DATE NULL, + `salaire` FLOAT NULL, + `cheque_repas` FLOAT NULL, + `revenus_locatifs` FLOAT NULL, + `chomage` FLOAT NULL, + `autre_revenu_montant` FLOAT NULL, + `autre_revenu_type` VARCHAR(45) NULL, + `parent_emprunteur` INT NULL, + `habitation_type` VARCHAR(45) NULL, + `habitation_loyer` FLOAT NULL, + `habitation_charge_hypothecaire` VARCHAR(45) NULL, + `habitation_sans_charge_locative` VARCHAR(45) NULL, + `remarques` TEXT NULL, + `FK_demande_creditdirect` INT NULL, + `FK_agence` INT NULL, + `FK_profession` INT NULL, + `FK_etat_civil` INT NULL, + PRIMARY KEY (`idemprunteur`), + INDEX `FK_profession_idx` (`FK_profession` ASC), + INDEX `FK_agences_idx` (`FK_agence` ASC), + INDEX `FK_demande_credit_idx` (`FK_demande_creditdirect` ASC), + INDEX `FK_etat_civil_idx` (`FK_etat_civil` ASC), + CONSTRAINT `FK_profession` + FOREIGN KEY (`FK_profession`) + REFERENCES `cdf_Profession` (`idprofession`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `FK_agences` + FOREIGN KEY (`FK_agence`) + REFERENCES `cdf_Agences` (`idAgences`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `FK_demande_credit` + FOREIGN KEY (`FK_demande_creditdirect`) + REFERENCES `cdf_Credit` (`idCredit`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `FK_etat_civil` + FOREIGN KEY (`FK_etat_civil`) + REFERENCES `cdf_Etat_civil` (`idetat_civil`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) + ENGINE = InnoDB; + CREATE TABLE `$wpdb->dbname`.`cdf_Type_creance` ( + `idtype_creance` INT NOT NULL AUTO_INCREMENT, + `nom_creance` VARCHAR(45) NULL, + PRIMARY KEY (`idtype_creance`)) + ENGINE = InnoDB; + CREATE TABLE `$wpdb->dbname`.`cdf_Autre_credit` ( + `idautrecredit` INT NOT NULL AUTO_INCREMENT, + `banque` VARCHAR(45) NULL, + `montant` FLOAT NULL, + `duree_credit` INT NULL, + `mensualite` INT NULL, + `date_premiere_echeance` DATE NULL, + `solde_restant_du` FLOAT NULL, + `cloture` INT NULL, + `solde` FLOAT NULL, + `FK_type_creance` INT NULL, + `FK_emprunteur` INT NULL, + PRIMARY KEY (`idautrecredit`), + INDEX `FK_type_creance_idx` (`FK_type_creance` ASC), + INDEX `FK_emprunteur_idx` (`FK_emprunteur` ASC), + CONSTRAINT `FK_type_creance` + FOREIGN KEY (`FK_type_creance`) + REFERENCES `cdf_Type_creance` (`idtype_creance`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `FK_emprunteur` + FOREIGN KEY (`FK_emprunteur`) + REFERENCES `cdf_Emprunteur` (`idemprunteur`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) + ENGINE = InnoDB; + "; + + dbDelta( $sql ); + + /** + * Hydrate table Agence + */ + /* $result = $wpdb->get_results('SELECT * FROM cdf_Agences LIMIT 0,1'); + + if (empty($result)) { + dbDelta( + "INSERT INTO cdf_Agences (Nom_agence, description_agence) VALUES + (\"Verviers\", NULL), + (\"Mons\", NULL), + (\"Liège\", NULL), + (\"Arlon\", NULL);" + ); + } */ + + /** + * Hydrate table Email + */ + /* $result = $wpdb->get_results('SELECT * FROM cdf_Emails LIMIT 0,1'); + + if (empty($result)) { + dbDelta( + "INSERT INTO cdf_Emails (email) VALUES + (\"pat@credit-direct.be\"), + (\"sylviane@credit-direct.be\"), + (\"annick@credit-direct.be\");" + ); + } */ + + /** + * Hydrate table Email + */ + /* $result = $wpdb->get_results('SELECT * FROM cdf_Agences_emails LIMIT 0,1'); + + if (empty($result)) { + dbDelta( + "INSERT INTO cdf_Agences_emails (FK_agence, FK_email, type_email) VALUES + (1, 1, \"to\"), + (2, 2, \"to\"), + (2, 1, \"cc\"), + (2, 3, \"cc\"), + (3, 1, \"to\"), + (4, 1, \"to\");" + ); + } */ + + /** + * Hydrate table Etat_civil + */ + $result = $wpdb->get_results('SELECT * FROM cdf_Etat_civil LIMIT 0,1'); + + if (empty($result)) { + dbDelta( + "INSERT INTO cdf_Etat_civil (nom_etat_civil) VALUES + (\"Célibataire\"), + (\"Divorcé(e)\"), + (\"Marié(e) avec contract de séparation de biens\"), + (\"Marié(e) sans contract de séparation de biens\"), + (\"Séparé(e)\"), + (\"Veuf(ve)\");" + ); + } + + /** + * Hydrate table Profession + */ + $result = $wpdb->get_results('SELECT * FROM cdf_Profession LIMIT 0,1'); + + if (empty($result)) { + dbDelta( + "INSERT INTO cdf_Profession (nom_profession) VALUES + (\"Chômeur\"), + (\"Employé\"), + (\"Enseignant\"), + (\"Fonctionnaire\"), + (\"Indépendant\"), + (\"Invalide\"), + (\"Militaire\"), + (\"Ouvrier\"), + (\"Pensionné\"), + (\"Policier\"), + (\"Prépensionné\"), + (\"Sans profession\");" + ); + } + + /** + * Hydrate table Profession + */ + $result = $wpdb->get_results('SELECT * FROM cdf_Type_creance LIMIT 0,1'); + + if (empty($result)) { + dbDelta( + "INSERT INTO cdf_Type_creance (nom_creance) VALUES + (\"Carte de crédit\"), + (\"Crédit ballon\"), + (\"Découvert bancaire\"), + (\"Financement véhicule\"), + (\"Leasing\"), + (\"Pension alimentaire à payer\"), + (\"Prêt à tempérament\"), + (\"Prêt hypothécaire\"), + (\"Réserve d'argent\");" + ); + } + } + + public static function create_uploadr_page() { + // Setup custom vars + $author_id = 1; + $total_step = 4; + for($i=1; $i<=$total_step; $i++){ + $possibleCurrentPage = get_page_by_path('credit-step' . $i); + + if (is_null($possibleCurrentPage)) { + $step = array( + 'comment_status' => 'closed', + 'ping_status' => 'closed', + 'post_author' => $author_id, + 'post_name' => "credit-step" . $i, + 'post_title' => "credit-step" . $i, + 'post_status' => 'publish', + 'post_type' => 'page', + 'page_template' => 'credit-step' . $i + ); + $post_id = wp_insert_post($step); + } + } + + } + + public static function start_session() { + if(!session_id()) { + session_start(); + } + } + + public static function CRED_page_template($page_template) { + + if (!defined('WP_CREDIT_FORM_PATH')) { + define('WP_CREDIT_FORM_PATH', dirname(__FILE__)); + } + + if ( is_page( 'credit-step1' ) ) { + $page_template = _CRED_BASE_PATH_ . '/app/controllers/credit-step1.php'; + }elseif (is_page( 'credit-step2' )) { + $page_template = _CRED_BASE_PATH_ . '/app/controllers/credit-step2.php'; + }elseif (is_page( 'credit-step3' )) { + $page_template = _CRED_BASE_PATH_ . '/app/controllers/credit-step3.php'; + }elseif (is_page( 'credit-step4' )) { + $page_template = _CRED_BASE_PATH_ . '/app/controllers/credit-step4.php'; + }elseif (is_page( 'credit-step5' )) { + $page_template = _CRED_BASE_PATH_ . '/app/controllers/credit-step5.php'; + } + + return $page_template; + } + + /** + * + */ + public static function cred_register_post_type($name, $label, $singular_label, $plural_label, $icon, $genre,$support=array()) { + + $genre_labels = array( + array('f' => 'Toutes', 'm' => 'Tous'), + array('f' => 'Nouvelle', 'm' => 'Nouveau'), + array('f' => 'trouvée', 'm' => 'trouvé'), + array('f' => 'une', 'm' => 'un'), + ); + + if(empty($support)) { + $support = array( + 'title', + ); + } + + register_post_type( + $name, + array( + 'label' => $label, + 'labels' => array( + 'name' => $label, + 'singular_name' => $singular_label, + 'all_items' => $genre_labels[0][$genre].' les '.strtolower($plural_label), + 'add_new_item' => 'Ajouter une '.strtolower($singular_label), + 'edit_item' => 'Éditer '.$genre_labels[3][$genre].' '.strtolower($singular_label), + 'new_item' => $genre_labels[1][$genre].' '.strtolower($singular_label), + 'view_item' => 'Voir le '.strtolower($plural_label), + 'search_items' => 'Rechercher parmi les '.strtolower($plural_label), + 'not_found' => 'Pas de '.strtolower($plural_label).' trouvées', + 'not_found_in_trash'=> 'Pas de '.strtolower($singular_label).' dans la corbeille', + ), + 'public' => true, + 'show_ui' => true, + 'show_in_menu' => true, + 'show_in_nav_menus' => true, + 'show_in_admin_bar' => true, + 'menu_position' => 5, + 'menu_icon' => $icon, + 'can_export' => true, + 'has_archive' => true, + 'exclude_from_search' => false, + 'publicly_queryable' => true, + 'capability_type' => 'page', + 'supports' => $support, + 'has_archive' => true + ) + ); + + + } + + public static function cred_register_post_taxonomy($name,$post_type, $label, $singular_label, $plural_label, $icon, $genre, $link_to_post_type = true) { + + $genre_labels = array( + array('f' => 'Toutes', 'm' => 'Tous'), + array('f' => 'Nouvelle', 'm' => 'Nouveau'), + array('f' => 'trouvée', 'm' => 'trouvé'), + array('f' => 'une', 'm' => 'un'), + array('f' => 'utilisée', 'm' => 'utilisé'), + ); + + register_taxonomy( + $name, + $post_type, + array( + 'label' => $label, + 'labels' => array( + 'name' => $label, + 'singular_name' => $singular_label, + 'all_items' => strtolower($singular_label), + 'edit_item' => 'Éditer un '.strtolower($singular_label), + 'view_item' => 'Voir '.$genre_labels[3][$genre].' '.strtolower($singular_label), + 'update_item' => 'Mettre à jour '.$genre_labels[3][$genre].' '.strtolower($singular_label), + 'add_new_item' => 'Ajouter '.$genre_labels[3][$genre].' '.strtolower($singular_label), + 'new_item_name' => $genre_labels[1][$genre].' '.strtolower($singular_label), + 'search_items' => 'Rechercher parmi les '.strtolower($plural_label), + 'popular_items' => $singular_label.' les plus '.$genre_labels[4][$genre] + ), + 'hierarchical' => true, + 'public' => true, + 'show_ui' => true, + 'show_in_menu' => true, + 'show_in_nav_menus' => true, + 'show_in_admin_bar' => true, + 'show_admin_column' => true, + 'menu_position' => 5, + 'menu_icon' => $icon, + 'can_export' => true, + 'has_archive' => true, + 'exclude_from_search' => false, + 'publicly_queryable' => true, + ) + ); + + if($link_to_post_type) { + register_taxonomy_for_object_type( $name, $post_type ); + } + + } + +} \ No newline at end of file diff --git a/app/libraries/simulateur.php b/app/libraries/simulateur.php new file mode 100644 index 0000000..4839563 --- /dev/null +++ b/app/libraries/simulateur.php @@ -0,0 +1,380 @@ + 'Nonce manquant')); + return; + } + + if (!wp_verify_nonce($_POST['nonce'], 'cd_47ax_412m')) { + wp_send_json_error(array('message' => 'Nonce invalide')); + return; + } + + $type = isset($_POST['type']) ? $_POST['type'] : 'pat'; + + $atts = array( + 'cd_default_loan_stimulator' => $type, + 'check_credit_type' => '' + ); + + $content = self::simulateur_shortcode($atts); + + wp_send_json_success(array( + 'html' => $content + )); + } + + /* public static function generate_loan_stimulator_with_vc() { + vc_map( array( + "name" => __( "Generate Loan Stimulator", "cd-loan-stimulator" ), + "base" => "loan_simulator", + "class" => "", + "category" => __( "Credit Direct Custom Blocks", "cd-custom-blocks"), + "params" => array( + + array( + "type" => "dropdown", + "holder" => "div", + "class" => "", + "heading" => __( "Default Stimulator", "cd-loan-stimulator" ), + "param_name" => "cd_default_loan_stimulator", + "value" => array( + __( "Prêt personnel / Tous motifs / Achats divers", "cd_loan_stimulator" ) => "pat", + __( "Financement frais de notaire ", "cd_loan_stimulator" ) => "frais_notaire", + __( "Crédit travaux / Rénovation / Energie", "cd_loan_stimulator" ) => "but_immo", + __( "Financement véhicule NEUF", "cd_loan_stimulator" ) => "fin_neuve", + __( "Financement véhicule d'occasion MOINS de 3 ans", "cd_loan_stimulator" ) => "fin_occ_m3a", + __( "Financement véhicule d'occasion PLUS de 3 ans", "cd_loan_stimulator" ) => "fin_occ_p3a", + __( "Crédit hypothécaire classique (achat maison, construction, refinancement, regroupement, travaux, achat à l'étranger)" ) => "am", + __( "Crédit hypothécaire social (achat maison, construction)", "cd_loan_stimulator" ) => "ph", + ), + "description" => __( "", "cd-loan-stimulator" ) + ) + ) + ) ); + } */ + + + public static function simulateur_shortcode($atts) { + + global $post; + $current_post_id = $post->ID; + + $vars = shortcode_atts( + array( + 'cd_default_loan_stimulator' => '', + 'check_credit_type' => '', + ), $atts ); + + $options = array( + array( + 'value' => 'pat', + 'heading' => 'Prêt personnel / Tous motifs / Achats divers', + 'short_title' => 'Prêt personnel', + 'page_slug' => 'pret-personnel', + 'page_id' => 55 + ), + array( + 'value' => 'financement_frais_de_notaire', + 'heading' => 'Financement frais de notaire', + 'short_title' => '', + 'page_slug' => 'financement-frais-de-notaire', + 'page_id' => 887 + ), + array( + 'value' => 'but_immo', + 'heading' => 'Crédit travaux / Rénovation / Energie', + 'short_title' => 'Prêt travaux', + 'page_slug' => 'credit-classique-achat-maison-travaux', + 'page_id' => 30 + ), + array( + 'value' => 'fin_neuve', + 'heading' => 'Financement véhicule NEUF', + 'short_title' => 'Crédit Auto', + 'page_id' => 'achat-vehicule-auto-moto-caravane', + 'page_slug' => 57 + ), + array( + 'value' => 'fin_occ_m3a', + 'heading' => 'Financement véhicule d\'occasion MOINS de 3 ans', + 'short_title' => '', + 'page_slug' => 'achat-vehicule-auto-moto-caravane', + 'page_id' => 57 + ), + array( + 'value' => 'fin_occ_p3a', + 'heading' => 'Financement véhicule d\'occasion PLUS de 3 ans', + 'short_title' => '', + 'page_slug' => 'achat-vehicule-auto-moto-caravane', + 'page_id' => 57 + ), + array( + 'value' => 'am', + 'heading' => 'Crédit hypothécaire classique (achat maison, construction, refinancement, regroupement, travaux, achat à l\'étranger)', + 'short_title' => 'Crédit hypothécaire', + 'page_slug' => 'credit-classique-achat-maison-travaux', + 'page_id' => 30 + ) + ); + + $fin_neuve_sub_credits = [ + 'fin_neuve' => array('label' => 'Financement auto neuve', 'icon' => 'icon-toiturecar-neuve', 'page' => 'achat-vehicule-auto-moto-caravane','page_ids' => array(57),'checked' => 1, 'sub_class' => 'fin_neuve', 'hidden' => 1), + 'fin_occ_m3a' => array('label' => 'Financement auto d\'occasion < 3 ans', 'icon' => 'icon-toiturecar-light', 'page' => 'achat-vehicule-auto-moto-caravane','page_ids' => array(57),'checked' => 0, 'sub_class' => 'fin_occ_m3a', 'hidden' => 0), + 'fin_occ_p3a' => array('label' => 'Financement auto d\'occasion > 3 ans', 'icon' => 'icon-toiturecar-old', 'page' => 'achat-vehicule-auto-moto-caravane','page_ids' => array(57),'checked' => 0, 'sub_class' => 'fin_occ_p3a', 'hidden' => 0), + 'mobil_carav' => array('label' => 'Mobil-home et caravane', 'icon' => 'icon-toiturecar-light', 'page' => 'achat-mobilhome-caravane','page_ids' => array(57),'checked' => 0, 'sub_class' => 'mobil_carav', 'hidden' => 0), + ]; + + $travaux_sub_credits = [ + 'but_immo' => array('label' => 'Travaux de rénovation', 'icon' => 'icon-toituretravaux-renovation', 'page' => 'travaux-de-renovation','page_ids' => array(800),'checked' => 0), + 'reno_energie' => array('label' => 'Rénovation énergétique', 'icon' => 'icon-toituretravaux-renovation', 'page' => 'renovation-energetique','page_ids' => array(800),'checked' => 0), + ]; + + $creditTypes = [ + 'pat' => array('label' => 'Prêt personnel tous motifs', 'icon' => 'icon-toiturepret-tout-motif', 'page' => 'pret-personnel-tous-motifs', 'page_ids' => array(3187),'checked' => 1, 'insertAfter' => ''), + 'regrouping' => array('label' => 'Regroupement de crédits', 'icon' => 'icon-toitureregroupement-credit', 'page' => 'regroupement-de-credits','page_ids' => array(55),'checked' => 0, 'insertAfter' => ''), + 'fin_neuve' => array('label' => 'Financement auto', 'icon' => 'icon-toiturecar-neuve', 'page' => 'achat-vehicule-auto-moto-caravane','page_ids' => array(57),'checked' => 0, 'insertAfter' => ''), + 'fin_occ_m3a' => array('label' => 'Financement auto d\'occasion < 3 ans', 'icon' => 'icon-toiturecar-light', 'page' => 'achat-vehicule-auto-moto-caravane','page_ids' => array(57),'checked' => 0, 'insertAfter' => ''), + 'fin_occ_p3a' => array('label' => 'Financement auto d\'occasion > 3 ans', 'icon' => 'icon-toiturecar-old', 'page' => 'achat-vehicule-auto-moto-caravane','page_ids' => array(57),'checked' => 0, 'insertAfter' => ''), + 'mobil_carav' => array('label' => 'Mobil-home et caravane', 'icon' => 'icon-toiturecar-light', 'page' => 'achat-mobilhome-caravane','page_ids' => array(57),'checked' => 0, 'insertAfter' => ''), + 'but_immo' => array('label' => 'Crédits travaux, rénovation', 'icon' => 'icon-toituretravaux-renovation', 'page' => 'travaux-renovation','page_ids' => array(62),'checked' => 0, 'insertAfter' => ''), + 'reno_energie' => array('label' => 'Rénovation énergétique', 'icon' => 'icon-toituretravaux-renovation', 'page' => 'renovation-energetique','page_ids' => array(800),'checked' => 0, 'insertAfter' => ''), + ]; + + $houseCreditTypes = [ + 'purchasehouse' => array('label' => 'Achat maison', 'icon' => 'icon-toitureachat-maison', 'page' => 'achat-maison','page_ids' => array(30),'checked' => 1), + 'construction' => array('label' => 'Nouvelle construction', 'icon' => 'icon-toiturenouvel-construction', 'page' => 'nouvelle-construction','page_ids' => array(33),'checked' => 0), + 'regrouping_immo' => array('label' => 'Regroupement de crédits', 'icon' => 'icon-toitureregroupement-credit', 'page' => 'regroupement-de-credit-hypothecaire-et-autre','page_ids' => array(838),'checked' => 0), + 'refinancing' => array('label' => 'Refinancement crédit(s) hypothécaire(s)', 'icon' => 'icon-toiturerefinancement', 'page' => 'refinancement-credit-hypothecaire','page_ids' => array(824),'checked' => 0), + 'purchaseabroad' => array('label' => 'Achat d\'une 2éme résidence (à l\'étranger, en belgique)', 'icon' => 'icon-toituremaison-vacances', 'page' => 'achat-seconde-residence','page_ids' => array(870),'checked' => 0), + 'but_immo_hypo' => array('label' => 'Travaux de rénovation', 'icon' => 'icon-toituretravaux-renovation', 'page' => 'travaux-de-renovation','page_ids' => array(800),'checked' => 0), + 'achat_maison_de_rapport' => array('label' => 'Achat maison de rapport', 'icon' => 'icon-toitureachat-maison', 'page' => 'achat-maison-de-rapport','page_ids' => array(871),'checked' => 0), + 'credit_pont' => array('label' => 'Crédit pont', 'icon' => 'icon-toiturerefinancement', 'page' => 'credit-pont','page_ids' => array(872),'checked' => 0), + 'independants_et_entreprises_en_difficultes' => array('label' => 'Indépendants et entreprises en difficultés', 'icon' => 'icon-toitureagrandissement-maison', 'page' => 'credit-pont-travaux','page_ids' => array(873),'checked' => 0), + 'regroupement_de_credit__rachats_de_credits' => array('label' => 'Rachats de crédits', 'icon' => 'icon-toitureregroupement-credit', 'page' => 'regroupement-de-credit-hypothecaire-et-autre','page_ids' => array(874),'checked' => 0), + 'financement_frais_de_notaire' => array('label' => 'Financement frais de notaire', 'icon' => 'icon-toituregavel-light', 'page' => 'financement-frais-de-notaire','page_ids' => array(875),'checked' => 0), + 'fonds_roulement_independants' => array('label' => 'Fonds de roulement pour indépendants', 'icon' => 'icon-toitureagrandissement-maison', 'page' => 'fonds-roulement-independants','page_ids' => array(876),'checked' => 0), + ]; + + $select_options = ''; + + $select_buttons = ''; + + $select_radio = ''; + $select_radio_orig = ''; + + $select_radio_immo = ''; + + $select_radio_pat = ''; + + $select_subradio_auto = ''; + + $select_subradio = ''; + + $after_select_tags = ''; + + $select_subradio_travaux = ''; + + $is_credit_hypothecaire = false; + $is_credit_pat = false; + $is_credit_auto = false; + + $type_credit_grid_class = 'col-md-6'; + $type_credit_auto_class = 'col-md-6'; + $house_credit_grid_class = 'col-md-2'; + $start_column_counter = 1; + + $type_credit_length = count($creditTypes); + $house_credit_length = count($houseCreditTypes); + $insertAfter = ''; + + $check_credit_type = $vars['check_credit_type']; + + $cd_default_loan_stimulator = ($vars['cd_default_loan_stimulator'] == "ph")?'am':$vars['cd_default_loan_stimulator']; + + if($vars['cd_default_loan_stimulator'] == 'am') + $is_credit_hypothecaire = true; + + if($vars['cd_default_loan_stimulator'] == 'fin_neuve') + $is_credit_auto = true; + + if(empty($cd_default_loan_stimulator)) + $cd_default_loan_stimulator = 'pat'; + + if($cd_default_loan_stimulator == 'pat') + $is_credit_pat = true; + + /* foreach($options as $option){ + + $cd_default_loan_stimulator = ($vars['cd_default_loan_stimulator'] == "ph")?'am':$vars['cd_default_loan_stimulator']; + $selected = ($option['value'] == $cd_default_loan_stimulator)?'selected="selected" ':''; + $select_options .= ''; + + if(!empty($option['short_title'])) { + + $checked = ''; + + if($option['value'] == $cd_default_loan_stimulator || (empty($cd_default_loan_stimulator) && $option['value'] == 'pat')) + $checked = ' checked '; + + $url = get_permalink( $option['page_id'] ); + + $select_buttons .= '
  • '.$option['short_title'].'
  • '; + + ob_start(); + ?> +
    + data-heading=""> + +
    + $v) { + + $checked = ''; + $typeCreditPages = $v['page_ids']; + + ob_start(); + ?> +
    + data-page=""> + +
    + $v) { + + $checked = ''; + $typeCreditPages = $v['page_ids']; + + $hasInsertAfter = !empty($v['insertAfter']) ? true : false; + + if($hasInsertAfter) { + $insertAfter = $v['insertAfter']; + } else { + $insertAfter = ''; + } + + if($hasInsertAfter) { + + if($start_column_counter % 2 != 0) { + $type_credit_grid_class = 'col-md-12'; + } + + ob_start(); + ?> +
    + $val) { + ?> +
    + data-page=""> + +
    + +
    + +
    + data-page=""> + +
    + $v) { + + $checked = ''; + $typeCreditPages = $v['page_ids']; + $type_credit_grid_class = 'col-md-6'; + + if(in_array($current_post_id, $typeCreditPages) || $v['checked'] == '1' || $check_credit_type == $k) + $checked = ' checked'; + + ob_start(); + ?> +
    + data-page=""> + +
    +wpdb->insert('cdf_Credit', array( + 'type_credit' => $data['loan_type'], + 'sel_credit' => $data['sub_loan_type'], + 'capital' => $data['selected_capital'], + 'duree' => $data['selected_months'], + 'cout_total' => $data['hidden_cout_total_value'], + 'mensualite' => $data['hidden_montant_total_value'], + 'taux_nominal_annuel' => $data['hidden_taeg_value'], + 'rgpd' => 'oui', + 'create_date' => (new \DateTime())->format('Y-m-d H:i:s') + )); + + $current_credit_id = $this->wpdb->insert_id; + $token = $this->generateToken($current_credit_id); + + $currentCredit = $this->getCredit($token); + + /* if($currentCredit->type_credit != 'pat') + return $token; + else + $this->save_step_1_pat($data); */ + + return $token; + + } catch (\Exception $e) { + die($e->getMessage()); + } + } + + public function save_step_1_all($data) { + + if(isset($data['email']) && strpos($data['email'], '@example.com') !== false) { + return false; // Rejeter la demande si l'adresse email contient @example.com + } + + $currentCredit = $this->getCredit($data['credit-direct-token']); + + if (!is_object($currentCredit)) { + return false; + } + + $borrower = $this->getBorrower($currentCredit); + $borrowerTableName = 'cdf_Emprunteur'; + $borrowerData = [ + 'nom' => $data['lastname'], + 'prenom' => $data['firstname'], + 'telephone' => $data['phone'], + 'email' => $data['email'], + 'FK_agence' => $data['agency'], + 'FK_demande_creditdirect' => $currentCredit->idCredit + ]; + + if (is_object($borrower)) { + $this->wpdb->update($borrowerTableName, $borrowerData, [ + 'idemprunteur' => $borrower->idemprunteur + ]); + } else { + $this->wpdb->insert($borrowerTableName, $borrowerData); + } + + /** + * Re-get the current credit to hydrate it + */ + $currentCredit = $this->getCredit($data['credit-direct-token']); + + $this->update_emprunteur($data, $currentCredit); + $this->save_autre_credit_emprunteur($data, $currentCredit); + + if (array_key_exists('hascoborrower', $data) && $data['hascoborrower'] === '1') { + $this->insert_co_emprunteur($data, $currentCredit); + $this->save_autre_credit_co_emprunteur($data, $currentCredit); + } + + $this->wpdb->update( + 'cdf_Credit', + array( + 'last_update_date' => (new \DateTime())->format('Y-m-d H:i:s'), + 'last_step' => '4' + ), + array('idCredit' => $this->currentCredit->idCredit) + ); + + } + + public function save_one_step($data) { + + $email_demande = $data['email']; + + /* if($this->is_webdev_user()) { + echo '
    ';
    +            print_r($data);
    +            echo '
    '; + die(); + } */ + + if(strpos($email_demande, '@example.com') !== false) { + return false; // Rejeter la demande si l'adresse email contient @example.com + } + + $currentCredit = $this->getCredit($data['credit-direct-token']); + + $included_hypo_credits = ['am','amr','cied','frais_notaire','cdp']; + + + + + if (!is_object($currentCredit)) { + return false; + } + + /* if($this->is_webdev_user()) { + echo '
    ';
    +            print_r($data);
    +            echo '
    '; + die(); + } */ + /* echo '
    ';
    +        print_r($data);
    +        echo '
    '; + die(); */ + + $ddn = null; + if (!empty($data['birthdate'])) { + $ddn = \DateTime::createFromFormat('d/m/Y', $data['birthdate']); + if ($ddn) { + $ddn = $ddn->format('Y-m-d'); + } + } + + // print_r($ddn); + + $independent_since = \DateTime::createFromFormat('d/m/Y', $data['independent_since']); + + if($independent_since) { + $independent_since = $independent_since->format('Y-m-d'); + } else { + $independent_since = ''; + } + + $borrower = $this->getBorrower($currentCredit); + $borrowerTableName = 'cdf_Emprunteur'; + $borrowerData = [ + 'nom' => $data['lastname'], + 'prenom' => $data['firstname'], + 'telephone' => $data['phone'], + 'email' => $data['email'], + 'date_naissance' => $ddn ?: '', + 'nationalité' => $data['nationality'], + 'adresse' => $data['address'], + 'code_postal' => $data['zip'], + 'localite' => $data['city'], + 'pays' => $data['country'], + 'contract_type' => $data['contract_type'], + 'independent_since' => $independent_since, + 'FK_profession' => $data['job'], + 'FK_etat_civil' => $data['civilstatus'], + 'salaire' => $data['salary'], + 'annual_taxable_income' => isset($data['annual_taxable_income']) ? $data['annual_taxable_income'] : null, + 'FK_demande_creditdirect' => $currentCredit->idCredit, + ]; + + /* if($this->is_webdev_user()) { + echo '
    ';
    +            print_r($borrowerData);
    +            echo '
    '; + die(); + } */ + + if (is_object($borrower)) { + $this->wpdb->update($borrowerTableName, $borrowerData, [ + 'idemprunteur' => $borrower->idemprunteur + ]); + } else { + $this->wpdb->insert($borrowerTableName, $borrowerData); + } + + //has another batiment + if(isset($data['isowner']) && $data['isowner'] === '1') { + $this->save_another_batiment($data, $currentCredit); + } + + if(!empty($data['comment'])) { + $this->wpdb->update( + 'cdf_Credit', + array('commentaire' => $data['comment']), + array('idCredit' => $currentCredit->idCredit) + ); + } + + if (array_key_exists('hascoborrower', $data) && $data['hascoborrower'] === '1') { + $this->insert_co_emprunteur_one_step($data); + } + + if (in_array($currentCredit->type_credit, $included_hypo_credits)) { + $this->save_FK_credit_hypothecaire($currentCredit,$data); + } + + if ( + $currentCredit->type_credit == 'fin_neuve' + || $currentCredit->type_credit == 'fin_occ_m3a' + || $currentCredit->type_credit == 'fin_occ_p3a' + ) { + $this->save_FK_credit_auto($currentCredit,$data); + } + + $this->save_to_credits_listing($currentCredit); + + } + + public function save_another_batiment($data, $currentCredit) { + $borrower = $this->getBorrower($currentCredit); + + + if (!is_object($borrower)) { + return; + } + + + // Sauvegarder les bâtiments + if (isset($data['isowner']) && $data['isowner'] === '1') { + + if (isset($data['building']) && is_array($data['building'])) { + + + $building_ids = []; // Pour stocker les IDs des bâtiments créés + + foreach ($data['building'] as $index => $building) { + // Ignorer les données fantômes des templates (clés __INDEX__) + if ($index === '__INDEX__') { + continue; + } + // Insertion du bâtiment + $batiment_pays = ''; + if (isset($building['inbelgium']) && $building['inbelgium'] === '0' && isset($building['country'])) { + $batiment_pays = sanitize_text_field($building['country']); + } + + $this->wpdb->insert( + 'cdf_Emprunteur_Batiments', + array( + 'FK_emprunteur' => $borrower->idemprunteur, + 'is_habitation' => isset($building['ishabitation']) ? intval($building['ishabitation']) : 0, + 'Is_rapport' => isset($building['israpport']) ? intval($building['israpport']) : 0, + 'en_belgique' => isset($building['inbelgium']) ? intval($building['inbelgium']) : 1, + 'batiment_pays' => $batiment_pays, + 'revenu_locatif' => isset($building['hasrentalincome']) ? intval($building['hasrentalincome']) : 0, + 'montant_locatif' => isset($building['rentalamount']) ? floatval($building['rentalamount']) : 0 + ) + ); + + // Récupérer l'ID du bâtiment créé + $building_id = $this->wpdb->insert_id; + if ($building_id) { + $building_ids[$index] = $building_id; + } + } + + // Sauvegarder les crédits associés aux bâtiments + if (isset($data['hasbuildingloans']) && $data['hasbuildingloans'] === '1') { + if (isset($data['buildingloan']) && is_array($data['buildingloan'])) { + + foreach ($data['buildingloan'] as $loanIndex => $loan) { + // Ignorer les données fantômes des templates (clés __LOANINDEX__) + if ($loanIndex === '__LOANINDEX__') { + continue; + } + // Traiter la date première échéance + $firstPaymentDate = null; + if (!empty($loan['firstpayment'])) { + // Format attendu : jj-mm-aaaa + $date = \DateTime::createFromFormat('d-m-Y', $loan['firstpayment']); + if ($date) { + $firstPaymentDate = $date->format('Y-m-d'); + } + } + + // Utiliser le dernier bâtiment créé comme FK_autre_batiment + // Dans une version plus avancée, on pourrait associer chaque crédit à un bâtiment spécifique + $building_id = !empty($building_ids) ? end($building_ids) : 0; + + // Convertir la durée d'années en mois + $duree_mois = isset($loan['duration']) ? intval($loan['duration']) * 12 : 0; + + $this->wpdb->insert( + 'cdf_Autre_credit', + array( + 'FK_emprunteur' => $borrower->idemprunteur, + 'FK_autre_batiment' => $building_id, + 'FK_type_creance' => isset($loan['type']) ? intval($loan['type']) : null, + 'banque' => isset($loan['bankname']) ? sanitize_text_field($loan['bankname']) : '', + 'montant' => isset($loan['capital']) ? floatval($loan['capital']) : 0, + 'duree_credit' => $duree_mois, + 'mensualite' => isset($loan['monthly']) ? floatval($loan['monthly']) : 0, + 'date_premiere_echeance' => $firstPaymentDate, + 'cloture' => 0, + 'solde_restant_du' => 0 + ) + ); + } + } + } + } + } + + // Gérer les suppressions de crédits si nécessaire + if (isset($data['delbuildingloans']) && !empty($data['delbuildingloans'])) { + $kuids = explode(',', $data['delbuildingloans']); + foreach ($kuids as $kuid) { + $kuid = trim($kuid); + if (!empty($kuid) && is_numeric($kuid)) { + $this->wpdb->delete( + 'cdf_Autre_credit', + array('idautrecredit' => intval($kuid)) + ); + } + } + } + } + + public function insert_co_emprunteur_one_step($data) { + + $currentCredit = $this->getCredit($data['credit-direct-token']); + + $borrower = $this->getBorrower($currentCredit); + + $this->wpdb->insert('cdf_Emprunteur',array( + 'nom' => $data['colastname'], + 'prenom' => $data['cofirstname'], + 'date_naissance' => $data['cobirthdate'], + 'nationalité' => $data['conationality'], + 'adresse' => $data['coaddress'], + 'code_postal' => $data['cozip'], + 'localite' => $data['cocity'], + 'pays' => $data['cocountry'], + 'contract_type' => $data['cocontract_type'], + 'independent_since' => isset($data['coindependent_since']) ? $data['coindependent_since'] : null, + 'salaire' => $data['cosalary'], + 'annual_taxable_income' => isset($data['coannual_taxable_income']) ? $data['coannual_taxable_income'] : null, + 'parent_emprunteur' => $borrower->idemprunteur, + 'FK_demande_creditdirect' => $currentCredit->idCredit, + 'FK_etat_civil' => $data['cocivilstatus'], + 'FK_profession' => $data['cojob'] + )); + } + + public function save_FK_credit_hypothecaire($currentCredit,$data) { + + $included_hypo_credits = ['am','amr','cied','frais_notaire','cdp']; + + if (in_array($currentCredit->type_credit, $included_hypo_credits)) { + $optionsTableName = 'cdf_Options_credit_hypotecaire'; + $optionsData = [ + 'type_credit' => $data['estateloantype'], + 'prix_achat' => $data['estatebuyingprice'], + 'fonds_propre' => $data['estateequity'], + 'compromis_signe' => $data['estatecompromise'], + 'montant_a_emprunter' => $data['batiment_emprunt'], + 'duree' => $data['batiment_duree'], + ]; + + /** + * job,contract_type,salary + */ + + if (!is_null($currentCredit->FK_credit_hypothecaire)) { + $this->wpdb->insert($optionsTableName, $optionsData, [ + 'FK_credit_hypothecaire' => $currentCredit->FK_credit_hypothecaire + ]); + } else { + $this->wpdb->insert($optionsTableName, $optionsData); + + $optionId = $this->wpdb->insert_id; + + $this->wpdb->update( + 'cdf_Credit', + array('FK_credit_hypothecaire' => $optionId), + array('idCredit' => $currentCredit->idCredit) + ); + } + + $currentCredit = $this->getCredit($data['credit-direct-token']); + + /* echo '
    ';
    +            print_r($currentCredit);
    +            echo '
    '; + die(); */ + } + + return $currentCredit; + } + + public function save_FK_credit_auto($currentCredit,$data) { + + if ( + $currentCredit->type_credit == 'fin_neuve' + || $currentCredit->type_credit == 'fin_occ_m3a' + || $currentCredit->type_credit == 'fin_occ_p3a' + ) { + + $optionsTableName = 'cdf_Options_credit_auto'; + $optionsData = [ + 'marque' => $data['marque'], + 'date_immatriculation' => $data['vehicleregistrationdate'], + 'nom_vendeur' => $data['sellername'], + 'adresse_vendeur' => $data['selleraddress'], + 'prix_vehicule' => $data['vehicleprice'], + 'montant_accompte' => $data['vehicule_accompte'], + 'montant_reprise' => $data['vehicule_reprise'], + 'montant_emprunt' => $data['vehicule_emprunt'], + 'duree' => $data['vehicule_duree'] + ]; + + if (!is_null($currentCredit->FK_credit_auto)) { + $this->wpdb->update($optionsTableName, $optionsData, [ + 'idOptions_credit_auto' => $currentCredit->FK_credit_auto + ]); + } else { + $this->wpdb->insert($optionsTableName, $optionsData); + + $optionId = $this->wpdb->insert_id; + + $this->wpdb->update( + 'cdf_Credit', + array('FK_credit_auto' => $optionId), + array('idCredit' => $currentCredit->idCredit) + ); + } + + /* $currentCredit = $this->getCredit($data['credit-direct-token']); */ + } + + /* return $currentCredit; */ + } +} \ No newline at end of file diff --git a/app/models/credit.php b/app/models/credit.php new file mode 100644 index 0000000..4b315a3 --- /dev/null +++ b/app/models/credit.php @@ -0,0 +1,2239 @@ + 'Contrat de travail à durée indéterminée (CDI)', + 'cdd' => 'Contrat de travail à durée déterminée (CDD)', + 'fon' => 'Nommé', + 'int' => 'Intérimaire', + 'oth' => 'Autre', + 'ssc' => 'Sans contrat de travail' + ]; + + protected $creditTypes = [ + 'pat' => 'Prêt personnel / Tous motifs / Achats divers', + 'frais_notaire' => 'Financement frais de notaire', + 'but_immo' => 'Crédit travaux / Rénovation / Energie', + 'fin_neuve' => 'Financement véhicule NEUF', + 'fin_occ_m3a' => 'Financement véhicule d\'occasion MOINS de 3 ans', + 'fin_occ_p3a' => 'Financement véhicule d\'occasion PLUS de 3 ans', + 'mobil_carav' => 'Financement Mobil-home et caravane', + 'reno_energie' => 'Rénovation énergétique', + 'regrouping' => 'Regroupement de crédit / Rachat de crédit', + 'regroup_cred' => 'Regroupement de crédit / Rachat de crédit' + ]; + + protected $creditTypesLabels = [ + 'pat' => 'Prêt à temprérament', + 'frais_notaire' => 'Financement frais de notaire', + 'but_immo' => 'Crédit travaux', + 'fin_neuve' => 'Financement véhicule NEUF', + 'fin_occ_m3a' => 'Financement véhicule d\'occasion MOINS de 3 ans', + 'fin_occ_p3a' => 'Financement véhicule d\'occasion PLUS de 3 ans', + 'am' => 'Crédit hypothécaire', + 'cied' => 'Indépendant et entreprise en difficulté' + ]; + + public $one_step_credit_types = [ + 'am','amr','cied','ph','frais_notaire','cdp' + ]; + + public $creditAutos = [ + 'fin_neuve', + 'fin_occ_m3a', + 'fin_occ_p3a', + 'mobil_carav' + ]; + + public $type_habitat = [ + 'proprietaire' => 'Propriétaire avec prêt hypothécaire', + 'proprietaire_sans_pret' => 'Propriétaire sans prêt hypothécaire', + 'locataire' => 'Locataire', + 'cohabitant' => 'Cohabitant' + ]; + + + /* protected $houseCreditTypes = [ + 'purchasehouse' => 'Achat bien immobilier', + 'construction' => 'Nouvelle construction', + 'purchaseabroad' => 'Achat d\'une 2éme résidence (à l\'étranger, en belgique)', + 'refinancing' => 'Prêt Hypothécaire (Refinancement)', + 'regrouping' => 'Prêt Hypothécaire (Regroupement)', + 'balance' => 'Soulte / Rachat de parts indivisées', + 'other'=> 'Autre' + ]; */ + + protected $houseCreditTypes = [ + 'purchasehouse' => 'Achat bien immobilier', + 'construction' => 'Nouvelle construction', + 'regrouping_immo' => 'Regroupement de crédits', + 'refinancing' => 'Refinancement crédit(s) hypothécaire(s)', + 'purchaseabroad' => 'Achat d\'une 2éme résidence (à l\'étranger, en belgique)', + 'but_immo_hypo' => 'Travaux de rénovation', + 'achat_maison_de_rapport' => 'Achat maison de rapport', + 'credit_pont' => 'Crédit pont', + 'independants_et_entreprises_en_difficultes' => 'Indépendants et entreprises en difficultés', + 'regroupement_de_credit__rachats_de_credits' => 'Rachats de crédits', + 'financement_frais_de_notaire' => 'Financement frais de notaire', + 'fonds_roulement_independants' => 'Fonds de roulement' + ]; + + protected $wpdb; + + private $isDevMode; + + private $synchroUrl; + + private $synchroClientId; + + public $main; + + /** + * Constructor + */ + public function __construct() + { + global $wpdb; + + $this->wpdb = $wpdb; + + $this->main = $this->getMain(); + + //instance de la classe + self::$instance = $this; + + /* $this->isDevMode = + strpos($_SERVER['HTTP_HOST'], 'localhost') !== false + || strpos($_SERVER['HTTP_HOST'], 'eteamsys') !== false + ; + + $this->synchroUrl = $this->isDevMode ? + 'https://staging-wshubspot.eteamsys.com/' + : 'https://prod-wshubspot.eteamsys.com/' + ; + + $this->synchroClientId = $this->isDevMode ? + 'JuIXU6EK37giPF3smU71IMBWiNHP9wlkW9TdUZwoY0u175DH11XixOQDSNi4Qmmi' + : 'RfQyevXwW0nZvoXwifnZu4VgKeGPhmlmGZsXjj0s6Aruy5qxCVOiho0Sdpw38Tcp' + ; */ + } + + /** + * @param $token + * @return object|null + */ + public function getCredit($token) { + + if (!is_string($token)) + return null; + + $currentCredit = $this->wpdb->get_row($this->wpdb->prepare("SELECT * FROM cdf_Credit WHERE token LIKE '%s'", $token)); + + if (is_object($currentCredit)) { + + if (!is_null($currentCredit->FK_credit_auto)) { + $currentCredit->options_credit_auto = $this->wpdb->get_row( + $this->wpdb->prepare( + "SELECT * FROM cdf_Options_credit_auto WHERE idOptions_credit_auto = %d", + $currentCredit->FK_credit_auto + ) + ); + } + + if (!is_null($currentCredit->FK_credit_hypothecaire)) { + $currentCredit->options_credit_hypothecaire = $this->wpdb->get_row( + $this->wpdb->prepare( + "SELECT * FROM cdf_Options_credit_hypotecaire WHERE idOptions_credit_hypotecaire = %d", + $currentCredit->FK_credit_hypothecaire + ) + ); + } + } + + return $currentCredit; + + } + + /** + * @return array + */ + public function getAgencies() { + $allAgencies = []; + + $args = array( + 'post_type' => 'agences', + 'post_status' => 'publish', + 'numberposts' => -1 + ); + + $agencies = get_posts($args); + + foreach($agencies as $agency) { + + $objAgency = new stdClass(); + + $objAgency->idAgences = $agency->ID; + + $objAgency->label = get_field('libele_champ',$agency->ID); + + $objAgency->Nom_agence = get_field('libele_champ',$agency->ID); + + $objAgency->description_agence = ''; + + + $objAgency->emails = get_field('listing_email',$agency->ID); + + $allAgencies[$agency->ID] = $objAgency; + + } + + return $allAgencies; + } + + /** + * @return array + */ + public function getCivilStatus() { + $allCivilStatus = []; + $civilStatus = $this->wpdb->get_results("SELECT * FROM cdf_Etat_civil"); + + foreach ($civilStatus as $etat_civil) { + $allCivilStatus[$etat_civil->idetat_civil] = $etat_civil; + } + + return $allCivilStatus; + } + + public function getCreditLabel($credit_selected) + { + if(isset($this->creditTypes[$credit_selected])){ + return $this->creditTypes[$credit_selected]; + } + + if(isset($this->houseCreditTypes[$credit_selected])){ + return $this->houseCreditTypes[$credit_selected]; + } + + return false; + } + + /** + * @return string[] + */ + public function getContractTypes() + { + return $this->contractTypes; + } + + /** + * @return string[] + */ + public function getCreditTypes() + { + return $this->creditTypes; + } + + /** + * @return string[] + */ + public function getCreditOptionsLabels($option_name) + { + if (!function_exists('get_field_object')) { + return false; + } + + $field = get_field_object($option_name, 'option'); + $field_inarray = ''; + + if (!$field) { + + if(isset($this->creditTypesLabels[$option_name])){ + return $this->creditTypesLabels[$option_name]; + } + + if(isset($this->houseCreditTypes[$option_name])){ + return $this->houseCreditTypes[$option_name]; + } + + return false; + } + + + if ($field && isset($field['type']) && $field['type'] === 'group' && isset($field['label'])) { + return $field['label']; + } + + return false; + } + + /** + * @return string[] + */ + public function getHouseCreditTypes() + { + return $this->houseCreditTypes; + } + + /** + * @return array + */ + public function getWorks() + { + $allWorks = []; + $works = $this->wpdb->get_results("SELECT * FROM cdf_Profession"); + + foreach ($works as $work) { + $allWorks[$work->idprofession] = $work; + } + + return $allWorks; + } + + /** + * @return array + */ + public function getExistingCreditTypes() + { + $allCreditTypes = []; + $creditTypes = $this->wpdb->get_results("SELECT * FROM cdf_Type_creance"); + + foreach ($creditTypes as $creditType) { + $allCreditTypes[$creditType->idtype_creance] = $creditType; + } + + return $allCreditTypes; + } + + /** + * @param $currentCredit + * @return array|object|void|null + */ + public function getBorrower($currentCredit) { + + $borrower = $this->wpdb->get_row( + $this->wpdb->prepare( + "SELECT * FROM cdf_Emprunteur WHERE FK_demande_creditdirect = %d", + $currentCredit->idCredit + ) + ); + + if (is_object($borrower)) { + /** + * Other credits + */ + $other_credits = $this->wpdb->get_results( + $this->wpdb->prepare( + "SELECT * FROM cdf_Autre_credit WHERE FK_emprunteur = %d", + $borrower->idemprunteur + ) + ); + + foreach($other_credits as $other_credit) { + + $FK_type_creance = $other_credit->FK_type_creance; + $type_creance = $this->wpdb->get_row( + $this->wpdb->prepare( + "SELECT * FROM cdf_Type_creance WHERE idtype_creance = %d", + $FK_type_creance + ) + ); + $other_credit->type_creance = $type_creance->nom_creance; + + $borrower->other_credits[] = $other_credit; + } + + + if (!is_null($borrower->FK_agence)) { + + $agency_id = $borrower->FK_agence; + + $agency = get_post($agency_id); + + $emails_data = get_field('listing_email',$agency_id); + + $emails = []; + + + foreach($emails_data as $email) { + /* $emails[]['email'] = $email['email']->name; + $emails[]['type_de_contact'] = $email['type_de_contact']; */ + + $emails[] = ['email' => $email['email']->name, 'type_de_contact' => $email['type_de_contact']]; + } + + $agency->emails = $emails; + + $borrower->agency = $agency; + + } + + /** + * Civil status + */ + if (!is_null($borrower->FK_etat_civil)) { + $borrower->etat_civil = $this->wpdb->get_results("SELECT * FROM cdf_Etat_civil WHERE idetat_civil = $borrower->FK_etat_civil"); + } + } + + return $borrower; + } + + /** + * @param $currentCredit + * @return array|object|void|null + */ + public function getCoBorrower($currentCredit) { + + $coBorrower = $this->wpdb->get_row( + $this->wpdb->prepare( + "SELECT * FROM cdf_Emprunteur WHERE FK_demande_creditdirect = %d AND parent_emprunteur IS NOT NULL", + $currentCredit->idCredit + ) + ); + + if (is_object($coBorrower)) { + $coBorrower->other_credits = $this->wpdb->get_results( + $this->wpdb->prepare( + "SELECT * FROM cdf_Autre_credit WHERE FK_emprunteur = %d", + $coBorrower->idemprunteur + ) + ); + + /** + * Civil status + */ + if (!is_null($coBorrower->FK_etat_civil)) { + $coBorrower->etat_civil = $this->wpdb->get_results("SELECT * FROM cdf_Etat_civil WHERE idetat_civil = $coBorrower->FK_etat_civil"); + } + } + + return $coBorrower; + } + + + /** + * @param $mailTitle + * @param $mailBody + * @param $borrower + * @return bool + */ + public function sendEmail($mailTitle, $mailBody, $borrower, $currentCredit, $attachments = [], $to_client = false) { + + /* $currentCredit = $this->getCredit($borrower->token); */ + + $credit_type = $currentCredit->type_credit; + + if(empty($credit_type)) { + $credit_type = 'credit'; + } + + $custom_from = 'demande-'.$credit_type.'@credit-direct.be'; + + $mailHeaders = [ + 'Content-Type: text/html; charset=UTF-8', + 'X-Mailer: PHP/' . phpversion(), + 'MIME-Version: 1.0', + 'From: Credit Direct <'.$custom_from.'>' + ]; + + $agencies = $this->getAgencies(); + + if (!empty($borrower->idemprunteur)) { + $to = []; + + $zipCode = $borrower->code_postal; + + if(!empty($zipCode)) { + $agency = $this->switchAgency_byZipCode($zipCode, $borrower); + } + + + /* echo 'prout'; */ + + foreach($agency['emails'] as $email) { + switch ($email['type_de_contact']) { + case 'to': + $to[] = $email['email']->name; + break; + case 'cc': + $mailHeaders[] = 'Cc: ' . $email['email']->name; + } + } + + + + /* $to[] = 'jps@esi-informatique.com'; */ + /* $to[] = 'testcreditdirect@yopmail.com'; */ + + if($to_client) { + $to = [$borrower->email]; + + $mailHeaders = [ + 'Content-Type: text/html; charset=UTF-8', + 'X-Mailer: PHP/' . phpversion(), + 'MIME-Version: 1.0', + 'From: Credit Direct ' + ]; + } + + if (!empty($to)) { + $mailBody = ' + + + + ' . $mailTitle . ' + + ' . $mailBody . ''; + + /* $attachments = []; */ + + /* foreach ($attachments as $file) { + if (file_exists($file)) { + @unlink($file); + } */ + + return wp_mail($to, $mailTitle, $mailBody, $mailHeaders, $attachments); + } + } + + return false; + } + + /** + * @param $datas + * @return void + */ + public function save_step($currentCredit) { + + /* $currentCredit = $this->getCredit($datas['credit-direct-token']); */ + + if(!is_object($currentCredit)) { + return false; + } + + $borrower = $this->getBorrower($currentCredit); + + if(!is_object($borrower)) { + return false; + } + + //save the current credit in a cookie for 2 months + $credit_data = [ + 'credit_token' => $currentCredit->token, + 'current_step' => $currentCredit->last_step, + 'type_credit_selected' => $currentCredit->sel_credit + ]; + setcookie('credit_data', json_encode($credit_data), time() + 5256000, '/'); + + } + + /** + * @param $creditId + * @return string + */ + + protected function generateToken($creditId) { + + $date = new \DateTime(); + $token = sha1($date->format('YmdHisu') . '-' . $creditId); + + $this->wpdb->update( + 'cdf_Credit', + ['token' => $token], + ['idCredit' => $creditId] + ); + + return $token; + } + + /** + * @param object $currentCredit + * @param object $borrower + * @return bool + */ + protected function mailchimpSynchro($currentCredit, $borrower) { + + global $post; + + $json = json_encode([ + 'form_id' => 'credit-application', + 'client_id' => $this->synchroClientId, + 'name' => $borrower->nom, + 'firstname' => $borrower->prenom, + 'mail' => $borrower->email, + 'recovery_url' => get_page_link($post) . '?token=' . $currentCredit->token, + 'last_action_date' => + !is_null($currentCredit->last_update_date) ? + $currentCredit->last_update_date : + $currentCredit->create_date + ]); + + $options = [ + CURLOPT_RETURNTRANSFER => true, + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_POST => true, + CURLOPT_ENCODING => '', + CURLOPT_SSL_VERIFYPEER => false, + CURLOPT_URL => $this->synchroUrl, + CURLOPT_HTTPHEADER => ['Content-Type: application/json', 'Content-Length: ' . strlen($json)], + CURLOPT_POSTFIELDS => $json + ]; + + $curl = curl_init(); + curl_setopt_array($curl, $options); + $response = curl_exec($curl); + curl_close($curl); + + return true; + } + + /** + * Mapping centralisé des champs formulaire vers la base de données pour l'emprunteur principal + */ + protected $borrowerFieldMap = [ + 'email' => 'email', + 'lastname' => 'nom', + 'firstname' => 'prenom', + 'phone' => 'telephone', + 'country' => 'pays', + 'num_registre_national' => 'num_registre_national', + 'birthdate' => 'date_naissance', + 'birthplace' => 'lieu_naissance', + 'nationality' => 'nationalité', + 'cardnumber' => 'num_carte_identite', + 'cnvaliditydate' => 'carte_identite_validite', + 'nationalregistrationnumber' => 'num_registre_national', + 'bankaccountnumber' => 'num_compte_bancaire', + 'address' => 'adresse', + 'zip' => 'code_postal', + 'city' => 'localite', + 'country' => 'pays', + 'movingdate' => 'date_emmenagement', + 'dependentchildren' => 'enfant_charge', + 'montant_allocation_familiale' => 'montant_allocation_familiale', + 'codependentchildren' => 'enfant_charge', + 'comontant_allocation_familiale' => 'montant_allocation_familiale', + // Mappings pour les champs co-emprunteur + 'cobirthdate' => 'date_naissance', + 'cobirthplace' => 'lieu_naissance', + 'conationality' => 'nationalité', + 'cocardnumber' => 'num_carte_identite', + 'cocnvaliditydate' => 'carte_identite_validite', + 'conationalregistrationnumber' => 'num_registre_national', + 'cobankaccountnumber' => 'num_compte_bancaire', + 'coaddress' => 'adresse', + 'cozip' => 'code_postal', + 'cocity' => 'localite', + 'cocountry' => 'pays', + 'cocontract_type' => 'contract_type', + 'coindependent_since' => 'independent_since', + 'contract_type' => 'contract_type', + 'independent_since' => 'independent_since', + 'emname' => 'nom_employeur', + 'emnumber' => 'numero_entreprise', + 'emaddress' => 'adresse_employeur', + 'emzip' => 'code_postal_employeur', + 'emcity' => 'localite_employeur', + 'emcountry' => 'pays_employeur', + 'commitmentdate' => 'date_engagement', + 'salary' => 'salaire', + 'annual_taxable_income' => 'annual_taxable_income', + 'oiamouthmealvoucher' => 'cheque_repas', + 'oiamouthrentalincome' => 'revenus_locatifs', + 'oiamouthunemployment' => 'chomage', + 'oiothertext' => 'autre_revenu_type', + 'oiamouthother' => 'autre_revenu_montant', + 'civilstatus' => 'FK_etat_civil', + 'job' => 'FK_profession', + 'habitation_type' => 'habitation_type', + 'habitation_loyer' => 'habitation_loyer', + 'autre_revenu_type' => 'autre_revenu_type', + 'autre_revenu_montant' => 'autre_revenu_montant', + 'fichage_status' => 'fichage_status', + 'housing_status' => 'housing_status', + 'remarques' => 'remarques', + // Ajoutez d'autres mappings si besoin + ]; + + protected $autresRevenusFieldMap = [ + 'oiamouthmealvoucher' => 'cheque_repas', + 'oiamouthrentalincome' => 'revenus_locatifs', + 'oiamouthunemployment' => 'chomage', + 'oiothertext' => 'autre_revenu_type', + 'oiamouthother' => 'autre_revenu_montant', + ]; + + protected $autoFieldMap = [ + 'marque' => 'marque', + 'vehicleregistrationdate' => 'date_immatriculation', + 'sellername' => 'nom_vendeur', + 'selleraddress' => 'adresse_vendeur', + 'vehicleprice' => 'prix_vehicule', + 'vehicule_accompte' => 'montant_accompte', + 'vehicule_reprise' => 'montant_reprise', + 'vehicule_emprunt' => 'montant_emprunt', + 'vehicule_duree' => 'duree' + ]; + + protected $dateFields = [ + 'birthdate', + 'cnvaliditydate', + 'movingdate', + 'commitmentdate', + 'vehicleregistrationdate', + 'independent_since', + 'date_envoi_dossier', + 'date_envoi_dossier_agence', + // Champs de date co-emprunteur + 'cobirthdate', + 'cocnvaliditydate', + 'coindependent_since' + ]; + + protected function insert_co_emprunteur($data, $currentCredit) { + // Vérifier si l'email du co-emprunteur contient @example.com + if(isset($data['coemail']) && strpos($data['coemail'], '@example.com') !== false) { + return false; // Rejeter la demande si l'adresse email du co-emprunteur contient @example.com + } + + $borrower = $this->getBorrower($currentCredit); + + if (!is_object($borrower)) { + error_log('Erreur insert_co_emprunteur: borrower non trouvé pour le crédit ID: ' . $currentCredit->idCredit); + return false; + } + + /* echo '
    ';
    +        print_r($data);
    +        echo '
    '; + die(); */ + + // Construire le tableau d'insertion en gérant les valeurs NULL et les valeurs par défaut + $insertData = array( + 'nom' => isset($data['colastname']) ? $data['colastname'] : null, + 'prenom' => isset($data['cofirstname']) ? $data['cofirstname'] : null, + 'email' => isset($data['coemail']) ? $data['coemail'] : null, + 'telephone' => isset($data['cophone']) ? $data['cophone'] : null, + 'date_naissance' => isset($data['cobirthdate']) ? $data['cobirthdate'] : null, + 'lieu_naissance' => isset($data['cobirthplace']) ? $data['cobirthplace'] : null, + 'nationalité' => isset($data['conationality']) ? $data['conationality'] : null, + 'num_carte_identite' => isset($data['cocardnumber']) ? $data['cocardnumber'] : null, + 'carte_identite_validite' => isset($data['cocnvaliditydate']) ? $data['cocnvaliditydate'] : null, + 'num_registre_national' => isset($data['conationalregistrationnumber']) ? $data['conationalregistrationnumber'] : null, + 'num_compte_bancaire' => isset($data['cobankaccountnumber']) ? $data['cobankaccountnumber'] : null, + 'adresse' => isset($data['coaddress']) ? $data['coaddress'] : null, + 'code_postal' => isset($data['cozip']) ? $data['cozip'] : null, + 'localite' => isset($data['cocity']) ? $data['cocity'] : null, + 'pays' => isset($data['cocountry']) ? $data['cocountry'] : null, + 'enfant_charge' => isset($data['codependentchildren']) ? $data['codependentchildren'] : null, + 'montant_allocation_familiale' => isset($data['comontant_allocation_familiale']) && !empty($data['comontant_allocation_familiale']) ? $data['comontant_allocation_familiale'] : 0, + 'contract_type' => isset($data['cocontract_type']) ? $data['cocontract_type'] : null, + 'independent_since' => isset($data['coindependent_since']) && !empty($data['coindependent_since']) ? $data['coindependent_since'] : '0000-00-00', + 'nom_employeur' => isset($data['coemname']) ? $data['coemname'] : null, + 'numero_entreprise' => isset($data['coemnumber']) ? $data['coemnumber'] : null, + 'adresse_employeur' => isset($data['coemaddress']) ? $data['coemaddress'] : null, + 'code_postal_employeur' => isset($data['coemzip']) ? $data['coemzip'] : null, + 'localite_employeur' => isset($data['coemcity']) ? $data['coemcity'] : null, + 'pays_employeur' => isset($data['coemcountry']) ? $data['coemcountry'] : null, + 'date_engagement' => isset($data['cocommitmentdate']) ? $data['cocommitmentdate'] : null, + 'salaire' => isset($data['cosalary']) ? $data['cosalary'] : null, + 'annual_taxable_income' => isset($data['coannual_taxable_income']) ? $data['coannual_taxable_income'] : null, + 'cheque_repas' => isset($data['cooiamouthmealvoucher']) ? $data['cooiamouthmealvoucher'] : null, + 'revenus_locatifs' => isset($data['cooiamouthrentalincome']) ? $data['cooiamouthrentalincome'] : null, + 'chomage' => isset($data['cooiamouthunemployment']) ? $data['cooiamouthunemployment'] : null, + 'autre_revenu_type' => isset($data['cooiothertext']) ? $data['cooiothertext'] : null, + 'autre_revenu_montant' => isset($data['cooiamouthother']) ? $data['cooiamouthother'] : null, + 'parent_emprunteur' => $borrower->idemprunteur, + 'habitation_type' => isset($data['coHabitation_type']) ? $data['coHabitation_type'] : null, + 'habitation_loyer' => isset($data['coHabitation_loyer']) ? $data['coHabitation_loyer'] : null, + 'FK_demande_creditdirect' => $currentCredit->idCredit, + 'FK_etat_civil' => isset($data['cocivilstatus']) ? $data['cocivilstatus'] : null, + 'FK_profession' => isset($data['cojob']) ? $data['cojob'] : null, + 'fichage_status' => isset($data['coFichage_status']) && !empty($data['coFichage_status']) ? $data['coFichage_status'] : '', + 'housing_status' => isset($data['cohousing_status']) && !empty($data['cohousing_status']) ? $data['cohousing_status'] : '' + ); + + $result = $this->wpdb->insert('cdf_Emprunteur', $insertData); + + if ($result === false) { + error_log('Erreur lors de l\'insertion du co-emprunteur. Erreur DB: ' . $this->wpdb->last_error); + error_log('Données: ' . print_r($data, true)); + return false; + } + + return $this->wpdb->insert_id; + } + + protected function save_autre_credit_emprunteur($data,$currentCredit) { + $borrower = $this->getBorrower($currentCredit); + $updateData = []; + + + /* $this->wpdb->update('cdf_Emprunteur', array( + 'habitation_type' => $data['habitation_type'], + 'habitation_loyer' => $data['habitation_loyer'], + 'habitation_charge_hypothecaire' => $data['homeowner'], + 'habitation_sans_charge_locative' => $data['homewithoutrentalcharge'], + 'remarques' => $data['commentary'] + ), array('idemprunteur' => $borrower->idemprunteur)); */ + + if(isset($data['habitation_type'])) { + $updateData = array( + 'habitation_type' => $data['habitation_type'], + ); + } + + // Protection pour habitation_loyer - ne pas écraser si pas présent + if (isset($data['habitation_loyer'])) { + $updateData['habitation_loyer'] = $data['habitation_loyer']; + } + + if(!empty($updateData)) { + $this->wpdb->update('cdf_Emprunteur', $updateData, array('idemprunteur' => $borrower->idemprunteur)); + } + + + if ( + array_key_exists('hascurrentloan', $data) && $data['hascurrentloan'] === '1' + && array_key_exists('currentloans', $data) && !empty($data['currentloans']) + ) { + + /* echo '
    ';
    +            print_r($data['currentloans']);
    +            echo '
    '; + die(); */ + + foreach ($data['currentloans'] as $currentLoan) { + $this->wpdb->insert( + 'cdf_Autre_credit', + array( + 'banque' => $currentLoan['bankname'], + 'montant' => $currentLoan['borrowedcapital'], + 'duree_credit' => $currentLoan['durationmonth'], + 'mensualite' => $currentLoan['monthlypayment'], + 'date_premiere_echeance' => $currentLoan['firstduedate'], + 'solde_restant_du' => $currentLoan['remainingbalance'], + 'cloture' => $currentLoan['hasclosed'], + 'FK_type_creance' => $currentLoan['loantype'], + 'FK_emprunteur' => $borrower->idemprunteur + ) + ); + } + } + } + + protected function save_autre_credit_co_emprunteur($data, $currentCredit) { + $borrower = $this->getBorrower($currentCredit); + + // Recharger le crédit pour s'assurer que le co-emprunteur nouvellement créé est disponible + if (is_object($currentCredit) && isset($currentCredit->token)) { + $currentCredit = $this->getCredit($currentCredit->token); + } + + $coBorrower = $this->getCoBorrower($currentCredit); + + // Si le co-emprunteur n'existe toujours pas, on ne peut pas continuer + if (!is_object($coBorrower)) { + return; + } + + $updateData = []; + + /* $this->wpdb->update('cdf_Emprunteur', array( + 'habitation_type' => $data['habitation_type'], + 'habitation_loyer' => $data['habitation_loyer'], + 'habitation_charge_hypothecaire' => $data['habitation_charge_hypothecaire'], + 'habitation_sans_charge_locative' => $data['habitation_sans_charge_locative'] + ), array( + 'idemprunteur' => $coBorrower->idemprunteur, + 'parent_emprunteur' => $borrower->idemprunteur + )); */ + + if(isset($data['coHabitation_type'])) { + $updateData = array( + 'habitation_type' => $data['coHabitation_type'], + ); + } + + // Protection pour habitation_loyer - ne pas écraser si pas présent + if (isset($data['coHabitation_loyer'])) { + $updateData['habitation_loyer'] = $data['coHabitation_loyer']; + } + + if(!empty($updateData)) { + $this->wpdb->update('cdf_Emprunteur', $updateData, array('idemprunteur' => $coBorrower->idemprunteur)); + } + + if ( + array_key_exists('cohascurrentloan', $data) && $data['cohascurrentloan'] === '1' + && array_key_exists('cocurrentloans', $data) && !empty($data['cocurrentloans']) + ) { + foreach ($data['cocurrentloans'] as $currentLoan) { + $this->wpdb->insert( + 'cdf_Autre_credit', + array( + 'banque' => $currentLoan['bankname'], + 'montant' => $currentLoan['borrowedcapital'], + 'duree_credit' => $currentLoan['durationmonth'], + 'mensualite' => $currentLoan['monthlypayment'], + 'date_premiere_echeance' => $currentLoan['firstduedate'], + 'solde_restant_du' => $currentLoan['remainingbalance'], + 'cloture' => $currentLoan['hasclosed'], + 'FK_type_creance' => $currentLoan['loantype'], + 'FK_emprunteur' => $coBorrower->idemprunteur + ) + ); + } + } + } + + /** + * Gère les uploads de fichiers et génère une liste HTML de liens + * @param array $files Les fichiers uploadés ($_FILES) + * @param array $allowed_types Les types MIME autorisés + * @param int $max_size Taille maximale en octets + * @param string $token Le token du crédit + * @return array ['files' => [], 'errors' => [], 'html_links' => string] + */ + public function handleUploads($files, $allowed_types, $max_size, $token) { + $uploaded_files = []; + $errors = []; + $html_links = ''; + + + + // Limite de taille totale pour l'envoi par email (10MB) + $total_size_limit = 10 * 1024 * 1024; // 10MB en octets + $total_size = 0; + + // Mapping des noms de champs vers les types de documents + $field_to_doc_type = [ + 'paycheck' => 'fiche_paie', + 'cojob' => 'fiche_paie_co', + 'notice_of_assessment' => 'avis_imposition', + 'conotice_of_assessment' => 'avis_imposition_co', + 'identity_card' => 'carte_identite', + 'coidentity_card' => 'carte_identite_co', + 'tax_notice' => 'avis_imposition', + 'cotax_notice' => 'avis_imposition_co', + 'property_tax' => 'taxe_fonciere', + 'coproperty_tax' => 'taxe_fonciere_co', + 'rent_receipt' => 'quittance_loyer', + 'corent_receipt' => 'quittance_loyer_co', + 'compromise' => 'compromis_vente', + 'cocompromise' => 'compromis_vente_co' + ]; + + // Première passe : calculer la taille totale des fichiers + // Détecter le type de structure de fichiers + $is_direct_structure = isset($files['name']) && is_array($files['name']); + + if ($is_direct_structure) { + // Structure directe : $files['name'], $files['type'], etc. + $file_count = count($files['name']); + for ($i = 0; $i < $file_count; $i++) { + // Sauter si pas de fichier uploadé + if ($files['error'][$i] === 4) continue; + + if ($files['error'][$i] === 0) { + $total_size += $files['size'][$i]; + } + } + } else { + // Structure avec champs nommés : $files['test1'], $files['test2'], etc. + foreach ($files as $field_name => $file) { + if (is_array($file['name'])) { + // Champ multiple + $file_count = count($file['name']); + for ($i = 0; $i < $file_count; $i++) { + if ($file['error'][$i] === 4) continue; + if ($file['error'][$i] === 0) { + $total_size += $file['size'][$i]; + } + } + } else { + // Champ simple + if ($file['error'] !== 4 && $file['error'] === 0) { + $total_size += $file['size']; + } + } + } + } + + // Vérifier la taille totale + if ($total_size > $total_size_limit) { + $errors[] = "La taille totale des fichiers (" . round($total_size / 1024 / 1024, 2) . " MB) dépasse la limite autorisée de 10 MB pour l'envoi par email."; + return [ + 'files' => [], + 'errors' => $errors, + 'html_links' => '' + ]; + } + + // Créer le dossier de destination s'il n'existe pas + $upload_dir = \wp_upload_dir()['basedir'] . '/credit_direct/clients/' . $token; + if (!file_exists($upload_dir)) { + \wp_mkdir_p($upload_dir); + } + + // Traiter chaque fichier uploadé + if ($is_direct_structure) { + // Structure directe : $files['name'], $files['type'], etc. + $file_count = count($files['name']); + for ($i = 0; $i < $file_count; $i++) { + // Sauter si pas de fichier uploadé + if ($files['error'][$i] === 4) continue; + + if ($files['error'][$i] !== 0) { + $errors[] = "Erreur lors de l'upload du fichier ($i): " . $this->getUploadErrorMessage($files['error'][$i]); + continue; + } + + if (!in_array($files['type'][$i], $allowed_types)) { + $errors[] = "Type de fichier non autorisé pour le fichier ($i): " . $files['type'][$i]; + continue; + } + + if ($files['size'][$i] > $max_size) { + $errors[] = "Fichier trop volumineux pour le fichier ($i): " . round($files['size'][$i] / 1024 / 1024, 2) . " Mo"; + continue; + } + + // Générer le nom du fichier avec index + $original_name = $files['name'][$i]; + $extension = pathinfo($original_name, PATHINFO_EXTENSION); + $new_filename = $token . '_document_' . ($i+1) . '.' . $extension; + $destination = $upload_dir . '/' . $new_filename; + + if (move_uploaded_file($files['tmp_name'][$i], $destination)) { + $uploaded_files[] = $destination; + $file_url = content_url('/uploads/credit_direct/clients/' . $token . '/' . $new_filename); + $html_links .= sprintf( + '
  • %s
  • ', + esc_url($file_url), + esc_html($original_name) + ); + } else { + $errors[] = "Impossible de déplacer le fichier ($i)"; + } + } + } else { + // Structure avec champs nommés : $files['test1'], $files['test2'], etc. + foreach ($files as $field_name => $file) { + if (is_array($file['name'])) { + // Champ multiple + $file_count = count($file['name']); + for ($i = 0; $i < $file_count; $i++) { + // Sauter si pas de fichier uploadé + if ($file['error'][$i] === 4) continue; + + if ($file['error'][$i] !== 0) { + $errors[] = "Erreur lors de l'upload du fichier $field_name ($i): " . $this->getUploadErrorMessage($file['error'][$i]); + continue; + } + + if (!in_array($file['type'][$i], $allowed_types)) { + $errors[] = "Type de fichier non autorisé pour $field_name ($i): " . $file['type'][$i]; + continue; + } + + if ($file['size'][$i] > $max_size) { + $errors[] = "Fichier trop volumineux pour $field_name ($i): " . round($file['size'][$i] / 1024 / 1024, 2) . " Mo"; + continue; + } + + // Générer le nom du fichier avec type de document + $doc_type = isset($field_to_doc_type[$field_name]) ? $field_to_doc_type[$field_name] : $field_name; + $extension = pathinfo($file['name'][$i], PATHINFO_EXTENSION); + $new_filename = $token . '_' . $doc_type . '_' . ($i+1) . '.' . $extension; + $destination = $upload_dir . '/' . $new_filename; + + if (move_uploaded_file($file['tmp_name'][$i], $destination)) { + $uploaded_files[] = $destination; + $file_url = content_url('/uploads/credit_direct/clients/' . $token . '/' . $new_filename); + $html_links .= sprintf( + '
  • %s
  • ', + esc_url($file_url), + esc_html(ucfirst(str_replace('_', ' ', $doc_type))) . ' (' . ($i+1) . ')' + ); + } else { + $errors[] = "Impossible de déplacer le fichier $field_name ($i)"; + } + } + } else { + // Champ simple + if ($file['error'] === 4) continue; // Pas de fichier uploadé + + if ($file['error'] !== 0) { + $errors[] = "Erreur lors de l'upload du fichier $field_name: " . $this->getUploadErrorMessage($file['error']); + continue; + } + + if (!in_array($file['type'], $allowed_types)) { + $errors[] = "Type de fichier non autorisé pour $field_name: " . $file['type']; + continue; + } + + if ($file['size'] > $max_size) { + $errors[] = "Fichier trop volumineux pour $field_name: " . round($file['size'] / 1024 / 1024, 2) . " Mo"; + continue; + } + + // Générer le nom du fichier + $doc_type = isset($field_to_doc_type[$field_name]) ? $field_to_doc_type[$field_name] : $field_name; + $extension = pathinfo($file['name'], PATHINFO_EXTENSION); + $new_filename = $token . '_' . $doc_type . '.' . $extension; + $destination = $upload_dir . '/' . $new_filename; + + if (move_uploaded_file($file['tmp_name'], $destination)) { + $uploaded_files[] = $destination; + $file_url = content_url('/uploads/credit_direct/clients/' . $token . '/' . $new_filename); + $html_links .= sprintf( + '
  • %s
  • ', + esc_url($file_url), + esc_html(ucfirst(str_replace('_', ' ', $doc_type))) + ); + } else { + $errors[] = "Impossible de déplacer le fichier $field_name"; + } + } + } + } + + return [ + 'files' => $uploaded_files, + 'errors' => $errors, + 'html_links' => $html_links ? '' : '' + ]; + } + + /** + * Retourne un message d'erreur lisible pour les codes d'erreur d'upload + * @param int $error_code Le code d'erreur PHP + * @return string Le message d'erreur + */ + private function getUploadErrorMessage($error_code) { + switch ($error_code) { + case UPLOAD_ERR_INI_SIZE: + return "Le fichier dépasse la taille maximale autorisée par PHP"; + case UPLOAD_ERR_FORM_SIZE: + return "Le fichier dépasse la taille maximale autorisée par le formulaire"; + case UPLOAD_ERR_PARTIAL: + return "Le fichier n'a été que partiellement uploadé"; + case UPLOAD_ERR_NO_FILE: + return "Aucun fichier n'a été uploadé"; + case UPLOAD_ERR_NO_TMP_DIR: + return "Dossier temporaire manquant"; + case UPLOAD_ERR_CANT_WRITE: + return "Impossible d'écrire le fichier sur le disque"; + case UPLOAD_ERR_EXTENSION: + return "Une extension PHP a arrêté l'upload du fichier"; + default: + return "Erreur inconnue lors de l'upload"; + } + } + + /** + * Récupère tous les fichiers uploadés pour un token de crédit donné + * @param string $token Le token du crédit + * @return array Array d'URLs des fichiers uploadés + */ + public function getUploadedFiles($token) { + $uploaded_files = []; + + // Limite de taille totale pour l'envoi par email (10MB) + $total_size_limit = 10 * 1024 * 1024; // 10MB en octets + $total_size = 0; + + // Construire le chemin du dossier + $upload_dir = \wp_upload_dir()['basedir'] . '/credit_direct/clients/' . $token; + + // Vérifier si le dossier existe + if (!file_exists($upload_dir) || !is_dir($upload_dir)) { + return $uploaded_files; + } + + // Récupérer tous les fichiers du dossier + $files = scandir($upload_dir); + + foreach ($files as $file) { + // Ignorer les dossiers . et .. + if ($file === '.' || $file === '..') { + continue; + } + + // Construire l'URL complète du fichier + $file_path = $upload_dir . '/' . $file; + + // Vérifier que c'est bien un fichier + if (is_file($file_path)) { + $file_size = filesize($file_path); + $total_size += $file_size; + + // Vérifier si la taille totale dépasse la limite + if ($total_size > $total_size_limit) { + // Retourner les fichiers déjà trouvés avec un avertissement + $uploaded_files[] = 'WARNING: Taille totale dépassée (' . round($total_size / 1024 / 1024, 2) . ' MB)'; + break; + } + + $file_url = content_url('/uploads/credit_direct/clients/' . $token . '/' . $file); + $uploaded_files[] = $file_url; + } + } + + // Trier les fichiers par ordre alphabétique + sort($uploaded_files); + + return $uploaded_files; + } + + /** + * Récupère tous les fichiers uploadés avec leurs métadonnées pour un token de crédit donné + * @param string $token Le token du crédit + * @return array Array avec les informations des fichiers (url, nom, type, taille, date) + */ + public function getUploadedFilesWithMetadata($token) { + $uploaded_files = []; + + // Limite de taille totale pour l'envoi par email (10MB) + $total_size_limit = 10 * 1024 * 1024; // 10MB en octets + $total_size = 0; + $size_limit_exceeded = false; + + // Construire le chemin du dossier + $upload_dir = \wp_upload_dir()['basedir'] . '/credit_direct/clients/' . $token; + + // Vérifier si le dossier existe + if (!file_exists($upload_dir) || !is_dir($upload_dir)) { + return $uploaded_files; + } + + // Récupérer tous les fichiers du dossier + $files = scandir($upload_dir); + + foreach ($files as $file) { + // Ignorer les dossiers . et .. + if ($file === '.' || $file === '..') { + continue; + } + + $file_path = $upload_dir . '/' . $file; + + // Vérifier que c'est bien un fichier + if (is_file($file_path)) { + $file_size = filesize($file_path); + $total_size += $file_size; + + // Vérifier si la taille totale dépasse la limite + if ($total_size > $total_size_limit && !$size_limit_exceeded) { + $size_limit_exceeded = true; + $uploaded_files[] = [ + 'url' => '', + 'filename' => 'WARNING', + 'doc_type' => 'size_limit', + 'size' => 0, + 'size_formatted' => '0 B', + 'modified_date' => time(), + 'extension' => '', + 'warning' => 'La taille totale des fichiers (' . round($total_size / 1024 / 1024, 2) . ' MB) dépasse la limite de 10 MB pour l\'envoi par email.' + ]; + break; + } + + $file_url = content_url('/uploads/credit_direct/clients/' . $token . '/' . $file); + + // Extraire le type de document du nom de fichier + $file_info = pathinfo($file); + $filename_parts = explode('_', $file_info['filename']); + + // Le type de document est généralement après le token + $doc_type = isset($filename_parts[1]) ? $filename_parts[1] : 'unknown'; + + $uploaded_files[] = [ + 'url' => $file_url, + 'filename' => $file, + 'doc_type' => $doc_type, + 'size' => $file_size, + 'size_formatted' => $this->formatFileSize($file_size), + 'modified_date' => filemtime($file_path), + 'extension' => strtolower($file_info['extension']), + 'total_size' => $total_size, + 'total_size_formatted' => $this->formatFileSize($total_size) + ]; + } + } + + // Trier par date de modification (plus récent en premier) + usort($uploaded_files, function($a, $b) { + return $b['modified_date'] - $a['modified_date']; + }); + + return $uploaded_files; + } + + /** + * Formate la taille d'un fichier en format lisible + * @param int $bytes Taille en octets + * @return string Taille formatée + */ + private function formatFileSize($bytes) { + $units = ['B', 'KB', 'MB', 'GB']; + + for ($i = 0; $bytes > 1024 && $i < count($units) - 1; $i++) { + $bytes /= 1024; + } + + return round($bytes, 2) . ' ' . $units[$i]; + } + + /** + * Vérifie si une demande de crédit est en cours pour l'utilisateur + * @return array|false Retourne les données de la demande en cours ou false + */ + public function checkOngoingCreditRequest($debug = false) { + + /* if(isset($_GET['debug'])) { + echo '
    ';
    +            print_r($_COOKIE['credit_data']);
    +            echo '
    '; + } */ + + $debug = false; + + + if (isset($_COOKIE['credit_data']) || $debug) { + + $_COOKIE['credit_data'] = stripslashes((string) ($_COOKIE['credit_data'] ?? '')); + $credit_data = null; + + if(isset($_COOKIE['credit_data'])) { + $credit_data = json_decode($_COOKIE['credit_data'], true); + } + + if($debug) { + $credit_data = []; + $credit_data['credit_token'] = '151b8853cc8a501e61bb4d0f0fdd05bc1a4d73e8'; + } + + if ($credit_data && isset($credit_data['credit_token'])) { + $currentCredit = $this->getCredit($credit_data['credit_token']); + + + if ($currentCredit && is_object($currentCredit)) { + // Récupérer les données de l'emprunteur pour avoir plus d'informations + $borrower = $this->getBorrower($currentCredit); + + return [ + 'token' => $currentCredit->token, + 'step' => $currentCredit->last_step, + 'type' => $currentCredit->type_credit, + 'capital' => $currentCredit->capital, + 'duree' => $currentCredit->duree, + 'has_borrower' => !empty($borrower), + 'has_co_borrower' => !empty($this->getCoBorrower($currentCredit)), + 'last_update_date' => $currentCredit->last_update_date + ]; + } + } + } + return false; + } + + public function get_ongoing_credit_token() { + $token = null; + + + if(isset($_GET['credit-direct-token'])) { + $token = $_GET['credit-direct-token']; + + $credit_data = $this->getCredit($token); + + if($credit_data) { + $token = $credit_data->token; + } + } else { + $ongoing_credit = $this->checkOngoingCreditRequest(); + + if($ongoing_credit) { + $token = $ongoing_credit['token']; + } + } + + return $token; + } + + public function get_agency($location) { + $agency_mail = ''; + + $location = sanitize_title((string) ($location ?? '')); + $agence = []; + + //location = slug de la page agence + + $args = array( + 'post_type' => 'agences', + 'name' => $location, + 'posts_per_page' => 1 + ); + + + $agencies = get_posts($args); + + if($agencies) { + $agency = $agencies[0]; + $agence['id'] = $agency->ID; + $agence['name'] = $agency->post_title; + $agence['emails'] = get_field('listing_email', $agency->ID); + } + + return $agence; + } + + public function switchAgency_byZipCode(int $zipCode, object $borrower): array { + + $agency_mail = []; + $mons = $this->get_agency('mons'); + $verviers = $this->get_agency('verviers'); + + $pays = $this->getFieldValue('pays', $borrower); + + if($pays == 'LU') { + $agency_mail = $verviers; + + return $agency_mail; + } + + if (($zipCode >= 4000 && $zipCode <= 4999) || // Liège + ($zipCode >= 6600 && $zipCode <= 6999)) { // Luxembourg + $agency_mail = $verviers; + } + + $wallonieBruxelles = + ($zipCode >= 1000 && $zipCode <= 1299) || // Bruxelles‑Capitale + ($zipCode >= 1300 && $zipCode <= 1499) || // Brabant wallon + ($zipCode >= 5000 && $zipCode <= 5680) || // Namur + ($zipCode >= 6000 && $zipCode <= 6599) || // Hainaut (partie 1) + ($zipCode >= 7000 && $zipCode <= 7999); + + $agency_mail = $wallonieBruxelles ? $mons : $verviers; + + return $agency_mail; + + } + + /** + * Vérifie si la taille totale des fichiers pour un token dépasse la limite email + * @param string $token Le token du crédit + * @return array ['exceeded' => bool, 'total_size' => int, 'total_size_formatted' => string, 'limit' => int, 'limit_formatted' => string] + */ + public function checkTotalFileSize($token) { + $total_size_limit = 10 * 1024 * 1024; // 10MB en octets + $total_size = 0; + + // Construire le chemin du dossier + $upload_dir = \wp_upload_dir()['basedir'] . '/credit_direct/clients/' . $token; + + // Vérifier si le dossier existe + if (!file_exists($upload_dir) || !is_dir($upload_dir)) { + return [ + 'exceeded' => false, + 'total_size' => 0, + 'total_size_formatted' => '0 B', + 'limit' => $total_size_limit, + 'limit_formatted' => '10 MB' + ]; + } + + // Récupérer tous les fichiers du dossier + $files = scandir($upload_dir); + + foreach ($files as $file) { + if ($file === '.' || $file === '..') { + continue; + } + + $file_path = $upload_dir . '/' . $file; + + if (is_file($file_path)) { + $total_size += filesize($file_path); + } + } + + return [ + 'exceeded' => $total_size > $total_size_limit, + 'total_size' => $total_size, + 'total_size_formatted' => $this->formatFileSize($total_size), + 'limit' => $total_size_limit, + 'limit_formatted' => '10 MB' + ]; + } + + /** + * Récupère la valeur d'un champ pour l'emprunteur ou le co-emprunteur + * @param string $fieldName Le nom du champ + * @param object $borrower Les données de l'emprunteur + * @return string La valeur à afficher dans le champ + */ + public function getFieldValue($fieldName, $borrower) { + $value = ''; + $map = $this->borrowerFieldMap; + + + + // Détermine si c'est un champ co-emprunteur basé sur le préfixe 'co' + $isCoBorrowerField = strpos($fieldName, 'co') === 0; + + if ($isCoBorrowerField) { + // Récupère le co-emprunteur automatiquement + $currentCredit = $this->getCreditFromBorrower($borrower); + $coBorrower = $currentCredit ? $this->getCoBorrower($currentCredit) : null; + + if (is_object($coBorrower)) { + // Retire le préfixe 'co' pour retrouver la clé de mapping + $baseField = substr($fieldName, 2); + if (isset($map[$baseField])) { + $dbField = $map[$baseField]; + if (isset($coBorrower->$dbField)) { + $value = $coBorrower->$dbField; + } + } elseif (isset($coBorrower->$fieldName)) { + $value = $coBorrower->$fieldName; + } + } + } else if (is_object($borrower)) { + if (isset($map[$fieldName])) { + $dbField = $map[$fieldName]; + + if (isset($borrower->$dbField)) { + $value = $borrower->$dbField; + } + } elseif (isset($borrower->$fieldName)) { + $value = $borrower->$fieldName; + } + } + + if(in_array($fieldName, $this->dateFields) && !empty($value)) { + + $value = \DateTime::createFromFormat('Y-m-d', $value)->format('d/m/Y'); + } + + if(!empty($value)) { + return htmlspecialchars((string) $value); + } + + // Toujours retourner une chaîne vide si aucune valeur n'est trouvée + return ''; + } + + /** + * Récupère le crédit à partir de l'emprunteur + * @param object $borrower Les données de l'emprunteur + * @return object|null Le crédit associé + */ + private function getCreditFromBorrower($borrower) { + if (!is_object($borrower) || !isset($borrower->FK_demande_creditdirect)) { + return null; + } + + return $this->wpdb->get_row( + $this->wpdb->prepare( + "SELECT * FROM cdf_Credit WHERE idCredit = %d", + $borrower->FK_demande_creditdirect + ) + ); + } + + /** + * Fonction helper pour vérifier si une option est sélectionnée + * @param string $fieldName Le nom du champ + * @param string $optionValue La valeur de l'option + * @param object $borrower Les données de l'emprunteur + * @return string 'selected' si l'option doit être sélectionnée + */ + public function isOptionSelected($fieldName, $optionValue, $borrower) { + $currentValue = $this->getFieldValue($fieldName, $borrower); + return ($currentValue == $optionValue) ? 'selected' : ''; + } + + /** + * Fonction helper pour vérifier si une radio est cochée + * @param string $fieldName Le nom du champ + * @param string $optionValue La valeur de l'option + * @param object $borrower Les données de l'emprunteur + * @return string 'checked' si l'option doit être cochée + */ + public function isRadioChecked($fieldName, $optionValue, $borrower) { + $currentValue = $this->getFieldValue($fieldName, $borrower); + return ($currentValue == $optionValue) ? 'checked' : ''; + } + + public function hasCreditCoBorrower($currentCredit) { + $hasCreditCoBorrower = false; + $coBorrower = $this->getCoBorrower($currentCredit); + + if($coBorrower) { + $hasCreditCoBorrower = true; + } + + return $hasCreditCoBorrower; + } + + /** + * Fonction helper pour vérifier si une checkbox est cochée + * @param string $fieldName Le nom du champ + * @param string $optionValue La valeur de l'option + * @param object $borrower Les données de l'emprunteur + * @return string 'checked' si l'option doit être cochée + */ + public function isCheckboxChecked($fieldName, $optionValue, $borrower) { + $currentValue = $this->getFieldValue($fieldName, $borrower); + return ($currentValue == $optionValue) ? 'checked' : ''; + } + + /** + * Récupère les crédits en cours d'un emprunteur + * @param object $borrower Les données de l'emprunteur + * @return array Liste des crédits en cours + */ + public function getCurrentLoans($borrower) { + if (!is_object($borrower) || !isset($borrower->idemprunteur)) { + return []; + } + + $query = $this->wpdb->prepare( + "SELECT * FROM cdf_Autre_credit WHERE FK_emprunteur = %d ORDER BY idautrecredit ASC", + $borrower->idemprunteur + ); + + return $this->wpdb->get_results($query); + } + + /** + * Génère le HTML pour pré-remplir les crédits en cours + * @param object $borrower Les données de l'emprunteur + * @param string $prefix Préfixe pour les champs co-emprunteur (ex: 'co') + * @return string HTML des crédits pré-remplis + */ + public function getCurrentLoansHTML($borrower, $prefix = '') { + $currentLoans = $this->getCurrentLoans($borrower); + $html = ''; + $index = 0; + + $class_col = $this->hasCoBorrower($borrower) ? 'col-md-3' : 'col-md-6'; + + foreach ($currentLoans as $loan) { + $html .= '
    '; + $html .= ''; + + $html .= '
    '; + + // Type de créance + $html .= '
    '; + $html .= ''; + $html .= '
    '; + + // Nom de l'organisme / Banque + $html .= '
    '; + $html .= ''; + $html .= ''; + $html .= '
    '; + + // Capital emprunté + $html .= '
    '; + $html .= ''; + $html .= ''; + $html .= '
    '; + + // Durée du crédit + $html .= '
    '; + $html .= ''; + $html .= ''; + $html .= '
    '; + + // Mensualité + $html .= '
    '; + $html .= ''; + $html .= ''; + $html .= '
    '; + + // Date 1ère échéance + $html .= '
    '; + $html .= ''; + $html .= ''; + $html .= '
    '; + + // Solde restant dû + $html .= '
    '; + $html .= ''; + $html .= ''; + $html .= '
    '; + + // À clôturer / Solder + $html .= '
    '; + $html .= '
    À clôturer / Solder ?
    '; + $html .= '
    '; + $html .= 'cloture == '0' ? 'checked' : '') . '>'; + $html .= ''; + $html .= '
    '; + $html .= '
    '; + $html .= 'cloture == '1' ? 'checked' : '') . '>'; + $html .= ''; + $html .= '
    '; + $html .= '
    '; + + $html .= ''; + $html .= '
    '; + $html .= '
    '; + + $index++; + } + + return $html; + } + + + /** + * Récupère les autres revenus d'un emprunteur ou co-emprunteur + * @param object $borrower Les données de l'emprunteur ou co-emprunteur + * @return array Array avec les autres revenus + */ + public function getAutresRevenus($borrower) { + if (!is_object($borrower) || !isset($borrower->idemprunteur)) { + return []; + } + + $autresRevenus = []; + + // Récupérer les autres revenus depuis la table cdf_Emprunteur + $query = $this->wpdb->prepare( + "SELECT + cheque_repas, + revenus_locatifs, + chomage, + autre_revenu_type, + autre_revenu_montant + FROM cdf_Emprunteur + WHERE idemprunteur = %d", + $borrower->idemprunteur + ); + + $result = $this->wpdb->get_row($query); + + if ($result) { + // Construire un array avec les autres revenus + if (!empty($result->cheque_repas)) { + $autresRevenus[] = [ + 'type' => 'Chèque repas', + 'montant' => $result->cheque_repas, + 'description' => 'Chèque repas mensuel' + ]; + } + + if (!empty($result->revenus_locatifs)) { + $autresRevenus[] = [ + 'type' => 'Revenus locatifs', + 'montant' => $result->revenus_locatifs, + 'description' => 'Revenus locatifs mensuels' + ]; + } + + if (!empty($result->chomage)) { + $autresRevenus[] = [ + 'type' => 'Chômage', + 'montant' => $result->chomage, + 'description' => 'Allocation de chômage mensuelle' + ]; + } + + if (!empty($result->autre_revenu_montant) && !empty($result->autre_revenu_type)) { + $autresRevenus[] = [ + 'type' => 'Autre revenu', + 'montant' => $result->autre_revenu_montant, + 'description' => $result->autre_revenu_type + ]; + } + } + + return $autresRevenus; + } + + /** + * @param $data + * @return void + */ + protected function update_emprunteur($data, $currentCredit) + { + // Vérifier si l'email de l'emprunteur contient @example.com + if(isset($data['email']) && strpos($data['email'], '@example.com') !== false) { + return false; // Rejeter la demande si l'adresse email contient @example.com + } + + $borrower = $this->getBorrower($currentCredit); + $updateData = []; + + foreach ($this->borrowerFieldMap as $formField => $dbField) { + + /* echo '
    ';
    +            print_r($data);
    +            echo '
    '; */ + + // Protection générale : ne mettre à jour que les champs présents dans les données POST + if (!isset($data[$formField])) { + continue; // On saute ce champ s'il n'est pas présent dans les données + } + + // Si le champ est un champ de date, on le formate correctement + if (in_array($formField, $this->dateFields)) { + if (!empty($data[$formField])) { + $date = \DateTime::createFromFormat('d/m/Y', $data[$formField]); + if ($date) { + $updateData[$dbField] = $date->format('Y-m-d'); + } else { + $updateData[$dbField] = null; // Si la date n'est pas valide, on met à null + } + } else { + $updateData[$dbField] = null; // Si le champ est vide, on met à null + } + } else { + // Pour les champs non-date, on utilise directement la valeur + $updateData[$dbField] = $data[$formField]; + } + } + + /* echo '
    ';
    +        print_r($updateData);
    +        echo '
    '; + die(); */ + + + $this->wpdb->update('cdf_Emprunteur', $updateData, array('idemprunteur' => $borrower->idemprunteur)); + } + + /** + * Met à jour les données du co-emprunteur + * @param $data + * @param $currentCredit + * @return void + */ + protected function update_co_emprunteur($data, $currentCredit) + { + // Vérifier si l'email du co-emprunteur contient @example.com + if(isset($data['coemail']) && strpos($data['coemail'], '@example.com') !== false) { + return false; // Rejeter la demande si l'adresse email du co-emprunteur contient @example.com + } + + $coBorrower = $this->getCoBorrower($currentCredit); + if (!is_object($coBorrower)) { + return; // Pas de co-emprunteur, on sort + } + + $updateData = []; + + foreach ($this->borrowerFieldMap as $formField => $dbField) { + // Vérifier si c'est un champ co-emprunteur (préfixe 'co') + if (strpos($formField, 'co') === 0) { + // Protection générale : ne mettre à jour que les champs présents dans les données POST + if (!isset($data[$formField])) { + continue; // On saute ce champ s'il n'est pas présent dans les données + } + + // Si le champ est un champ de date, on le formate correctement + if (in_array($formField, $this->dateFields)) { + if (!empty($data[$formField])) { + $date = \DateTime::createFromFormat('d/m/Y', $data[$formField]); + if ($date) { + $updateData[$dbField] = $date->format('Y-m-d'); + } else { + $updateData[$dbField] = null; // Si la date n'est pas valide, on met à null + } + } else { + $updateData[$dbField] = null; // Si le champ est vide, on met à null + } + } else { + // Pour les champs non-date, on utilise directement la valeur + $updateData[$dbField] = $data[$formField]; + } + } + } + + if (!empty($updateData)) { + $this->wpdb->update('cdf_Emprunteur', $updateData, array('idemprunteur' => $coBorrower->idemprunteur)); + } + } + + public function is_credit_pat($currentCredit) { + + $type_credit = $currentCredit->type_credit; + + + if(array_key_exists($type_credit, $this->one_step_credit_types)) { + return true; + } + + return false; + } + + public function is_credit_auto($currentCredit) { + $type_credit = $currentCredit->type_credit; + + if(in_array($type_credit, $this->creditAutos)) { + return true; + } + + return false; + } + + public function hasCoBorrower($currentCredit) { + $borrower = $this->getBorrower($currentCredit); + $coBorrower = $this->getCoBorrower($currentCredit); + + if($coBorrower) { + return true; + } + + return false; + } + + public function hasOtherIncome($borrower) { + $cheque_repas = $this->getFieldValue('cheque_repas', $borrower); + $revenus_locatifs = $this->getFieldValue('revenus_locatifs', $borrower); + $chomage = $this->getFieldValue('chomage', $borrower); + $autre_revenu_montant = $this->getFieldValue('autre_revenu_montant', $borrower); + $autre_revenu_type = $this->getFieldValue('autre_revenu_type', $borrower); + + if($cheque_repas || $revenus_locatifs || $chomage || $autre_revenu_montant || $autre_revenu_type) { + return true; + } + + return false; + } + + public function estFicheBanqueNational($borrower) { + + $fichage_status = $borrower->fichage_status; + + if(!empty($fichage_status)) { + return true; + } + + return false; + + } + + public function is_locataire($borrower) { + + $habitation_type = $borrower->habitation_type; + + if(empty($habitation_type)) { + return false; + } + + if($habitation_type == 'locataire') { + return true; + } + + return false; + } + + /** + * Génère des liens HTML pour les documents uploadés + * @param string $token Le token du crédit + * @param bool $include_metadata Inclure les métadonnées (taille, date) dans l'affichage + * @param string $css_class Classe CSS pour le conteneur des liens + * @return string HTML des liens vers les documents uploadés + */ + public function generateUploadedFilesLinksHTML($token, $include_metadata = false, $css_class = 'uploaded-documents') { + $html = ''; + + if ($include_metadata) { + $files = $this->getUploadedFilesWithMetadata($token); + } else { + $files = $this->getUploadedFiles($token); + } + + if (empty($files)) { + return '

    Aucun document uploadé

    '; + } + + $html .= '
    '; + $html .= '

    Documents uploadés :

    '; + $html .= '
      '; + + foreach ($files as $file) { + if ($include_metadata && is_array($file)) { + // Fichier avec métadonnées + if (isset($file['warning'])) { + $html .= '
    • ⚠️ ' . esc_html($file['warning']) . '
    • '; + continue; + } + + $file_url = $file['url']; + $filename = $file['filename']; + $doc_type = $file['doc_type']; + $size_formatted = $file['size_formatted']; + $modified_date = date('d/m/Y H:i', $file['modified_date']); + + // Traduire le type de document + $doc_type_labels = [ + 'fiche_paie' => 'Fiche de paie', + 'fiche_paie_co' => 'Fiche de paie (co-emprunteur)', + 'avis_imposition' => 'Avis d\'imposition', + 'avis_imposition_co' => 'Avis d\'imposition (co-emprunteur)', + 'carte_identite' => 'Carte d\'identité', + 'carte_identite_co' => 'Carte d\'identité (co-emprunteur)', + 'taxe_fonciere' => 'Taxe foncière', + 'taxe_fonciere_co' => 'Taxe foncière (co-emprunteur)', + 'quittance_loyer' => 'Quittance de loyer', + 'quittance_loyer_co' => 'Quittance de loyer (co-emprunteur)', + 'compromis_vente' => 'Compromis de vente', + 'compromis_vente_co' => 'Compromis de vente (co-emprunteur)' + ]; + + $doc_label = isset($doc_type_labels[$doc_type]) ? $doc_type_labels[$doc_type] : ucfirst(str_replace('_', ' ', $doc_type)); + + $html .= '
    • '; + $html .= ''; + $html .= '📄 ' . esc_html($doc_label); + $html .= ''; + $html .= '
      '; + $html .= 'Taille: ' . esc_html($size_formatted) . ' | Modifié le: ' . esc_html($modified_date); + $html .= '
      '; + $html .= '
    • '; + + } else { + // Fichier simple (URL seulement) + if (is_string($file) && strpos($file, 'WARNING:') === 0) { + $html .= '
    • ⚠️ ' . esc_html($file) . '
    • '; + continue; + } + + $file_url = $file; + $filename = basename($file_url); + + $html .= '
    • '; + $html .= ''; + $html .= '📄 ' . esc_html($filename); + $html .= ''; + $html .= '
    • '; + } + } + + $html .= '
    '; + $html .= '
    '; + + return $html; + } + + /** + * Génère des liens HTML simples pour les documents uploadés (version simplifiée) + * @param string $token Le token du crédit + * @param string $css_class Classe CSS pour le conteneur des liens + * @return string HTML des liens vers les documents uploadés + */ + public function generateSimpleUploadedFilesLinksHTML($token, $css_class = 'uploaded-documents-simple') { + $files = $this->getUploadedFiles($token); + + if (empty($files)) { + return ''; + } + + $html = '
    '; + $html .= '

    Documents joints :

    '; + $html .= '
      '; + + foreach ($files as $file) { + if (is_string($file) && strpos($file, 'WARNING:') === 0) { + $html .= '
    • ⚠️ ' . esc_html($file) . '
    • '; + continue; + } + + $file_url = $file; + $filename = basename($file_url); + + $html .= '
    • '; + $html .= ''; + $html .= esc_html($filename); + $html .= ''; + $html .= '
    • '; + } + + $html .= '
    '; + $html .= '
    '; + + return $html; + } + + /** + * get exemple_infod_from acf + */ + public function get_exemples_infos($credit_types) { + + $credit_type_map = array( + 'but_immo' => 'credit_travaux__renovation__energie', + 'fin_neuve' => 'financement_vehicule_neuf', + 'fin_occ_m3a' => 'financement_vehicule_doccasion_moins_de_3_ans', + 'fin_occ_p3a' => 'financement_vehicule_doccasion_plus_de_3_ans', + 'mobil_carav' => 'financement_mobilhome_et_caravane_de_moins_de_3_ans', + 'reno_energie' => 'credit_travaux__renovation__energie', + 'regroup_cred' => 'regroupement_de_credit__rachats_de_credits', + 'frais_notaire' => 'financement_frais_de_notaire', + 'pat' => 'pret_personnel__tous_motifs__achats_divers', + 'ph' => 'credit_hypothecaire_social', + 'am' => 'credit_hypothecaire_classique', + 'amr' => 'achat_maison_de_rapport', + 'cdp' => 'credit_pont', + 'cied' => 'independants_et_entreprises_en_difficultes', + 'reno_energie' => 'credit_travaux__renovation__energie', + 'but_immo_hypo' => 'credit_hypothecaire_classique', + ); + + $credit = $credit_type_map[$credit_types]; + + $exemple_info = get_field($credit, 'option'); + + // Vérifier que $exemple_info existe et est un tableau avant d'accéder à la clé + if (!is_array($exemple_info) || !isset($exemple_info['exemple_et_infos'])) { + return false; + } + + $exemple_info = $exemple_info['exemple_et_infos']; + + if(empty($exemple_info)) { + return false; + } + + return $exemple_info; + + } + + /** + * check if is webdev user + */ + public function is_webdev_user() { + $user = wp_get_current_user(); + + $user_id = $user->ID; + + if($user_id == 1) { + return true; + } + return false; + } + + /** + * Sauvegarde dans cdf_Credits_listing + * @param object $currentCredit Le crédit actuel + * @return void + */ + public function save_to_credits_listing($currentCredit) { + // Récupérer les données complètes du crédit + $credit_data = $this->wpdb->get_row($this->wpdb->prepare( + "SELECT * FROM cdf_Credit WHERE idCredit = %d", + $currentCredit->idCredit + )); + + $code_type_credit = $this->is_credit_pat($currentCredit) ? 'pat' : 'ph'; + + // Récupérer les données de l'emprunteur + $emprunteur_data = $this->wpdb->get_row($this->wpdb->prepare( + "SELECT * FROM cdf_Emprunteur WHERE FK_demande_creditdirect = %d", + $currentCredit->idCredit + )); + + // Récupérer les autres crédits de l'emprunteur + $other_credits_ids = ''; + if ($emprunteur_data) { + $borrower = $this->getBorrower($currentCredit); + if ($borrower && isset($borrower->other_credits) && is_array($borrower->other_credits)) { + $ids = array(); + foreach ($borrower->other_credits as $other_credit) { + if (isset($other_credit->idautre_credit)) { + $ids[] = $other_credit->idautre_credit; + } + } + $other_credits_ids = implode(',', $ids); + } + } + + // Vérifier si l'enregistrement existe déjà + $existing = $this->wpdb->get_row($this->wpdb->prepare( + "SELECT id FROM cdf_Credits_listing WHERE credit_id = %d", + $currentCredit->idCredit + )); + + $credit_label = $this->getCreditLabel($credit_data->sel_credit); + + $listing_data = array( + 'credit_id' => $currentCredit->idCredit, + 'emprunteur_id' => $emprunteur_data ? $emprunteur_data->idemprunteur : 0, + 'autre_credit_id' => $other_credits_ids, + 'credit_auto_id' => $credit_data ? $credit_data->FK_credit_auto : 0, + 'credit_hypotecaire_id' => $credit_data ? $credit_data->FK_credit_hypothecaire : 0, + 'credit_code_select' => $credit_data->sel_credit, + 'code_credit' => $credit_data->type_credit, + 'type_credit' => $code_type_credit, + 'nom' => $emprunteur_data ? $emprunteur_data->nom : '', + 'prenom' => $emprunteur_data ? $emprunteur_data->prenom : '', + 'adresse' => $emprunteur_data ? $emprunteur_data->adresse : '', + 'localite' => $emprunteur_data ? $emprunteur_data->localite : '', + 'code_postal' => $emprunteur_data ? intval($emprunteur_data->code_postal) : 0, + 'pays' => $emprunteur_data ? (is_numeric($emprunteur_data->pays) ? intval($emprunteur_data->pays) : 0) : 0, + 'email' => $emprunteur_data ? $emprunteur_data->email : '', + 'telephone' => $emprunteur_data ? $emprunteur_data->telephone : '', + 'gsm' => $emprunteur_data ? $emprunteur_data->telephone : '', // Utiliser telephone comme gsm si pas de gsm séparé + 'type_habitation' => $emprunteur_data ? $emprunteur_data->habitation_type : '', + 'societe_credit' => '', + 'montant' => $credit_data ? floatval($credit_data->capital) : 0, + 'date' => $credit_data ? $credit_data->create_date : date('Y-m-d'), + 'date_signature' => '', // Par défaut non signé + 'numero_dossier' => '', + 'code' => '', + 'remarque' => $credit_data ? $credit_data->commentaire : '', + 'status' => 0, + ); + + if ($existing) { + // Mettre à jour l'enregistrement existant + $this->wpdb->update( + 'cdf_Credits_listing', + $listing_data, + array('id' => $existing->id), + array( + '%d', '%d', '%s', '%d', '%d', '%s', '%s', '%s', '%s', '%s', + '%s', '%d', '%d', '%s', '%s', '%s', '%s', '%f', '%s', '%s', '%s', '%s', '%s', '%d' + ) + ); + } else { + // Créer un nouvel enregistrement + $this->wpdb->insert( + 'cdf_Credits_listing', + $listing_data, + array( + '%d', '%d', '%s', '%d', '%d', '%s', '%s', '%s', '%s', '%s', + '%s', '%d', '%d', '%s', '%s', '%s', '%s', '%f', '%s', '%s', '%s', '%s', '%s', '%d' + ) + ); + } + } +} \ No newline at end of file diff --git a/app/models/credit_step2.php b/app/models/credit_step2.php new file mode 100644 index 0000000..665e5d9 --- /dev/null +++ b/app/models/credit_step2.php @@ -0,0 +1,239 @@ + false, + 'errors' => ['email' => 'Adresse email invalide'], + 'formatted_errors' => 'Adresse email invalide' + ]; + } + + // Validation des données seulement si demandé + if ($validate) { + $validator = new FormValidator($data); + $errors = $validator->validateStep2($data); + + if (!empty($errors)) { + // Retourner les erreurs pour affichage + return [ + 'success' => false, + 'errors' => $errors, + 'formatted_errors' => $validator->getFormattedErrors() + ]; + } + } + + $currentCredit = $this->getCredit($data['credit-direct-token']); + + $id_credit = $currentCredit->idCredit; + + if (!is_object($currentCredit)) { + return false; + } + + $borrower = $this->getBorrower($currentCredit); + $borrowerTableName = 'cdf_Emprunteur'; + $borrowerData = [ + 'nom' => $data['lastname'], + 'prenom' => $data['firstname'], + 'telephone' => $data['phone'], + 'email' => $data['email'], + 'pays' => $data['country'], + 'code_postal' => $data['zip'], + 'FK_demande_creditdirect' => $currentCredit->idCredit + ]; + + /* $borrowerData = [ + 'nom' => $data['lastname'], + 'prenom' => $data['firstname'], + 'telephone' => $data['phone'], + 'email' => $data['email'], + 'FK_agence' => $data['agency'], + 'FK_demande_creditdirect' => $currentCredit->idCredit + ]; */ + + if (is_object($borrower)) { + $this->wpdb->update($borrowerTableName, $borrowerData, [ + 'idemprunteur' => $borrower->idemprunteur + ]); + } else { + $this->wpdb->insert($borrowerTableName, $borrowerData); + } + + if(!empty($data['comment'])) { + $this->wpdb->update( + 'cdf_Credit', + array('commentaire' => $data['comment']), + array('idCredit' => $currentCredit->idCredit) + ); + } + + if (in_array($currentCredit->type_credit, $this->creditAutos)) { + $optionsTableName = 'cdf_Options_credit_auto'; + + + $optionsData = [ + 'marque' => $data['marque'], + 'date_immatriculation' => $data['vehicleregistrationdate'], + 'nom_vendeur' => $data['sellername'], + 'date_immatriculation' => !empty($data['vehicleregistrationdate']) ? (DateTime::createFromFormat('d/m/Y', $data['vehicleregistrationdate']) ? DateTime::createFromFormat('d/m/Y', $data['vehicleregistrationdate'])->format('Y-m-d') : $data['vehicleregistrationdate']) : null, + 'adresse_vendeur' => $data['selleraddress'], + 'prix_vehicule' => $data['vehicleprice'], + 'montant_accompte' => $data['vehicule_accompte'], + 'montant_reprise' => $data['vehicule_reprise'], + 'montant_emprunt' => $data['vehicule_emprunt'], + 'duree' => $data['vehicule_duree'] + ]; + + + if (!is_null($currentCredit->FK_credit_auto)) { + $this->wpdb->update($optionsTableName, $optionsData, [ + 'idOptions_credit_auto' => $currentCredit->FK_credit_auto + ]); + } else { + $this->wpdb->insert($optionsTableName, $optionsData); + + $optionId = $this->wpdb->insert_id; + + $this->wpdb->update( + 'cdf_Credit', + array('FK_credit_auto' => $optionId), + array('idCredit' => $currentCredit->idCredit) + ); + } + } + + if (in_array($currentCredit->type_credit, $this->one_step_credit_types)) { + $optionsTableName = 'cdf_Options_credit_hypotecaire'; + $optionsData = [ + 'type_credit' => $data['estateloantype'], + 'prix_achat' => $data['estatebuyingprice'], + 'prix_construction_tvac' => $data['prix_achat_tvac'], + 'valeur_batiment' => $data['valeur_batiment'], + 'fonds_propre' => $data['estateequity'], + 'compromis_signe' => $data['estatecompromise'], + 'montant_revenu_cadastral' => $data['estatcadastralincome'], + 'montant_a_emprunter' => $data['batiment_emprunt'], + 'duree' => $data['batiment_duree'] + ]; + + if (!is_null($currentCredit->FK_credit_hypothecaire)) { + $this->wpdb->insert($optionsTableName, $optionsData, [ + 'FK_credit_hypothecaire' => $currentCredit->FK_credit_hypothecaire + ]); + } else { + $this->wpdb->insert($optionsTableName, $optionsData); + + $optionId = $this->wpdb->insert_id; + + $this->wpdb->update( + 'cdf_Credit', + array('FK_credit_hypothecaire' => $optionId), + array('idCredit' => $currentCredit->idCredit) + ); + } + } + + /** + * Re-get the current credit to hydrate it + */ + $currentCredit = $this->getCredit($data['credit-direct-token']); + + /** + * Send mail + */ + if ($currentCredit->last_step < 2) { + $agencies = $this->getAgencies(); + $borrower = $this->getBorrower($currentCredit); + $map_credit_type = $this->getCreditTypes(); + $mapHouseCreditTypes = $this->getHouseCreditTypes(); + + // S'assurer que le type de crédit est défini + if (!isset($currentCredit->type_credit) || !array_key_exists($currentCredit->type_credit, $map_credit_type)) { + error_log('Type de crédit inconnu: ' . $currentCredit->type_credit); + } + + $is_credit_auto = $this->is_credit_auto($currentCredit); + $is_one_step_credit = in_array($currentCredit->type_credit, $this->one_step_credit_types); + + + //update the credit id in the cdf_Credit with comment data + + if(!empty($data['comment'])) { + $this->wpdb->update( + 'cdf_Credit', + array('commentaire' => $data['comment']), + array('idCredit' => $id_credit) + ); + } + + ob_start(); + include(_CRED_BASE_PATH_ . '/templates/email/credit-step2-mail.php'); + $message = ob_get_clean(); + + + ob_start(); + include(_CRED_BASE_PATH_ . '/templates/email/clients_emails/credit-step2-mail-client.php'); + $message_client = ob_get_clean(); + + $this->mailchimpSynchro($currentCredit, $borrower); + + + if(!isset($data['isback']) || $data['isback'] != '1') { + if(isset($data['type_credit_selected']) && !empty($data['type_credit_selected']) || isset($data['sub_loan_type']) && !empty($data['sub_loan_type'])) + $type_credit_selected = isset($data['sub_loan_type']) ? $data['sub_loan_type'] : $data['type_credit_selected']; + + + $creditOptionsLabels = !empty($type_credit_selected) ? $this->getCreditLabel($type_credit_selected) : $map_credit_type[$currentCredit->type_credit]; + + // Exception : ne pas envoyer de mail si l'utilisateur connecté a l'ID 1 + if (!is_user_logged_in() || get_current_user_id() != 1) { + // Envoyer l'email uniquement à l'administrateur (to_client = false) + $this->sendEmail('Demande de crédit', $message, $borrower, $currentCredit, [], false); + + // Envoyer l'email à l'emprunteur (to_client = true) + $this->sendEmail('Demande de crédit', $message_client, $borrower, $currentCredit, [], true); + } + } + } + + /** + * Update Credit info + */ + $updateInfos = [ + 'last_update_date' => (new \DateTime())->format('Y-m-d H:i:s'), + ]; + + if (intval($currentCredit->last_step) === 1) { + $updateInfos['last_step'] = '2'; + } + + $this->wpdb->update( + 'cdf_Credit', + $updateInfos, + array('idCredit' => $currentCredit->idCredit) + ); + + $this->wpdb->suppress_errors = false; + + return true; + } +} \ No newline at end of file diff --git a/app/models/credit_step3.php b/app/models/credit_step3.php new file mode 100644 index 0000000..d67d4e3 --- /dev/null +++ b/app/models/credit_step3.php @@ -0,0 +1,105 @@ +validateStep3($data); + + if (!empty($errors)) { + // Retourner les erreurs pour affichage + return [ + 'success' => false, + 'errors' => $errors, + 'formatted_errors' => $validator->getFormattedErrors() + ]; + } + + $this->currentCredit = $currentCredit; + + foreach ($data as $k => $d) { + if ($d === '') { + $data[$k] = null; + } + } + + $curreentUser = wp_get_current_user(); + + if($curreentUser->ID == 1) { + + echo '
    ';
    +            echo 'data';
    +            print_r($data);
    +            echo '
    '; + + } + + $this->update_emprunteur($data, $currentCredit); + $this->save_autre_credit_emprunteur($data,$currentCredit); + + // Vérifier si hascoborrower est présent dans les données + // Note: pour les radio buttons, si aucun n'est coché, la clé peut être absente + // On vérifie aussi s'il y a des données de co-emprunteur pour détecter sa présence + $hasCoBorrowerInData = array_key_exists('hascoborrower', $data) && ($data['hascoborrower'] === '1' || $data['hascoborrower'] === 1); + $hasCoBorrowerFields = !empty($data['cofirstname']) || !empty($data['colastname']) || !empty($data['coemail']) || !empty($data['cophone']); + + // Si hascoborrower est à '1' OU si des champs co-emprunteur sont présents, traiter le co-emprunteur + if ($hasCoBorrowerInData || $hasCoBorrowerFields) { + // Vérifier si le co-emprunteur existe déjà + $coBorrower = $this->getCoBorrower($currentCredit); + if (is_object($coBorrower)) { + // Le co-emprunteur existe, on le met à jour + $this->update_co_emprunteur($data, $currentCredit); + } else { + // Le co-emprunteur n'existe pas, on le crée seulement si hascoborrower === '1' + // (pour éviter de créer un co-emprunteur par erreur) + if ($hasCoBorrowerInData) { + // Vérifier que le borrower existe avant d'insérer le co-emprunteur + $borrower = $this->getBorrower($currentCredit); + if (is_object($borrower)) { + $insertId = $this->insert_co_emprunteur($data, $currentCredit); + // Vérifier si l'insertion a réussi + if ($insertId === false || $insertId === 0) { + error_log('Erreur lors de l\'insertion du co-emprunteur pour le crédit ID: ' . $currentCredit->idCredit); + error_log('Dernière erreur DB: ' . $this->wpdb->last_error); + error_log('Dernière requête: ' . $this->wpdb->last_query); + } else { + // L'insertion a réussi, recharger le crédit pour que getCoBorrower trouve le nouveau co-emprunteur + $currentCredit = $this->getCredit($currentCredit->token); + } + } else { + error_log('Impossible de créer le co-emprunteur : borrower non trouvé pour le crédit ID: ' . $currentCredit->idCredit); + } + } + } + // Sauvegarder les autres crédits du co-emprunteur seulement si hascoborrower === '1' + if ($hasCoBorrowerInData) { + $this->save_autre_credit_co_emprunteur($data,$currentCredit); + } + } + + $this->wpdb->update( + 'cdf_Credit', + array( + 'last_update_date' => (new \DateTime())->format('Y-m-d H:i:s'), + 'last_step' => '3' + ), + array('idCredit' => $this->currentCredit->idCredit) + ); + } +} \ No newline at end of file diff --git a/app/models/credit_step4.php b/app/models/credit_step4.php new file mode 100644 index 0000000..a4f0a13 --- /dev/null +++ b/app/models/credit_step4.php @@ -0,0 +1,49 @@ +currentCredit = $currentCredit; + + $this->save_autre_credit_emprunteur($data,$currentCredit); + + $this->update_emprunteur($data,$currentCredit); + + $curreentUser = wp_get_current_user(); + + if($curreentUser->ID == 1) { + + echo '
    ';
    +            echo 'data';
    +            print_r($data);
    +            echo '
    '; + + } + + // Vérifier si le co-emprunteur existe et mettre à jour ses données + $coBorrower = $this->getCoBorrower($currentCredit); + if (is_object($coBorrower)) { + // Mettre à jour les données du co-emprunteur + $this->update_co_emprunteur($data, $currentCredit); + + // Sauvegarder les autres crédits du co-emprunteur si nécessaire + if (array_key_exists('cohometype', $data)) { + $this->save_autre_credit_co_emprunteur($data,$currentCredit); + } + } + + $this->wpdb->update( + 'cdf_Credit', + array( + 'last_update_date' => (new \DateTime())->format('Y-m-d H:i:s'), + 'last_step' => '4', + 'token' => $this->currentCredit->token + ), + array('idCredit' => $this->currentCredit->idCredit) + ); + } +} \ No newline at end of file diff --git a/app/models/credit_step5.php b/app/models/credit_step5.php new file mode 100644 index 0000000..63821b4 --- /dev/null +++ b/app/models/credit_step5.php @@ -0,0 +1,95 @@ +currentCredit = $currentCredit; + + // Sauvegarder les données de l'étape 4 + $this->save_emprunteur_address($data, $currentCredit); + + if (array_key_exists('cohometype', $data)) { + $this->save_co_emprunteur_address($data, $currentCredit); + } + + $this->wpdb->update( + 'cdf_Credit', + array( + 'last_update_date' => (new \DateTime())->format('Y-m-d H:i:s'), + 'last_step' => '5', + 'token' => null + ), + array('idCredit' => $this->currentCredit->idCredit) + ); + + //save into cdf_Credits_listing + $this->save_to_credits_listing($currentCredit); + + return $this->wpdb->insert_id; + } + + // Méthode pour sauvegarder l'adresse de l'emprunteur + private function save_emprunteur_address($data, $currentCredit) { + $borrower = $this->getBorrower($currentCredit); + + /* echo '
    ';
    +        print_r($borrower);
    +        print_r($data);
    +        echo '
    '; + die(); */ + + $datas_update = array( + 'adresse' => $data['address'], + 'code_postal' => $data['zip'], + 'localite' => $data['city'], + 'pays' => $data['country'], + 'date_emmenagement' => $data['movingdate'], + 'nom_employeur' => $data['emname'], + 'adresse_employeur' => $data['emaddress'], + 'code_postal_employeur' => $data['emzip'], + 'localite_employeur' => $data['emcity'], + 'date_engagement' => $data['commitmentdate'] + ); + + /* echo '
    ';
    +        print_r($datas_update);
    +        echo '
    '; + die(); */ + + if ($borrower) { + $this->wpdb->update( + 'cdf_Emprunteur', + $datas_update, + array('idemprunteur' => $borrower->idemprunteur) + ); + } + } + + // Méthode pour sauvegarder l'adresse du co-emprunteur + private function save_co_emprunteur_address($data, $currentCredit) { + $coBorrower = $this->getCoBorrower($currentCredit); + + if ($coBorrower) { + $this->wpdb->update( + 'cdf_Emprunteur', + array( + 'adresse' => $data['coaddress'], + 'code_postal' => $data['cozip'], + 'localite' => $data['cocity'], + 'pays' => $data['cocountry'], + 'date_emmenagement' => $data['comovingdate'], + 'nom_employeur' => $data['coemname'], + 'adresse_employeur' => $data['coemaddress'], + 'code_postal_employeur' => $data['coemzip'], + 'localite_employeur' => $data['coemcity'], + 'date_engagement' => $data['cocommitmentdate'] + ), + array('idemprunteur' => $coBorrower->idemprunteur) + ); + } + } +} \ No newline at end of file diff --git a/app/models/old/credit-step1.php b/app/models/old/credit-step1.php new file mode 100644 index 0000000..089b1ad --- /dev/null +++ b/app/models/old/credit-step1.php @@ -0,0 +1,331 @@ +wpdb->insert('cdf_Credit', array( + 'type_credit' => $data['loan_type'], + 'sel_credit' => $data['sub_loan_type'], + 'capital' => $data['selected_capital'], + 'duree' => $data['selected_months'], + 'cout_total' => $data['hidden_cout_total_value'], + 'mensualite' => $data['hidden_montant_total_value'], + 'taux_nominal_annuel' => $data['hidden_taeg_value'], + 'rgpd' => 'oui', + 'create_date' => (new \DateTime())->format('Y-m-d H:i:s') + )); + + $current_credit_id = $this->wpdb->insert_id; + $token = $this->generateToken($current_credit_id); + + $currentCredit = $this->getCredit($token); + + /* if($currentCredit->type_credit != 'pat') + return $token; + else + $this->save_step_1_pat($data); */ + + return $token; + + } catch (\Exception $e) { + die($e->getMessage()); + } + } + + public function save_step_1_all($data) { + + if(isset($data['email']) && strpos($data['email'], '@example.com') !== false) { + return false; // Rejeter la demande si l'adresse email contient @example.com + } + + $currentCredit = $this->getCredit($data['credit-direct-token']); + + if (!is_object($currentCredit)) { + return false; + } + + $borrower = $this->getBorrower($currentCredit); + $borrowerTableName = 'cdf_Emprunteur'; + $borrowerData = [ + 'nom' => $data['lastname'], + 'prenom' => $data['firstname'], + 'telephone' => $data['phone'], + 'email' => $data['email'], + 'FK_agence' => $data['agency'], + 'FK_demande_creditdirect' => $currentCredit->idCredit + ]; + + if (is_object($borrower)) { + $this->wpdb->update($borrowerTableName, $borrowerData, [ + 'idemprunteur' => $borrower->idemprunteur + ]); + } else { + $this->wpdb->insert($borrowerTableName, $borrowerData); + } + + /** + * Re-get the current credit to hydrate it + */ + $currentCredit = $this->getCredit($data['credit-direct-token']); + + $this->update_emprunteur($data, $currentCredit); + $this->save_autre_credit_emprunteur($data, $currentCredit); + + if (array_key_exists('hascoborrower', $data) && $data['hascoborrower'] === '1') { + $this->insert_co_emprunteur($data, $currentCredit); + $this->save_autre_credit_co_emprunteur($data, $currentCredit); + } + + $this->wpdb->update( + 'cdf_Credit', + array( + 'last_update_date' => (new \DateTime())->format('Y-m-d H:i:s'), + 'last_step' => '4' + ), + array('idCredit' => $this->currentCredit->idCredit) + ); + + } + + public function save_one_step($data) { + + $email_demande = $data['email']; + + if(strpos($email_demande, '@example.com') !== false) { + return false; // Rejeter la demande si l'adresse email contient @example.com + } + + $currentCredit = $this->getCredit($data['credit-direct-token']); + + $included_hypo_credits = ['am','amr','cied','frais_notaire','cdp']; + + if (!is_object($currentCredit)) { + return false; + } + + /* if($this->is_webdev_user()) { + echo '
    ';
    +            print_r($data);
    +            echo '
    '; + die(); + } */ + /* echo '
    ';
    +        print_r($data);
    +        echo '
    '; + die(); */ + + $ddn = null; + if (!empty($data['birthdate'])) { + $ddn = \DateTime::createFromFormat('d/m/Y', $data['birthdate']); + if ($ddn) { + $ddn = $ddn->format('Y-m-d'); + } + } + + // print_r($ddn); + + $independent_since = \DateTime::createFromFormat('d/m/Y', $data['independent_since']); + + if($independent_since) { + $independent_since = $independent_since->format('Y-m-d'); + } else { + $independent_since = ''; + } + + $borrower = $this->getBorrower($currentCredit); + $borrowerTableName = 'cdf_Emprunteur'; + $borrowerData = [ + 'nom' => $data['lastname'], + 'prenom' => $data['firstname'], + 'telephone' => $data['phone'], + 'email' => $data['email'], + 'date_naissance' => $ddn ?: '', + 'nationalité' => $data['nationality'], + 'adresse' => $data['address'], + 'code_postal' => $data['zip'], + 'localite' => $data['city'], + 'pays' => $data['country'], + 'contract_type' => $data['contract_type'], + 'independent_since' => $independent_since, + 'FK_profession' => $data['job'], + 'FK_etat_civil' => $data['civilstatus'], + 'salaire' => $data['salary'], + 'annual_taxable_income' => isset($data['annual_taxable_income']) ? $data['annual_taxable_income'] : null, + 'FK_demande_creditdirect' => $currentCredit->idCredit, + ]; + + /* if($this->is_webdev_user()) { + echo '
    ';
    +            print_r($borrowerData);
    +            echo '
    '; + die(); + } */ + + if (is_object($borrower)) { + $this->wpdb->update($borrowerTableName, $borrowerData, [ + 'idemprunteur' => $borrower->idemprunteur + ]); + } else { + $this->wpdb->insert($borrowerTableName, $borrowerData); + } + + if(!empty($data['comment'])) { + $this->wpdb->update( + 'cdf_Credit', + array('commentaire' => $data['comment']), + array('idCredit' => $currentCredit->idCredit) + ); + } + + if (array_key_exists('hascoborrower', $data) && $data['hascoborrower'] === '1') { + $this->insert_co_emprunteur_one_step($data); + } + + if (in_array($currentCredit->type_credit, $included_hypo_credits)) { + $this->save_FK_credit_hypothecaire($currentCredit,$data); + } + + if ( + $currentCredit->type_credit == 'fin_neuve' + || $currentCredit->type_credit == 'fin_occ_m3a' + || $currentCredit->type_credit == 'fin_occ_p3a' + ) { + $this->save_FK_credit_auto($currentCredit,$data); + } + + $this->save_to_credits_listing($currentCredit); + + } + + public function insert_co_emprunteur_one_step($data) { + + $currentCredit = $this->getCredit($data['credit-direct-token']); + + $borrower = $this->getBorrower($currentCredit); + + $this->wpdb->insert('cdf_Emprunteur',array( + 'nom' => $data['colastname'], + 'prenom' => $data['cofirstname'], + 'date_naissance' => $data['cobirthdate'], + 'nationalité' => $data['conationality'], + 'adresse' => $data['coaddress'], + 'code_postal' => $data['cozip'], + 'localite' => $data['cocity'], + 'pays' => $data['cocountry'], + 'contract_type' => $data['cocontract_type'], + 'independent_since' => isset($data['coindependent_since']) ? $data['coindependent_since'] : null, + 'salaire' => $data['cosalary'], + 'annual_taxable_income' => isset($data['coannual_taxable_income']) ? $data['coannual_taxable_income'] : null, + 'parent_emprunteur' => $borrower->idemprunteur, + 'FK_demande_creditdirect' => $currentCredit->idCredit, + 'FK_etat_civil' => $data['cocivilstatus'], + 'FK_profession' => $data['cojob'] + )); + } + + public function save_FK_credit_hypothecaire($currentCredit,$data) { + + $included_hypo_credits = ['am','amr','cied','frais_notaire','cdp']; + + if (in_array($currentCredit->type_credit, $included_hypo_credits)) { + $optionsTableName = 'cdf_Options_credit_hypotecaire'; + $optionsData = [ + 'type_credit' => $data['estateloantype'], + 'prix_achat' => $data['estatebuyingprice'], + 'fonds_propre' => $data['estateequity'], + 'compromis_signe' => $data['estatecompromise'], + 'montant_a_emprunter' => $data['batiment_emprunt'], + 'duree' => $data['batiment_duree'], + ]; + + /** + * job,contract_type,salary + */ + + if (!is_null($currentCredit->FK_credit_hypothecaire)) { + $this->wpdb->insert($optionsTableName, $optionsData, [ + 'FK_credit_hypothecaire' => $currentCredit->FK_credit_hypothecaire + ]); + } else { + $this->wpdb->insert($optionsTableName, $optionsData); + + $optionId = $this->wpdb->insert_id; + + $this->wpdb->update( + 'cdf_Credit', + array('FK_credit_hypothecaire' => $optionId), + array('idCredit' => $currentCredit->idCredit) + ); + } + + $currentCredit = $this->getCredit($data['credit-direct-token']); + + /* echo '
    ';
    +            print_r($currentCredit);
    +            echo '
    '; + die(); */ + } + + return $currentCredit; + } + + public function save_FK_credit_auto($currentCredit,$data) { + + if ( + $currentCredit->type_credit == 'fin_neuve' + || $currentCredit->type_credit == 'fin_occ_m3a' + || $currentCredit->type_credit == 'fin_occ_p3a' + ) { + + $optionsTableName = 'cdf_Options_credit_auto'; + $optionsData = [ + 'marque' => $data['marque'], + 'date_immatriculation' => $data['vehicleregistrationdate'], + 'nom_vendeur' => $data['sellername'], + 'adresse_vendeur' => $data['selleraddress'], + 'prix_vehicule' => $data['vehicleprice'], + 'montant_accompte' => $data['vehicule_accompte'], + 'montant_reprise' => $data['vehicule_reprise'], + 'montant_emprunt' => $data['vehicule_emprunt'], + 'duree' => $data['vehicule_duree'] + ]; + + if (!is_null($currentCredit->FK_credit_auto)) { + $this->wpdb->update($optionsTableName, $optionsData, [ + 'idOptions_credit_auto' => $currentCredit->FK_credit_auto + ]); + } else { + $this->wpdb->insert($optionsTableName, $optionsData); + + $optionId = $this->wpdb->insert_id; + + $this->wpdb->update( + 'cdf_Credit', + array('FK_credit_auto' => $optionId), + array('idCredit' => $currentCredit->idCredit) + ); + } + + /* $currentCredit = $this->getCredit($data['credit-direct-token']); */ + } + + /* return $currentCredit; */ + } +} \ No newline at end of file diff --git a/app/models/old/credit.php b/app/models/old/credit.php new file mode 100644 index 0000000..e3192eb --- /dev/null +++ b/app/models/old/credit.php @@ -0,0 +1,2275 @@ + 'Contrat de travail à durée indéterminée (CDI)', + 'cdd' => 'Contrat de travail à durée déterminée (CDD)', + 'fon' => 'Nommé', + 'int' => 'Intérimaire', + 'oth' => 'Autre', + 'ssc' => 'Sans contrat de travail' + ]; + + protected $creditTypes = [ + 'pat' => 'Prêt personnel / Tous motifs / Achats divers', + 'frais_notaire' => 'Financement frais de notaire', + 'but_immo' => 'Crédit travaux / Rénovation / Energie', + 'fin_neuve' => 'Financement véhicule NEUF', + 'fin_occ_m3a' => 'Financement véhicule d\'occasion MOINS de 3 ans', + 'fin_occ_p3a' => 'Financement véhicule d\'occasion PLUS de 3 ans', + 'mobil_carav' => 'Financement Mobil-home et caravane', + 'reno_energie' => 'Rénovation énergétique', + 'regrouping' => 'Regroupement de crédit / Rachat de crédit', + 'regroup_cred' => 'Regroupement de crédit / Rachat de crédit' + ]; + + protected $creditTypesLabels = [ + 'pat' => 'Prêt à temprérament', + 'frais_notaire' => 'Financement frais de notaire', + 'but_immo' => 'Crédit travaux', + 'fin_neuve' => 'Financement véhicule NEUF', + 'fin_occ_m3a' => 'Financement véhicule d\'occasion MOINS de 3 ans', + 'fin_occ_p3a' => 'Financement véhicule d\'occasion PLUS de 3 ans', + 'am' => 'Crédit hypothécaire', + 'cied' => 'Indépendant et entreprise en difficulté' + ]; + + public $one_step_credit_types = [ + 'am','amr','cied','ph','frais_notaire','cdp' + ]; + + public $creditAutos = [ + 'fin_neuve', + 'fin_occ_m3a', + 'fin_occ_p3a', + 'mobil_carav' + ]; + + public $type_habitat = [ + 'proprietaire' => 'Propriétaire avec prêt hypothécaire', + 'proprietaire_sans_pret' => 'Propriétaire sans prêt hypothécaire', + 'locataire' => 'Locataire', + 'cohabitant' => 'Cohabitant' + ]; + + + /* protected $houseCreditTypes = [ + 'purchasehouse' => 'Achat bien immobilier', + 'construction' => 'Nouvelle construction', + 'purchaseabroad' => 'Achat d\'une 2éme résidence (à l\'étranger, en belgique)', + 'refinancing' => 'Prêt Hypothécaire (Refinancement)', + 'regrouping' => 'Prêt Hypothécaire (Regroupement)', + 'balance' => 'Soulte / Rachat de parts indivisées', + 'other'=> 'Autre' + ]; */ + + protected $houseCreditTypes = [ + 'purchasehouse' => 'Achat bien immobilier', + 'construction' => 'Nouvelle construction', + 'regrouping_immo' => 'Regroupement de crédits', + 'refinancing' => 'Refinancement crédit(s) hypothécaire(s)', + 'purchaseabroad' => 'Achat d\'une 2éme résidence (à l\'étranger, en belgique)', + 'but_immo_hypo' => 'Travaux de rénovation', + 'achat_maison_de_rapport' => 'Achat maison de rapport', + 'credit_pont' => 'Crédit pont', + 'independants_et_entreprises_en_difficultes' => 'Indépendants et entreprises en difficultés', + 'regroupement_de_credit__rachats_de_credits' => 'Rachats de crédits', + 'financement_frais_de_notaire' => 'Financement frais de notaire', + 'fonds_roulement_independants' => 'Fonds de roulement' + ]; + + protected $wpdb; + + private $isDevMode; + + private $synchroUrl; + + private $synchroClientId; + + public $main; + + /** + * Constructor + */ + public function __construct() + { + global $wpdb; + + $this->wpdb = $wpdb; + + $this->main = $this->getMain(); + + //instance de la classe + self::$instance = $this; + + /* $this->isDevMode = + strpos($_SERVER['HTTP_HOST'], 'localhost') !== false + || strpos($_SERVER['HTTP_HOST'], 'eteamsys') !== false + ; + + $this->synchroUrl = $this->isDevMode ? + 'https://staging-wshubspot.eteamsys.com/' + : 'https://prod-wshubspot.eteamsys.com/' + ; + + $this->synchroClientId = $this->isDevMode ? + 'JuIXU6EK37giPF3smU71IMBWiNHP9wlkW9TdUZwoY0u175DH11XixOQDSNi4Qmmi' + : 'RfQyevXwW0nZvoXwifnZu4VgKeGPhmlmGZsXjj0s6Aruy5qxCVOiho0Sdpw38Tcp' + ; */ + } + + /** + * @param $token + * @return object|null + */ + public function getCredit($token) { + + if (!is_string($token)) + return null; + + $currentCredit = $this->wpdb->get_row($this->wpdb->prepare("SELECT * FROM cdf_Credit WHERE token LIKE '%s'", $token)); + + if (is_object($currentCredit)) { + + if (!is_null($currentCredit->FK_credit_auto)) { + $currentCredit->options_credit_auto = $this->wpdb->get_row( + $this->wpdb->prepare( + "SELECT * FROM cdf_Options_credit_auto WHERE idOptions_credit_auto = %d", + $currentCredit->FK_credit_auto + ) + ); + } + + if (!is_null($currentCredit->FK_credit_hypothecaire)) { + $currentCredit->options_credit_hypothecaire = $this->wpdb->get_row( + $this->wpdb->prepare( + "SELECT * FROM cdf_Options_credit_hypotecaire WHERE idOptions_credit_hypotecaire = %d", + $currentCredit->FK_credit_hypothecaire + ) + ); + } + } + + return $currentCredit; + + } + + /** + * @return array + */ + public function getAgencies() { + $allAgencies = []; + + $args = array( + 'post_type' => 'agences', + 'post_status' => 'publish', + 'numberposts' => -1 + ); + + $agencies = get_posts($args); + + foreach($agencies as $agency) { + + $objAgency = new stdClass(); + + $objAgency->idAgences = $agency->ID; + + $objAgency->label = get_field('libele_champ',$agency->ID); + + $objAgency->Nom_agence = get_field('libele_champ',$agency->ID); + + $objAgency->description_agence = ''; + + + $objAgency->emails = get_field('listing_email',$agency->ID); + + $allAgencies[$agency->ID] = $objAgency; + + } + + return $allAgencies; + } + + /** + * @return array + */ + public function getCivilStatus() { + $allCivilStatus = []; + $civilStatus = $this->wpdb->get_results("SELECT * FROM cdf_Etat_civil"); + + foreach ($civilStatus as $etat_civil) { + $allCivilStatus[$etat_civil->idetat_civil] = $etat_civil; + } + + return $allCivilStatus; + } + + public function getCreditLabel($credit_selected) + { + if(isset($this->creditTypes[$credit_selected])){ + return $this->creditTypes[$credit_selected]; + } + + if(isset($this->houseCreditTypes[$credit_selected])){ + return $this->houseCreditTypes[$credit_selected]; + } + + return false; + } + + /** + * @return string[] + */ + public function getContractTypes() + { + return $this->contractTypes; + } + + /** + * @return string[] + */ + public function getCreditTypes() + { + return $this->creditTypes; + } + + /** + * @return string[] + */ + public function getCreditOptionsLabels($option_name) + { + if (!function_exists('get_field_object')) { + return false; + } + + $field = get_field_object($option_name, 'option'); + $field_inarray = ''; + + if (!$field) { + + if(isset($this->creditTypesLabels[$option_name])){ + return $this->creditTypesLabels[$option_name]; + } + + if(isset($this->houseCreditTypes[$option_name])){ + return $this->houseCreditTypes[$option_name]; + } + + return false; + } + + + if ($field && isset($field['type']) && $field['type'] === 'group' && isset($field['label'])) { + return $field['label']; + } + + return false; + } + + /** + * @return string[] + */ + public function getHouseCreditTypes() + { + return $this->houseCreditTypes; + } + + /** + * @return array + */ + public function getWorks() + { + $allWorks = []; + $works = $this->wpdb->get_results("SELECT * FROM cdf_Profession"); + + foreach ($works as $work) { + $allWorks[$work->idprofession] = $work; + } + + return $allWorks; + } + + /** + * @return array + */ + public function getExistingCreditTypes() + { + $allCreditTypes = []; + $creditTypes = $this->wpdb->get_results("SELECT * FROM cdf_Type_creance"); + + foreach ($creditTypes as $creditType) { + $allCreditTypes[$creditType->idtype_creance] = $creditType; + } + + return $allCreditTypes; + } + + /** + * @param $currentCredit + * @return array|object|void|null + */ + public function getBorrower($currentCredit) { + + $borrower = $this->wpdb->get_row( + $this->wpdb->prepare( + "SELECT * FROM cdf_Emprunteur WHERE FK_demande_creditdirect = %d", + $currentCredit->idCredit + ) + ); + + if (is_object($borrower)) { + /** + * Other credits + */ + $other_credits = $this->wpdb->get_results( + $this->wpdb->prepare( + "SELECT * FROM cdf_Autre_credit WHERE FK_emprunteur = %d", + $borrower->idemprunteur + ) + ); + + foreach($other_credits as $other_credit) { + + $FK_type_creance = $other_credit->FK_type_creance; + $type_creance = $this->wpdb->get_row( + $this->wpdb->prepare( + "SELECT * FROM cdf_Type_creance WHERE idtype_creance = %d", + $FK_type_creance + ) + ); + $other_credit->type_creance = $type_creance->nom_creance; + + $borrower->other_credits[] = $other_credit; + } + + + if (!is_null($borrower->FK_agence)) { + + $agency_id = $borrower->FK_agence; + + $agency = get_post($agency_id); + + $emails_data = get_field('listing_email',$agency_id); + + $emails = []; + + + foreach($emails_data as $email) { + /* $emails[]['email'] = $email['email']->name; + $emails[]['type_de_contact'] = $email['type_de_contact']; */ + + $emails[] = ['email' => $email['email']->name, 'type_de_contact' => $email['type_de_contact']]; + } + + $agency->emails = $emails; + + $borrower->agency = $agency; + + } + + /** + * Civil status + */ + if (!is_null($borrower->FK_etat_civil)) { + $borrower->etat_civil = $this->wpdb->get_results("SELECT * FROM cdf_Etat_civil WHERE idetat_civil = $borrower->FK_etat_civil"); + } + } + + return $borrower; + } + + /** + * @param $currentCredit + * @return array|object|void|null + */ + public function getCoBorrower($currentCredit) { + + $coBorrower = $this->wpdb->get_row( + $this->wpdb->prepare( + "SELECT * FROM cdf_Emprunteur WHERE FK_demande_creditdirect = %d AND parent_emprunteur IS NOT NULL", + $currentCredit->idCredit + ) + ); + + if (is_object($coBorrower)) { + $coBorrower->other_credits = $this->wpdb->get_results( + $this->wpdb->prepare( + "SELECT * FROM cdf_Autre_credit WHERE FK_emprunteur = %d", + $coBorrower->idemprunteur + ) + ); + + /** + * Civil status + */ + if (!is_null($coBorrower->FK_etat_civil)) { + $coBorrower->etat_civil = $this->wpdb->get_results("SELECT * FROM cdf_Etat_civil WHERE idetat_civil = $coBorrower->FK_etat_civil"); + } + } + + return $coBorrower; + } + + + /** + * @param $mailTitle + * @param $mailBody + * @param $borrower + * @return bool + */ + public function sendEmail($mailTitle, $mailBody, $borrower, $currentCredit, $attachments = [], $to_client = false) { + + /* $currentCredit = $this->getCredit($borrower->token); */ + + $credit_type = $currentCredit->type_credit; + + if(empty($credit_type)) { + $credit_type = 'credit'; + } + + $custom_from = 'demande-'.$credit_type.'@credit-direct.be'; + + $mailHeaders = [ + 'Content-Type: text/html; charset=UTF-8', + 'X-Mailer: PHP/' . phpversion(), + 'MIME-Version: 1.0', + 'From: Credit Direct <'.$custom_from.'>' + ]; + + $agencies = $this->getAgencies(); + + if (!empty($borrower->idemprunteur)) { + $to = []; + + $zipCode = $borrower->code_postal; + + if(!empty($zipCode)) { + $agency = $this->switchAgency_byZipCode($zipCode, $borrower); + } + + + /* echo 'prout'; */ + + foreach($agency['emails'] as $email) { + switch ($email['type_de_contact']) { + case 'to': + $to[] = $email['email']->name; + break; + case 'cc': + $mailHeaders[] = 'Cc: ' . $email['email']->name; + } + } + + + + /* $to[] = 'jps@esi-informatique.com'; */ + /* $to[] = 'testcreditdirect@yopmail.com'; */ + + if($to_client) { + $to = [$borrower->email]; + + $mailHeaders = [ + 'Content-Type: text/html; charset=UTF-8', + 'X-Mailer: PHP/' . phpversion(), + 'MIME-Version: 1.0', + 'From: Credit Direct ' + ]; + } + + if (!empty($to)) { + $mailBody = ' + + + + ' . $mailTitle . ' + + ' . $mailBody . ''; + + /* $attachments = []; */ + + /* foreach ($attachments as $file) { + if (file_exists($file)) { + @unlink($file); + } */ + + return wp_mail($to, $mailTitle, $mailBody, $mailHeaders, $attachments); + } + } + + return false; + } + + /** + * @param $datas + * @return void + */ + public function save_step($currentCredit) { + + /* $currentCredit = $this->getCredit($datas['credit-direct-token']); */ + + if(!is_object($currentCredit)) { + return false; + } + + $borrower = $this->getBorrower($currentCredit); + + if(!is_object($borrower)) { + return false; + } + + //save the current credit in a cookie for 2 months + $credit_data = [ + 'credit_token' => $currentCredit->token, + 'current_step' => $currentCredit->last_step, + 'type_credit_selected' => $currentCredit->sel_credit + ]; + setcookie('credit_data', json_encode($credit_data), time() + 5256000, '/'); + + } + + /** + * @param $creditId + * @return string + */ + + protected function generateToken($creditId) { + + $date = new \DateTime(); + $token = sha1($date->format('YmdHisu') . '-' . $creditId); + + $this->wpdb->update( + 'cdf_Credit', + ['token' => $token], + ['idCredit' => $creditId] + ); + + return $token; + } + + /** + * @param object $currentCredit + * @param object $borrower + * @return bool + */ + protected function mailchimpSynchro($currentCredit, $borrower) { + + global $post; + + $json = json_encode([ + 'form_id' => 'credit-application', + 'client_id' => $this->synchroClientId, + 'name' => $borrower->nom, + 'firstname' => $borrower->prenom, + 'mail' => $borrower->email, + 'recovery_url' => get_page_link($post) . '?token=' . $currentCredit->token, + 'last_action_date' => + !is_null($currentCredit->last_update_date) ? + $currentCredit->last_update_date : + $currentCredit->create_date + ]); + + $options = [ + CURLOPT_RETURNTRANSFER => true, + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_POST => true, + CURLOPT_ENCODING => '', + CURLOPT_SSL_VERIFYPEER => false, + CURLOPT_URL => $this->synchroUrl, + CURLOPT_HTTPHEADER => ['Content-Type: application/json', 'Content-Length: ' . strlen($json)], + CURLOPT_POSTFIELDS => $json + ]; + + $curl = curl_init(); + curl_setopt_array($curl, $options); + $response = curl_exec($curl); + curl_close($curl); + + return true; + } + + /** + * Mapping centralisé des champs formulaire vers la base de données pour l'emprunteur principal + */ + protected $borrowerFieldMap = [ + 'email' => 'email', + 'lastname' => 'nom', + 'firstname' => 'prenom', + 'phone' => 'telephone', + 'country' => 'pays', + 'num_registre_national' => 'num_registre_national', + 'birthdate' => 'date_naissance', + 'birthplace' => 'lieu_naissance', + 'nationality' => 'nationalité', + 'cardnumber' => 'num_carte_identite', + 'cnvaliditydate' => 'carte_identite_validite', + 'nationalregistrationnumber' => 'num_registre_national', + 'bankaccountnumber' => 'num_compte_bancaire', + 'address' => 'adresse', + 'zip' => 'code_postal', + 'city' => 'localite', + 'country' => 'pays', + 'movingdate' => 'date_emmenagement', + 'dependentchildren' => 'enfant_charge', + 'montant_allocation_familiale' => 'montant_allocation_familiale', + 'codependentchildren' => 'enfant_charge', + 'comontant_allocation_familiale' => 'montant_allocation_familiale', + // Mappings pour les champs co-emprunteur + 'cobirthdate' => 'date_naissance', + 'cobirthplace' => 'lieu_naissance', + 'conationality' => 'nationalité', + 'cocardnumber' => 'num_carte_identite', + 'cocnvaliditydate' => 'carte_identite_validite', + 'conationalregistrationnumber' => 'num_registre_national', + 'cobankaccountnumber' => 'num_compte_bancaire', + 'coaddress' => 'adresse', + 'cozip' => 'code_postal', + 'cocity' => 'localite', + 'cocountry' => 'pays', + 'cocontract_type' => 'contract_type', + 'coindependent_since' => 'independent_since', + 'contract_type' => 'contract_type', + 'independent_since' => 'independent_since', + 'emname' => 'nom_employeur', + 'emnumber' => 'numero_entreprise', + 'emaddress' => 'adresse_employeur', + 'emzip' => 'code_postal_employeur', + 'emcity' => 'localite_employeur', + 'emcountry' => 'pays_employeur', + 'commitmentdate' => 'date_engagement', + 'salary' => 'salaire', + 'annual_taxable_income' => 'annual_taxable_income', + 'oiamouthmealvoucher' => 'cheque_repas', + 'oiamouthrentalincome' => 'revenus_locatifs', + 'oiamouthunemployment' => 'chomage', + 'oiothertext' => 'autre_revenu_type', + 'oiamouthother' => 'autre_revenu_montant', + 'civilstatus' => 'FK_etat_civil', + 'job' => 'FK_profession', + 'habitation_type' => 'habitation_type', + 'habitation_loyer' => 'habitation_loyer', + 'autre_revenu_type' => 'autre_revenu_type', + 'autre_revenu_montant' => 'autre_revenu_montant', + 'fichage_status' => 'fichage_status', + 'housing_status' => 'housing_status', + 'remarques' => 'remarques', + // Ajoutez d'autres mappings si besoin + ]; + + protected $autresRevenusFieldMap = [ + 'oiamouthmealvoucher' => 'cheque_repas', + 'oiamouthrentalincome' => 'revenus_locatifs', + 'oiamouthunemployment' => 'chomage', + 'oiothertext' => 'autre_revenu_type', + 'oiamouthother' => 'autre_revenu_montant', + ]; + + protected $autoFieldMap = [ + 'marque' => 'marque', + 'vehicleregistrationdate' => 'date_immatriculation', + 'sellername' => 'nom_vendeur', + 'selleraddress' => 'adresse_vendeur', + 'vehicleprice' => 'prix_vehicule', + 'vehicule_accompte' => 'montant_accompte', + 'vehicule_reprise' => 'montant_reprise', + 'vehicule_emprunt' => 'montant_emprunt', + 'vehicule_duree' => 'duree' + ]; + + protected $dateFields = [ + 'birthdate', + 'cnvaliditydate', + 'movingdate', + 'commitmentdate', + 'vehicleregistrationdate', + 'independent_since', + 'date_envoi_dossier', + 'date_envoi_dossier_agence', + // Champs de date co-emprunteur + 'cobirthdate', + 'cocnvaliditydate', + 'coindependent_since' + ]; + + protected function insert_co_emprunteur($data, $currentCredit) { + // Vérifier si l'email du co-emprunteur contient @example.com + if(isset($data['coemail']) && strpos($data['coemail'], '@example.com') !== false) { + return false; // Rejeter la demande si l'adresse email du co-emprunteur contient @example.com + } + + $borrower = $this->getBorrower($currentCredit); + + if (!is_object($borrower)) { + error_log('Erreur insert_co_emprunteur: borrower non trouvé pour le crédit ID: ' . $currentCredit->idCredit); + return false; + } + + /* echo '
    ';
    +        print_r($data);
    +        echo '
    '; + die(); */ + + // Construire le tableau d'insertion en gérant les valeurs NULL et les valeurs par défaut + $insertData = array( + 'nom' => isset($data['colastname']) ? $data['colastname'] : null, + 'prenom' => isset($data['cofirstname']) ? $data['cofirstname'] : null, + 'email' => isset($data['coemail']) ? $data['coemail'] : null, + 'telephone' => isset($data['cophone']) ? $data['cophone'] : null, + 'date_naissance' => isset($data['cobirthdate']) ? $data['cobirthdate'] : null, + 'lieu_naissance' => isset($data['cobirthplace']) ? $data['cobirthplace'] : null, + 'nationalité' => isset($data['conationality']) ? $data['conationality'] : null, + 'num_carte_identite' => isset($data['cocardnumber']) ? $data['cocardnumber'] : null, + 'carte_identite_validite' => isset($data['cocnvaliditydate']) ? $data['cocnvaliditydate'] : null, + 'num_registre_national' => isset($data['conationalregistrationnumber']) ? $data['conationalregistrationnumber'] : null, + 'num_compte_bancaire' => isset($data['cobankaccountnumber']) ? $data['cobankaccountnumber'] : null, + 'adresse' => isset($data['coaddress']) ? $data['coaddress'] : null, + 'code_postal' => isset($data['cozip']) ? $data['cozip'] : null, + 'localite' => isset($data['cocity']) ? $data['cocity'] : null, + 'pays' => isset($data['cocountry']) ? $data['cocountry'] : null, + 'enfant_charge' => isset($data['codependentchildren']) ? $data['codependentchildren'] : null, + 'montant_allocation_familiale' => isset($data['comontant_allocation_familiale']) && !empty($data['comontant_allocation_familiale']) ? $data['comontant_allocation_familiale'] : 0, + 'contract_type' => isset($data['cocontract_type']) ? $data['cocontract_type'] : null, + 'independent_since' => isset($data['coindependent_since']) && !empty($data['coindependent_since']) ? $data['coindependent_since'] : '0000-00-00', + 'nom_employeur' => isset($data['coemname']) ? $data['coemname'] : null, + 'numero_entreprise' => isset($data['coemnumber']) ? $data['coemnumber'] : null, + 'adresse_employeur' => isset($data['coemaddress']) ? $data['coemaddress'] : null, + 'code_postal_employeur' => isset($data['coemzip']) ? $data['coemzip'] : null, + 'localite_employeur' => isset($data['coemcity']) ? $data['coemcity'] : null, + 'pays_employeur' => isset($data['coemcountry']) ? $data['coemcountry'] : null, + 'date_engagement' => isset($data['cocommitmentdate']) ? $data['cocommitmentdate'] : null, + 'salaire' => isset($data['cosalary']) ? $data['cosalary'] : null, + 'annual_taxable_income' => isset($data['coannual_taxable_income']) ? $data['coannual_taxable_income'] : null, + 'cheque_repas' => isset($data['cooiamouthmealvoucher']) ? $data['cooiamouthmealvoucher'] : null, + 'revenus_locatifs' => isset($data['cooiamouthrentalincome']) ? $data['cooiamouthrentalincome'] : null, + 'chomage' => isset($data['cooiamouthunemployment']) ? $data['cooiamouthunemployment'] : null, + 'autre_revenu_type' => isset($data['cooiothertext']) ? $data['cooiothertext'] : null, + 'autre_revenu_montant' => isset($data['cooiamouthother']) ? $data['cooiamouthother'] : null, + 'parent_emprunteur' => $borrower->idemprunteur, + 'habitation_type' => isset($data['coHabitation_type']) ? $data['coHabitation_type'] : null, + 'habitation_loyer' => isset($data['coHabitation_loyer']) ? $data['coHabitation_loyer'] : null, + 'FK_demande_creditdirect' => $currentCredit->idCredit, + 'FK_etat_civil' => isset($data['cocivilstatus']) ? $data['cocivilstatus'] : null, + 'FK_profession' => isset($data['cojob']) ? $data['cojob'] : null, + 'fichage_status' => isset($data['coFichage_status']) && !empty($data['coFichage_status']) ? $data['coFichage_status'] : '', + 'housing_status' => isset($data['cohousing_status']) && !empty($data['cohousing_status']) ? $data['cohousing_status'] : '' + ); + + $result = $this->wpdb->insert('cdf_Emprunteur', $insertData); + + if ($result === false) { + error_log('Erreur lors de l\'insertion du co-emprunteur. Erreur DB: ' . $this->wpdb->last_error); + error_log('Données: ' . print_r($data, true)); + return false; + } + + return $this->wpdb->insert_id; + } + + protected function save_autre_credit_emprunteur($data,$currentCredit) { + $borrower = $this->getBorrower($currentCredit); + $updateData = []; + + + /* $this->wpdb->update('cdf_Emprunteur', array( + 'habitation_type' => $data['habitation_type'], + 'habitation_loyer' => $data['habitation_loyer'], + 'habitation_charge_hypothecaire' => $data['homeowner'], + 'habitation_sans_charge_locative' => $data['homewithoutrentalcharge'], + 'remarques' => $data['commentary'] + ), array('idemprunteur' => $borrower->idemprunteur)); */ + + if(isset($data['habitation_type'])) { + $updateData = array( + 'habitation_type' => $data['habitation_type'], + ); + } + + // Protection pour habitation_loyer - ne pas écraser si pas présent + if (isset($data['habitation_loyer'])) { + $updateData['habitation_loyer'] = $data['habitation_loyer']; + } + + if(!empty($updateData)) { + $this->wpdb->update('cdf_Emprunteur', $updateData, array('idemprunteur' => $borrower->idemprunteur)); + } + + + if ( + array_key_exists('hascurrentloan', $data) && $data['hascurrentloan'] === '1' + && array_key_exists('currentloans', $data) && !empty($data['currentloans']) + ) { + + /* echo '
    ';
    +            print_r($data['currentloans']);
    +            echo '
    '; + die(); */ + + foreach ($data['currentloans'] as $currentLoan) { + $this->wpdb->insert( + 'cdf_Autre_credit', + array( + 'banque' => $currentLoan['bankname'], + 'montant' => $currentLoan['borrowedcapital'], + 'duree_credit' => $currentLoan['durationmonth'], + 'mensualite' => $currentLoan['monthlypayment'], + 'date_premiere_echeance' => $currentLoan['firstduedate'], + 'solde_restant_du' => $currentLoan['remainingbalance'], + 'cloture' => $currentLoan['hasclosed'], + 'FK_type_creance' => $currentLoan['loantype'], + 'FK_emprunteur' => $borrower->idemprunteur + ) + ); + } + } + } + + protected function save_autre_credit_co_emprunteur($data, $currentCredit) { + $borrower = $this->getBorrower($currentCredit); + + // Recharger le crédit pour s'assurer que le co-emprunteur nouvellement créé est disponible + if (is_object($currentCredit) && isset($currentCredit->token)) { + $currentCredit = $this->getCredit($currentCredit->token); + } + + $coBorrower = $this->getCoBorrower($currentCredit); + + // Si le co-emprunteur n'existe toujours pas, on ne peut pas continuer + if (!is_object($coBorrower)) { + return; + } + + $updateData = []; + + /* $this->wpdb->update('cdf_Emprunteur', array( + 'habitation_type' => $data['habitation_type'], + 'habitation_loyer' => $data['habitation_loyer'], + 'habitation_charge_hypothecaire' => $data['habitation_charge_hypothecaire'], + 'habitation_sans_charge_locative' => $data['habitation_sans_charge_locative'] + ), array( + 'idemprunteur' => $coBorrower->idemprunteur, + 'parent_emprunteur' => $borrower->idemprunteur + )); */ + + if(isset($data['coHabitation_type'])) { + $updateData = array( + 'habitation_type' => $data['coHabitation_type'], + ); + } + + // Protection pour habitation_loyer - ne pas écraser si pas présent + if (isset($data['coHabitation_loyer'])) { + $updateData['habitation_loyer'] = $data['coHabitation_loyer']; + } + + if(!empty($updateData)) { + $this->wpdb->update('cdf_Emprunteur', $updateData, array('idemprunteur' => $coBorrower->idemprunteur)); + } + + if ( + array_key_exists('cohascurrentloan', $data) && $data['cohascurrentloan'] === '1' + && array_key_exists('cocurrentloans', $data) && !empty($data['cocurrentloans']) + ) { + foreach ($data['cocurrentloans'] as $currentLoan) { + $this->wpdb->insert( + 'cdf_Autre_credit', + array( + 'banque' => $currentLoan['bankname'], + 'montant' => $currentLoan['borrowedcapital'], + 'duree_credit' => $currentLoan['durationmonth'], + 'mensualite' => $currentLoan['monthlypayment'], + 'date_premiere_echeance' => $currentLoan['firstduedate'], + 'solde_restant_du' => $currentLoan['remainingbalance'], + 'cloture' => $currentLoan['hasclosed'], + 'FK_type_creance' => $currentLoan['loantype'], + 'FK_emprunteur' => $coBorrower->idemprunteur + ) + ); + } + } + } + + /** + * Gère les uploads de fichiers et génère une liste HTML de liens + * @param array $files Les fichiers uploadés ($_FILES) + * @param array $allowed_types Les types MIME autorisés + * @param int $max_size Taille maximale en octets + * @param string $token Le token du crédit + * @return array ['files' => [], 'errors' => [], 'html_links' => string] + */ + public function handleUploads($files, $allowed_types, $max_size, $token) { + $uploaded_files = []; + $errors = []; + $html_links = ''; + + + + // Limite de taille totale pour l'envoi par email (10MB) + $total_size_limit = 10 * 1024 * 1024; // 10MB en octets + $total_size = 0; + + // Mapping des noms de champs vers les types de documents + $field_to_doc_type = [ + 'paycheck' => 'fiche_paie', + 'cojob' => 'fiche_paie_co', + 'notice_of_assessment' => 'avis_imposition', + 'conotice_of_assessment' => 'avis_imposition_co', + 'identity_card' => 'carte_identite', + 'coidentity_card' => 'carte_identite_co', + 'tax_notice' => 'avis_imposition', + 'cotax_notice' => 'avis_imposition_co', + 'property_tax' => 'taxe_fonciere', + 'coproperty_tax' => 'taxe_fonciere_co', + 'rent_receipt' => 'quittance_loyer', + 'corent_receipt' => 'quittance_loyer_co', + 'compromise' => 'compromis_vente', + 'cocompromise' => 'compromis_vente_co' + ]; + + // Première passe : calculer la taille totale des fichiers + // Détecter le type de structure de fichiers + $is_direct_structure = isset($files['name']) && is_array($files['name']); + + if ($is_direct_structure) { + // Structure directe : $files['name'], $files['type'], etc. + $file_count = count($files['name']); + for ($i = 0; $i < $file_count; $i++) { + // Sauter si pas de fichier uploadé + if ($files['error'][$i] === 4) continue; + + if ($files['error'][$i] === 0) { + $total_size += $files['size'][$i]; + } + } + } else { + // Structure avec champs nommés : $files['test1'], $files['test2'], etc. + foreach ($files as $field_name => $file) { + if (is_array($file['name'])) { + // Champ multiple + $file_count = count($file['name']); + for ($i = 0; $i < $file_count; $i++) { + if ($file['error'][$i] === 4) continue; + if ($file['error'][$i] === 0) { + $total_size += $file['size'][$i]; + } + } + } else { + // Champ simple + if ($file['error'] !== 4 && $file['error'] === 0) { + $total_size += $file['size']; + } + } + } + } + + // Vérifier la taille totale + if ($total_size > $total_size_limit) { + $errors[] = "La taille totale des fichiers (" . round($total_size / 1024 / 1024, 2) . " MB) dépasse la limite autorisée de 10 MB pour l'envoi par email."; + return [ + 'files' => [], + 'errors' => $errors, + 'html_links' => '' + ]; + } + + // Créer le dossier de destination s'il n'existe pas + $upload_dir = \wp_upload_dir()['basedir'] . '/credit_direct/clients/' . $token; + if (!file_exists($upload_dir)) { + \wp_mkdir_p($upload_dir); + } + + // Traiter chaque fichier uploadé + if ($is_direct_structure) { + // Structure directe : $files['name'], $files['type'], etc. + $file_count = count($files['name']); + for ($i = 0; $i < $file_count; $i++) { + // Sauter si pas de fichier uploadé + if ($files['error'][$i] === 4) continue; + + if ($files['error'][$i] !== 0) { + $errors[] = "Erreur lors de l'upload du fichier ($i): " . $this->getUploadErrorMessage($files['error'][$i]); + continue; + } + + if (!in_array($files['type'][$i], $allowed_types)) { + $errors[] = "Type de fichier non autorisé pour le fichier ($i): " . $files['type'][$i]; + continue; + } + + if ($files['size'][$i] > $max_size) { + $errors[] = "Fichier trop volumineux pour le fichier ($i): " . round($files['size'][$i] / 1024 / 1024, 2) . " Mo"; + continue; + } + + // Générer le nom du fichier avec index + $original_name = $files['name'][$i]; + $extension = pathinfo($original_name, PATHINFO_EXTENSION); + $new_filename = $token . '_document_' . ($i+1) . '.' . $extension; + $destination = $upload_dir . '/' . $new_filename; + + if (move_uploaded_file($files['tmp_name'][$i], $destination)) { + $uploaded_files[] = $destination; + $file_url = content_url('/uploads/credit_direct/clients/' . $token . '/' . $new_filename); + $html_links .= sprintf( + '
  • %s
  • ', + esc_url($file_url), + esc_html($original_name) + ); + } else { + $errors[] = "Impossible de déplacer le fichier ($i)"; + } + } + } else { + // Structure avec champs nommés : $files['test1'], $files['test2'], etc. + foreach ($files as $field_name => $file) { + if (is_array($file['name'])) { + // Champ multiple + $file_count = count($file['name']); + for ($i = 0; $i < $file_count; $i++) { + // Sauter si pas de fichier uploadé + if ($file['error'][$i] === 4) continue; + + if ($file['error'][$i] !== 0) { + $errors[] = "Erreur lors de l'upload du fichier $field_name ($i): " . $this->getUploadErrorMessage($file['error'][$i]); + continue; + } + + if (!in_array($file['type'][$i], $allowed_types)) { + $errors[] = "Type de fichier non autorisé pour $field_name ($i): " . $file['type'][$i]; + continue; + } + + if ($file['size'][$i] > $max_size) { + $errors[] = "Fichier trop volumineux pour $field_name ($i): " . round($file['size'][$i] / 1024 / 1024, 2) . " Mo"; + continue; + } + + // Générer le nom du fichier avec type de document + $doc_type = isset($field_to_doc_type[$field_name]) ? $field_to_doc_type[$field_name] : $field_name; + $extension = pathinfo($file['name'][$i], PATHINFO_EXTENSION); + $new_filename = $token . '_' . $doc_type . '_' . ($i+1) . '.' . $extension; + $destination = $upload_dir . '/' . $new_filename; + + if (move_uploaded_file($file['tmp_name'][$i], $destination)) { + $uploaded_files[] = $destination; + $file_url = content_url('/uploads/credit_direct/clients/' . $token . '/' . $new_filename); + $html_links .= sprintf( + '
  • %s
  • ', + esc_url($file_url), + esc_html(ucfirst(str_replace('_', ' ', $doc_type))) . ' (' . ($i+1) . ')' + ); + } else { + $errors[] = "Impossible de déplacer le fichier $field_name ($i)"; + } + } + } else { + // Champ simple + if ($file['error'] === 4) continue; // Pas de fichier uploadé + + if ($file['error'] !== 0) { + $errors[] = "Erreur lors de l'upload du fichier $field_name: " . $this->getUploadErrorMessage($file['error']); + continue; + } + + if (!in_array($file['type'], $allowed_types)) { + $errors[] = "Type de fichier non autorisé pour $field_name: " . $file['type']; + continue; + } + + if ($file['size'] > $max_size) { + $errors[] = "Fichier trop volumineux pour $field_name: " . round($file['size'] / 1024 / 1024, 2) . " Mo"; + continue; + } + + // Générer le nom du fichier + $doc_type = isset($field_to_doc_type[$field_name]) ? $field_to_doc_type[$field_name] : $field_name; + $extension = pathinfo($file['name'], PATHINFO_EXTENSION); + $new_filename = $token . '_' . $doc_type . '.' . $extension; + $destination = $upload_dir . '/' . $new_filename; + + if (move_uploaded_file($file['tmp_name'], $destination)) { + $uploaded_files[] = $destination; + $file_url = content_url('/uploads/credit_direct/clients/' . $token . '/' . $new_filename); + $html_links .= sprintf( + '
  • %s
  • ', + esc_url($file_url), + esc_html(ucfirst(str_replace('_', ' ', $doc_type))) + ); + } else { + $errors[] = "Impossible de déplacer le fichier $field_name"; + } + } + } + } + + return [ + 'files' => $uploaded_files, + 'errors' => $errors, + 'html_links' => $html_links ? '
      ' . $html_links . '
    ' : '' + ]; + } + + /** + * Retourne un message d'erreur lisible pour les codes d'erreur d'upload + * @param int $error_code Le code d'erreur PHP + * @return string Le message d'erreur + */ + private function getUploadErrorMessage($error_code) { + switch ($error_code) { + case UPLOAD_ERR_INI_SIZE: + return "Le fichier dépasse la taille maximale autorisée par PHP"; + case UPLOAD_ERR_FORM_SIZE: + return "Le fichier dépasse la taille maximale autorisée par le formulaire"; + case UPLOAD_ERR_PARTIAL: + return "Le fichier n'a été que partiellement uploadé"; + case UPLOAD_ERR_NO_FILE: + return "Aucun fichier n'a été uploadé"; + case UPLOAD_ERR_NO_TMP_DIR: + return "Dossier temporaire manquant"; + case UPLOAD_ERR_CANT_WRITE: + return "Impossible d'écrire le fichier sur le disque"; + case UPLOAD_ERR_EXTENSION: + return "Une extension PHP a arrêté l'upload du fichier"; + default: + return "Erreur inconnue lors de l'upload"; + } + } + + /** + * Récupère tous les fichiers uploadés pour un token de crédit donné + * @param string $token Le token du crédit + * @return array Array d'URLs des fichiers uploadés + */ + public function getUploadedFiles($token) { + $uploaded_files = []; + + // Limite de taille totale pour l'envoi par email (10MB) + $total_size_limit = 10 * 1024 * 1024; // 10MB en octets + $total_size = 0; + + // Construire le chemin du dossier + $upload_dir = \wp_upload_dir()['basedir'] . '/credit_direct/clients/' . $token; + + // Vérifier si le dossier existe + if (!file_exists($upload_dir) || !is_dir($upload_dir)) { + return $uploaded_files; + } + + // Récupérer tous les fichiers du dossier + $files = scandir($upload_dir); + + foreach ($files as $file) { + // Ignorer les dossiers . et .. + if ($file === '.' || $file === '..') { + continue; + } + + // Construire l'URL complète du fichier + $file_path = $upload_dir . '/' . $file; + + // Vérifier que c'est bien un fichier + if (is_file($file_path)) { + $file_size = filesize($file_path); + $total_size += $file_size; + + // Vérifier si la taille totale dépasse la limite + if ($total_size > $total_size_limit) { + // Retourner les fichiers déjà trouvés avec un avertissement + $uploaded_files[] = 'WARNING: Taille totale dépassée (' . round($total_size / 1024 / 1024, 2) . ' MB)'; + break; + } + + $file_url = content_url('/uploads/credit_direct/clients/' . $token . '/' . $file); + $uploaded_files[] = $file_url; + } + } + + // Trier les fichiers par ordre alphabétique + sort($uploaded_files); + + return $uploaded_files; + } + + /** + * Récupère tous les fichiers uploadés avec leurs métadonnées pour un token de crédit donné + * @param string $token Le token du crédit + * @return array Array avec les informations des fichiers (url, nom, type, taille, date) + */ + public function getUploadedFilesWithMetadata($token) { + $uploaded_files = []; + + // Limite de taille totale pour l'envoi par email (10MB) + $total_size_limit = 10 * 1024 * 1024; // 10MB en octets + $total_size = 0; + $size_limit_exceeded = false; + + // Construire le chemin du dossier + $upload_dir = \wp_upload_dir()['basedir'] . '/credit_direct/clients/' . $token; + + // Vérifier si le dossier existe + if (!file_exists($upload_dir) || !is_dir($upload_dir)) { + return $uploaded_files; + } + + // Récupérer tous les fichiers du dossier + $files = scandir($upload_dir); + + foreach ($files as $file) { + // Ignorer les dossiers . et .. + if ($file === '.' || $file === '..') { + continue; + } + + $file_path = $upload_dir . '/' . $file; + + // Vérifier que c'est bien un fichier + if (is_file($file_path)) { + $file_size = filesize($file_path); + $total_size += $file_size; + + // Vérifier si la taille totale dépasse la limite + if ($total_size > $total_size_limit && !$size_limit_exceeded) { + $size_limit_exceeded = true; + $uploaded_files[] = [ + 'url' => '', + 'filename' => 'WARNING', + 'doc_type' => 'size_limit', + 'size' => 0, + 'size_formatted' => '0 B', + 'modified_date' => time(), + 'extension' => '', + 'warning' => 'La taille totale des fichiers (' . round($total_size / 1024 / 1024, 2) . ' MB) dépasse la limite de 10 MB pour l\'envoi par email.' + ]; + break; + } + + $file_url = content_url('/uploads/credit_direct/clients/' . $token . '/' . $file); + + // Extraire le type de document du nom de fichier + $file_info = pathinfo($file); + $filename_parts = explode('_', $file_info['filename']); + + // Le type de document est généralement après le token + $doc_type = isset($filename_parts[1]) ? $filename_parts[1] : 'unknown'; + + $uploaded_files[] = [ + 'url' => $file_url, + 'filename' => $file, + 'doc_type' => $doc_type, + 'size' => $file_size, + 'size_formatted' => $this->formatFileSize($file_size), + 'modified_date' => filemtime($file_path), + 'extension' => strtolower($file_info['extension']), + 'total_size' => $total_size, + 'total_size_formatted' => $this->formatFileSize($total_size) + ]; + } + } + + // Trier par date de modification (plus récent en premier) + usort($uploaded_files, function($a, $b) { + return $b['modified_date'] - $a['modified_date']; + }); + + return $uploaded_files; + } + + /** + * Formate la taille d'un fichier en format lisible + * @param int $bytes Taille en octets + * @return string Taille formatée + */ + private function formatFileSize($bytes) { + $units = ['B', 'KB', 'MB', 'GB']; + + for ($i = 0; $bytes > 1024 && $i < count($units) - 1; $i++) { + $bytes /= 1024; + } + + return round($bytes, 2) . ' ' . $units[$i]; + } + + /** + * Vérifie si une demande de crédit est en cours pour l'utilisateur + * @return array|false Retourne les données de la demande en cours ou false + */ + public function checkOngoingCreditRequest($debug = false) { + + /* if(isset($_GET['debug'])) { + echo '
    ';
    +            print_r($_COOKIE['credit_data']);
    +            echo '
    '; + } */ + + $debug = false; + + + if (isset($_COOKIE['credit_data']) || $debug) { + + $_COOKIE['credit_data'] = stripslashes($_COOKIE['credit_data']); + $credit_data = null; + + if(isset($_COOKIE['credit_data'])) { + $credit_data = json_decode($_COOKIE['credit_data'], true); + } + + if($debug) { + $credit_data = []; + $credit_data['credit_token'] = '151b8853cc8a501e61bb4d0f0fdd05bc1a4d73e8'; + } + + if ($credit_data && isset($credit_data['credit_token'])) { + $currentCredit = $this->getCredit($credit_data['credit_token']); + + + if ($currentCredit && is_object($currentCredit)) { + // Récupérer les données de l'emprunteur pour avoir plus d'informations + $borrower = $this->getBorrower($currentCredit); + + return [ + 'token' => $currentCredit->token, + 'step' => $currentCredit->last_step, + 'type' => $currentCredit->type_credit, + 'capital' => $currentCredit->capital, + 'duree' => $currentCredit->duree, + 'has_borrower' => !empty($borrower), + 'has_co_borrower' => !empty($this->getCoBorrower($currentCredit)), + 'last_update_date' => $currentCredit->last_update_date + ]; + } + } + } + return false; + } + + public function get_ongoing_credit_token() { + $token = null; + + + if(isset($_GET['credit-direct-token'])) { + $token = $_GET['credit-direct-token']; + + $credit_data = $this->getCredit($token); + + if($credit_data) { + $token = $credit_data->token; + } + } else { + $ongoing_credit = $this->checkOngoingCreditRequest(); + + if($ongoing_credit) { + $token = $ongoing_credit['token']; + } + } + + return $token; + } + + public function get_agency($location) { + $agency_mail = ''; + + $location = sanitize_title($location); + $agence = []; + + //location = slug de la page agence + + $args = array( + 'post_type' => 'agences', + 'name' => $location, + 'posts_per_page' => 1 + ); + + + $agencies = get_posts($args); + + if($agencies) { + $agency = $agencies[0]; + $agence['id'] = $agency->ID; + $agence['name'] = $agency->post_title; + $agence['emails'] = get_field('listing_email', $agency->ID); + } + + return $agence; + } + + public function switchAgency_byZipCode(int $zipCode, object $borrower): array { + + $agency_mail = []; + $mons = $this->get_agency('mons'); + $verviers = $this->get_agency('verviers'); + + $pays = $this->getFieldValue('pays', $borrower); + + if($pays == 'LU') { + $agency_mail = $verviers; + + return $agency_mail; + } + + if (($zipCode >= 4000 && $zipCode <= 4999) || // Liège + ($zipCode >= 6600 && $zipCode <= 6999)) { // Luxembourg + $agency_mail = $verviers; + } + + $wallonieBruxelles = + ($zipCode >= 1000 && $zipCode <= 1299) || // Bruxelles‑Capitale + ($zipCode >= 1300 && $zipCode <= 1499) || // Brabant wallon + ($zipCode >= 5000 && $zipCode <= 5680) || // Namur + ($zipCode >= 6000 && $zipCode <= 6599) || // Hainaut (partie 1) + ($zipCode >= 7000 && $zipCode <= 7999); + + $agency_mail = $wallonieBruxelles ? $mons : $verviers; + + return $agency_mail; + + } + + /** + * Vérifie si la taille totale des fichiers pour un token dépasse la limite email + * @param string $token Le token du crédit + * @return array ['exceeded' => bool, 'total_size' => int, 'total_size_formatted' => string, 'limit' => int, 'limit_formatted' => string] + */ + public function checkTotalFileSize($token) { + $total_size_limit = 10 * 1024 * 1024; // 10MB en octets + $total_size = 0; + + // Construire le chemin du dossier + $upload_dir = \wp_upload_dir()['basedir'] . '/credit_direct/clients/' . $token; + + // Vérifier si le dossier existe + if (!file_exists($upload_dir) || !is_dir($upload_dir)) { + return [ + 'exceeded' => false, + 'total_size' => 0, + 'total_size_formatted' => '0 B', + 'limit' => $total_size_limit, + 'limit_formatted' => '10 MB' + ]; + } + + // Récupérer tous les fichiers du dossier + $files = scandir($upload_dir); + + foreach ($files as $file) { + if ($file === '.' || $file === '..') { + continue; + } + + $file_path = $upload_dir . '/' . $file; + + if (is_file($file_path)) { + $total_size += filesize($file_path); + } + } + + return [ + 'exceeded' => $total_size > $total_size_limit, + 'total_size' => $total_size, + 'total_size_formatted' => $this->formatFileSize($total_size), + 'limit' => $total_size_limit, + 'limit_formatted' => '10 MB' + ]; + } + + /** + * Récupère la valeur d'un champ pour l'emprunteur ou le co-emprunteur + * @param string $fieldName Le nom du champ + * @param object $borrower Les données de l'emprunteur + * @return string La valeur à afficher dans le champ + */ + public function getFieldValue($fieldName, $borrower) { + $value = ''; + $map = $this->borrowerFieldMap; + + + + // Détermine si c'est un champ co-emprunteur basé sur le préfixe 'co' + $isCoBorrowerField = strpos($fieldName, 'co') === 0; + + if ($isCoBorrowerField) { + // Récupère le co-emprunteur automatiquement + $currentCredit = $this->getCreditFromBorrower($borrower); + $coBorrower = $currentCredit ? $this->getCoBorrower($currentCredit) : null; + + if (is_object($coBorrower)) { + // Retire le préfixe 'co' pour retrouver la clé de mapping + $baseField = substr($fieldName, 2); + if (isset($map[$baseField])) { + $dbField = $map[$baseField]; + if (isset($coBorrower->$dbField)) { + $value = $coBorrower->$dbField; + } + } elseif (isset($coBorrower->$fieldName)) { + $value = $coBorrower->$fieldName; + } + } + } else if (is_object($borrower)) { + if (isset($map[$fieldName])) { + $dbField = $map[$fieldName]; + + if (isset($borrower->$dbField)) { + $value = $borrower->$dbField; + } + } elseif (isset($borrower->$fieldName)) { + $value = $borrower->$fieldName; + } + } + + if(in_array($fieldName, $this->dateFields) && !empty($value)) { + + $value = \DateTime::createFromFormat('Y-m-d', $value)->format('d/m/Y'); + } + + if(!empty($value)) { + return htmlspecialchars($value); + } + + } + + /** + * Récupère le crédit à partir de l'emprunteur + * @param object $borrower Les données de l'emprunteur + * @return object|null Le crédit associé + */ + private function getCreditFromBorrower($borrower) { + if (!is_object($borrower) || !isset($borrower->FK_demande_creditdirect)) { + return null; + } + + return $this->wpdb->get_row( + $this->wpdb->prepare( + "SELECT * FROM cdf_Credit WHERE idCredit = %d", + $borrower->FK_demande_creditdirect + ) + ); + } + + /** + * Fonction helper pour vérifier si une option est sélectionnée + * @param string $fieldName Le nom du champ + * @param string $optionValue La valeur de l'option + * @param object $borrower Les données de l'emprunteur + * @return string 'selected' si l'option doit être sélectionnée + */ + public function isOptionSelected($fieldName, $optionValue, $borrower) { + $currentValue = $this->getFieldValue($fieldName, $borrower); + return ($currentValue == $optionValue) ? 'selected' : ''; + } + + /** + * Fonction helper pour vérifier si une radio est cochée + * @param string $fieldName Le nom du champ + * @param string $optionValue La valeur de l'option + * @param object $borrower Les données de l'emprunteur + * @return string 'checked' si l'option doit être cochée + */ + public function isRadioChecked($fieldName, $optionValue, $borrower) { + $currentValue = $this->getFieldValue($fieldName, $borrower); + return ($currentValue == $optionValue) ? 'checked' : ''; + } + + public function hasCreditCoBorrower($currentCredit) { + $hasCreditCoBorrower = false; + $coBorrower = $this->getCoBorrower($currentCredit); + + if($coBorrower) { + $hasCreditCoBorrower = true; + } + + return $hasCreditCoBorrower; + } + + /** + * Fonction helper pour vérifier si une checkbox est cochée + * @param string $fieldName Le nom du champ + * @param string $optionValue La valeur de l'option + * @param object $borrower Les données de l'emprunteur + * @return string 'checked' si l'option doit être cochée + */ + public function isCheckboxChecked($fieldName, $optionValue, $borrower) { + $currentValue = $this->getFieldValue($fieldName, $borrower); + return ($currentValue == $optionValue) ? 'checked' : ''; + } + + /** + * Récupère les crédits en cours d'un emprunteur + * @param object $borrower Les données de l'emprunteur + * @return array Liste des crédits en cours + */ + public function getCurrentLoans($borrower) { + if (!is_object($borrower) || !isset($borrower->idemprunteur)) { + return []; + } + + $query = $this->wpdb->prepare( + "SELECT * FROM cdf_Autre_credit WHERE FK_emprunteur = %d ORDER BY idautrecredit ASC", + $borrower->idemprunteur + ); + + return $this->wpdb->get_results($query); + } + + /** + * Génère le HTML pour pré-remplir les crédits en cours + * @param object $borrower Les données de l'emprunteur + * @param string $prefix Préfixe pour les champs co-emprunteur (ex: 'co') + * @return string HTML des crédits pré-remplis + */ + public function getCurrentLoansHTML($borrower, $prefix = '') { + $currentLoans = $this->getCurrentLoans($borrower); + $html = ''; + $index = 0; + + $class_col = $this->hasCoBorrower($borrower) ? 'col-md-3' : 'col-md-6'; + + foreach ($currentLoans as $loan) { + $html .= '
    '; + $html .= ''; + + $html .= '
    '; + + // Type de créance + $html .= '
    '; + $html .= ''; + $html .= '
    '; + + // Nom de l'organisme / Banque + $html .= '
    '; + $html .= ''; + $html .= ''; + $html .= '
    '; + + // Capital emprunté + $html .= '
    '; + $html .= ''; + $html .= ''; + $html .= '
    '; + + // Durée du crédit + $html .= '
    '; + $html .= ''; + $html .= ''; + $html .= '
    '; + + // Mensualité + $html .= '
    '; + $html .= ''; + $html .= ''; + $html .= '
    '; + + // Date 1ère échéance + $html .= '
    '; + $html .= ''; + $html .= ''; + $html .= '
    '; + + // Solde restant dû + $html .= '
    '; + $html .= ''; + $html .= ''; + $html .= '
    '; + + // À clôturer / Solder + $html .= '
    '; + $html .= '
    À clôturer / Solder ?
    '; + $html .= '
    '; + $html .= 'cloture == '0' ? 'checked' : '') . '>'; + $html .= ''; + $html .= '
    '; + $html .= '
    '; + $html .= 'cloture == '1' ? 'checked' : '') . '>'; + $html .= ''; + $html .= '
    '; + $html .= '
    '; + + $html .= ''; + $html .= '
    '; + $html .= '
    '; + + $index++; + } + + return $html; + } + + + /** + * Récupère les autres revenus d'un emprunteur ou co-emprunteur + * @param object $borrower Les données de l'emprunteur ou co-emprunteur + * @return array Array avec les autres revenus + */ + public function getAutresRevenus($borrower) { + if (!is_object($borrower) || !isset($borrower->idemprunteur)) { + return []; + } + + $autresRevenus = []; + + // Récupérer les autres revenus depuis la table cdf_Emprunteur + $query = $this->wpdb->prepare( + "SELECT + cheque_repas, + revenus_locatifs, + chomage, + autre_revenu_type, + autre_revenu_montant + FROM cdf_Emprunteur + WHERE idemprunteur = %d", + $borrower->idemprunteur + ); + + $result = $this->wpdb->get_row($query); + + if ($result) { + // Construire un array avec les autres revenus + if (!empty($result->cheque_repas)) { + $autresRevenus[] = [ + 'type' => 'Chèque repas', + 'montant' => $result->cheque_repas, + 'description' => 'Chèque repas mensuel' + ]; + } + + if (!empty($result->revenus_locatifs)) { + $autresRevenus[] = [ + 'type' => 'Revenus locatifs', + 'montant' => $result->revenus_locatifs, + 'description' => 'Revenus locatifs mensuels' + ]; + } + + if (!empty($result->chomage)) { + $autresRevenus[] = [ + 'type' => 'Chômage', + 'montant' => $result->chomage, + 'description' => 'Allocation de chômage mensuelle' + ]; + } + + if (!empty($result->autre_revenu_montant) && !empty($result->autre_revenu_type)) { + $autresRevenus[] = [ + 'type' => 'Autre revenu', + 'montant' => $result->autre_revenu_montant, + 'description' => $result->autre_revenu_type + ]; + } + } + + return $autresRevenus; + } + + /** + * @param $data + * @return void + */ + protected function update_emprunteur($data, $currentCredit) + { + // Vérifier si l'email de l'emprunteur contient @example.com + if(isset($data['email']) && strpos($data['email'], '@example.com') !== false) { + return false; // Rejeter la demande si l'adresse email contient @example.com + } + + $borrower = $this->getBorrower($currentCredit); + $updateData = []; + + foreach ($this->borrowerFieldMap as $formField => $dbField) { + + /* echo '
    ';
    +            print_r($data);
    +            echo '
    '; */ + + // Protection générale : ne mettre à jour que les champs présents dans les données POST + if (!isset($data[$formField])) { + continue; // On saute ce champ s'il n'est pas présent dans les données + } + + // Si le champ est un champ de date, on le formate correctement + if (in_array($formField, $this->dateFields)) { + if (!empty($data[$formField])) { + $date = \DateTime::createFromFormat('d/m/Y', $data[$formField]); + if ($date) { + $updateData[$dbField] = $date->format('Y-m-d'); + } else { + $updateData[$dbField] = null; // Si la date n'est pas valide, on met à null + } + } else { + $updateData[$dbField] = null; // Si le champ est vide, on met à null + } + } else { + // Pour les champs non-date, on utilise directement la valeur + $updateData[$dbField] = $data[$formField]; + } + } + + /* echo '
    ';
    +        print_r($updateData);
    +        echo '
    '; + die(); */ + + + $this->wpdb->update('cdf_Emprunteur', $updateData, array('idemprunteur' => $borrower->idemprunteur)); + } + + /** + * Met à jour les données du co-emprunteur + * @param $data + * @param $currentCredit + * @return void + */ + protected function update_co_emprunteur($data, $currentCredit) + { + // Vérifier si l'email du co-emprunteur contient @example.com + if(isset($data['coemail']) && strpos($data['coemail'], '@example.com') !== false) { + return false; // Rejeter la demande si l'adresse email du co-emprunteur contient @example.com + } + + $coBorrower = $this->getCoBorrower($currentCredit); + if (!is_object($coBorrower)) { + return; // Pas de co-emprunteur, on sort + } + + $updateData = []; + + foreach ($this->borrowerFieldMap as $formField => $dbField) { + // Vérifier si c'est un champ co-emprunteur (préfixe 'co') + if (strpos($formField, 'co') === 0) { + // Protection générale : ne mettre à jour que les champs présents dans les données POST + if (!isset($data[$formField])) { + continue; // On saute ce champ s'il n'est pas présent dans les données + } + + // Si le champ est un champ de date, on le formate correctement + if (in_array($formField, $this->dateFields)) { + if (!empty($data[$formField])) { + $date = \DateTime::createFromFormat('d/m/Y', $data[$formField]); + if ($date) { + $updateData[$dbField] = $date->format('Y-m-d'); + } else { + $updateData[$dbField] = null; // Si la date n'est pas valide, on met à null + } + } else { + $updateData[$dbField] = null; // Si le champ est vide, on met à null + } + } else { + // Pour les champs non-date, on utilise directement la valeur + $updateData[$dbField] = $data[$formField]; + } + } + } + + if (!empty($updateData)) { + $this->wpdb->update('cdf_Emprunteur', $updateData, array('idemprunteur' => $coBorrower->idemprunteur)); + } + } + + public function is_credit_pat($currentCredit) { + + $type_credit = $currentCredit->type_credit; + + + if(array_key_exists($type_credit, $this->one_step_credit_types)) { + return true; + } + + return false; + } + + public function is_credit_auto($currentCredit) { + $type_credit = $currentCredit->type_credit; + + if(in_array($type_credit, $this->creditAutos)) { + return true; + } + + return false; + } + + public function hasCoBorrower($currentCredit) { + $borrower = $this->getBorrower($currentCredit); + $coBorrower = $this->getCoBorrower($currentCredit); + + if($coBorrower) { + return true; + } + + return false; + } + + public function hasOtherIncome($borrower) { + $cheque_repas = $this->getFieldValue('cheque_repas', $borrower); + $revenus_locatifs = $this->getFieldValue('revenus_locatifs', $borrower); + $chomage = $this->getFieldValue('chomage', $borrower); + $autre_revenu_montant = $this->getFieldValue('autre_revenu_montant', $borrower); + $autre_revenu_type = $this->getFieldValue('autre_revenu_type', $borrower); + + if($cheque_repas || $revenus_locatifs || $chomage || $autre_revenu_montant || $autre_revenu_type) { + return true; + } + + return false; + } + + public function estFicheBanqueNational($borrower) { + + $fichage_status = $borrower->fichage_status; + + if(!empty($fichage_status)) { + return true; + } + + return false; + + } + + public function is_locataire($borrower) { + + $habitation_type = $borrower->habitation_type; + + if(empty($habitation_type)) { + return false; + } + + if($habitation_type == 'locataire') { + return true; + } + + return false; + } + + /** + * Génère des liens HTML pour les documents uploadés + * @param string $token Le token du crédit + * @param bool $include_metadata Inclure les métadonnées (taille, date) dans l'affichage + * @param string $css_class Classe CSS pour le conteneur des liens + * @return string HTML des liens vers les documents uploadés + */ + public function generateUploadedFilesLinksHTML($token, $include_metadata = false, $css_class = 'uploaded-documents') { + $html = ''; + + if ($include_metadata) { + $files = $this->getUploadedFilesWithMetadata($token); + } else { + $files = $this->getUploadedFiles($token); + } + + if (empty($files)) { + return '

    Aucun document uploadé

    '; + } + + $html .= '
    '; + $html .= '

    Documents uploadés :

    '; + $html .= '
      '; + + foreach ($files as $file) { + if ($include_metadata && is_array($file)) { + // Fichier avec métadonnées + if (isset($file['warning'])) { + $html .= '
    • ⚠️ ' . esc_html($file['warning']) . '
    • '; + continue; + } + + $file_url = $file['url']; + $filename = $file['filename']; + $doc_type = $file['doc_type']; + $size_formatted = $file['size_formatted']; + $modified_date = date('d/m/Y H:i', $file['modified_date']); + + // Traduire le type de document + $doc_type_labels = [ + 'fiche_paie' => 'Fiche de paie', + 'fiche_paie_co' => 'Fiche de paie (co-emprunteur)', + 'avis_imposition' => 'Avis d\'imposition', + 'avis_imposition_co' => 'Avis d\'imposition (co-emprunteur)', + 'carte_identite' => 'Carte d\'identité', + 'carte_identite_co' => 'Carte d\'identité (co-emprunteur)', + 'taxe_fonciere' => 'Taxe foncière', + 'taxe_fonciere_co' => 'Taxe foncière (co-emprunteur)', + 'quittance_loyer' => 'Quittance de loyer', + 'quittance_loyer_co' => 'Quittance de loyer (co-emprunteur)', + 'compromis_vente' => 'Compromis de vente', + 'compromis_vente_co' => 'Compromis de vente (co-emprunteur)' + ]; + + $doc_label = isset($doc_type_labels[$doc_type]) ? $doc_type_labels[$doc_type] : ucfirst(str_replace('_', ' ', $doc_type)); + + $html .= '
    • '; + $html .= ''; + $html .= '📄 ' . esc_html($doc_label); + $html .= ''; + $html .= '
      '; + $html .= 'Taille: ' . esc_html($size_formatted) . ' | Modifié le: ' . esc_html($modified_date); + $html .= '
      '; + $html .= '
    • '; + + } else { + // Fichier simple (URL seulement) + if (is_string($file) && strpos($file, 'WARNING:') === 0) { + $html .= '
    • ⚠️ ' . esc_html($file) . '
    • '; + continue; + } + + $file_url = $file; + $filename = basename($file_url); + + $html .= '
    • '; + $html .= ''; + $html .= '📄 ' . esc_html($filename); + $html .= ''; + $html .= '
    • '; + } + } + + $html .= '
    '; + $html .= '
    '; + + return $html; + } + + /** + * Génère des liens HTML simples pour les documents uploadés (version simplifiée) + * @param string $token Le token du crédit + * @param string $css_class Classe CSS pour le conteneur des liens + * @return string HTML des liens vers les documents uploadés + */ + public function generateSimpleUploadedFilesLinksHTML($token, $css_class = 'uploaded-documents-simple') { + $files = $this->getUploadedFiles($token); + + if (empty($files)) { + return ''; + } + + $html = '
    '; + $html .= '

    Documents joints :

    '; + $html .= '
      '; + + foreach ($files as $file) { + if (is_string($file) && strpos($file, 'WARNING:') === 0) { + $html .= '
    • ⚠️ ' . esc_html($file) . '
    • '; + continue; + } + + $file_url = $file; + $filename = basename($file_url); + + $html .= '
    • '; + $html .= ''; + $html .= esc_html($filename); + $html .= ''; + $html .= '
    • '; + } + + $html .= '
    '; + $html .= '
    '; + + return $html; + } + + /** + * Récupère les limites basse et haute pour un type de crédit depuis ACF + */ + public function get_credit_limits($credit_types) { + $credit_type_map = array( + 'but_immo' => 'credit_travaux__renovation__energie', + 'fin_neuve' => 'financement_vehicule_neuf', + 'fin_occ_m3a' => 'financement_vehicule_doccasion_moins_de_3_ans', + 'fin_occ_p3a' => 'financement_vehicule_doccasion_plus_de_3_ans', + 'mobil_carav' => 'financement_mobilhome_et_caravane_de_moins_de_3_ans', + 'reno_energie' => 'credit_travaux__renovation__energie', + 'regroup_cred' => 'regroupement_de_credit__rachats_de_credits', + 'frais_notaire' => 'financement_frais_de_notaire', + 'pat' => 'pret_personnel__tous_motifs__achats_divers', + 'ph' => 'credit_hypothecaire_social', + 'am' => 'credit_hypothecaire_classique', + 'amr' => 'achat_maison_de_rapport', + 'cied' => 'independants_et_entreprises_en_difficultes', + 'cdp' => 'credit_pont' + ); + + $acf_field_name = isset($credit_type_map[$credit_types]) ? $credit_type_map[$credit_types] : null; + + if (!$acf_field_name || !function_exists('get_field')) { + return [ + 'limite_basse' => 0, + 'limite_haute' => PHP_INT_MAX + ]; + } + + $credit_data = get_field($acf_field_name, 'option'); + + if (!$credit_data || !is_array($credit_data)) { + return [ + 'limite_basse' => 0, + 'limite_haute' => PHP_INT_MAX + ]; + } + + return [ + 'limite_basse' => isset($credit_data['limite_basse']) ? (int)$credit_data['limite_basse'] : 0, + 'limite_haute' => isset($credit_data['limite_haute']) ? (int)$credit_data['limite_haute'] : PHP_INT_MAX + ]; + } + + /** + * get exemple_infod_from acf + */ + public function get_exemples_infos($credit_types) { + + $credit_type_map = array( + 'but_immo' => 'credit_travaux__renovation__energie', + 'fin_neuve' => 'financement_vehicule_neuf', + 'fin_occ_m3a' => 'financement_vehicule_doccasion_moins_de_3_ans', + 'fin_occ_p3a' => 'financement_vehicule_doccasion_plus_de_3_ans', + 'mobil_carav' => 'financement_mobilhome_et_caravane_de_moins_de_3_ans', + 'reno_energie' => 'credit_travaux__renovation__energie', + 'regroup_cred' => 'regroupement_de_credit__rachats_de_credits', + 'frais_notaire' => 'financement_frais_de_notaire', + 'pat' => 'pret_personnel__tous_motifs__achats_divers', + 'ph' => 'credit_hypothecaire_social', + 'am' => 'credit_hypothecaire_classique', + 'amr' => 'achat_maison_de_rapport', + 'cdp' => 'credit_pont', + 'cied' => 'independants_et_entreprises_en_difficultes', + 'reno_energie' => 'credit_travaux__renovation__energie', + 'but_immo_hypo' => 'credit_hypothecaire_classique', + ); + + $credit = $credit_type_map[$credit_types]; + + $exemple_info = get_field($credit, 'option'); + + $exemple_info = $exemple_info['exemple_et_infos']; + + if(empty($exemple_info)) { + return false; + } + + return $exemple_info; + + } + + /** + * check if is webdev user + */ + public function is_webdev_user() { + $user = wp_get_current_user(); + + $user_id = $user->ID; + + if($user_id == 1) { + return true; + } + return false; + } + + /** + * Sauvegarde dans cdf_Credits_listing + * @param object $currentCredit Le crédit actuel + * @return void + */ + public function save_to_credits_listing($currentCredit) { + // Récupérer les données complètes du crédit + $credit_data = $this->wpdb->get_row($this->wpdb->prepare( + "SELECT * FROM cdf_Credit WHERE idCredit = %d", + $currentCredit->idCredit + )); + + $code_type_credit = $this->is_credit_pat($currentCredit) ? 'pat' : 'ph'; + + // Récupérer les données de l'emprunteur + $emprunteur_data = $this->wpdb->get_row($this->wpdb->prepare( + "SELECT * FROM cdf_Emprunteur WHERE FK_demande_creditdirect = %d", + $currentCredit->idCredit + )); + + // Récupérer les autres crédits de l'emprunteur + $other_credits_ids = ''; + if ($emprunteur_data) { + $borrower = $this->getBorrower($currentCredit); + if ($borrower && isset($borrower->other_credits) && is_array($borrower->other_credits)) { + $ids = array(); + foreach ($borrower->other_credits as $other_credit) { + if (isset($other_credit->idautre_credit)) { + $ids[] = $other_credit->idautre_credit; + } + } + $other_credits_ids = implode(',', $ids); + } + } + + // Vérifier si l'enregistrement existe déjà + $existing = $this->wpdb->get_row($this->wpdb->prepare( + "SELECT id FROM cdf_Credits_listing WHERE credit_id = %d", + $currentCredit->idCredit + )); + + $credit_label = $this->getCreditLabel($credit_data->sel_credit); + + $listing_data = array( + 'credit_id' => $currentCredit->idCredit, + 'emprunteur_id' => $emprunteur_data ? $emprunteur_data->idemprunteur : 0, + 'autre_credit_id' => $other_credits_ids, + 'credit_auto_id' => $credit_data ? $credit_data->FK_credit_auto : 0, + 'credit_hypotecaire_id' => $credit_data ? $credit_data->FK_credit_hypothecaire : 0, + 'title' => $credit_label, + 'credit_code_select' => $credit_data->sel_credit, + 'code_credit' => $credit_data->type_credit, + 'type_credit' => $code_type_credit, + 'nom' => $emprunteur_data ? $emprunteur_data->nom : '', + 'prenom' => $emprunteur_data ? $emprunteur_data->prenom : '', + 'adresse' => $emprunteur_data ? $emprunteur_data->adresse : '', + 'localite' => $emprunteur_data ? $emprunteur_data->localite : '', + 'email' => $emprunteur_data ? $emprunteur_data->email : '', + 'telephone' => $emprunteur_data ? $emprunteur_data->telephone : '', + 'gsm' => $emprunteur_data ? $emprunteur_data->telephone : '', // Utiliser telephone comme gsm si pas de gsm séparé + 'societe_credit' => '', + 'montant' => $credit_data ? floatval($credit_data->capital) : 0, + 'date' => $credit_data ? $credit_data->create_date : date('Y-m-d'), + 'date_signature' => '', // Par défaut non signé + 'numero_dossier' => '', + 'code' => '', + 'remarque' => $credit_data ? $credit_data->commentaire : '', + 'status' => 0, + ); + + if ($existing) { + // Mettre à jour l'enregistrement existant + $this->wpdb->update( + 'cdf_Credits_listing', + $listing_data, + array('id' => $existing->id), + array( + '%d', '%d', '%d', '%d', '%d', '%s', '%s', '%s', '%s', '%s', + '%s', '%s', '%s', '%s', '%f', '%s', '%d', '%s', '%s', '%s' + ) + ); + } else { + // Créer un nouvel enregistrement + $this->wpdb->insert( + 'cdf_Credits_listing', + $listing_data, + array( + '%d', '%d', '%d', '%d', '%d', '%s', '%s', '%s', '%s', '%s', + '%s', '%s', '%s', '%s', '%f', '%s', '%d', '%s', '%s', '%s' + ) + ); + } + } +} \ No newline at end of file diff --git a/app/models/old/credit_step2.php b/app/models/old/credit_step2.php new file mode 100644 index 0000000..2f9057b --- /dev/null +++ b/app/models/old/credit_step2.php @@ -0,0 +1,237 @@ + false, + 'errors' => ['email' => 'Adresse email invalide'], + 'formatted_errors' => 'Adresse email invalide' + ]; + } + + // Validation des données + $validator = new FormValidator($data, $this); + $errors = $validator->validateStep2($data); + + if (!empty($errors)) { + // Retourner les erreurs pour affichage + return [ + 'success' => false, + 'errors' => $errors, + 'formatted_errors' => $validator->getFormattedErrors() + ]; + } + + $currentCredit = $this->getCredit($data['credit-direct-token']); + + $id_credit = $currentCredit->idCredit; + + if (!is_object($currentCredit)) { + return false; + } + + $borrower = $this->getBorrower($currentCredit); + $borrowerTableName = 'cdf_Emprunteur'; + $borrowerData = [ + 'nom' => $data['lastname'], + 'prenom' => $data['firstname'], + 'telephone' => $data['phone'], + 'email' => $data['email'], + 'pays' => $data['country'], + 'code_postal' => $data['zip'], + 'FK_demande_creditdirect' => $currentCredit->idCredit + ]; + + /* $borrowerData = [ + 'nom' => $data['lastname'], + 'prenom' => $data['firstname'], + 'telephone' => $data['phone'], + 'email' => $data['email'], + 'FK_agence' => $data['agency'], + 'FK_demande_creditdirect' => $currentCredit->idCredit + ]; */ + + if (is_object($borrower)) { + $this->wpdb->update($borrowerTableName, $borrowerData, [ + 'idemprunteur' => $borrower->idemprunteur + ]); + } else { + $this->wpdb->insert($borrowerTableName, $borrowerData); + } + + if(!empty($data['comment'])) { + $this->wpdb->update( + 'cdf_Credit', + array('commentaire' => $data['comment']), + array('idCredit' => $currentCredit->idCredit) + ); + } + + if (in_array($currentCredit->type_credit, $this->creditAutos)) { + $optionsTableName = 'cdf_Options_credit_auto'; + + + $optionsData = [ + 'marque' => $data['marque'], + 'date_immatriculation' => $data['vehicleregistrationdate'], + 'nom_vendeur' => $data['sellername'], + 'date_immatriculation' => !empty($data['vehicleregistrationdate']) ? (DateTime::createFromFormat('d/m/Y', $data['vehicleregistrationdate']) ? DateTime::createFromFormat('d/m/Y', $data['vehicleregistrationdate'])->format('Y-m-d') : $data['vehicleregistrationdate']) : null, + 'adresse_vendeur' => $data['selleraddress'], + 'prix_vehicule' => $data['vehicleprice'], + 'montant_accompte' => $data['vehicule_accompte'], + 'montant_reprise' => $data['vehicule_reprise'], + 'montant_emprunt' => $data['vehicule_emprunt'], + 'duree' => $data['vehicule_duree'] + ]; + + + if (!is_null($currentCredit->FK_credit_auto)) { + $this->wpdb->update($optionsTableName, $optionsData, [ + 'idOptions_credit_auto' => $currentCredit->FK_credit_auto + ]); + } else { + $this->wpdb->insert($optionsTableName, $optionsData); + + $optionId = $this->wpdb->insert_id; + + $this->wpdb->update( + 'cdf_Credit', + array('FK_credit_auto' => $optionId), + array('idCredit' => $currentCredit->idCredit) + ); + } + } + + if (in_array($currentCredit->type_credit, $this->one_step_credit_types)) { + $optionsTableName = 'cdf_Options_credit_hypotecaire'; + $optionsData = [ + 'type_credit' => $data['estateloantype'], + 'prix_achat' => $data['estatebuyingprice'], + 'prix_construction_tvac' => $data['prix_achat_tvac'], + 'valeur_batiment' => $data['valeur_batiment'], + 'fonds_propre' => $data['estateequity'], + 'compromis_signe' => $data['estatecompromise'], + 'montant_revenu_cadastral' => $data['estatcadastralincome'], + 'montant_a_emprunter' => $data['batiment_emprunt'], + 'duree' => $data['batiment_duree'] + ]; + + if (!is_null($currentCredit->FK_credit_hypothecaire)) { + $this->wpdb->insert($optionsTableName, $optionsData, [ + 'FK_credit_hypothecaire' => $currentCredit->FK_credit_hypothecaire + ]); + } else { + $this->wpdb->insert($optionsTableName, $optionsData); + + $optionId = $this->wpdb->insert_id; + + $this->wpdb->update( + 'cdf_Credit', + array('FK_credit_hypothecaire' => $optionId), + array('idCredit' => $currentCredit->idCredit) + ); + } + } + + /** + * Re-get the current credit to hydrate it + */ + $currentCredit = $this->getCredit($data['credit-direct-token']); + + /** + * Send mail + */ + if ($currentCredit->last_step < 2) { + $agencies = $this->getAgencies(); + $borrower = $this->getBorrower($currentCredit); + $map_credit_type = $this->getCreditTypes(); + $mapHouseCreditTypes = $this->getHouseCreditTypes(); + + // S'assurer que le type de crédit est défini + if (!isset($currentCredit->type_credit) || !array_key_exists($currentCredit->type_credit, $map_credit_type)) { + error_log('Type de crédit inconnu: ' . $currentCredit->type_credit); + } + + $is_credit_auto = $this->is_credit_auto($currentCredit); + $is_one_step_credit = in_array($currentCredit->type_credit, $this->one_step_credit_types); + + + //update the credit id in the cdf_Credit with comment data + + if(!empty($data['comment'])) { + $this->wpdb->update( + 'cdf_Credit', + array('commentaire' => $data['comment']), + array('idCredit' => $id_credit) + ); + } + + ob_start(); + include(_CRED_BASE_PATH_ . '/templates/email/credit-step2-mail.php'); + $message = ob_get_clean(); + + + ob_start(); + include(_CRED_BASE_PATH_ . '/templates/email/clients_emails/credit-step2-mail-client.php'); + $message_client = ob_get_clean(); + + $this->mailchimpSynchro($currentCredit, $borrower); + + + if(!isset($data['isback']) || $data['isback'] != '1') { + if(isset($data['type_credit_selected']) && !empty($data['type_credit_selected']) || isset($data['sub_loan_type']) && !empty($data['sub_loan_type'])) + $type_credit_selected = isset($data['sub_loan_type']) ? $data['sub_loan_type'] : $data['type_credit_selected']; + + + $creditOptionsLabels = !empty($type_credit_selected) ? $this->getCreditLabel($type_credit_selected) : $map_credit_type[$currentCredit->type_credit]; + + // Exception : ne pas envoyer de mail si l'utilisateur connecté a l'ID 1 + if (!is_user_logged_in() || get_current_user_id() != 1) { + // Envoyer l'email uniquement à l'administrateur (to_client = false) + $this->sendEmail('Demande de crédit', $message, $borrower, $currentCredit, [], false); + + // Envoyer l'email à l'emprunteur (to_client = true) + $this->sendEmail('Demande de crédit', $message_client, $borrower, $currentCredit, [], true); + } + } + } + + /** + * Update Credit info + */ + $updateInfos = [ + 'last_update_date' => (new \DateTime())->format('Y-m-d H:i:s'), + ]; + + if (intval($currentCredit->last_step) === 1) { + $updateInfos['last_step'] = '2'; + } + + $this->wpdb->update( + 'cdf_Credit', + $updateInfos, + array('idCredit' => $currentCredit->idCredit) + ); + + $this->wpdb->suppress_errors = false; + + return true; + } +} \ No newline at end of file diff --git a/app/models/old/credit_step3.php b/app/models/old/credit_step3.php new file mode 100644 index 0000000..379e027 --- /dev/null +++ b/app/models/old/credit_step3.php @@ -0,0 +1,105 @@ +validateStep3($data); + + if (!empty($errors)) { + // Retourner les erreurs pour affichage + return [ + 'success' => false, + 'errors' => $errors, + 'formatted_errors' => $validator->getFormattedErrors() + ]; + } + + $this->currentCredit = $currentCredit; + + foreach ($data as $k => $d) { + if ($d === '') { + $data[$k] = null; + } + } + + /* $curreentUser = wp_get_current_user(); + + if($curreentUser->ID == 1) { + + echo '
    ';
    +            echo 'data';
    +            print_r($data);
    +            echo '
    '; + + } */ + + $this->update_emprunteur($data, $currentCredit); + $this->save_autre_credit_emprunteur($data,$currentCredit); + + // Vérifier si hascoborrower est présent dans les données + // Note: pour les radio buttons, si aucun n'est coché, la clé peut être absente + // On vérifie aussi s'il y a des données de co-emprunteur pour détecter sa présence + $hasCoBorrowerInData = array_key_exists('hascoborrower', $data) && ($data['hascoborrower'] === '1' || $data['hascoborrower'] === 1); + $hasCoBorrowerFields = !empty($data['cofirstname']) || !empty($data['colastname']) || !empty($data['coemail']) || !empty($data['cophone']); + + // Si hascoborrower est à '1' OU si des champs co-emprunteur sont présents, traiter le co-emprunteur + if ($hasCoBorrowerInData || $hasCoBorrowerFields) { + // Vérifier si le co-emprunteur existe déjà + $coBorrower = $this->getCoBorrower($currentCredit); + if (is_object($coBorrower)) { + // Le co-emprunteur existe, on le met à jour + $this->update_co_emprunteur($data, $currentCredit); + } else { + // Le co-emprunteur n'existe pas, on le crée seulement si hascoborrower === '1' + // (pour éviter de créer un co-emprunteur par erreur) + if ($hasCoBorrowerInData) { + // Vérifier que le borrower existe avant d'insérer le co-emprunteur + $borrower = $this->getBorrower($currentCredit); + if (is_object($borrower)) { + $insertId = $this->insert_co_emprunteur($data, $currentCredit); + // Vérifier si l'insertion a réussi + if ($insertId === false || $insertId === 0) { + error_log('Erreur lors de l\'insertion du co-emprunteur pour le crédit ID: ' . $currentCredit->idCredit); + error_log('Dernière erreur DB: ' . $this->wpdb->last_error); + error_log('Dernière requête: ' . $this->wpdb->last_query); + } else { + // L'insertion a réussi, recharger le crédit pour que getCoBorrower trouve le nouveau co-emprunteur + $currentCredit = $this->getCredit($currentCredit->token); + } + } else { + error_log('Impossible de créer le co-emprunteur : borrower non trouvé pour le crédit ID: ' . $currentCredit->idCredit); + } + } + } + // Sauvegarder les autres crédits du co-emprunteur seulement si hascoborrower === '1' + if ($hasCoBorrowerInData) { + $this->save_autre_credit_co_emprunteur($data,$currentCredit); + } + } + + $this->wpdb->update( + 'cdf_Credit', + array( + 'last_update_date' => (new \DateTime())->format('Y-m-d H:i:s'), + 'last_step' => '3' + ), + array('idCredit' => $this->currentCredit->idCredit) + ); + } +} \ No newline at end of file diff --git a/app/models/old/credit_step4.php b/app/models/old/credit_step4.php new file mode 100644 index 0000000..a4f0a13 --- /dev/null +++ b/app/models/old/credit_step4.php @@ -0,0 +1,49 @@ +currentCredit = $currentCredit; + + $this->save_autre_credit_emprunteur($data,$currentCredit); + + $this->update_emprunteur($data,$currentCredit); + + $curreentUser = wp_get_current_user(); + + if($curreentUser->ID == 1) { + + echo '
    ';
    +            echo 'data';
    +            print_r($data);
    +            echo '
    '; + + } + + // Vérifier si le co-emprunteur existe et mettre à jour ses données + $coBorrower = $this->getCoBorrower($currentCredit); + if (is_object($coBorrower)) { + // Mettre à jour les données du co-emprunteur + $this->update_co_emprunteur($data, $currentCredit); + + // Sauvegarder les autres crédits du co-emprunteur si nécessaire + if (array_key_exists('cohometype', $data)) { + $this->save_autre_credit_co_emprunteur($data,$currentCredit); + } + } + + $this->wpdb->update( + 'cdf_Credit', + array( + 'last_update_date' => (new \DateTime())->format('Y-m-d H:i:s'), + 'last_step' => '4', + 'token' => $this->currentCredit->token + ), + array('idCredit' => $this->currentCredit->idCredit) + ); + } +} \ No newline at end of file diff --git a/app/models/old/credit_step5.php b/app/models/old/credit_step5.php new file mode 100644 index 0000000..63821b4 --- /dev/null +++ b/app/models/old/credit_step5.php @@ -0,0 +1,95 @@ +currentCredit = $currentCredit; + + // Sauvegarder les données de l'étape 4 + $this->save_emprunteur_address($data, $currentCredit); + + if (array_key_exists('cohometype', $data)) { + $this->save_co_emprunteur_address($data, $currentCredit); + } + + $this->wpdb->update( + 'cdf_Credit', + array( + 'last_update_date' => (new \DateTime())->format('Y-m-d H:i:s'), + 'last_step' => '5', + 'token' => null + ), + array('idCredit' => $this->currentCredit->idCredit) + ); + + //save into cdf_Credits_listing + $this->save_to_credits_listing($currentCredit); + + return $this->wpdb->insert_id; + } + + // Méthode pour sauvegarder l'adresse de l'emprunteur + private function save_emprunteur_address($data, $currentCredit) { + $borrower = $this->getBorrower($currentCredit); + + /* echo '
    ';
    +        print_r($borrower);
    +        print_r($data);
    +        echo '
    '; + die(); */ + + $datas_update = array( + 'adresse' => $data['address'], + 'code_postal' => $data['zip'], + 'localite' => $data['city'], + 'pays' => $data['country'], + 'date_emmenagement' => $data['movingdate'], + 'nom_employeur' => $data['emname'], + 'adresse_employeur' => $data['emaddress'], + 'code_postal_employeur' => $data['emzip'], + 'localite_employeur' => $data['emcity'], + 'date_engagement' => $data['commitmentdate'] + ); + + /* echo '
    ';
    +        print_r($datas_update);
    +        echo '
    '; + die(); */ + + if ($borrower) { + $this->wpdb->update( + 'cdf_Emprunteur', + $datas_update, + array('idemprunteur' => $borrower->idemprunteur) + ); + } + } + + // Méthode pour sauvegarder l'adresse du co-emprunteur + private function save_co_emprunteur_address($data, $currentCredit) { + $coBorrower = $this->getCoBorrower($currentCredit); + + if ($coBorrower) { + $this->wpdb->update( + 'cdf_Emprunteur', + array( + 'adresse' => $data['coaddress'], + 'code_postal' => $data['cozip'], + 'localite' => $data['cocity'], + 'pays' => $data['cocountry'], + 'date_emmenagement' => $data['comovingdate'], + 'nom_employeur' => $data['coemname'], + 'adresse_employeur' => $data['coemaddress'], + 'code_postal_employeur' => $data['coemzip'], + 'localite_employeur' => $data['coemcity'], + 'date_engagement' => $data['cocommitmentdate'] + ), + array('idemprunteur' => $coBorrower->idemprunteur) + ); + } + } +} \ No newline at end of file diff --git a/assets/css/bootstrap.min.css b/assets/css/bootstrap.min.css new file mode 100644 index 0000000..fc59f96 --- /dev/null +++ b/assets/css/bootstrap.min.css @@ -0,0 +1,7 @@ +/*! + * Bootstrap v4.6.2 (https://getbootstrap.com/) + * Copyright 2011-2022 The Bootstrap Authors + * Copyright 2011-2022 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([class]){color:inherit;text-decoration:none}a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit;text-align:-webkit-match-parent}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:.875em;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:.875em;color:#6c757d}.blockquote-footer::before{content:"\2014\00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#e83e8c;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-ms-flex-order:-1;order:-1}.order-last{-ms-flex-order:13;order:13}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-sm-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-sm-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-sm-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-sm-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-sm-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-sm-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-ms-flex-order:-1;order:-1}.order-sm-last{-ms-flex-order:13;order:13}.order-sm-0{-ms-flex-order:0;order:0}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-md-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-md-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-md-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-md-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-md-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-md-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 30.333333%;flex:0 0 30.333333%;max-width:30.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-ms-flex-order:-1;order:-1}.order-md-last{-ms-flex-order:13;order:13}.order-md-0{-ms-flex-order:0;order:0}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-lg-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-lg-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-lg-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-lg-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-lg-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-lg-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-ms-flex-order:-1;order:-1}.order-lg-last{-ms-flex-order:13;order:13}.order-lg-0{-ms-flex-order:0;order:0}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-xl-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-xl-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-xl-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-xl-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-xl-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-xl-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-ms-flex-order:-1;order:-1}.order-xl-last{-ms-flex-order:13;order:13}.order-xl-0{-ms-flex-order:0;order:0}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;margin-bottom:1rem;color:#212529}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{color:#212529;background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#7abaff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#b3b7bb}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#8fd19e}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#86cfda}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ffdf7e}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#ed969e}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#fbfcfc}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#95999c}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#343a40;border-color:#454d55}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#343a40}.table-dark td,.table-dark th,.table-dark thead th{border-color:#454d55}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}input[type=date].form-control,input[type=datetime-local].form-control,input[type=month].form-control,input[type=time].form-control{-webkit-appearance:none;-moz-appearance:none;appearance:none}select.form-control:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;font-size:1rem;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}select.form-control[multiple],select.form-control[size]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#28a745}.valid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.form-row>.col>.valid-tooltip,.form-row>[class*=col-]>.valid-tooltip{left:5px}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#28a745;padding-right:calc(1.5em + .75rem)!important;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.was-validated select.form-control:valid,select.form-control.is-valid{padding-right:3rem!important;background-position:right 1.5rem center}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-valid,.was-validated .custom-select:valid{border-color:#28a745;padding-right:calc(.75em + 2.3125rem)!important;background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat,#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem) no-repeat}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{border-color:#28a745}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{border-color:#34ce57;background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before{border-color:#28a745}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.form-row>.col>.invalid-tooltip,.form-row>[class*=col-]>.invalid-tooltip{left:5px}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem)!important;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.was-validated select.form-control:invalid,select.form-control.is-invalid{padding-right:3rem!important;background-position:right 1.5rem center}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-invalid,.was-validated .custom-select:invalid{border-color:#dc3545;padding-right:calc(.75em + 2.3125rem)!important;background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat,#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e") center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem) no-repeat}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{border-color:#dc3545}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{border-color:#e4606d;background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before{border-color:#dc3545}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-ms-flexbox;display:flex;-ms-flex:0 0 auto;flex:0 0 auto;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;-ms-flex-negative:0;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#0069d9;border-color:#0062cc;box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{color:#fff;background-color:#5a6268;border-color:#545b62;box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#218838;border-color:#1e7e34;box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#138496;border-color:#117a8b;box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{color:#212529;background-color:#e0a800;border-color:#d39e00;box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c82333;border-color:#bd2130;box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{color:#212529;background-color:#e2e6ea;border-color:#dae0e5;box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{color:#fff;background-color:#23272b;border-color:#1d2124;box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-outline-primary{color:#007bff;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;text-decoration:none}.btn-link:hover{color:#0056b3;text-decoration:underline}.btn-link.focus,.btn-link:focus{text-decoration:underline}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.collapsing.width{width:0;height:auto;transition:width .35s ease}@media (prefers-reduced-motion:reduce){.collapsing.width{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#e9ecef}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#adb5bd;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-ms-flex:1 1 auto;flex:1 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-toolbar{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:center;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;min-width:0;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group:not(.has-validation)>.custom-file:not(:last-child) .custom-file-label,.input-group:not(.has-validation)>.custom-file:not(:last-child) .custom-file-label::after,.input-group:not(.has-validation)>.custom-select:not(:last-child),.input-group:not(.has-validation)>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>.custom-file:nth-last-child(n+3) .custom-file-label,.input-group.has-validation>.custom-file:nth-last-child(n+3) .custom-file-label::after,.input-group.has-validation>.custom-select:nth-last-child(n+3),.input-group.has-validation>.form-control:nth-last-child(n+3){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-append,.input-group-prepend{display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group.has-validation>.input-group-append:nth-last-child(n+3)>.btn,.input-group.has-validation>.input-group-append:nth-last-child(n+3)>.input-group-text,.input-group:not(.has-validation)>.input-group-append:not(:last-child)>.btn,.input-group:not(.has-validation)>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;z-index:1;display:block;min-height:1.5rem;padding-left:1.5rem;-webkit-print-color-adjust:exact;color-adjust:exact;print-color-adjust:exact}.custom-control-inline{display:-ms-inline-flexbox;display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;left:0;z-index:-1;width:1rem;height:1.25rem;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#007bff;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#80bdff}.custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#b3d7ff;border-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label,.custom-control-input[disabled]~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before,.custom-control-input[disabled]~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fff;border:1px solid #adb5bd}.custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:50%/50% 50% no-repeat}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#007bff;background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label::after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-switch .custom-control-label::after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#fff;-webkit-transform:translateX(.75rem);transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{display:none}.custom-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + .75rem + 2px);margin:0;overflow:hidden;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:disabled~.custom-file-label,.custom-file-input[disabled]~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;overflow:hidden;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;height:1.4rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{-moz-transition:none;transition:none}}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;-ms-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{-ms-transition:none;transition:none}}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-link{margin-bottom:-1px;background-color:transparent;border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{isolation:isolate;border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{background:0 0;border:0;border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item,.nav-fill>.nav-link{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;padding:.5rem 1rem}.navbar .container,.navbar .container-fluid,.navbar .container-lg,.navbar .container-md,.navbar .container-sm,.navbar .container-xl{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:50%/100% 100% no-repeat}.navbar-nav-scroll{max-height:75vh;overflow-y:auto}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{-ms-flex:1 1 auto;flex:1 1 auto;min-height:1px;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem;border-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom,.card-img-top{-ms-flex-negative:0;flex-shrink:0;width:100%}.card-img,.card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{-ms-flex:1 0 0%;flex:1 0 0%;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion{overflow-anchor:none}.accordion>.card{overflow:hidden}.accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0}.accordion>.card>.card-header{border-radius:0;margin-bottom:-1px}.breadcrumb{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:3;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:3;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.badge{transition:none}}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}a.badge-primary:focus,a.badge-primary:hover{color:#fff;background-color:#0062cc}a.badge-primary.focus,a.badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.badge-secondary{color:#fff;background-color:#6c757d}a.badge-secondary:focus,a.badge-secondary:hover{color:#fff;background-color:#545b62}a.badge-secondary.focus,a.badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.badge-success{color:#fff;background-color:#28a745}a.badge-success:focus,a.badge-success:hover{color:#fff;background-color:#1e7e34}a.badge-success.focus,a.badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.badge-info{color:#fff;background-color:#17a2b8}a.badge-info:focus,a.badge-info:hover{color:#fff;background-color:#117a8b}a.badge-info.focus,a.badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.badge-warning{color:#212529;background-color:#ffc107}a.badge-warning:focus,a.badge-warning:hover{color:#212529;background-color:#d39e00}a.badge-warning.focus,a.badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.badge-danger{color:#fff;background-color:#dc3545}a.badge-danger:focus,a.badge-danger:hover{color:#fff;background-color:#bd2130}a.badge-danger.focus,a.badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.badge-light{color:#212529;background-color:#f8f9fa}a.badge-light:focus,a.badge-light:hover{color:#212529;background-color:#dae0e5}a.badge-light.focus,a.badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.badge-dark{color:#fff;background-color:#343a40}a.badge-dark:focus,a.badge-dark:hover{color:#fff;background-color:#1d2124}a.badge-dark.focus,a.badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;z-index:2;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;line-height:0;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:1s linear infinite progress-bar-stripes;animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.media{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start}.media-body{-ms-flex:1;flex:1}.list-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width:576px){.list-group-horizontal-sm{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:768px){.list-group-horizontal-md{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:992px){.list-group-horizontal-lg{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:1200px){.list-group-horizontal-xl{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75}button.close{padding:0;background-color:transparent;border:0}a.close.disabled{pointer-events:none}.toast{-ms-flex-preferred-size:350px;flex-basis:350px;max-width:350px;font-size:.875rem;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .25rem .75rem rgba(0,0,0,.1);opacity:0;border-radius:.25rem}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.25rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05);border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-50px);transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{-webkit-transform:none;transform:none}.modal.modal-static .modal-dialog{-webkit-transform:scale(1.02);transform:scale(1.02)}.modal-dialog-scrollable{display:-ms-flexbox;display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{-ms-flex-negative:0;flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);height:-webkit-min-content;height:-moz-min-content;height:min-content;content:""}.modal-dialog-centered.modal-dialog-scrollable{-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable::before{content:none}.modal-content{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:justify;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem}.modal-footer{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:end;justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)}.modal-footer>*{margin:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered::before{height:calc(100vh - 3.5rem);height:-webkit-min-content;height:-moz-min-content;height:min-content}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top]>.arrow,.bs-popover-top>.arrow{bottom:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=top]>.arrow::before,.bs-popover-top>.arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top]>.arrow::after,.bs-popover-top>.arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right]>.arrow,.bs-popover-right>.arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right]>.arrow::before,.bs-popover-right>.arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right]>.arrow::after,.bs-popover-right>.arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom]>.arrow,.bs-popover-bottom>.arrow{top:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=bottom]>.arrow::before,.bs-popover-bottom>.arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom]>.arrow::after,.bs-popover-bottom>.arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left]>.arrow,.bs-popover-left>.arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left]>.arrow::before,.bs-popover-left>.arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left]>.arrow::after,.bs-popover-left>.arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{-ms-touch-action:pan-y;touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){-webkit-transform:translateX(100%);transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){-webkit-transform:translateX(-100%);transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;-webkit-transform:none;transform:none}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:0 0;border:0;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:50%/100% 100% no-repeat}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@-webkit-keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;border:.25em solid currentcolor;border-right-color:transparent;border-radius:50%;-webkit-animation:.75s linear infinite spinner-border;animation:.75s linear infinite spinner-border}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@-webkit-keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1;-webkit-transform:none;transform:none}}@keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1;-webkit-transform:none;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;background-color:currentcolor;border-radius:50%;opacity:0;-webkit-animation:.75s linear infinite spinner-grow;animation:.75s linear infinite spinner-grow}.spinner-grow-sm{width:1rem;height:1rem}@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{-webkit-animation-duration:1.5s;animation-duration:1.5s}}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded-sm{border-radius:.2rem!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-lg{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-sm-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-sm-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-sm-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-sm-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-sm-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-md-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-md-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-md-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-md-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-md-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-lg-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-lg-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-lg-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-lg-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-lg-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-xl-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-xl-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-xl-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-xl-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-xl-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;-ms-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;-ms-user-select:none!important;user-select:none!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:rgba(0,0,0,0)}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace!important}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0056b3!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#494f54!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#19692c!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#0f6674!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#ba8b00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#a71d2a!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#cbd3da!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#121416!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-break{word-break:break-word!important;word-wrap:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}} +/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/assets/css/buildings.css b/assets/css/buildings.css new file mode 100644 index 0000000..ca8efc1 --- /dev/null +++ b/assets/css/buildings.css @@ -0,0 +1,112 @@ +/** + * Styles pour la gestion des bâtiments + * credit-one-step.php + */ + +.wpcf-buildings-section { + margin-top: 30px; +} + +.building-block { + background-color: #f8f9fa !important; + border-radius: 8px; + margin-bottom: 20px; + padding: 20px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + position: relative; +} + +.building-block h5 { + margin-bottom: 20px; + font-size: 1.1rem; + font-weight: 600; +} + +.building-label { + color: #ff6b35; + font-weight: bold; +} + +.building-country-select, +.building-rental-amount { + animation: slideDown 0.3s ease; +} + +@keyframes slideDown { + from { + opacity: 0; + transform: translateY(-10px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.building-loan-block { + background-color: #fff; + border: 1px solid #dee2e6; + border-radius: 6px; + padding: 20px; + margin-bottom: 15px; + position: relative; +} + +.wpcf-buildingloan-remove { + position: absolute; + top: 10px; + right: 10px; + z-index: 10; + font-size: 0.875rem; + padding: 0.375rem 0.75rem; +} + +.wpcf-buildingloan-add { + margin-top: 15px; +} + +/* Amélioration des radio buttons */ +.form-check-inline { + margin-right: 15px; +} + +.col-form-label { + font-weight: 500; + margin-bottom: 10px; +} + +/* Responsive */ +@media (max-width: 768px) { + .building-block { + padding: 15px; + } + + .building-loan-block { + padding: 15px; + } + + .wpcf-buildingloan-remove { + position: relative; + top: 0; + right: 0; + margin-bottom: 15px; + width: 100%; + } +} + +/* Style pour la section de crédits */ +.wpcf-buildingloans { + margin-top: 30px; + padding: 20px; + background-color: #f8f9fa; + border-radius: 8px; +} + +.wpcf-buildingloans h4 { + margin-bottom: 20px; +} + +#building-loans-container { + margin-top: 20px; +} + diff --git a/assets/css/cd_main.css b/assets/css/cd_main.css new file mode 100644 index 0000000..45fefeb --- /dev/null +++ b/assets/css/cd_main.css @@ -0,0 +1,1568 @@ +@import url('fonts.css'); +@import url('range-selector.css'); + +:root { + --orange-credit-direct: #F76622; + --text-dark: #333333; + --background-light: #f5f5f5; +} + +.load_simulator { + /* display: -webkit-flex; + display: flex; */ + color: #192c4a; +} + +.cout_total_value.final { + font-size: 16px; + font-weight: 800; +} + +.ls_result_label.final { + font-size: 16px; + font-weight: 800; +} + +h3.simulator_title { + font-size: 30px !important; + color: #001954 !important; + text-align: center; + margin-top: 3rem !important; + margin-bottom: 1rem !important; +} + +h4.simulator_subtitle { + font-size: 18px !important; + color: #001954 !important; + margin: 2em 0 1em 0; +} + +.load_simulator label { + vertical-align: baseline; + color: #192c4a; +} + +.widget-input-text { + border: 1px #E8E8E8 solid; + padding: 5px; +} + +#date-range-selector { + margin: 0; + text-align: center; + margin-bottom: 10px; + margin-top: 10px; + padding: 0px; +} + +.date-range-buttons { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 4px; +} + +.date-range-buttons li:last-child:nth-child(odd) { + grid-column: 1 / -1; +} + +li.months-inactive, +li.months-active { + list-style: none; + display: inline-block; + padding: 5px 10px; + /* border-bottom: 2px solid #274471; */ + color: #274471; + font-weight: 700; + cursor: pointer; +} + +li.months-inactive, +li.months-active { + box-shadow: 0 5px 10px 0 rgba(184, 184, 184, 0.1); + border-radius: 8px; + border: 1px solid #e0e0e0; + margin: 6px; + transition: all ease-in 0.3s; + font-size: 0.9em; + font-weight: normal; +} + +li.months-active .mensualite { + font-size: 1.2em; + font-weight: 700; +} + +li.months-inactive { + border-color: #c3c3c3; + color: #c3c3c3; + cursor: default; +} + +li.months-active.selected, +li.months-active:hover { + /* border-bottom: 2px solid #fe8c1e; */ + background: #fe8c1e; + color: #fff; +} + +.stimulator-slider-control { + border: none; + border-radius: 50%; + width: 22px; + background-color: #274471; + color: #fff; + float: left; +} + +.slider-count-wrapper { + width: calc(100% - 44px); + display: block; + float: left; + margin-top: 5px; + background: linear-gradient(#e9e9e9, #fff); + border-color: #1c3050; + color: #fff; +} + +div.stimulator_info_block { + display: inline-block; +} + +.stimulator_label, +.stimulator_value { + font-size: 12px; + margin-bottom: 5px; +} + +#additional_messages, +.disclaimer p { + font-size: 12px; + text-align: justify; + margin: 1.5rem 0 1rem 0 !important; +} + +.disclaimer p.credit-example { + color: #192c4a; + font-size: 12px; + margin: 0 !important; +} + +p em { + color: #192c4a; + font-size: 10px; + margin: 0 !important; +} + +.exemple-info p em { + font-size: 0.8em; +} + +.disclaimer p.credit-example strong { + font-weight: 900; +} + +#additional_messages { + color: #fd841f +} + +#additional_messages:empty { + display: none; +} + +.stimulated-results { + background: url("images/blug-abstract-bg.png"); + background-size: cover; + min-height: 387px !important; +} + +.load_simulator .vc_col-md-8, +.load_simulator .vc_col-md-4 { + padding: 20px; +} + +.ls_result_label { + float: left; + font-size: 15px; + font-weight: 700; + color: #fff; + text-transform: uppercase; + margin-bottom: 20px; +} + +.ls_result_value { + float: right; +} + +.ls_result_value, +.ls_result_value span { + font-size: 15px; + font-weight: 700; + color: #fff; +} + +.btn.stimulator_result_btn {} + +.load_simulator .vc_col-md-12 { + width: 100%; +} + +.load_simulator .vc_col-md-12, +.load_simulator .vc_col-md-6, +.load_simulator .vc_col-lg-4 { + padding: 0; + display: inline-block; +} + +form.load_simulator>div, +div.load_simulator>div { + padding: 10px 20px !important; + /* background-color: #f5f5f5; */ +} + +.first-col { + background: #fff; + background-size: cover; + min-height: 387px !important; + box-shadow: 0 4px 19px 0 rgba(8, 41, 78, .15); + border-radius: 15px; + /* margin: 1rem; */ +} + +.stimulated-results { + background: #fff; + background-size: cover; + min-height: 387px !important; + box-shadow: 0 4px 19px 0 rgba(8, 41, 78, .15); + border-radius: 15px; + /* margin: 1rem; */ +} + +.advice-text { + color: #192c4a; +} + +.ls_result_label { + float: left; + font-size: 14px; + font-weight: 700; + color: #192c4a; + margin-bottom: 20px; + text-transform: none; +} + +.ls_result_value { + float: right; +} + +.ls_result_value, +.ls_result_value span { + font-size: 15px; + font-weight: 700; + color: #192c4a; +} + +.stimulator_result_btn { + font-size: 20px !important; + width: 100%; + padding: 25px 0 !important; + font-weight: 600 !important; +} + +.show-on-mobile { + display: none; +} + +.btn { + display: inline-block; + padding: 6px 12px; + margin-bottom: 0; + font-size: 14px; + font-weight: 400; + line-height: 1.42857143; + text-align: center; + white-space: nowrap; + vertical-align: middle; + -ms-touch-action: manipulation; + touch-action: manipulation; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + background-image: none; + border: 1px solid transparent; + border-radius: 8px; + margin-top: 1rem; +} + +.btn-warning, +.vc_btn3-color-warning, +.vc_btn3.vc_btn3-color-warning.vc_btn3-style-modern { + color: #fff !important; + border-color: #ff921d !important; + background: #ff921d !important; + background: #ff921d !important; + background: #ff921d !important; + background: #ff921d!important; + font-weight: bolder !important; + font-size: 14px !important; +} + +.stimulator_result_btn { + font-size: 15px !important; + width: 100%; + padding: 15px 0 !important; + font-weight: 600 !important; +} + +.ui-slider-input { + display: none !important; +} + +.range_selector { + display: inline-block; + width: 100%; +} + +.slider-count-wrapper { + margin-left: 1.5rem; +} + +.icon-check label.form-check-label:hover, +.icon-check label.form-check-label.active { + background-color: #fe8c1e; + color: white; +} + +.icon-check label.form-check-label:active { + background-color: #fe8c1e !important; + color: white!important; +} + +.range_selector.selected_months { + margin-bottom: 10px; +} + +.stimulator_value { + float: right; + font-weight: 700; +} + +.stimulator_label { + float: left; + font-weight: 700; +} + +.stimulator_label, +.stimulator_value { + font-size: 12px; + margin-bottom: 5px; +} + +input.widget-input-text.col-lg-8 { + width: 66.66666667%; +} + +.stimulator-slider-control { + border: none; + border-radius: 6px; + /* padding: 4px 12px; */ + margin: 0 6px; + /* width: 22px; */ + height: 20px; + line-height: 2px; + background-color: #1c3050; + color: #fff; + float: left; + font-weight: 700; +} + +.slider-count-wrapper { + position: relative; + width: calc(100% - 8px); + display: block; + float: left; + margin-top: 5px; + background-color: #d6d7db; + border-color: #1c3050; + color: #fff; + /* margin: 50px 0 20px 0; */ + margin: 15px 0 20px 0; +} + + +/* .slider-count-wrapper::after { + content: ''; + position: absolute; + height: 12px; + width: 100%; + top: 0; + border-radius: 8px; + background-color: #f76622; +} */ + +.slider-count-wrapper .after_bar { + position: absolute; + height: 12px; + width: 100%; + top: 0; + border-radius: 8px; +} + + +.after_bar_month { + position: absolute; + height: 12px; + width: 100%; + top: 0; + border-radius: 8px; + background-color: #fe8c1e; +} + +.slider-count-wrapper .after_bar.active { + background-color: #fe8c1e; +} + +.slider-count-wrapper {} + +.ui-slider-horizontal span { + font-weight: bold; +} + +#selected_capital { + /* margin-bottom: 10px; */ +} + +#selected_months { + /* display: none; + color: #f6931f; */ + font-weight: bold; +} + +.simulator_selectors>.form-group>label { + padding: 5px 0; + margin-bottom: 0; +} + +.stimulated-results .disclaimer-results { + margin-top: 20px; +} + +.stimulated-results, +.stimulated-results .disclaimer-results p, +.stimulated-results .disclaimer-results p em, +.stimulated-results .disclaimer-results a { + color: #fff; + font-weight: 300; + font-size: 12px; +} + +h3.ui-accordion-header { + color: #333; + background: none; + border: none; + border-bottom: 1px solid #284776; + font-size: 1.4em; + padding-bottom: 5px; + border-radius: 0; + cursor: pointer; +} + +h3.ui-accordion-header i { + color: #284776; +} + +.wp-credit-form { + padding: 25px 0; +} + +.wp-credit-form input[type="number"], +.wp-credit-form input[type="date"], +.wp-credit-form input[type="text"], +.wp-credit-form input[type="tel"], +.wp-credit-form input[type="email"], +#selected_capital { + border: 1px solid #ccc; +} + +.form-group { + margin-top: 15px; +} + +label { + display: inline-block; + max-width: 100%; + margin-bottom: 5px; + font-weight: 700; + font-size: 10px; +} + +.form-control { + display: block; + width: 100%; + height: var(--form_input_height); + padding: 6px 12px; + font-size: 14px; + line-height: 1.42857143; + color: #555; + background-color: #fff; + background-image: none; + border: 1px solid #ccc; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s; + -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; +} + +.hidden { + display: none; +} + +.date-range-buttons .mensualite { + display: block; + margin-top: 8px; + text-align: center; +} + +ul.credit_type, +div.loan_type_radio { + padding-left: 0; + margin-left: -7.5px; + margin-right: -7.5px; +} + +.credit_type li, +.loan_type_radio .form_check { + list-style: none; + padding: 0 8px; + margin-bottom: 16px; +} + +.credit_type li a { + display: block; + height: 100%; + padding: 8px 12px; + border: 1px solid #ccc; + border-radius: 4px; + transition: all ease-in 0.3s; +} + +.loan_type_radio .loan_type, +.loan_type_radio .sub_loan_type, +.loan_type_radio .sub_auto_loan_type { + display: none; +} + +/* .sub_auto { + margin-top: 15px 0; + padding: 15px 0; + border-top: 1px solid #f2f3f5; +} */ + +.sub_radio_sel { + margin-top: 15px; + padding: 12px; + border-radius: 8px; + background: 1px solid #f2f3f5; +} + +.loan_type_radio label { + display: inline-block; + width: 100%; + height: 100%; + cursor: pointer; + text-align: center; + line-height: normal; + border-radius: 8px; + border: 1px solid #cfcdcd; + transition: all ease-in 0.3s; + font-size: 0.7em; + font-weight: normal; + padding: 15px 5px 10px 5px; +} + +/* .col-md-4 { + padding: 10px 20px !important; +} */ + +/* .col-md-12:not(.co-emprunteur) { + padding: 0px !important; +} */ + +.loan_type_radio label i { + display: inline-block; + text-align: center; + font-size: 1.3em; + padding: 5px; +} + +.loan_type_radio label .label_text { + display: inline-block; + /* margin-top: 15px; */ + width: 100%; + font-weight: bold; +} + +.simu_step { + display: inline-block; + width: 30px; + height: 30px; + border-radius: 50%; + background-color: #ff921d; + color: #fff; + text-align: center; + font-size: 0.8em; + line-height: 30px; + font-weight: 700; + margin-right: 8px; +} + +.credit_type li a:hover, +.loan_type_radio label:hover i, +.loan_type_radio .loan_type:checked+label, +.loan_type_radio .sub_loan_type:checked+label i, +.loan_type_radio .sub_auto_loan_type:checked+label i, +.credit_type li a.active { + text-decoration: none; +} + + +/**multistep progress**/ + +.progressbar { + display: flex; + justify-content: center; + list-style: none; + counter-reset: container 0; +} + +.progressbar li { + /* display: flex; */ + text-align: center; + list-style: none; + text-transform: uppercase; + counter-increment: container 1; + position: relative; + /* margin-right: 133px; + margin-top: 20px; */ + width: 33.33%; + /* float: left; */ + letter-spacing: 1px; +} + + +/* .progressbar li.active-step::before { + background-color: #f76622; + border: none; + color: #fff; +} */ + +.progressbar li.active-step:before, +.progressbar li.active-step:after { + background: #f76622; + color: white; +} + +.progressbar li::before { + /* content: counter(container); + position: absolute; + height: 40px; + width: 40px; + border-radius: 50%; + border: 2px solid #f76622; + color: #f76622; + text-align: center; + line-height: 40px; + z-index: 10; + background-color: #fff; + font-weight: 700; */ + content: counter(container); + position: relative; + counter-increment: step; + width: 40px; + height: 40px; + line-height: 35px; + display: block; + font-size: 12px; + color: #f76622; + text-align: center; + background: white; + border: 2px solid #f76622; + border-radius: 50%; + margin: 0 auto 10px auto; + font-size: 1.2em; + z-index: 1; +} + +.progressbar li::after { + /* content: ''; + position: absolute; + height: 2px; + width: 140px; + background-color: #f76622; + top: 12px; + right: -10px; */ + content: ''; + width: 100%; + height: 2px; + background: #f76622; + position: absolute; + left: -50%; + top: 18px; + z-index: 0; +} + +.progressbar li:first-child::after { + content: none; +} + +#selected_capital_range { + background-color: #d6d7db; + box-shadow: none; + border-radius: 8px; + height: 12px; +} + +.outside_box_wrapper { + display: flex; + justify-content: center; + margin-top: 15px; + align-items: center; +} + +.outside_box{ + border-color: #1c3050; + background: #1c3050; + min-width: 1.2em; + min-height: 1.2em; + cursor: grab; + padding: 4px 8px; + text-wrap: nowrap; + border-radius: 4px; + font-size: 1.25em; + line-height: 22px; + font-weight: 700; +} + +.ui-slider-horizontal .ui-slider-handle .slider_capital_box, .ui-slider-horizontal .ui-slider-handle .slider_duree_box { + display: none; + position: absolute; + top: -38px; + border-color: #1c3050; + background: #1c3050; + min-width: 1.2em; + min-height: 1.2em; + cursor: grab; + padding: 2px 6px; + text-wrap: nowrap; + border-radius: 4px; + left: -50px; +} + +.ui-slider-horizontal .ui-slider-handle .slider_duree_box { + left: -22px; +} + +.ui-slider-horizontal .ui-slider-handle { + display: inline-block; + text-align: center; + font-size: 1.25em; + line-height: 22px; + width: 26px; + height: 26px; + border-radius: 50%; + background: #1c3050; + border: 0; + cursor: pointer; + -webkit-box-shadow: none; + box-shadow: 0px 0px 0px 4px rgba(28, 48, 80, 0.3); +} + +#selected_months_range { + background-color: #d6d7db; + box-shadow: none; + border-radius: 8px; + height: 12px; + margin: 0; +} + +#selected_months_range .ui-slider-handle { + display: inline-block; + text-align: center; + font-size: 1.25em; + line-height: 23px; + width: 26px; + height: 26px; + border-radius: 50%; + background: #1c3050; + border: 0; + cursor: pointer; + -webkit-box-shadow: none; + box-shadow: 0px 0px 0px 4px rgba(28, 48, 80, 0.3); + +} + +#selected_months_range .ui-slider-handle .slider_months_box { + position: absolute; + top: -38px; + border-color: #1c3050; + background: #1c3050; + min-width: 1.2em; + min-height: 1.2em; + cursor: grab; + padding: 2px 6px; + text-wrap: nowrap; + border-radius: 4px; + left: -50px; +} + + +/*.active-step { + display: block !important; +} */ + +.pivot-value { + color: #f76622 !important; +} + +#selected_capital_range { + position: relative; + overflow: visible; +} + +.pivot-zone { + border-radius: 0 8px 8px 0; + z-index: 1; + background-color: rgba(247, 102, 34, 0.15) !important; +} + +.stimulator_result_btn.disabled { + opacity: 0.6; + cursor: not-allowed; + background: #cccccc !important; + border-color: #cccccc !important; +} + +.credit-recap { + background-color: #fff; + padding: 20px 0; + /* box-shadow: 0 2px 4px rgba(0,0,0,0.05); */ + /* border: 1px solid #e0e0e0; */ +} + +.infos-credits-top { + background-color: #f8f9fa; + padding: 20px 0; + margin: 0 -15px; +} + +.steps-holder { + /* background-color: #f8f9fa; + padding: 20px 0; + margin: 0 -15px; */ + /* box-shadow: 0 2px 4px rgba(0,0,0,0.05); */ + /* border: 1px solid #e0e0e0; */ +} + +.credit-recap-holder { + padding: 3rem 0; + width: 100%; +} + +.credit-recap-container { + max-width: 1200px; + margin: 0 auto; + display: flex; + justify-content: space-between; + align-items: center; + /* padding: 0 30px; */ +} + +.credit-info { + display: flex; + align-items: stretch; + gap: 0; + width: 100%; +} + +.credit-item { + display: flex; + flex-direction: column; + gap: 8px; + min-width: 140px; + border: 1px solid #e0e0e0; + padding: 10px 15px; + background-color: #fff; + margin-left: -1px; + flex: 1; +} + +.credit-item:first-child { + margin-left: 0; +} + +.credit-label { + font-size: 14px; + color: #666; + font-weight: normal; +} + +.credit-value { + font-size: 18px; + font-weight: bold; + color: var(--text-dark); +} + +.credit-value.highlight { + color: var(--orange-credit-direct); +} + +.progress-steps { + display: flex; + justify-content: space-between; + max-width: 1200px; + margin: 20px auto; + padding: 0 15px; +} + +.step { + display: flex; + align-items: center; + gap: 10px; +} + +.step-number { + width: 24px; + height: 24px; + border-radius: 50%; + background-color: #fff; + border: 2px solid #ddd; + display: flex; + align-items: center; + justify-content: center; + font-weight: bold; + font-size: 14px; +} + +.step.active .step-number { + background-color: var(--orange-credit-direct); + border-color: var(--orange-credit-direct); + color: white; +} + +.step-text { + color: #999; + font-size: 14px; +} + +.step.active .step-text { + color: var(--text-dark); + font-weight: bold; +} + +.credit-step-header { + background-color: #001954; + color: #fff; + padding: 40px 20px; + margin: 0 -20px; +} + +.credit-step-header h2 { + color: #fff; + margin-bottom: 0; +} + +.iziModal-header.inner-header { + background: none; + box-shadow: none; + border-bottom: none; +} + +.comment_fieldset { + margin-top: 20px; +} + +.stimulated-results.info_active .btn_holder { + position: relative; + right: 0; + left: 0; + width: 100%; + +} + +@media (max-width: 768px) { + .credit-info { + flex-wrap: wrap; + gap: 15px; + } + + .credit-item { + flex: 1 1 calc(50% - 15px); + } + + .progress-steps { + flex-wrap: wrap; + gap: 20px; + } + + .step { + flex: 1 1 calc(50% - 10px); + } + + body .container { + width: 100%; + } +} + +@media (max-width: 480px) { + .credit-item { + flex: 1 1 100%; + } + + .step { + flex: 1 1 100%; + } +} + + +/**end progress bar**/ + +@media (max-width: 600px) { + .show-on-mobile { + display: block; + } + .hide-on-mobile { + display: none !important; + } + .master-slider-parent { + display: none; + } +} + +@media (max-width: 648px) { + .form-body .nav-justified>li { + width: 20%; + display: inline-block; + margin: 0; + box-sizing: border-box; + float: left; + } + .form-wizard ul li span.number { + width: 48px; + padding: 7px 4px; + font-size: 12px; + } + .form-body>ul { + display: flex; + } + .form-wizard ul li span.desc { + font-size: 12px; + font-weight: 900; + word-wrap: break-word; + } +} + +/* Styles pour les colonnes de crédit */ +/* .credit-cols { + display: flex; + flex-wrap: wrap; + margin: 0 -15px; +} */ + +.credit-cols .wpcf-borrower, +.credit-cols .wpcf-coborrower { + padding: 15px; + transition: all 0.3s ease; +} + +/* Style pour le mode deux colonnes */ +.credit-cols .wpcf-borrower.col-md-6, +.credit-cols .wpcf-coborrower.col-md-6 { + width: 50%; + border-right: 1px solid #dee2e6; +} + +/* Ajustements responsives */ +@media (max-width: 768px) { + .credit-cols .wpcf-borrower.col-md-6, + .credit-cols .wpcf-coborrower.col-md-6 { + width: 100%; + border-right: none; + border-bottom: 1px solid #dee2e6; + } + + .credit-cols .wpcf-borrower.col-md-6:last-child, + .credit-cols .wpcf-coborrower.col-md-6:last-child { + border-bottom: none; + } +} + +/* Animation pour l'apparition/disparition */ +.wpcf-coborrower { + opacity: 1; + transition: opacity 0.3s ease; +} + +.wpcf-coborrower.d-none { + opacity: 0; + display: none !important; +} + +legend.sub-section { + margin-top: 15px; +} + +/* Styles pour le rappel de crédit */ +.credit-reminder { + position: fixed; + bottom: 20px; + left: 20px; + max-width: 400px; + z-index: 9999; + box-shadow: 0 2px 10px rgba(0,0,0,0.1); + border-radius: 8px; + background-color: #fff; + border: 1px solid #e0e0e0; + transition: all 0.3s ease; +} + +.credit-reminder:hover { + box-shadow: 0 4px 15px rgba(0,0,0,0.15); + transform: translateY(-2px); +} + +.credit-reminder .button { + background-color: #007bff; + color: white; + padding: 8px 15px; + text-decoration: none; + border-radius: 4px; + display: inline-block; + transition: background-color 0.3s ease; +} + +.credit-reminder .button:hover { + background-color: #0056b3; +} + +.credit-reminder h4 { + margin: 0 0 10px 0; + color: #333; + font-size: 1.1em; +} + +.credit-reminder p { + margin: 0 0 5px 0; + color: #666; + font-size: 0.95em; + line-height: 1.4; +} + +.credit-reminder .time-info { + color: #999; + font-size: 0.85em; + margin-top: 8px; +} + +.col-sim { + position: relative; +} + +.active_btn { + background: #ff921d !important; + border: none !important; +} + +/* Credit Reminder Button Styles */ +.credit-reminder-wrapper { + position: fixed; + bottom: 75px; + left: 15px; + z-index: 9999; +} + +.credit-reminder-btn { + background: #fff; + border-radius: 50%; + width: 45px; + height: 45px; + display: flex; + align-items: center; + justify-content: center; + box-shadow: 0 2px 10px rgba(0,0,0,0.2); + cursor: pointer; + transition: all 0.3s ease; + padding: 8px; + position: relative; +} + +.credit-reminder-btn:hover { + transform: scale(1.1); + box-shadow: 0 4px 15px rgba(0,0,0,0.3); +} + +.credit-reminder-btn img { + width: 100%; + height: 100%; + object-fit: contain; +} + +.notification-badge { + position: absolute; + top: -5px; + right: -5px; + background: #ff6b00; + color: white; + border-radius: 50%; + width: 22px; + height: 22px; + display: flex; + align-items: center; + justify-content: center; + font-size: 12px; + font-weight: bold; + border: 2px solid #fff; + box-shadow: 0 2px 5px rgba(0,0,0,0.2); +} + +.stimulated-results .btn_holder { + position: absolute; + bottom: 15px; + left: 15px; + right: 15px; + width: calc(100% - 30px); +} + +/**modal override**/ +.modal-backdrop.fade.show { + opacity: 0.5 !important; /* ou 1 selon votre préférence */ + z-index: 1050 !important; /* valeur Bootstrap standard, à ajuster si besoin */ +} + +.modal.fade.show { opacity: 1 !important; } + +section.co-emprunteur { + padding: 12px; + border-radius: 6px; +} + +.credit-incentive { + text-align: center; +} + +.fusion-tb-header .main-header-container { + z-index: 999 !important; +} + +.iziModal-overlay { + z-index: 1000 !important; +} + +#creditReminderModal { + z-index: 1001 !important; +} + + +@media (max-width: 768px) { + .credit-reminder { + left: 10px; + right: 10px; + bottom: 10px; + max-width: none; + } + .credit-reminder > div { + flex-direction: column; + text-align: center; + } + .credit-reminder .button { + margin-top: 10px; + width: 100%; + text-align: center; + } + + .credit-reminder-wrapper { + bottom: 75px; + left: 15px; + } + + .credit-reminder-btn { + width: 35px; + height: 35px; + padding: 6px; + } + + .notification-badge { + width: 18px; + height: 18px; + font-size: 10px; + } +} + +/* Spinner de chargement */ +.cd-loading-spinner { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + z-index: 1000; + width: 40px; + height: 40px; + border: 4px solid #f3f3f3; + border-top: 4px solid #ff6b00; + border-radius: 50%; + animation: cd-spin 1s linear infinite; +} + +@keyframes cd-spin { + 0% { transform: translate(-50%, -50%) rotate(0deg); } + 100% { transform: translate(-50%, -50%) rotate(360deg); } +} + +/* Animations de transition */ +@keyframes slideInUp { + 0% { + transform: translateY(100%); + } + 100% { + transform: translateY(0); + } +} + +@keyframes slideOutDown { + 0% { + transform: translateY(0); + } + 100% { + transform: translateY(100%); + } +} + +.animate-slide-in-up { + animation: slideInUp 0.5s ease-out forwards; +} + +.animate-slide-out-down { + animation: slideOutDown 0.5s ease-in forwards; +} + +.fade-out { + animation: fadeOut 0.3s ease-out forwards; +} + +.fade-in { + animation: fadeIn 0.3s ease-in forwards; +} + +@keyframes fadeOut { + from { + opacity: 1; + } + to { + opacity: 0; + } +} + +@keyframes fadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +/* Styles pour les boutons de navigation entre étapes */ + +section.bottom-form { + width: 100%; +} + +.form-buttons { + display: flex; + justify-content: space-between; + align-items: center; + gap: 20px; +} + +.form-buttons .btn { + flex: 1; + max-width: 200px; +} + +.form-buttons .btn-secondary { + background-color: #6c757d; + border-color: #6c757d; + color: #fff; +} + +.form-buttons .btn-secondary:hover { + background-color: #5a6268; + border-color: #545b62; + color: #fff; +} + +button.wpcf-btn-retirer { + padding: 8px 6px; + border-radius: 6px; + border: 1px solid #c0392b; + background-color: #fff; + color: #000; + font-size: 14px; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.5px; + transition: all 0.3s ease; +} + +button.wpcf-btn-retirer:hover { + background-color: #c0392b; + color: #fff; +} + +@media (max-width: 768px) { + .form-buttons { + flex-direction: column; + gap: 15px; + } + + .form-buttons .btn { + max-width: 100%; + width: 100%; + } +} + +/* ======================================== + SYSTÈME DE SAUVEGARDE AUTOMATIQUE LOCALSTORAGE + ======================================== */ + +/* Indicateur de sauvegarde */ +.auto-save-indicator { + position: fixed; + top: 20px; + right: 20px; + background: #28a745; + color: white; + padding: 10px 15px; + border-radius: 5px; + font-size: 14px; + z-index: 9999; + opacity: 0; + transform: translateY(-20px); + transition: all 0.3s ease; + box-shadow: 0 2px 10px rgba(0,0,0,0.1); +} + +.auto-save-indicator.show { + opacity: 1; + transform: translateY(0); +} + +.auto-save-indicator.saving { + background: #ffc107; + color: #212529; +} + +.auto-save-indicator.error { + background: #dc3545; +} + +/* Animation de pulsation pour indiquer la sauvegarde */ +.auto-save-indicator.saving::before { + content: ''; + display: inline-block; + width: 12px; + height: 12px; + border: 2px solid currentColor; + border-radius: 50%; + border-top-color: transparent; + animation: spin 1s linear infinite; + margin-right: 8px; +} + +@keyframes spin { + to { + transform: rotate(360deg); + } +} + +/* Style pour les champs modifiés */ +.field-modified { + border-color: #28a745 !important; + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25) !important; + transition: all 0.3s ease; +} + +/* Style pour les champs restaurés */ +.field-restored { + border-color: #17a2b8 !important; + box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.25) !important; + transition: all 0.3s ease; +} + +/* Message d'information localStorage */ +.localstorage-info { + background: #e7f3ff; + border: 1px solid #b3d9ff; + border-radius: 5px; + padding: 10px 15px; + margin-bottom: 20px; + font-size: 14px; + color: #0056b3; +} + +.localstorage-info .icon { + margin-right: 8px; + font-weight: bold; +} + +/* Bouton pour effacer les données sauvegardées */ +.clear-storage-btn { + background: #6c757d; + color: white; + border: none; + padding: 5px 10px; + border-radius: 3px; + font-size: 12px; + cursor: pointer; + margin-left: 10px; +} + +.clear-storage-btn:hover { + background: #5a6268; +} + +.simu_steps { + display: grid; + gap: 20px; + grid-template-columns: repeat(3, 1fr); + grid-template-rows: 1fr; +} + +.first-col, +.second-col, +.third-col { + padding: 15px; +} + +@media screen and (max-width: 992px) { + .simu_steps { + grid-template-columns: 1fr; + grid-template-rows: 1fr; + } + + .stimulated-results .btn_holder { + position: relative; + } +} + +/* Responsive pour la sauvegarde automatique */ +@media (max-width: 768px) { + .auto-save-indicator { + top: 10px; + right: 10px; + left: 10px; + text-align: center; + } +} \ No newline at end of file diff --git a/assets/css/credit-manager.css b/assets/css/credit-manager.css new file mode 100644 index 0000000..6970491 --- /dev/null +++ b/assets/css/credit-manager.css @@ -0,0 +1,1212 @@ +/* ======================================== + CREDIT MANAGER - NOTIFICATIONS + ======================================== */ + +/* Indicateur de sauvegarde / Notification */ +.auto-save-indicator { + position: fixed; + top: 20px; + right: 20px; + background: #28a745; + color: white; + padding: 12px 20px; + border-radius: 8px; + font-size: 14px; + font-weight: 500; + z-index: 9999; + opacity: 0; + transform: translateY(-20px); + transition: all 0.3s ease; + box-shadow: 0 4px 15px rgba(0,0,0,0.2); + display: flex; + align-items: center; + gap: 10px; +} + +.auto-save-indicator.show { + opacity: 1; + transform: translateY(0); +} + +.auto-save-indicator.saving { + background: #ffc107; + color: #212529; +} + +.auto-save-indicator.error { + background: #dc3545; + color: white; +} + +/* Animation de pulsation pour indiquer la sauvegarde */ +.auto-save-indicator.saving::before { + content: ''; + display: inline-block; + width: 12px; + height: 12px; + border: 2px solid currentColor; + border-radius: 50%; + border-top-color: transparent; + animation: spin 1s linear infinite; + margin-right: 8px; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +/* Icône de succès */ +.auto-save-indicator.show:not(.saving):not(.error)::before { + content: '✓'; + display: inline-flex; + align-items: center; + justify-content: center; + width: 18px; + height: 18px; + border-radius: 50%; + background: rgba(255, 255, 255, 0.3); + font-weight: bold; + font-size: 14px; +} + +/* Icône d'erreur */ +.auto-save-indicator.error::before { + content: '✕'; + display: inline-flex; + align-items: center; + justify-content: center; + width: 18px; + height: 18px; + border-radius: 50%; + background: rgba(255, 255, 255, 0.3); + font-weight: bold; + font-size: 14px; +} + +/* Responsive */ +@media (max-width: 768px) { + .auto-save-indicator { + top: 10px; + right: 10px; + font-size: 12px; + padding: 10px 15px; + } +} + +/* ======================================== + CREDIT MANAGER - STATUS QUICK FILTERS + ======================================== */ + +.status-quick-filters { + background: #fff; + border: 1px solid #ddd; + border-radius: 8px; + padding: 20px; + margin: 20px 0; + box-shadow: 0 2px 5px rgba(0,0,0,0.05); +} + +.status-quick-filters h3 { + margin: 0 0 15px 0; + padding-bottom: 10px; + border-bottom: 2px solid #0073aa; + font-size: 16px; + display: flex; + align-items: center; + gap: 8px; +} + +.status-filters-buttons { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); + gap: 15px; +} + +.status-filter-btn { + display: flex; + flex-direction: row; + align-items: center; + justify-content: flex-start; + gap: 8px; + padding: 10px 12px; + border: 2px solid #ddd; + border-radius: 8px; + background: linear-gradient(145deg, #ffffff, #f8f9fa); + cursor: pointer; + transition: all 0.3s ease; + font-family: inherit; + position: relative; + overflow: hidden; +} + +.status-filter-btn::before { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent); + transition: left 0.5s; +} + +.status-filter-btn:hover::before { + left: 100%; +} + +.status-filter-btn:hover { + transform: translateY(-2px); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); + border-color: #0073aa; +} + +/* Couleurs par statut - reprises des boutons d'action */ +.status-filter-btn.status-pending { + border-color: #ff9d00; +} + +.status-filter-btn.status-pending .status-icon { + color: #ff9d00; +} + +.status-filter-btn.status-pending.active { + background: linear-gradient(135deg, #ff9d00, #e68a00); + border-color: #ff9d00; + color: white; + box-shadow: 0 4px 15px rgba(255, 157, 0, 0.4); +} + +.status-filter-btn.status-pending:hover:not(.active) { + border-color: #ff9d00; + background: linear-gradient(145deg, #fff, #fff5e6); +} + +.status-filter-btn.status-accepted-unsigned { + border-color: #8B5CF6; +} + +.status-filter-btn.status-accepted-unsigned .status-icon { + color: #8B5CF6; +} + +.status-filter-btn.status-accepted-unsigned.active { + background: linear-gradient(135deg, #8B5CF6, #7C3AED); + border-color: #8B5CF6; + color: white; + box-shadow: 0 4px 15px rgba(139, 92, 246, 0.4); +} + +.status-filter-btn.status-accepted-unsigned:hover:not(.active) { + border-color: #8B5CF6; + background: linear-gradient(145deg, #fff, #F5F3FF); +} + +.status-filter-btn.status-accepted-filed { + border-color: #46b450; +} + +.status-filter-btn.status-accepted-filed .status-icon { + color: #46b450; +} + +.status-filter-btn.status-accepted-filed.active { + background: linear-gradient(135deg, #46b450, #3a9d42); + border-color: #46b450; + color: white; + box-shadow: 0 4px 15px rgba(70, 180, 80, 0.4); +} + +.status-filter-btn.status-accepted-filed:hover:not(.active) { + border-color: #46b450; + background: linear-gradient(145deg, #fff, #f0f9f1); +} + +.status-filter-btn.status-refused { + border-color: #dc3232; +} + +.status-filter-btn.status-refused .status-icon { + color: #dc3232; +} + +.status-filter-btn.status-refused.active { + background: linear-gradient(135deg, #dc3232, #c62828); + border-color: #dc3232; + color: white; + box-shadow: 0 4px 15px rgba(220, 50, 50, 0.4); +} + +.status-filter-btn.status-refused:hover:not(.active) { + border-color: #dc3232; + background: linear-gradient(145deg, #fff, #fff0f0); +} + +/* Bouton "Tous" */ +.status-filter-btn.status-filter-all.active { + border-color: #0073aa; + background: linear-gradient(135deg, #0073aa, #005a87); + color: white; + box-shadow: 0 4px 15px rgba(0, 115, 170, 0.3); +} + +/* Icônes actives en blanc */ +.status-filter-btn.active .status-icon, +.status-filter-btn.active .status-label, +.status-filter-btn.active .status-count { + color: white; +} + +.status-icon { + font-size: 18px; + line-height: 1; +} + +.status-label { + font-weight: 600; + font-size: 13px; + color: #23282d; + white-space: nowrap; +} + +.status-count { + font-size: 12px; + color: #666; + font-weight: 500; + margin-left: auto; +} + +.status-filter-btn:disabled { + opacity: 0.5; + cursor: not-allowed; +} + +.status-filter-btn:disabled:hover { + transform: none; + box-shadow: none; +} + +/* Animation au clic */ +.status-filter-btn:active { + transform: scale(0.95); +} + +/* Responsive */ +@media (max-width: 768px) { + .status-filters-buttons { + grid-template-columns: 1fr 1fr; + } + + .status-filter-btn { + padding: 12px 15px; + gap: 5px; + } + + .status-icon { + font-size: 20px; + } + + .status-label { + font-size: 12px; + } + + .status-count { + font-size: 11px; + } +} + +@media (max-width: 480px) { + .status-filters-buttons { + grid-template-columns: 1fr; + } +} + +/* ======================================== + CREDIT MANAGER - FILTERS PANEL + ======================================== */ + +.credit-filters-panel { + background: #fff; + border: 1px solid #ddd; + border-radius: 8px; + padding: 20px; + margin: 20px 0; + box-shadow: 0 2px 5px rgba(0,0,0,0.05); +} + +.credit-filters-panel h3 { + margin: 0 0 15px 0; + padding-bottom: 10px; + border-bottom: 2px solid #0073aa; + font-size: 16px; + display: flex; + align-items: center; + gap: 8px; +} + +.filters-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 15px; + margin-bottom: 15px; +} + +.filter-group { + display: flex; + flex-direction: column; + width: 100%; +} + +.filter-group label { + font-weight: 600; + margin-bottom: 5px; + color: #23282d; + font-size: 13px; +} + +.filter-group input[type="text"], +.filter-group input[type="number"], +.filter-group input[type="date"], +.filter-group select { + padding: 8px; + border: 1px solid #ddd; + border-radius: 4px; + font-size: 13px; +} + +.filter-group select optgroup { + font-weight: 700; + font-style: normal; + color: #0073aa; + padding: 5px 0; +} + +.filter-group select option { + padding: 5px 10px; +} + +.filter-range .range-inputs { + display: flex; + flex-direction: column; + align-items: center; + gap: 8px; +} + +.filter-range .range-inputs input { + flex: 1; +} + +.filter-range .range-inputs span { + font-weight: 600; + color: #666; +} + +.filter-actions { + display: flex; + gap: 10px; + padding-top: 15px; + border-top: 1px solid #eee; +} + +.filter-actions .button { + display: inline-flex; + align-items: center; + gap: 5px; +} + +/* ======================================== + CREDIT MANAGER - MODAL STYLES + ======================================== */ + +/* Modal Container - Style Bootstrap élégant */ +.credit-modal { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 999999; + display: none; + animation: fadeIn 0.3s ease-out; +} + +.credit-modal.show { + display: flex; + align-items: center; + justify-content: center; + animation: fadeIn 0.3s ease-out; +} + +.credit-modal-overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: linear-gradient(135deg, rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.8)); + backdrop-filter: blur(5px); + animation: fadeIn 0.3s ease-out; +} + +.credit-modal-content { + position: relative; + background: linear-gradient(145deg, #ffffff, #f8f9fa); + margin: 0; + width: 90%; + max-width: 1000px; + max-height: 90vh; + overflow-y: auto; + border-radius: 20px; + box-shadow: + 0 20px 60px rgba(0, 0, 0, 0.3), + 0 0 0 1px rgba(255, 255, 255, 0.1), + inset 0 1px 0 rgba(255, 255, 255, 0.2); + padding: 0; + transform: scale(0.9); + animation: modalSlideIn 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards; + border: 1px solid rgba(255, 255, 255, 0.2); +} + +.credit-modal-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 25px 30px; + border-bottom: 1px solid rgba(0, 0, 0, 0.1); + background: linear-gradient(135deg, #001954 0%, #003580 100%); + border-radius: 20px 20px 0 0; + position: relative; + overflow: hidden; +} + +.credit-modal-header::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: linear-gradient(135deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.05)); + pointer-events: none; +} + +.credit-modal-header h2 { + margin: 0; + color: #ffffff; + font-size: 24px; + font-weight: 600; + text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); + position: relative; + z-index: 1; +} + +.credit-modal-close { + background: rgba(255, 255, 255, 0.2); + border: none; + font-size: 20px; + cursor: pointer; + color: #ffffff; + padding: 8px; + width: 40px; + height: 40px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + transition: all 0.3s ease; + position: relative; + z-index: 1; + backdrop-filter: blur(10px); +} + +.credit-modal-close:hover { + background: rgba(255, 255, 255, 0.3); + transform: scale(1.1); + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); +} + +.credit-modal-body { + padding: 20px; +} + +.credit-form { + padding: 20px; + margin: 0; +} + +/* Form Grid */ +.form-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 20px; +} + +/* Form Columns - Layout en deux colonnes */ +.form-columns { + display: flex; + gap: 0; + margin: 0; + padding: 0; +} + +.form-column { + flex: 1; + padding: 0; + margin: 0; +} + +.form-column:first-child { + border-right: 1px solid #e0e0e0; + padding-right: 20px; +} + +.form-column:last-child { + padding-left: 20px; +} + +.form-group { + display: flex; + flex-direction: column; + margin-bottom: 20px; +} + +.form-group-full { + display: flex; + flex-direction: column; + width: 100%; + margin-top: 20px; + padding-top: 20px; + border-top: 1px solid #e0e0e0; + grid-column: 1 / -1; +} + +.form-group label { + margin-bottom: 5px; + font-weight: 600; + color: #333; +} + +.form-group input, +.form-group select, +.form-group textarea { + padding: 8px 12px; + border: 1px solid #ddd; + border-radius: 4px; + font-size: 14px; + transition: border-color 0.3s ease; +} + +.form-group input:focus, +.form-group select:focus, +.form-group textarea:focus { + outline: none; + border-color: #001954; + box-shadow: 0 0 0 1px #001954; +} + +.form-actions { + display: flex; + justify-content: flex-end; + gap: 15px; + margin-top: 30px; + padding: 25px 30px; + border-top: 1px solid rgba(0, 0, 0, 0.1); + background: linear-gradient(135deg, #f8f9fa, #e9ecef); + border-radius: 0 0 20px 20px; +} + +.button { + padding: 12px 24px; + border: none; + border-radius: 12px; + cursor: pointer; + font-size: 14px; + font-weight: 600; + text-decoration: none; + display: inline-flex; + align-items: center; + gap: 8px; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + position: relative; + overflow: hidden; + min-width: 120px; + justify-content: center; +} + +.button::before { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); + transition: left 0.5s; +} + +.button:hover::before { + left: 100%; +} + +.button-primary { + background: linear-gradient(135deg, #001954 0%, #ff9d00 100%); + color: white; + box-shadow: 0 4px 15px rgba(0, 25, 84, 0.4); +} + +.button-primary:hover { + transform: translateY(-2px); + box-shadow: 0 8px 25px rgba(255, 157, 0, 0.6); +} + +.button-secondary { + background: linear-gradient(135deg, #f8f9fa, #e9ecef); + color: #495057; + border: 1px solid rgba(0, 0, 0, 0.1); + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); +} + +.button-secondary:hover { + background: linear-gradient(135deg, #e9ecef, #dee2e6); + transform: translateY(-2px); + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.15); +} + +/* ======================================== + CREDIT MANAGER - DATATABLE BUTTONS + ======================================== */ + +/* Conteneur des boutons DataTables */ +.dt-buttons { + display: flex; + gap: 10px; + margin-bottom: 20px; + padding: 15px; + background: #f9f9f9; + border-radius: 8px; + border: 1px solid #ddd; +} + +/* Boutons d'export Excel */ +.btn-export-excel { + background: linear-gradient(135deg, #1d6f42, #165a36) !important; + color: white !important; + border: none !important; + padding: 10px 20px !important; + border-radius: 6px !important; + font-weight: 600 !important; + cursor: pointer !important; + transition: all 0.3s ease !important; + display: inline-flex !important; + align-items: center !important; + gap: 8px !important; + box-shadow: 0 2px 5px rgba(29, 111, 66, 0.3) !important; +} + +.btn-export-excel:hover { + background: linear-gradient(135deg, #228b52, #1d6f42) !important; + transform: translateY(-2px) !important; + box-shadow: 0 4px 10px rgba(29, 111, 66, 0.4) !important; +} + +/* Boutons d'export CSV */ +.btn-export-csv { + background: linear-gradient(135deg, #0073aa, #005a87) !important; + color: white !important; + border: none !important; + padding: 10px 20px !important; + border-radius: 6px !important; + font-weight: 600 !important; + cursor: pointer !important; + transition: all 0.3s ease !important; + display: inline-flex !important; + align-items: center !important; + gap: 8px !important; + box-shadow: 0 2px 5px rgba(0, 115, 170, 0.3) !important; +} + +.btn-export-csv:hover { + background: linear-gradient(135deg, #008fd5, #0073aa) !important; + transform: translateY(-2px) !important; + box-shadow: 0 4px 10px rgba(0, 115, 170, 0.4) !important; +} + +/* Icônes dans les boutons */ +.btn-export-excel i, +.btn-export-csv i { + font-size: 16px; +} + +/* ======================================== + CREDIT MANAGER - TABLE STYLES + ======================================== */ + +.credit-actions-header { + margin-bottom: 20px; + padding: 15px 0; + border-bottom: 1px solid #ddd; +} + +.credit-actions-header .button { + display: inline-flex; + align-items: center; + gap: 5px; +} + +.credit-actions-header .description { + color: #666; + font-style: italic; + margin: 0; +} + +.credits-table { + margin-top: 20px; +} + +.credits-table th { + background-color: #f1f1f1; + font-weight: 600; +} + +.credits-table .actions-column { + text-align: center; + white-space: nowrap; +} + +.credits-table .actions-column .button { + margin: 0 2px; + display: inline-flex; + align-items: center; + gap: 3px; +} + +.credits-table .actions-column .button-small { + padding: 4px 8px; + font-size: 12px; +} + +.credits-table .button-link-delete { + color: #a00; +} + +.credits-table .button-link-delete:hover { + color: #dc3232; +} + +/* Badges de statut dans la table */ +.status-badge { + display: inline-block; + padding: 4px 8px; + border-radius: 6px; + font-size: 12px; + font-weight: 600; + line-height: 1; + color: #fff; + text-align: center; + border: 1px solid transparent; +} + +.status-badge.status-pending { + /* color: #7a4a00; + background: #fff5e6; */ + background: #ff9d00; + border-color: #ff9d00; +} + +.status-badge.status-accepted-unsigned { + /* color: #1f5d28; */ + /* background: #f0f9f1; */ + background: #8B5CF6; + border-color: #8B5CF6; +} + +.status-badge.status-accepted-filed { + /* color: #1f5d28; + background: #f0f9f1; */ + background: #46b450; + border-color: #46b450; +} + +.status-badge.status-refused { + /* color: #7a1a1a; + background: #fff0f0; */ + background: #dc3232; + border-color: #dc3232; +} + +/* ======================================== + CREDIT MANAGER - ACTIONS GRID (Adaptative) + ======================================== */ + +.credit-actions-grid { + display: grid; + grid-template-columns: repeat(2, 1fr); + grid-template-rows: 1fr 1fr; + gap: 5px; + padding: 5px; + width: 100%; + max-width: 120px; + margin: 0 auto; +} + +.credit-action-btn { + position: relative; + display: flex; + align-items: center; + justify-content: center; + width: 40px; + height: 40px; + border: none; + border-radius: 6px; + cursor: pointer; + font-size: 16px; + transition: all 0.3s ease; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); +} + +.credit-action-btn:hover { + transform: translateY(-2px); + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); +} + +.credit-action-btn i { + font-size: 16px; +} + +/* Couleurs des boutons */ +.btn-edit { + background: linear-gradient(135deg, #007cba, #0071a1); + color: white; +} + +.btn-edit:hover { + background: linear-gradient(135deg, #008fd5, #007cba); +} + +.btn-accepted-unsigned { + background: linear-gradient(135deg, #8B5CF6, #7C3AED); + color: white; +} + +.btn-accepted-unsigned:hover { + background: linear-gradient(135deg, #A78BFA, #8B5CF6); +} + +.btn-accepted-filed { + background: linear-gradient(135deg, #46b450, #3a9d42); + color: white; +} + +.btn-accepted-filed:hover { + background: linear-gradient(135deg, #55c95f, #46b450); +} + +.btn-refused { + background: linear-gradient(135deg, #dc3232, #c62828); + color: white; +} + +.btn-refused:hover { + background: linear-gradient(135deg, #e65454, #dc3232); +} + +/* Boutons désactivés */ +.credit-action-btn:disabled { + opacity: 0.4; + cursor: not-allowed; + pointer-events: none; + filter: grayscale(50%); +} + +.credit-action-btn:disabled:hover { + transform: none; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); +} + +/* Tooltips personnalisés */ +.credit-action-btn::before { + content: attr(title); + position: absolute; + bottom: 100%; + left: 50%; + transform: translateX(-50%) translateY(-5px); + background: rgba(0, 0, 0, 0.9); + color: white; + padding: 6px 10px; + border-radius: 4px; + font-size: 12px; + white-space: nowrap; + opacity: 0; + pointer-events: none; + transition: opacity 0.3s ease, transform 0.3s ease; + z-index: 1000; +} + +.credit-action-btn::after { + content: ''; + position: absolute; + bottom: 100%; + left: 50%; + transform: translateX(-50%); + border: 5px solid transparent; + border-top-color: rgba(0, 0, 0, 0.9); + opacity: 0; + pointer-events: none; + transition: opacity 0.3s ease; + z-index: 999; +} + +.credit-action-btn:hover::before { + opacity: 1; + transform: translateX(-50%) translateY(-10px); +} + +.credit-action-btn:hover::after { + opacity: 1; +} + +/* Ajustement pour petits écrans */ +@media (max-width: 768px) { + .credit-actions-grid { + max-width: 100px; + gap: 3px; + } + + .credit-action-btn { + width: 35px; + height: 35px; + font-size: 14px; + } + + .credit-action-btn i { + font-size: 14px; + } +} + +.no-credits { + text-align: center; + padding: 40px 20px; + color: #666; +} + +.no-credits .button-link { + color: #001954; + text-decoration: none; + border: none; + background: none; + cursor: pointer; + font-size: inherit; +} + +.no-credits .button-link:hover { + color: #ff9d00; + text-decoration: underline; +} + +/* ======================================== + STATISTIQUES + ======================================== */ + +.credit-stats-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + gap: 20px; + margin: 20px 0; +} + +.stats-card { + background: #fff; + border: 1px solid #ddd; + border-radius: 8px; + padding: 20px; + text-align: center; + box-shadow: 0 2px 4px rgba(0,0,0,0.1); + transition: transform 0.2s ease, box-shadow 0.2s ease; +} + +.stats-card:hover { + transform: translateY(-2px); + box-shadow: 0 4px 8px rgba(0,0,0,0.15); +} + +.stats-card h3 { + margin: 0 0 10px 0; + color: #333; + font-size: 16px; + font-weight: 600; +} + +.stats-number { + font-size: 32px; + font-weight: bold; + color: #001954; + margin: 10px 0; +} + +.stats-chart { + background: #fff; + border: 1px solid #ddd; + border-radius: 8px; + padding: 20px; + margin: 20px 0; + box-shadow: 0 2px 4px rgba(0,0,0,0.1); +} + +.stats-chart h3 { + margin: 0 0 15px 0; + color: #333; + font-size: 18px; + font-weight: 600; +} + +/* ======================================== + RESPONSIVE DESIGN + ======================================== */ + +/* Animations */ +@keyframes fadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +@keyframes modalSlideIn { + from { + opacity: 0; + transform: scale(0.8) translateY(-50px); + } + to { + opacity: 1; + transform: scale(1) translateY(0); + } +} + +@keyframes slideOut { + from { + opacity: 1; + transform: scale(1) translateY(0); + } + to { + opacity: 0; + transform: scale(0.8) translateY(-50px); + } +} + +/* Animation de fermeture */ +.credit-modal.closing .credit-modal-content { + animation: slideOut 0.3s ease-in forwards; +} + +.credit-modal.closing .credit-modal-overlay { + animation: fadeOut 0.3s ease-in forwards; +} + +@keyframes fadeOut { + from { + opacity: 1; + } + to { + opacity: 0; + } +} + +/* Effet de focus sur les inputs */ +.form-group input:focus, +.form-group select:focus, +.form-group textarea:focus { + outline: none; + border-color: #001954; + box-shadow: + 0 0 0 3px rgba(0, 25, 84, 0.1), + 0 2px 10px rgba(255, 157, 0, 0.2); + transform: translateY(-1px); +} + +/* Modal Responsive */ +@media (max-width: 768px) { + .form-columns { + grid-template-columns: 1fr; + } + + .credit-modal-content { + width: 95%; + margin: 5% auto; + } + + .credit-modal-header { + padding: 20px; + } + + .credit-modal-header h2 { + font-size: 20px; + } + + .form-actions { + flex-direction: column; + gap: 10px; + } + + .button { + width: 100%; + } +} + +/* Table Responsive */ +@media (max-width: 1200px) { + .credits-table { + font-size: 12px; + } + + .credits-table th, + .credits-table td { + padding: 8px 4px; + } +} + +@media (max-width: 768px) { + .credits-table { + display: block; + overflow-x: auto; + white-space: nowrap; + } + + .credits-table thead, + .credits-table tbody, + .credits-table th, + .credits-table td, + .credits-table tr { + display: block; + } + + .credits-table thead tr { + position: absolute; + top: -9999px; + left: -9999px; + } + + .credits-table tr { + border: 1px solid #ccc; + margin-bottom: 10px; + padding: 10px; + } + + .credits-table td { + border: none; + position: relative; + padding-left: 50%; + white-space: normal; + } + + .credits-table td:before { + content: attr(data-label) ": "; + position: absolute; + left: 6px; + width: 45%; + padding-right: 10px; + white-space: nowrap; + font-weight: bold; + } +} diff --git a/assets/css/datatables-credit-manager.css b/assets/css/datatables-credit-manager.css new file mode 100644 index 0000000..5294552 --- /dev/null +++ b/assets/css/datatables-credit-manager.css @@ -0,0 +1,268 @@ +/* DataTables Credit Manager Styles */ + +/* Table styling */ +#credits-datatable { + width: 100% !important; + border-collapse: collapse; + margin-top: 20px; +} + +#credits-datatable thead th { + background-color: #f1f1f1; + border: 1px solid #ddd; + padding: 12px 8px; + text-align: left; + font-weight: bold; + color: #333; +} + +#credits-datatable tbody td { + border: 1px solid #ddd; + padding: 8px; + vertical-align: top; +} + +#credits-datatable tbody tr:nth-child(even) { + background-color: #f9f9f9; +} + +#credits-datatable tbody tr:hover { + background-color: #f5f5f5; +} + +/* DataTables controls */ +.dataTables_wrapper { + margin-top: 20px; +} + +.dataTables_length, +.dataTables_filter, +.dataTables_info, +.dataTables_paginate { + margin: 10px 0; +} + +.dataTables_filter input { + margin-left: 10px; + padding: 5px; + border: 1px solid #ddd; + border-radius: 3px; +} + +/* Export buttons styling */ +.dt-buttons { + margin-bottom: 20px; +} + +.dt-button { + background: #0073aa; + color: white; + border: none; + padding: 8px 16px; + margin-right: 5px; + border-radius: 3px; + cursor: pointer; + font-size: 13px; + text-decoration: none; + display: inline-block; +} + +.dt-button:hover { + background: #005a87; + color: white; +} + +.dt-button.buttons-excel { + background: #1d6f42; +} + +.dt-button.buttons-csv { + background: #f39c12; +} + +.dt-button.buttons-pdf { + background: #e74c3c; +} + +.dt-button.buttons-print { + background: #6c757d; +} + +/* Responsive table */ +@media (max-width: 768px) { + .dataTables_wrapper .dataTables_length, + .dataTables_wrapper .dataTables_filter { + text-align: center; + margin: 10px 0; + } + + .dt-buttons { + text-align: center; + margin-bottom: 15px; + } + + .dt-button { + margin: 2px; + font-size: 12px; + padding: 6px 12px; + } +} + +/* Loading spinner */ +.dataTables_processing { + background: rgba(255, 255, 255, 0.9); + border: 1px solid #ddd; + border-radius: 3px; + color: #333; + font-size: 14px; + font-weight: bold; + left: 50%; + margin-left: -100px; + margin-top: -20px; + padding: 20px; + position: absolute; + text-align: center; + top: 50%; + width: 200px; + z-index: 2000; +} + +/* Action buttons in table */ +.action-buttons { + white-space: nowrap; +} + +.action-buttons .button { + margin: 2px; + padding: 4px 8px; + font-size: 12px; +} + +/* Modal styling for credit form */ +.credit-modal { + display: none; + position: fixed; + z-index: 1000; + left: 0; + top: 0; + width: 100%; + height: 100%; + background-color: rgba(0,0,0,0.5); +} + +.credit-modal-content { + background-color: #fefefe; + margin: 5% auto; + padding: 20px; + border: 1px solid #888; + width: 90%; + max-width: 800px; + max-height: 80vh; + overflow-y: auto; + border-radius: 5px; +} + +.credit-modal-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 20px; + padding-bottom: 10px; + border-bottom: 1px solid #ddd; +} + +.credit-modal-close { + color: #aaa; + font-size: 28px; + font-weight: bold; + cursor: pointer; +} + +.credit-modal-close:hover { + color: #000; +} + +/* Form styling */ +.credit-form { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 15px; +} + +.credit-form .form-group { + display: flex; + flex-direction: column; +} + +.credit-form .form-group.full-width { + grid-column: 1 / -1; +} + +.credit-form label { + font-weight: bold; + margin-bottom: 5px; + color: #333; +} + +.credit-form input, +.credit-form textarea, +.credit-form select { + padding: 8px; + border: 1px solid #ddd; + border-radius: 3px; + font-size: 14px; +} + +.credit-form textarea { + resize: vertical; + min-height: 80px; +} + +.credit-form .required { + color: #e74c3c; +} + +/* Success/Error messages */ +.credit-message { + padding: 10px; + margin: 10px 0; + border-radius: 3px; + display: none; +} + +.credit-message.success { + background-color: #d4edda; + color: #155724; + border: 1px solid #c3e6cb; +} + +.credit-message.error { + background-color: #f8d7da; + color: #721c24; + border: 1px solid #f5c6cb; +} + +/* Loading state */ +.loading { + opacity: 0.6; + pointer-events: none; +} + +/* Custom scrollbar for modal */ +.credit-modal-content::-webkit-scrollbar { + width: 8px; +} + +.credit-modal-content::-webkit-scrollbar-track { + background: #f1f1f1; + border-radius: 4px; +} + +.credit-modal-content::-webkit-scrollbar-thumb { + background: #c1c1c1; + border-radius: 4px; +} + +.credit-modal-content::-webkit-scrollbar-thumb:hover { + background: #a8a8a8; +} diff --git a/assets/css/fonts.css b/assets/css/fonts.css new file mode 100644 index 0000000..23480a6 --- /dev/null +++ b/assets/css/fonts.css @@ -0,0 +1,160 @@ +/* cyrillic-ext */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 400; + src: url(https://fonts.gstatic.com/s/raleway/v19/1Ptug8zYS_SKggPNyCAIT5lu.woff2) format('woff2'); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 400; + src: url(https://fonts.gstatic.com/s/raleway/v19/1Ptug8zYS_SKggPNyCkIT5lu.woff2) format('woff2'); + unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* vietnamese */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 400; + src: url(https://fonts.gstatic.com/s/raleway/v19/1Ptug8zYS_SKggPNyCIIT5lu.woff2) format('woff2'); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 400; + src: url(https://fonts.gstatic.com/s/raleway/v19/1Ptug8zYS_SKggPNyCMIT5lu.woff2) format('woff2'); + unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 400; + src: url(https://fonts.gstatic.com/s/raleway/v19/1Ptug8zYS_SKggPNyC0ITw.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 500; + src: url(https://fonts.gstatic.com/s/raleway/v19/1Ptug8zYS_SKggPNyCAIT5lu.woff2) format('woff2'); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 500; + src: url(https://fonts.gstatic.com/s/raleway/v19/1Ptug8zYS_SKggPNyCkIT5lu.woff2) format('woff2'); + unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* vietnamese */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 500; + src: url(https://fonts.gstatic.com/s/raleway/v19/1Ptug8zYS_SKggPNyCIIT5lu.woff2) format('woff2'); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 500; + src: url(https://fonts.gstatic.com/s/raleway/v19/1Ptug8zYS_SKggPNyCMIT5lu.woff2) format('woff2'); + unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 500; + src: url(https://fonts.gstatic.com/s/raleway/v19/1Ptug8zYS_SKggPNyC0ITw.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 600; + src: url(https://fonts.gstatic.com/s/raleway/v19/1Ptug8zYS_SKggPNyCAIT5lu.woff2) format('woff2'); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 600; + src: url(https://fonts.gstatic.com/s/raleway/v19/1Ptug8zYS_SKggPNyCkIT5lu.woff2) format('woff2'); + unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* vietnamese */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 600; + src: url(https://fonts.gstatic.com/s/raleway/v19/1Ptug8zYS_SKggPNyCIIT5lu.woff2) format('woff2'); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 600; + src: url(https://fonts.gstatic.com/s/raleway/v19/1Ptug8zYS_SKggPNyCMIT5lu.woff2) format('woff2'); + unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 600; + src: url(https://fonts.gstatic.com/s/raleway/v19/1Ptug8zYS_SKggPNyC0ITw.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 700; + src: url(https://fonts.gstatic.com/s/raleway/v19/1Ptug8zYS_SKggPNyCAIT5lu.woff2) format('woff2'); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 700; + src: url(https://fonts.gstatic.com/s/raleway/v19/1Ptug8zYS_SKggPNyCkIT5lu.woff2) format('woff2'); + unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* vietnamese */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 700; + src: url(https://fonts.gstatic.com/s/raleway/v19/1Ptug8zYS_SKggPNyCIIT5lu.woff2) format('woff2'); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 700; + src: url(https://fonts.gstatic.com/s/raleway/v19/1Ptug8zYS_SKggPNyCMIT5lu.woff2) format('woff2'); + unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 700; + src: url(https://fonts.gstatic.com/s/raleway/v19/1Ptug8zYS_SKggPNyC0ITw.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} diff --git a/assets/css/fonts/glyphicons-halflings-regular.eot b/assets/css/fonts/glyphicons-halflings-regular.eot new file mode 100644 index 0000000..b93a495 Binary files /dev/null and b/assets/css/fonts/glyphicons-halflings-regular.eot differ diff --git a/assets/css/fonts/glyphicons-halflings-regular.svg b/assets/css/fonts/glyphicons-halflings-regular.svg new file mode 100644 index 0000000..94fb549 --- /dev/null +++ b/assets/css/fonts/glyphicons-halflings-regular.svg @@ -0,0 +1,288 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/css/fonts/glyphicons-halflings-regular.ttf b/assets/css/fonts/glyphicons-halflings-regular.ttf new file mode 100644 index 0000000..1413fc6 Binary files /dev/null and b/assets/css/fonts/glyphicons-halflings-regular.ttf differ diff --git a/assets/css/fonts/glyphicons-halflings-regular.woff b/assets/css/fonts/glyphicons-halflings-regular.woff new file mode 100644 index 0000000..9e61285 Binary files /dev/null and b/assets/css/fonts/glyphicons-halflings-regular.woff differ diff --git a/assets/css/fonts/glyphicons-halflings-regular.woff2 b/assets/css/fonts/glyphicons-halflings-regular.woff2 new file mode 100644 index 0000000..64539b5 Binary files /dev/null and b/assets/css/fonts/glyphicons-halflings-regular.woff2 differ diff --git a/assets/css/form_main.css b/assets/css/form_main.css new file mode 100644 index 0000000..41f369d --- /dev/null +++ b/assets/css/form_main.css @@ -0,0 +1,9 @@ +.wpcf-prototype { + display: none; +} + +.warning-message { + color: #f44336; + font-weight: bold; + margin-top: 1rem !important; +} \ No newline at end of file diff --git a/assets/css/iziModal.min.css b/assets/css/iziModal.min.css new file mode 100644 index 0000000..4517966 --- /dev/null +++ b/assets/css/iziModal.min.css @@ -0,0 +1,6 @@ +/* +* iziModal | v1.6.1 +* https://izimodal.marcelodolza.com +* by Marcelo Dolza. +*/ +.iziModal{display:none;position:fixed;top:0;bottom:0;left:0;right:0;margin:auto;background:#fff;box-shadow:0 0 8px rgba(0,0,0,.3);transition:margin-top .3s ease,height .3s ease;transform:translateZ(0);box-sizing:border-box}.iziModal *{box-sizing:border-box;-webkit-font-smoothing:antialiased}.iziModal::after{content:'';width:100%;height:0;opacity:0;position:absolute;left:0;bottom:0;z-index:1;background:-moz-linear-gradient(top,rgba(0,0,0,0) 0,rgba(0,0,0,.35) 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,rgba(0,0,0,0)),color-stop(100%,rgba(0,0,0,.35)));background:-webkit-linear-gradient(top,rgba(0,0,0,0) 0,rgba(0,0,0,.35) 100%);background:-o-linear-gradient(top,rgba(0,0,0,0) 0,rgba(0,0,0,.35) 100%);background:-ms-linear-gradient(top,rgba(0,0,0,0) 0,rgba(0,0,0,.35) 100%);background:linear-gradient(to bottom,rgba(0,0,0,0) 0,rgba(0,0,0,.35) 100%);transition:height .3s ease-in-out,opacity .3s ease-in-out;pointer-events:none}.iziModal.hasShadow::after{height:30px;opacity:1}.iziModal .iziModal-progressbar{position:absolute;left:0;top:0;width:100%;z-index:1}.iziModal .iziModal-progressbar>div{height:2px;width:100%}.iziModal .iziModal-header{background:#88a0b9;padding:14px 18px 15px 18px;box-shadow:inset 0 -10px 15px -12px rgba(0,0,0,.3),0 0 0 #555;overflow:hidden;position:relative;z-index:10}.iziModal .iziModal-header-icon{font-size:40px;color:rgba(255,255,255,.5);padding:0 15px 0 0;margin:0;float:left}.iziModal .iziModal-header-title{color:#fff;font-size:18px;font-weight:600;line-height:1.3}.iziModal .iziModal-header-subtitle{color:rgba(255,255,255,.6);font-size:12px;line-height:1.45}.iziModal .iziModal-header-subtitle,.iziModal .iziModal-header-title{display:block;margin:0;padding:0;font-family:Lato,Arial;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:left}.iziModal .iziModal-header-buttons{position:absolute;top:50%;right:10px;margin:-17px 0 0 0}.iziModal .iziModal-button{display:block;float:right;z-index:2;outline:0;height:34px;width:34px;border:0;padding:0;margin:0;opacity:.3;border-radius:50%;transition:transform .3s cubic-bezier(.16,.81,.32,1),opacity .3s ease;background-size:67%!important;-webkit-tap-highlight-color:transparent;-webkit-tap-highlight-color:transparent}.iziModal .iziModal-button-close{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAYAAAAehFoBAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTMyIDc5LjE1OTI4NCwgMjAxNi8wNC8xOS0xMzoxMzo0MCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUuNSAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6ODZCQkIzQ0I0RTg0MTFFNjlBODI4QTFBRTRBMkFCMDQiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6ODZCQkIzQ0M0RTg0MTFFNjlBODI4QTFBRTRBMkFCMDQiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4NkJCQjNDOTRFODQxMUU2OUE4MjhBMUFFNEEyQUIwNCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo4NkJCQjNDQTRFODQxMUU2OUE4MjhBMUFFNEEyQUIwNCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PsgTJLcAAALJSURBVHja3JnLS1VBHMfvQ7g9dBXRRrwEFRciAhMi1JRW1aIHVEIYEkW0iVpUhOD/ICK6cFMgSbUpC6VFkQa9NtpjkauriRY9Noa3pHT8/mIODMM5Or85o87pC5/NPf5mvmc8M7+Z36SFEKkY2gj2gUawF2wHW8A6+fwv+A6KYAQMg+dg2rbDtKXhGnAaHJIms4zYz9J4HxgAf1g9k2EGteAhWBBuNApaQNrUg6nRTaAbzIuV0RCocWW4DoyJlVcJXI5ruFk2tJqi/2TWxvA5sXbqA2Ucw01i7dVjargazAo/dE33p6/DlAheg50pP0SJpwG8CH7IaH/Q5pFZUhnoArkwwwVwJeWfdoMLYYZvqG+yTGo9CerAoIWBT+A4qAdPDWOugwo1NVcxJtpFZRLkwH3GJCqCghJfxVjnz1JMMMKnwAbGRAg0B5rAA4O4CblZ+qj8tkBjZthvSzDCtFIMM0ZpQhslk5Eej4jpZ/T7G+ygwG1ghrk+jjNMFy1eMPJzpOAzlou6iWmXZkm91EBHjEwUZXoQTDk2SxqhRh7HTJ9hpstB3rFZ0ldq6J2DnB9m2rXZfxOPlrX1DrJRXiaBXSHPaMHvB0cd9JPLpBImMvzLQTuUFA6A9yHPfoIjhsllOc1l5N4grtmDWgYrl5+JTUZcSjNkeMyxWdpA3ZN72IJj01OJTByJS82J2/wQVxmB5y1HK8x0JWMf/kzdD98FJcY5S51gdwyTQl6eUAraspo27PeWXgy8afim0+CELAwOWHyH9EkdkyWwJ4Yxk6BCP+bTm48anutWW5dAp34IpbW03UOzb0FPVEHbx0LKfvAyqpAyKw97JU8Mt6pml6rAJ6oY6Eu5NfvfF7QTeWWQyEsZr6694lwsNoPD8mKRo29gCNwGj7gXi7aGA1EBcY+8vq0GW8FmJb3Pgx9gEnwAr8Ab8MW2w0UBBgAVyyyaohV7ewAAAABJRU5ErkJggg==) no-repeat 50% 50%}.iziModal .iziModal-button-fullscreen{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAYAAAAehFoBAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTMyIDc5LjE1OTI4NCwgMjAxNi8wNC8xOS0xMzoxMzo0MCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUuNSAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RTBBOUI4RUM0RTg0MTFFNjk0NTY4NUNFRkZFNEFEQzIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RTBBOUI4RUQ0RTg0MTFFNjk0NTY4NUNFRkZFNEFEQzIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpFMEE5QjhFQTRFODQxMUU2OTQ1Njg1Q0VGRkU0QURDMiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpFMEE5QjhFQjRFODQxMUU2OTQ1Njg1Q0VGRkU0QURDMiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PrQO6gAAAANmSURBVHjazJlbSBRRGMd3x92i0ForRRMiKiUoX4ouiFlJkRVBDxW9GJERwUasvdRT9FD00osRQtAFqegGBUHRBY0uaCVKEkSRpVR0tSwrQtp1+p/4Bk7D7M45M/Ot/uGHu+Psmf+c+eY753wnbJpmyIfGgvmgiv6WgkKQBwzwE3wBr0AnuAta6ZgnhT0aFuY2ghoyGdH4bS+4Dc6CZjCkdWVhWIPF4JoZnB6CDToeVE8sBidNPt0E5UEZrgG9Jr8GwHa/huMgaWZXDSDsxfBuc/jUBAwdw3Fz+NWoang5SJkjQwm7P3seLqQEX2LLfgfBdZcMORMcBqNDwekPqASP0uXhpjR3Ok0x/fUw9HIHGGVdw5DuRtzJpgxDsJui2qOWmuaAOuuLbHivz4YLwLgQj/aAXNmwuItlHhtbA7pAG5jEZHgKWCcbrhUTIY+NPQVjqFFObbYMi/hc6aOhl2AJ9TKnFoIyYXgemKEzJQXVVkyR3oFVzKZFuqw2qHdyFPKhrHPgMoWC3fRjRtNVVg+7SR5IiqmXxUt60cG0CK/vTIZniZVCmcKJF0C3ZNjKBqvJ9Hrwm46tsN1EkCoRQ/M3fBjvs6GrYAvdwHEfGcd1qBaGkwoxrKI+xjz83yJ0iLFHApd46X4xX+M+WECh4lepCNUIcpnMijrEWtAvTRHrbOd8FZNG8uA2Nf0hpmwtjBPwpQ5T0GPS/+tBAZhIq+b3Lu09EyHRwRgO+0C+7dhWcII+PwCf6Sk/Aa9d2vtn+A7nyASugJiD6YSDQcOlvVbxiCaAN8xrs3sgprBiac/QhlhnzjUo6JuZM0UlDS5FPtoQIdNlPYJTWUihFaDex+9Pg6T1KHJAJ2NI7ASllA28hEQ/KJIXoSlwgKlnh+jFe+GjLtwIPtjfyktUt+UaUZWqvw7H3oJD1peI7eQdoF1xWa+zQikHH13OmwqmOxxP0EiZtgK/DRwNuIcHwSeXc2K01WAPhbhKBb5hBNTVbskVH7fqpZGhbJUNtYF83fqwQSXPbOsGjb6etwx2gcEsmT3iFAZeNmUqaMeHSz2qu0k6W15Rqsx3B2i0D+xXGAHTFrRVlEeFuVoqH+ku6VNUbDkPzlAtg30nVK66i8rRIjAbTKaSQVQyN0DD6nOqcLZQld9TLfmvAAMAeMcvp3eCFqQAAAAASUVORK5CYII=) no-repeat 50% 50%}.iziModal.isFullscreen .iziModal-button-fullscreen{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAYAAAAehFoBAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTMyIDc5LjE1OTI4NCwgMjAxNi8wNC8xOS0xMzoxMzo0MCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUuNSAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MkFFRTU5NDA0RTg1MTFFNjk0NEZFQzBGMkVBMDYyRDkiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MkFFRTU5NDE0RTg1MTFFNjk0NEZFQzBGMkVBMDYyRDkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDoyQUVFNTkzRTRFODUxMUU2OTQ0RkVDMEYyRUEwNjJEOSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDoyQUVFNTkzRjRFODUxMUU2OTQ0RkVDMEYyRUEwNjJEOSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PuDFfX8AAANASURBVHjazJlZSBVRGMfHcWlB0xZM68GKukQLYaGkmEUR2EsvRfQS+BSJPUQE+lTR8hqIZY8hFS0ERVCRoW3gpUApghYpszLTVnCB3O70/+K7MAwzc78Z58z4hx8XzpzvzJ+Zc+d85ztphmFoU9BsUAoq+XcFyAc5QAfD4BfoBp3gCWjnNl9K82mYzO0FVWwyw0NsD3gIroBWkPB0ZzLsgc3grhGcnoE9XjxIOxaCC4Y6tYC1QRmuAj2Geg2CA1M1XAsmjHDVANL8GK4zolMz0L0YrjWiV5PU8HYw6TBIf8imD6UynA96HYKPg3mgMUTDY6DUzXCzQ+AxSz+r6QEQZz4HbLoDZNkZrnAIoOlRZjN1Gk3XS0zty/gTFaRq7Ay3uAR8BcU2ps/z9QJTWw74HrDhTyDbbHg9SKQI+sb9rKa3mV8ZmAt+KJjP1TS+zinFPkqEUqQdBeAOKLa0UwIzpqlXtcYpIKWIO4RBZPoRKNfC10YQI8MlYLkwaAB8ABsiMDwDbKU8dgtIFwRMgJ3guRadKpNPWBMa7tOi1WoyHJPuTsC4oN+IQsOLM3gPJlEWqOE/neMGBqwDeYoMz6G8c0I4h6eFyHBC8A2eVoaH8JutaPwuUA/+uvSht1sHKgTjTWZwjUCVYdrK3xT0iwkND+lc5FClUQ9fINHCRYY7FBrWPSz5Er2lAR9H9P+hpfYGl64OCmPadQ7ojcDwOJetysBMQX/6mrWS4d+cIoYtMnAEnBT2fwVeJufYxZBMFoKFlrajQtOX/uczvEtIB50Kdgn1lt3JGdANltjsXE64jPMnuQ1LPuFJcFrBE11gzQXAUnAPFNk86esO4zSBfmu5lVa9toCf8DC4Ba6C22DEdO01KDLdP5fLr1Z94X2ibV1ilWVQ1XrDpvPAU4c+u1KVqvaHXI7q43ltp3PSYmDDNCgGPrCUD1wN6y5lqzAUN89baX1Y55Jn2LrPRUffRwaHwWhIZs/aTQM/hzLlDp+coPRReprk5cgrkyvz7wM0+hOcAvOlPvwcLNIp526ux1H5aJbHeFpVX4Br4LLXWoffk9CkVnLlaBNYAxaBXJBpMjfIy+o7EAdtfIyb8HPDfwIMAM1WPs8F9tcxAAAAAElFTkSuQmCC) no-repeat 50% 50%}.iziModal .iziModal-button-close:hover{transform:rotate(180deg)}.iziModal .iziModal-button:hover{opacity:.8}.iziModal .iziModal-header.iziModal-noSubtitle{height:auto;padding:10px 15px 12px 15px}.iziModal .iziModal-header.iziModal-noSubtitle .iziModal-header-icon{font-size:23px;padding-right:13px}.iziModal .iziModal-header.iziModal-noSubtitle .iziModal-header-title{font-size:15px;margin:3px 0 0 0;font-weight:400}.iziModal .iziModal-header.iziModal-noSubtitle .iziModal-header-buttons{right:6px;margin:-16px 0 0 0}.iziModal .iziModal-header.iziModal-noSubtitle .iziModal-button{height:30px;width:30px}.iziModal-rtl{direction:rtl}.iziModal-rtl .iziModal-header{padding:14px 18px 15px 40px}.iziModal-rtl .iziModal-header-icon{float:right;padding:0 0 0 15px}.iziModal-rtl .iziModal-header-buttons{right:initial!important;left:10px}.iziModal-rtl .iziModal-button{float:left}.iziModal-rtl .iziModal-header-subtitle,.iziModal-rtl .iziModal-header-title{text-align:right;font-family:Tahoma,Lato,Arial;font-weight:500}.iziModal-rtl .iziModal-header.iziModal-noSubtitle{padding:10px 15px 12px 40px}.iziModal-rtl .iziModal-header.iziModal-noSubtitle .iziModal-header-icon{padding:0 0 0 13px}.iziModal.iziModal-light .iziModal-header-icon{color:rgba(0,0,0,.5)}.iziModal.iziModal-light .iziModal-header-title{color:#000}.iziModal.iziModal-light .iziModal-header-subtitle{color:rgba(0,0,0,.6)}.iziModal.iziModal-light .iziModal-button-close{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAYAAAAehFoBAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA4JpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTM4IDc5LjE1OTgyNCwgMjAxNi8wOS8xNC0wMTowOTowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDoyQTU1RUZDNzRFODQxMUU2ODAxOEUwQzg0QjBDQjI3OSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo1NEM4MTU1MEI4QUExMUU2QjNGOEVBMjg4OTRBRTg2NyIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo0RTNFNENDMkI4QUExMUU2QjNGOEVBMjg4OTRBRTg2NyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxNyAoTWFjaW50b3NoKSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjZjYzMwMmE1LWFlMjEtNDI3ZS1hMmE4LTJlYjhlMmZlY2E3NSIgc3RSZWY6ZG9jdW1lbnRJRD0iYWRvYmU6ZG9jaWQ6cGhvdG9zaG9wOjdmYmU3NGE3LTAxMDUtMTE3YS1hYmM3LWEzNWNkOWU1Yzc4NyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Po24QssAAANtSURBVHja3JlJaBRBFIa7ZxyTSXADHUkikuAawZNLEOOGGrwJQYko8R4RBQ+OICoqghJQUVwPYjzFY0QUBQU1kogoKO6CG0pcIwbiNibj/8JraNvu6Xo9NTOtP3xzSKe6/65+Ve9VlWlkp2IwGUwFE0E5GA4G8/U+0APegWfgHrgPuq0bpNNp0QPNgEYngHlgGpuMCNp2s+kr4BYM/8ql4WqwHEzP4mXteg7awOW0YlerPnQIaARLNBl1ikLlBDw/1WF4ClgHKozc6idogekz2RheANbaBlE+dB4chfF+qeHF3LOF0FWwF6b7nBe8RvecApolzQVr3C64GR4H1huFV51pmvV+hikRbABFRji0GqarMxluAGON8CgKmmA65mZ4DFhqhE9VPP//ZXgZiCmm1t1gI6XWAAY+gF0gCe4qtqlHL8fthkeBWsXGreA6eMgPviEw+x5sBZ3gAdjPCcNPI8Fsu+FawUCzz40psEfRNJndBl7b/pZmVLTQMkzJo0bQSys43iWm3cxS+DUJOmoSwqKCRmEZWKkYv6RSMBPc5lqXRGm0A1Q6XiaT2aSwo8jrK/qZwZlFIlXTusxa6iXDddTdARpnMj2ek9AWjWYH7h/lubcs4A28THdyAdOl0ezAmKNBNyLLiT0Btjti9zuHg06zpJKIprohwXNypcu1OIdGjYbnxCLGPyYy/EPDfejzbwYvXK59AzuFGdFLKTL8WYNZ59RVzGESJCNm0teI40E6zNIA2wSaA2REP32iaW0omKXRbJKTUVyYEVV0J8oxvEiQmiUZrFSz6XNkuJe3nBKCelaSbjOZrhLsd1BInYxweSeJq9YA6dYtuZCBI4JZ6jGW/W+sebhd0DAaMIO5mTYFW1+X6GeQ7TO3W0WyQj3cw0ulBg4nSUbcAY7zPVYp7ip95FXOH29Hb35AOPjypWMIh7PORSjFZVsIzdKW7AWvfYnTVNWHyCytHw+jd1Nehqks3KepvtChUzD7yGvE2/cduqxldQF1EWZb/PbWLF3jAVgo0WrlkN+c6hSd+rzlaSuaR7O0oX0wyIa2pVAdGaj0HCUVOqIq4dVwrg5lmmG2w+8f/9tjL6foYHE+Gy8Xtv3CPUpf7WauDxadKuIwoeNbOmoYDYbZ0ns/1wxUC7ykigs8sS/LpEe3vwUYALiKDDDSgEiSAAAAAElFTkSuQmCC) no-repeat 50% 50%}.iziModal.iziModal-light .iziModal-button-fullscreen{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAYAAAAehFoBAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA4JpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTM4IDc5LjE1OTgyNCwgMjAxNi8wOS8xNC0wMTowOTowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpEQTg1NTA2NTRFODQxMUU2OTQ0N0VERjY2Q0M5ODYwRCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo0RTNFNENCQkI4QUExMUU2QjNGOEVBMjg4OTRBRTg2NyIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo0RTNFNENCQUI4QUExMUU2QjNGOEVBMjg4OTRBRTg2NyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxNyAoTWFjaW50b3NoKSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjFlNTQwYzczLTVhZmEtNDJlYi04YzJlLWMwMzFlYmFiYmIyNiIgc3RSZWY6ZG9jdW1lbnRJRD0iYWRvYmU6ZG9jaWQ6cGhvdG9zaG9wOmVkYmRiMzM1LTAxMDUtMTE3YS1hYmM3LWEzNWNkOWU1Yzc4NyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PvIicdUAAAOvSURBVHjaxJlZbA1hFMe/qaItUUsspakg1laJ7UUisQuRvvTFA15sQSRCLBFrQryhHqxNHxEPtaQ8CCUkIrVVRbVBJdZYSrXVonr9/3pGxnTunZk78/X+k1+aO+1899/vnnvO+c4YKpi6ghEgW34OBD1BKjBAM6gH78Fz8BhUyrW/ikQivt7QiNMozU0DE8RkJx/3fgCPwA1QHvHp2K/hHJAPJqpwVA2K4flW2IZ7gyVgptKjh6AQxl+GYZi7uRr0U3rVBIpg+nIQwwvACpCkOk4XwYlosR3LMGN1qUqMroGDTqaNGDu7SiVWl+D3iP2i00c9HqxUidd8wzDy3HY4HRwCfWzXz4L7Lm+QKfHeOUTTLWAzdro6muH1YIbDjculWrmpUEM2YYXcCNMt9pAYE8WsWYLdlAxaNYTGMDDHKYYXBVy4B0jTFM/5iOcUc1fM/2JcnItNAYtBNzGtQ33BVHDV3OHpARqhV6CLLKpTs8yQYHxOCrDQO7AV1Gg2PBJhMYiGh4MMnx1eLkixXKsFuzSbZrrMpeGxHnqFFtvrTWCbhILd9AuNpnPMHXaTtZD0kl1mRdwSxXSjJsNZfONjcmqIJR5p3lp6Y+sXrAzsBz/lNXvmtZYMFKbqafi0pKQgKpOSPhmsC5BxXEs1Fz4fUr/7TWMe/q9bC2s3tJs1Df/Q/B5PwAZwJYS1WpPlo0zRZJZziL2gQU7I1GyHL7QSD26taVOytI26DpinxKypApvpk+C6dHlMnXskbUbT1yTpN3WJHWB327UCS3hUoc+tA/VyxP/ost5rGq7QWZnAdoe0eZgnYweDbgmgkoafgk8aTfNgsMNmmqfhC+Czj3V4T3mSBH255kxB0ztd4tNNDJkas2CUdkAKHQ3yAtxfijj/bdb7Cumyhmoyexzcs6Qwv2qUbPKvJDOtnNFklrF3R5qneA2XYHe/2A+ht1Xb3FZXRY1XTAjFTgtxJ45qKtWDpZK1g6dhIQuvBzjcy8FgQ6y8Nw+sCdnwL1Dn8jdMe6m2a+3ma9ESNUdOC1VixSH3bnPiYyraswnO0fqDIQkyW8WmCWab7b+I9TCF3+x0j2e+MPUA7LPGrVfD1F3VNsrPVR0zhS8BB5x21muzYa1Sy1Tb4y4d4qOwIi9Pk/wcj1gV50p5zQjJKAsJH8KcY4vpdYrjV0w9HMxxHjfKNpfwdMyRNuAmyy2M1vq5OegBNFMmR9lSHDizSLPMJGjuO2BZfSOtLKvpMylUvh/d/hFgAOH4+ibxGTZuAAAAAElFTkSuQmCC) no-repeat 50% 50%}.iziModal.iziModal-light.isFullscreen .iziModal-button-fullscreen{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAYAAAAehFoBAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3BpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTM4IDc5LjE1OTgyNCwgMjAxNi8wOS8xNC0wMTowOTowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDoyRUUxMkYxODRFODUxMUU2Qjc3RDk0MUUzMzJDRjBEOCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo0RTNFNENCRkI4QUExMUU2QjNGOEVBMjg4OTRBRTg2NyIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo0RTNFNENCRUI4QUExMUU2QjNGOEVBMjg4OTRBRTg2NyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxNyAoTWFjaW50b3NoKSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjgzM2MwOWZiLWJjOTEtNGVlZS05MDM1LTRkMmU2ZmE1ZjBmMiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDoyRUUxMkYxODRFODUxMUU2Qjc3RDk0MUUzMzJDRjBEOCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pv1Q9Z8AAAOXSURBVHjaxJlLbA1RGMfPjIs+EvoIRYt4FVUl2EkkRTxKUqQbG0SEho2FjUQ8YtEICbEgTdFYeK1KaGvVeoUltyStt0UlNE17aWhV2+v/9X5XJpMzc8/0zpn5kl+aO3Nm7r/fnPu9xhDp2URQDJbw3xkgB2QCAwyAPvANfARvQDsfG7V4PO7pC40xCiVxa8AKFjnOw7VdoA08BtG4R8VeBZeCKrBS+GPvQAM0P/NbcB7YBdYJPfYKXIXwL34IJm8eBFOFXusH9RDdnI7gLWA/MEVwdh/UOe1tN8G0V3eLcKwFXJCJNl08G5ZYsrWgWnZCJng5OOBwo1iAoisMw6hMJXgyOOywVW7xj+9BgKL3QHSxm+C9IF9y4U2GMlStRPQP8Jbp9lFwhJwE0RHrgaSV8N6xG238l7Zjtfx3K58/Bd7zsWngIqdnP2we2ACa7B7e6RL6joK5EtHNfL7b5u1Bn7dGFbycYRVM/8WyFJnuJK+z2iVwzFrMcF1h+Cx4ClhtFVyu8CW54ITE01EwFMAPcH1SMJWIqxQvItE1YHEIsXkhtkUhCV4ApiteFOPadn4IgseDMooSSxVrhWFwmkvCsKw06WGhKLhHhGuzSHChh9pZ5cc1oFFwfoTTsWrWqQCvXdZQEpkDsjUJziSv3Qu43k3LTA1BXqvRY/4DMjTd/yu4niJVm9wslCjcb4QE/9Qo+Al44baAmgpKCIqC+01OBLrsr8/de8zkiYwuUxWSq7iuM8JhantIqfYItkOepKBysnbycIfPXYKqURL6DhaBCQrrKcZHTa5loyEIJgHXwG3F9TQV+pxMGK0BiaTHn2OLEjcURbdi7XBSMO3jTxoEjtg+7wDnhG3spSD6F3hk7Tjoxnc0CJ5k+5wFCrhplYl2mmI24nyvvWumAE9z2zIfBW8WifnxIHc2yb6xiHtEoms0/hlGtpAPHCkgNDjFyZngPN88COvkPpEe+XGHbFcD7z53C+ybwKEAo0UPZ8QCybkmiL3sNvkheygSI08RYOSQiaUhd52sUpIZLWwJsYqkkdcZeHfIS66nc9XcZQRpNBY7C7F9Yy1OtonErDgSgNhGcEXmWa/VFA1O9onE6y4dRqGtXuVtkpf2iDy8EVR6GLykMnrsNFC867QF0hH8v3MVicFcuYdKy56uqQx4SukWQj3NOtJtQIt4ckSvbmdziMqy7HcS9xv0cn/Xwdn0A1drnl/d/hNgAGQa6Lgarp6BAAAAAElFTkSuQmCC) no-repeat 50% 50%}.iziModal .iziModal-loader{background:#fff url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDQiIGhlaWdodD0iNDQiIHZpZXdCb3g9IjAgMCA0NCA0NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBzdHJva2U9IiM5OTkiPiAgICA8ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZS13aWR0aD0iMiI+ICAgICAgICA8Y2lyY2xlIGN4PSIyMiIgY3k9IjIyIiByPSIxIj4gICAgICAgICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJyIiAgICAgICAgICAgICAgICBiZWdpbj0iMHMiIGR1cj0iMS40cyIgICAgICAgICAgICAgICAgdmFsdWVzPSIxOyAyMCIgICAgICAgICAgICAgICAgY2FsY01vZGU9InNwbGluZSIgICAgICAgICAgICAgICAga2V5VGltZXM9IjA7IDEiICAgICAgICAgICAgICAgIGtleVNwbGluZXM9IjAuMTY1LCAwLjg0LCAwLjQ0LCAxIiAgICAgICAgICAgICAgICByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgLz4gICAgICAgICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJzdHJva2Utb3BhY2l0eSIgICAgICAgICAgICAgICAgYmVnaW49IjBzIiBkdXI9IjEuNHMiICAgICAgICAgICAgICAgIHZhbHVlcz0iMTsgMCIgICAgICAgICAgICAgICAgY2FsY01vZGU9InNwbGluZSIgICAgICAgICAgICAgICAga2V5VGltZXM9IjA7IDEiICAgICAgICAgICAgICAgIGtleVNwbGluZXM9IjAuMywgMC42MSwgMC4zNTUsIDEiICAgICAgICAgICAgICAgIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPiAgICAgICAgPC9jaXJjbGU+ICAgICAgICA8Y2lyY2xlIGN4PSIyMiIgY3k9IjIyIiByPSIxIj4gICAgICAgICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJyIiAgICAgICAgICAgICAgICBiZWdpbj0iLTAuOXMiIGR1cj0iMS40cyIgICAgICAgICAgICAgICAgdmFsdWVzPSIxOyAyMCIgICAgICAgICAgICAgICAgY2FsY01vZGU9InNwbGluZSIgICAgICAgICAgICAgICAga2V5VGltZXM9IjA7IDEiICAgICAgICAgICAgICAgIGtleVNwbGluZXM9IjAuMTY1LCAwLjg0LCAwLjQ0LCAxIiAgICAgICAgICAgICAgICByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgLz4gICAgICAgICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJzdHJva2Utb3BhY2l0eSIgICAgICAgICAgICAgICAgYmVnaW49Ii0wLjlzIiBkdXI9IjEuNHMiICAgICAgICAgICAgICAgIHZhbHVlcz0iMTsgMCIgICAgICAgICAgICAgICAgY2FsY01vZGU9InNwbGluZSIgICAgICAgICAgICAgICAga2V5VGltZXM9IjA7IDEiICAgICAgICAgICAgICAgIGtleVNwbGluZXM9IjAuMywgMC42MSwgMC4zNTUsIDEiICAgICAgICAgICAgICAgIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPiAgICAgICAgPC9jaXJjbGU+ICAgIDwvZz48L3N2Zz4=) no-repeat 50% 50%;position:absolute;left:0;right:0;top:0;bottom:0;z-index:9}.iziModal .iziModal-content-loader{background:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDQiIGhlaWdodD0iNDQiIHZpZXdCb3g9IjAgMCA0NCA0NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBzdHJva2U9IiM5OTkiPiAgICA8ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZS13aWR0aD0iMiI+ICAgICAgICA8Y2lyY2xlIGN4PSIyMiIgY3k9IjIyIiByPSIxIj4gICAgICAgICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJyIiAgICAgICAgICAgICAgICBiZWdpbj0iMHMiIGR1cj0iMS40cyIgICAgICAgICAgICAgICAgdmFsdWVzPSIxOyAyMCIgICAgICAgICAgICAgICAgY2FsY01vZGU9InNwbGluZSIgICAgICAgICAgICAgICAga2V5VGltZXM9IjA7IDEiICAgICAgICAgICAgICAgIGtleVNwbGluZXM9IjAuMTY1LCAwLjg0LCAwLjQ0LCAxIiAgICAgICAgICAgICAgICByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgLz4gICAgICAgICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJzdHJva2Utb3BhY2l0eSIgICAgICAgICAgICAgICAgYmVnaW49IjBzIiBkdXI9IjEuNHMiICAgICAgICAgICAgICAgIHZhbHVlcz0iMTsgMCIgICAgICAgICAgICAgICAgY2FsY01vZGU9InNwbGluZSIgICAgICAgICAgICAgICAga2V5VGltZXM9IjA7IDEiICAgICAgICAgICAgICAgIGtleVNwbGluZXM9IjAuMywgMC42MSwgMC4zNTUsIDEiICAgICAgICAgICAgICAgIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPiAgICAgICAgPC9jaXJjbGU+ICAgICAgICA8Y2lyY2xlIGN4PSIyMiIgY3k9IjIyIiByPSIxIj4gICAgICAgICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJyIiAgICAgICAgICAgICAgICBiZWdpbj0iLTAuOXMiIGR1cj0iMS40cyIgICAgICAgICAgICAgICAgdmFsdWVzPSIxOyAyMCIgICAgICAgICAgICAgICAgY2FsY01vZGU9InNwbGluZSIgICAgICAgICAgICAgICAga2V5VGltZXM9IjA7IDEiICAgICAgICAgICAgICAgIGtleVNwbGluZXM9IjAuMTY1LCAwLjg0LCAwLjQ0LCAxIiAgICAgICAgICAgICAgICByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgLz4gICAgICAgICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJzdHJva2Utb3BhY2l0eSIgICAgICAgICAgICAgICAgYmVnaW49Ii0wLjlzIiBkdXI9IjEuNHMiICAgICAgICAgICAgICAgIHZhbHVlcz0iMTsgMCIgICAgICAgICAgICAgICAgY2FsY01vZGU9InNwbGluZSIgICAgICAgICAgICAgICAga2V5VGltZXM9IjA7IDEiICAgICAgICAgICAgICAgIGtleVNwbGluZXM9IjAuMywgMC42MSwgMC4zNTUsIDEiICAgICAgICAgICAgICAgIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPiAgICAgICAgPC9jaXJjbGU+ICAgIDwvZz48L3N2Zz4=) no-repeat 50% 50%}.iziModal .iziModal-content:after,.iziModal .iziModal-content:before{content:'';display:table}.iziModal .iziModal-content:after{clear:both}.iziModal .iziModal-content{zoom:1;width:100%}.iziModal .iziModal-wrap{width:100%;position:relative}.iziModal .iziModal-iframe{border:0;margin:0 0 -6px 0;width:100%;transition:height .3s ease}.iziModal-overlay{display:block;position:fixed;top:0;left:0;height:100%;width:100%}.iziModal-navigate{position:fixed;left:0;right:0;top:0;bottom:0;pointer-events:none}.iziModal-navigate-caption{position:absolute;left:10px;top:10px;color:#fff;line-height:16px;font-size:9px;font-family:Lato,Arial;letter-spacing:.1em;text-indent:0;text-align:center;width:70px;padding:5px 0;text-transform:uppercase;display:none}.iziModal-navigate-caption::after,.iziModal-navigate-caption::before{position:absolute;top:2px;width:20px;height:20px;text-align:center;line-height:14px;font-size:12px;content:'';background-size:100%!important}.iziModal-navigate-caption:before{left:0;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAoCAYAAACFFRgXAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA4ZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTMyIDc5LjE1OTI4NCwgMjAxNi8wNC8xOS0xMzoxMzo0MCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDoyNmFjNjAyMy04OWU0LWE0NDAtYmMxMy1kOTA5MTQ3MmYzYjAiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NDREQ0YwRjA1MzQzMTFFNkE5NUNDRDkyQzEwMzM5RTMiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NDREQ0YwRUY1MzQzMTFFNkE5NUNDRDkyQzEwMzM5RTMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUuNSAoV2luZG93cykiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpmNmM0Nzk3Ni1mNzE3LTk5NDAtYTgyYS1mNTdjNmNiYmU0NWMiIHN0UmVmOmRvY3VtZW50SUQ9ImFkb2JlOmRvY2lkOnBob3Rvc2hvcDowZGVmYTEyZC01MzM0LTExZTYtYWRkYi04Y2NmYjI5ZTAxNjYiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7oo0ptAAACWklEQVR42uyZTWsTYRSFZybxo4kWk5g2NC5qTAU3Kq30A9udi1oXolV/hWuhv6R/Q6utioi4LbbVFHemamlRU0OCEk0wZjwXzwtDoBDopHMHcuFJMplZnLm5ue+589qu61qeOApyYAjEgG0FEyLqN/gKiqBuTtgewWlwCZw056xgwwirgU3wxSv4NJgCUV5YBRXQDEhsBJwCSSauBVZFdJRlIJk9Av7wbj577jDIOENtRmPVwcsw6KfAAvikRKzEDlhnhuU/lRPBWaa9wsxqC6ndPX7OiOA4D8qW3vjO9z7H0w3+KhZstNmOFbLoCQ6DYGmL+bAInmGfLFC4asFXwRJIgB+goVmw+I7HXO+/gevGnGgUPEGxktkSmAMbWmt4HDwBKS6XN1jDKrvEFYoVK7oLroE3h93Woh1eNwqWafJ/gQV65vM+ail34mc6EZwBK2CAx8fAIjjeBYMzDT4cVHCEXtRbRvEu/Nr9HCIOnGGp15vgEec9KYn74B0nAT/CZnv86FcNvwK3wENwAjwAs2Bbs5d4CW5zir0AXvv8p+tKH34B5lkW4h2egRHtbu05uMMHHWfB0zC4NRF5l09kzvE4rd2tyUJyjy4tz7akZqXbL8QETbJ/FsMgWOJtb6brCQ5YsBsC8Uab63DVkkgqFpzie93h8OhScFah2LTHi5ccWroaLd5l6//+hpYQoWP05LKqFs2WQYbTsNxAi+5fxpWmdfh7HS7XhwSzG+H3a2JnvZsyktmLbdOFhpDMvrf4sN1u2/aK0cwMcmYLcturweceW+CnOfFPgAEA8uWFFylBJYoAAAAASUVORK5CYII=) no-repeat 50% 50%}.iziModal-navigate-caption:after{right:0;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAoCAYAAACFFRgXAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAADhmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxMzIgNzkuMTU5Mjg0LCAyMDE2LzA0LzE5LTEzOjEzOjQwICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjI2YWM2MDIzLTg5ZTQtYTQ0MC1iYzEzLWQ5MDkxNDcyZjNiMCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo0NERDRjBGMDUzNDMxMUU2QTk1Q0NEOTJDMTAzMzlFMyIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo0NERDRjBFRjUzNDMxMUU2QTk1Q0NEOTJDMTAzMzlFMyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxNS41IChXaW5kb3dzKSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOmY2YzQ3OTc2LWY3MTctOTk0MC1hODJhLWY1N2M2Y2JiZTQ1YyIgc3RSZWY6ZG9jdW1lbnRJRD0iYWRvYmU6ZG9jaWQ6cGhvdG9zaG9wOjBkZWZhMTJkLTUzMzQtMTFlNi1hZGRiLThjY2ZiMjllMDE2NiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PuijSm0AAAKbSURBVFhH7ZnJj0xRGEerzFoIMTaCZmOIedhaiJj55yz8DaYdNhIJEUMQbCTG3rQ02hDSiEY553XdTpHS3nv96taV9ElO6lVt6peb7933fffVG41GrYW5uBaX4EysYzcw1Fd8hc/wM2a0Bl6Nm3BW9i0dDPsQX/olBF6FO72AH/gG3+N3jL3KBpqGC3ERTsGfeAsHDTyHi71oCXzBe/gaU2A5bscZOIxXTb8OLQNX9i6mElYsg/voqruwfQb2BhODWgqpMYDv0NLsNXC4yd42P1PEwNJj4HBTWdipErLVDfxfMRm408QMvBu3jV6WJ1Zg9/rbeBOP+UNZYgX+iE/Rp+lpPIKliBXYB9IhtPNy3z/T/F6YmDXsChvyBc7Gs3gACxEzsDzBg9iPPXgO92NuYgeWx2h3+AhtaM7jPsyF7aV37XR8gNZYO/pwKY51+xPkG27Fk2joT3gCr2A7NuJ6HMkTeAPadlp3VeMChF7G0P6X3dmfjAXOUxIj6LZkv1ylNuStDZejkL+PS96ScFzRqnDAtI5PoTefvbg7iNNOOwqVRCfYghdxBbpHH8Y7+DcKlUTV7MLLaNghPIrjhf2N2IF34AVcjE44hrXHyE3MwE6/loEzpEcIlqKjeyFiBe7FS+he/gENewMLEyuwXdo8dGWP43UsRazA9g7uDNbwNX8oS8watlsz+ISIGbgSJgN3GgOHlnFq8zNFQraGgT1iFc9iUyU0XsMGHhy9zh6XbvCp4ZuBBWglDBj4OdqLeu0+uRJTwMZ+Dbp/e21P3m97yWe2snsw1LTHmz5C/9lQdwhfGbiq89GwvrrwUT4UAouhN6MzloTRpVuEYI5O9urZYXtrYPGQw2OlZegM163QhrJMfWVgyTq0Qq32C/N7uPz9OknWAAAAAElFTkSuQmCC) no-repeat 50% 50%}.iziModal-navigate>button{position:fixed;bottom:0;top:0;border:0;height:100%;width:84px;background-size:100%!important;cursor:pointer;padding:0;opacity:.2;transition:opacity .3s ease;pointer-events:all;margin:0;outline:0}.iziModal-navigate>button:hover{opacity:1}.iziModal-navigate-prev{left:50%;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALwAAAC8CAYAAADCScSrAAAACXBIWXMAAAsTAAALEwEAmpwYAAA5sGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxMzIgNzkuMTU5Mjg0LCAyMDE2LzA0LzE5LTEzOjEzOjQwICAgICAgICAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgICAgICAgICAgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiCiAgICAgICAgICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgICAgICAgICB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOnRpZmY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vdGlmZi8xLjAvIgogICAgICAgICAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyI+CiAgICAgICAgIDx4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ+eG1wLmRpZDo2NDkyYzcxMy05ZDM0LTZlNGQtYmUwNi1hMDMyY2Q4NDVjNGU8L3htcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOkRvY3VtZW50SUQ+eG1wLmRpZDo1QjIzMUMxODU3RjcxMUU2ODUzRkRBRjE5RDhDQjZBRDwveG1wTU06RG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOkluc3RhbmNlSUQ+eG1wLmlpZDpjZmMwNzVmNC1kODA3LWI0NDMtYWIwYS02YWVhZjRjMDgxZWE8L3htcE1NOkluc3RhbmNlSUQ+CiAgICAgICAgIDx4bXBNTTpEZXJpdmVkRnJvbSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgIDxzdFJlZjppbnN0YW5jZUlEPnhtcC5paWQ6NjQ5MmM3MTMtOWQzNC02ZTRkLWJlMDYtYTAzMmNkODQ1YzRlPC9zdFJlZjppbnN0YW5jZUlEPgogICAgICAgICAgICA8c3RSZWY6ZG9jdW1lbnRJRD54bXAuZGlkOjY0OTJjNzEzLTlkMzQtNmU0ZC1iZTA2LWEwMzJjZDg0NWM0ZTwvc3RSZWY6ZG9jdW1lbnRJRD4KICAgICAgICAgPC94bXBNTTpEZXJpdmVkRnJvbT4KICAgICAgICAgPHhtcE1NOkhpc3Rvcnk+CiAgICAgICAgICAgIDxyZGY6U2VxPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOmNmYzA3NWY0LWQ4MDctYjQ0My1hYjBhLTZhZWFmNGMwODFlYTwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxNi0wOC0wMVQxMTo1ODowNC0wMzowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENDIDIwMTUuNSAoV2luZG93cyk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpjaGFuZ2VkPi88L3N0RXZ0OmNoYW5nZWQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICA8L3JkZjpTZXE+CiAgICAgICAgIDwveG1wTU06SGlzdG9yeT4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAxNS41IChXaW5kb3dzKTwveG1wOkNyZWF0b3JUb29sPgogICAgICAgICA8eG1wOkNyZWF0ZURhdGU+MjAxNi0wOC0wMVQwOTo0MDo1Ni0wMzowMDwveG1wOkNyZWF0ZURhdGU+CiAgICAgICAgIDx4bXA6TW9kaWZ5RGF0ZT4yMDE2LTA4LTAxVDExOjU4OjA0LTAzOjAwPC94bXA6TW9kaWZ5RGF0ZT4KICAgICAgICAgPHhtcDpNZXRhZGF0YURhdGU+MjAxNi0wOC0wMVQxMTo1ODowNC0wMzowMDwveG1wOk1ldGFkYXRhRGF0ZT4KICAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9wbmc8L2RjOmZvcm1hdD4KICAgICAgICAgPHBob3Rvc2hvcDpDb2xvck1vZGU+MzwvcGhvdG9zaG9wOkNvbG9yTW9kZT4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WFJlc29sdXRpb24+NzIwMDAwLzEwMDAwPC90aWZmOlhSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpZUmVzb2x1dGlvbj43MjAwMDAvMTAwMDA8L3RpZmY6WVJlc29sdXRpb24+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDxleGlmOkNvbG9yU3BhY2U+NjU1MzU8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxYRGltZW5zaW9uPjE4ODwvZXhpZjpQaXhlbFhEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj4xODg8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/PvAvv7QAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAAAmdJREFUeNrs1LsJQkEQhtH/mtmBgQ8QA7tQK1e7MBBBMbADwzUZEyuQveeDCXbD4TBDay3SWJpYgYCXgJeAl4CXgJeAl4CXgJeAl4CXgJeAF/AS8BLwEvAS8BLwEvAS8BLwEvAS8BLwAl4CXgJeAl4CXv/WJskpyQJ4jQH7Mcmu0C+BV+/Y5/VeF/oV8Ood+7dpDfDqHvsrySHJBXjBDrxgB16wAy/YgRfswAt24AU78IIdeMEOPOywAw+7gIcdeMEOvGAHXrADL9iBF+zAC3bgBTvwsMMOPOwCHnYBD7uAhx14wQ68YAdesAMv2IEX7MDDDjvwsAt42AU87AIedgEPu4CHXcDDDrxgB16wAw877MDDDjvwsAt42AU87AIedgEPu4CHXcDDLuBhB16wAw877MDDLuBhF/CwC3jYBTzsAh52AQ+7gIddwEtjB3+tS/78+Z/V5d9iATz0Ah56AQ+9gIdewEMv4KEX8NALeOgFPPQCHnoBDz3wgh54QQ889NADDz30wEMv4KEX8NALeOgFPPQCHnoBD72Ahx54QQ+8oAde0AMv6IEX9MBDDz3w0EMPPPQCHnoBD72Ah17AQw+8FUAPvKAHXtADL+iBF/TAC3rgBT3wgh546KEHHnrogYdewEMv4KEHXtADL+iBF/TAC3rgBT3wgh54QQ+8oAde0AMv6IGHHnrgoU/yrgFe3aO/JdknuQOv3tGfC/tjjEsYWmsoyIWXgJeAl4CXgJeAl4CXgJeAl4CXgJeAF/AS8BLwEvAS8BLwEvAS8BLwEvAS8BLwAl4CXgJeAl4CXvqnPgAAAP//AwCEcoCBRabYzAAAAABJRU5ErkJggg==) no-repeat 50% 50%}.iziModal-navigate-next{right:50%;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALwAAAC8CAYAAADCScSrAAAACXBIWXMAAB3SAAAd0gEUasEwAAA7pGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxMzIgNzkuMTU5Mjg0LCAyMDE2LzA0LzE5LTEzOjEzOjQwICAgICAgICAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIKICAgICAgICAgICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgICAgICAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgICAgICAgICAgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIj4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAxNS41IChXaW5kb3dzKTwveG1wOkNyZWF0b3JUb29sPgogICAgICAgICA8eG1wOkNyZWF0ZURhdGU+MjAxNi0wOC0wMVQwOTo0MDoxNC0wMzowMDwveG1wOkNyZWF0ZURhdGU+CiAgICAgICAgIDx4bXA6TW9kaWZ5RGF0ZT4yMDE2LTA4LTAxVDExOjU4OjEyLTAzOjAwPC94bXA6TW9kaWZ5RGF0ZT4KICAgICAgICAgPHhtcDpNZXRhZGF0YURhdGU+MjAxNi0wOC0wMVQxMTo1ODoxMi0wMzowMDwveG1wOk1ldGFkYXRhRGF0ZT4KICAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9wbmc8L2RjOmZvcm1hdD4KICAgICAgICAgPHBob3Rvc2hvcDpDb2xvck1vZGU+MzwvcGhvdG9zaG9wOkNvbG9yTW9kZT4KICAgICAgICAgPHhtcE1NOkluc3RhbmNlSUQ+eG1wLmlpZDphZjljN2Q2MC00MTg2LWE3NGQtYTBiMS1mMGU5ODUwYzg2ZGY8L3htcE1NOkluc3RhbmNlSUQ+CiAgICAgICAgIDx4bXBNTTpEb2N1bWVudElEPnhtcC5kaWQ6NjQ5MmM3MTMtOWQzNC02ZTRkLWJlMDYtYTAzMmNkODQ1YzRlPC94bXBNTTpEb2N1bWVudElEPgogICAgICAgICA8eG1wTU06T3JpZ2luYWxEb2N1bWVudElEPnhtcC5kaWQ6NjQ5MmM3MTMtOWQzNC02ZTRkLWJlMDYtYTAzMmNkODQ1YzRlPC94bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ+CiAgICAgICAgIDx4bXBNTTpIaXN0b3J5PgogICAgICAgICAgICA8cmRmOlNlcT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+Y3JlYXRlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOjY0OTJjNzEzLTlkMzQtNmU0ZC1iZTA2LWEwMzJjZDg0NWM0ZTwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxNi0wOC0wMVQwOTo0MDoxNC0wMzowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENDIDIwMTUuNSAoV2luZG93cyk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOjAxNjJjMmE3LWZmMjYtYzE0ZC05Yjg4LTc2MGM2NzAxYjYzNzwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxNi0wOC0wMVQxMTo1MTowNy0wMzowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENDIDIwMTUuNSAoV2luZG93cyk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpjaGFuZ2VkPi88L3N0RXZ0OmNoYW5nZWQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOmFmOWM3ZDYwLTQxODYtYTc0ZC1hMGIxLWYwZTk4NTBjODZkZjwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxNi0wOC0wMVQxMTo1ODoxMi0wMzowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENDIDIwMTUuNSAoV2luZG93cyk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpjaGFuZ2VkPi88L3N0RXZ0OmNoYW5nZWQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICA8L3JkZjpTZXE+CiAgICAgICAgIDwveG1wTU06SGlzdG9yeT4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WFJlc29sdXRpb24+MTkzOTAzNi8xMDAwMDwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+MTkzOTAzNi8xMDAwMDwvdGlmZjpZUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6UmVzb2x1dGlvblVuaXQ+MjwvdGlmZjpSZXNvbHV0aW9uVW5pdD4KICAgICAgICAgPGV4aWY6Q29sb3JTcGFjZT42NTUzNTwvZXhpZjpDb2xvclNwYWNlPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+MTg4PC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjE4ODwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIAo8P3hwYWNrZXQgZW5kPSJ3Ij8+nbt1mgAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAACQklEQVR42uzSsQ3CQAAEQTdiOyGg/wrciJ0QUMYSECEKAP3PSdvAaZZqkWbJCQJeAl4CXgJeAl4CXgJeAl4CXgJeAl4CXsBLwEvAS8BLwEvAS8BLwEvAS8BLwEvAC3gJeAl4CXgJ+D9vrY7qBgLwo7dVZ+89oAd+5Pbq6nPQAz9s9+rZ96AHHnoBD72Ah17AQy/goRfw0At46AU89AIeegEPvYCHHnhBD7ygBx566IGHHnrgoRfw0At46AU89AIeegEPvYCHXsBDL+ChB17QAy/ogRf0wAt64KGHHnjooQceegEPvYCHXsBDL+ChF/DQAy/ogRf0wAt64AU98IIeeEEPvKAHXtADDz30wEPvI+ChF/DQAy/ogRf0wAt64AU98IIeeEEPvKAHXtADL+iBF/TAC3rgoZ8ePRDAAy/YgRfswAt24AU78IIdeMEOvGAHXrADL9iBhx124GEX8LADL9iBF+zAC3bgBTvwgh14wQ68YAcedtiBh13Awy7gYRfwsAMv2IEX7MALduAFO/CCHXjYYQcedgEPu4CHXcDDLuBhF/CwA+8E2IEX7MALduAFO/Cwww487AIedgEPu4CHXcDDLuBhF/CwC3jYgRfswMMOO/CwC3jYBTzsAh52AQ+7gIddwMMu4GEX8LBravB7dcEO/Ext1Qk78DO1VgfswEvAS8BLwEvAS8BLwEvAS8BLwEvAS8ALeAl4CXgJeAl4CXgJeAl4CXgJeAl4CXgBLwEvAS8BLwEvAS/9shcAAAD//wMAtAygvJrkwJUAAAAASUVORK5CYII=) no-repeat 50% 50%}.iziModal.isAttachedTop .iziModal-header{border-top-left-radius:0;border-top-right-radius:0}.iziModal.isAttachedTop{margin-top:0!important;margin-bottom:auto!important;border-top-left-radius:0!important;border-top-right-radius:0!important}.iziModal.isAttachedBottom{margin-top:auto!important;margin-bottom:0!important;border-bottom-left-radius:0!important;border-bottom-right-radius:0!important}.iziModal.isFullscreen{max-width:100%!important;margin:0!important;height:100%!important;border-radius:0!important}.iziModal.isAttached{border-radius:0!important}.iziModal.hasScroll .iziModal-wrap{overflow-y:auto;overflow-x:hidden}html.iziModal-isOverflow{overflow:hidden}html.iziModal-isAttached body,html.iziModal-isOverflow body{overflow-y:scroll;position:relative}html.iziModal-isAttached{overflow:hidden}.iziModal ::-webkit-scrollbar{overflow:visible;height:7px;width:7px}.iziModal ::-webkit-scrollbar-thumb{background-color:rgba(0,0,0,.2);background-clip:padding-box;border:solid transparent;border-width:0;min-height:28px;padding:100px 0 0;box-shadow:inset 1px 1px 0 rgba(0,0,0,.1),inset 0 -1px 0 rgba(0,0,0,.07)}.iziModal ::-webkit-scrollbar-thumb:active{background-color:rgba(0,0,0,.4)}.iziModal ::-webkit-scrollbar-button{height:0;width:0}.iziModal ::-webkit-scrollbar-track{background-clip:padding-box;border:solid transparent;border-width:0 0 0 2px}.iziModal.transitionIn .iziModal-header{-webkit-animation:iziM-slideDown .7s cubic-bezier(.7,0,.3,1);-moz-animation:iziM-slideDown .7s cubic-bezier(.7,0,.3,1);animation:iziM-slideDown .7s cubic-bezier(.7,0,.3,1)}.iziModal.transitionIn .iziModal-header .iziModal-header-icon{-webkit-animation:iziM-revealIn 1s cubic-bezier(.16,.81,.32,1) both;-moz-animation:iziM-revealIn 1s cubic-bezier(.16,.81,.32,1) both;animation:iziM-revealIn 1s cubic-bezier(.16,.81,.32,1) both}.iziModal.transitionIn .iziModal-header .iziModal-header-subtitle,.iziModal.transitionIn .iziModal-header .iziModal-header-title{-webkit-animation:iziM-slideIn 1s cubic-bezier(.16,.81,.32,1) both;-moz-animation:iziM-slideIn 1s cubic-bezier(.16,.81,.32,1) both;animation:iziM-slideIn 1s cubic-bezier(.16,.81,.32,1) both}.iziModal.transitionIn .iziModal-header .iziModal-button{-webkit-animation:iziM-revealIn 1.2s cubic-bezier(.7,0,.3,1);-moz-animation:iziM-revealIn 1.2s cubic-bezier(.7,0,.3,1);animation:iziM-revealIn 1.2s cubic-bezier(.7,0,.3,1)}.iziModal.transitionIn .iziModal-iframe,.iziModal.transitionIn .iziModal-wrap{-webkit-animation:iziM-fadeIn 1.3s;-moz-animation:iziM-fadeIn 1.3s;animation:iziM-fadeIn 1.3s}.iziModal.transitionIn .iziModal-header{-webkit-animation-delay:0ms;-moz-animation:0ms;animation-delay:0ms}.iziModal.transitionIn .iziModal-header .iziModal-header-icon,.iziModal.transitionIn .iziModal-header .iziModal-header-title{-webkit-animation-delay:.4s;-moz-animation:.4s;animation-delay:.4s}.iziModal.transitionIn .iziModal-header .iziModal-header-subtitle{-webkit-animation-delay:.5s;-moz-animation:.5s;animation-delay:.5s}.iziModal.transitionOut .iziModal-header,.iziModal.transitionOut .iziModal-header *{transition:none!important}.iziModal .fadeOut,.iziModal-navigate.fadeOut,.iziModal-overlay.fadeOut,.iziModal.fadeOut{-webkit-animation:iziM-fadeOut .5s;-moz-animation:iziM-fadeOut .5s;animation:iziM-fadeOut .5s;animation-fill-mode:forwards}.iziModal .fadeIn,.iziModal-navigate.fadeIn,.iziModal-overlay.fadeIn,.iziModal.fadeIn{-webkit-animation:iziM-fadeIn .5s;-moz-animation:iziM-fadeIn .5s;animation:iziM-fadeIn .5s}.iziModal-overlay.comingIn,.iziModal.comingIn{-webkit-animation:iziM-comingIn .5s ease;-moz-animation:iziM-comingIn .5s ease;animation:iziM-comingIn .5s ease}.iziModal-overlay.comingOut,.iziModal.comingOut{-webkit-animation:iziM-comingOut .5s cubic-bezier(.16,.81,.32,1);-moz-animation:iziM-comingOut .5s cubic-bezier(.16,.81,.32,1);animation:iziM-comingOut .5s cubic-bezier(.16,.81,.32,1);animation-fill-mode:forwards}.iziModal-overlay.bounceInDown,.iziModal.bounceInDown{-webkit-animation:iziM-bounceInDown .7s ease;animation:iziM-bounceInDown .7s ease}.iziModal-overlay.bounceOutDown,.iziModal.bounceOutDown{-webkit-animation:iziM-bounceOutDown .7s ease;animation:iziM-bounceOutDown .7s ease}.iziModal-overlay.bounceInUp,.iziModal.bounceInUp{-webkit-animation:iziM-bounceInUp .7s ease;animation:iziM-bounceInUp .7s ease}.iziModal-overlay.bounceOutUp,.iziModal.bounceOutUp{-webkit-animation:iziM-bounceOutUp .7s ease;animation:iziM-bounceOutUp .7s ease}.iziModal-overlay.bounceInLeft,.iziModal.bounceInLeft{-webkit-animation:iziM-bounceInLeft .7s ease;animation:iziM-bounceInLeft .7s ease}.iziModal-overlay.bounceOutLeft,.iziModal.bounceOutLeft{-webkit-animation:iziM-bounceOutLeft .7s ease;animation:iziM-bounceOutLeft .7s ease}.iziModal-overlay.bounceInRight,.iziModal.bounceInRight{-webkit-animation:iziM-bounceInRight .7s ease;animation:iziM-bounceInRight .7s ease}.iziModal-overlay.bounceOutRight,.iziModal.bounceOutRight{-webkit-animation:iziM-bounceOutRight .7s ease;animation:iziM-bounceOutRight .7s ease}.iziModal-overlay.fadeInDown,.iziModal.fadeInDown{-webkit-animation:iziM-fadeInDown .7s cubic-bezier(.16,.81,.32,1);animation:iziM-fadeInDown .7s cubic-bezier(.16,.81,.32,1)}.iziModal-overlay.fadeOutDown,.iziModal.fadeOutDown{-webkit-animation:iziM-fadeOutDown .5s ease;animation:iziM-fadeOutDown .5s ease}.iziModal-overlay.fadeInUp,.iziModal.fadeInUp{-webkit-animation:iziM-fadeInUp .7s cubic-bezier(.16,.81,.32,1);animation:iziM-fadeInUp .7s cubic-bezier(.16,.81,.32,1)}.iziModal-overlay.fadeOutUp,.iziModal.fadeOutUp{-webkit-animation:iziM-fadeOutUp .5s ease;animation:iziM-fadeOutUp .5s ease}.iziModal-overlay.fadeInLeft,.iziModal.fadeInLeft{-webkit-animation:iziM-fadeInLeft .7s cubic-bezier(.16,.81,.32,1);animation:iziM-fadeInLeft .7s cubic-bezier(.16,.81,.32,1)}.iziModal-overlay.fadeOutLeft,.iziModal.fadeOutLeft{-webkit-animation:iziM-fadeOutLeft .5s ease;animation:iziM-fadeOutLeft .5s ease}.iziModal-overlay.fadeInRight,.iziModal.fadeInRight{-webkit-animation:iziM-fadeInRight .7s cubic-bezier(.16,.81,.32,1);animation:iziM-fadeInRight .7s cubic-bezier(.16,.81,.32,1)}.iziModal-overlay.fadeOutRight,.iziModal.fadeOutRight{-webkit-animation:iziM-fadeOutRight .5s ease;animation:iziM-fadeOutRight .5s ease}.iziModal-overlay.flipInX,.iziModal.flipInX{-webkit-animation:iziM-flipInX .7s ease;animation:iziM-flipInX .7s ease}.iziModal-overlay.flipOutX,.iziModal.flipOutX{-webkit-animation:iziM-flipOutX .7s ease;animation:iziM-flipOutX .7s ease}@-webkit-keyframes iziM-comingIn{0%{opacity:0;transform:scale(.9) translateY(-20px) perspective(600px) rotateX(10deg)}100%{opacity:1;transform:scale(1) translateY(0) perspective(600px) rotateX(0)}}@-moz-keyframes iziM-comingIn{0%{opacity:0;transform:scale(.9) translateY(-20px) perspective(600px) rotateX(10deg)}100%{opacity:1;transform:scale(1) translateY(0) perspective(600px) rotateX(0)}}@keyframes iziM-comingIn{0%{opacity:0;transform:scale(.9) translateY(-20px) perspective(600px) rotateX(10deg)}100%{opacity:1;transform:scale(1) translateY(0) perspective(600px) rotateX(0)}}@-webkit-keyframes iziM-comingOut{0%{opacity:1;transform:scale(1)}100%{opacity:0;transform:scale(.9)}}@-moz-keyframes iziM-comingOut{0%{opacity:1;transform:scale(1)}100%{opacity:0;transform:scale(.9)}}@keyframes iziM-comingOut{0%{opacity:1;transform:scale(1)}100%{opacity:0;transform:scale(.9)}}@-webkit-keyframes iziM-fadeOut{0%{opacity:1}100%{opacity:0}}@-moz-keyframes iziM-fadeOut{0%{opacity:1}100%{opacity:0}}@keyframes iziM-fadeOut{0%{opacity:1}100%{opacity:0}}@-webkit-keyframes iziM-fadeIn{0%{opacity:0}100%{opacity:1}}@-moz-keyframes iziM-fadeIn{0%{opacity:0}100%{opacity:1}}@keyframes iziM-fadeIn{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes iziM-slideIn{0%{opacity:0;-webkit-transform:translateX(50px)}100%{opacity:1;-webkit-transform:translateX(0)}}@-moz-keyframes iziM-slideIn{0%{opacity:0;-moz-transform:translateX(50px)}100%{opacity:1;-moz-transform:translateX(0)}}@keyframes iziM-slideIn{0%{opacity:0;transform:translateX(50px)}100%{opacity:1;transform:translateX(0)}}@-webkit-keyframes iziM-slideDown{0%{opacity:0;-webkit-transform:scale(1,0) translateY(-40px);-webkit-transform-origin:center top}}@-moz-keyframes iziM-slideDown{0%{opacity:0;-moz-transform:scale(1,0) translateY(-40px);-moz-transform-origin:center top}}@keyframes iziM-slideDown{0%{opacity:0;transform:scale(1,0) translateY(-40px);transform-origin:center top}}@-webkit-keyframes iziM-revealIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,1)}}@-moz-keyframes iziM-revealIn{0%{opacity:0;-moz-transform:scale3d(.3,.3,1)}}@keyframes iziM-revealIn{0%{opacity:0;transform:scale3d(.3,.3,1)}}@-webkit-keyframes iziM-bounceInDown{60%,75%,90%,from,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,-1000px,0);transform:translate3d(0,-1000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}to{-webkit-transform:none;transform:none}}@keyframes iziM-bounceInDown{60%,75%,90%,from,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,-1000px,0);transform:translate3d(0,-1000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}to{-webkit-transform:none;transform:none}}@-webkit-keyframes iziM-bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}to{opacity:0;-webkit-transform:translate3d(0,1000px,0);transform:translate3d(0,1000px,0)}}@keyframes iziM-bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}to{opacity:0;-webkit-transform:translate3d(0,1000px,0);transform:translate3d(0,1000px,0)}}@-webkit-keyframes iziM-bounceInUp{60%,75%,90%,from,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}from{opacity:0;-webkit-transform:translate3d(0,1000px,0);transform:translate3d(0,1000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes iziM-bounceInUp{60%,75%,90%,from,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}from{opacity:0;-webkit-transform:translate3d(0,1000px,0);transform:translate3d(0,1000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@-webkit-keyframes iziM-bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}to{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes iziM-bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}to{opacity:0;-webkit-transform:translate3d(0,-1000px,0);transform:translate3d(0,-1000px,0)}}@-webkit-keyframes iziM-bounceInLeft{60%,75%,90%,from,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(-1000px,0,0);transform:translate3d(-1000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}to{-webkit-transform:none;transform:none}}@keyframes iziM-bounceInLeft{60%,75%,90%,from,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(-1000px,0,0);transform:translate3d(-1000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}to{-webkit-transform:none;transform:none}}@-webkit-keyframes iziM-bounceOutLeft{20%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}40%,45%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}to{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes iziM-bounceOutLeft{20%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}40%,45%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}to{opacity:0;-webkit-transform:translate3d(-1000px,0,0);transform:translate3d(-1000px,0,0)}}@-webkit-keyframes iziM-bounceInRight{60%,75%,90%,from,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}from{opacity:0;-webkit-transform:translate3d(1000px,0,0);transform:translate3d(1000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes iziM-bounceInRight{60%,75%,90%,from,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}from{opacity:0;-webkit-transform:translate3d(1000px,0,0);transform:translate3d(1000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@-webkit-keyframes iziM-bounceOutRight{20%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}40%,45%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}to{opacity:0;-webkit-transform:translate3d(1000px,0,0);transform:translate3d(1000px,0,0)}}@keyframes iziM-bounceOutRight{20%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}40%,45%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}to{opacity:0;-webkit-transform:translate3d(1000px,0,0);transform:translate3d(1000px,0,0)}}@-webkit-keyframes iziM-fadeInDown{from{opacity:0;-webkit-transform:translate3d(0,-100px,0);transform:translate3d(0,-100px,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes iziM-fadeInDown{from{opacity:0;-webkit-transform:translate3d(0,-100px,0);transform:translate3d(0,-100px,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-webkit-keyframes iziM-fadeOutDown{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,100px,0);transform:translate3d(0,100px,0)}}@keyframes iziM-fadeOutDown{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,100px,0);transform:translate3d(0,100px,0)}}@-webkit-keyframes iziM-fadeInUp{from{opacity:0;-webkit-transform:translate3d(0,100px,0);transform:translate3d(0,100px,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes iziM-fadeInUp{from{opacity:0;-webkit-transform:translate3d(0,100px,0);transform:translate3d(0,100px,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-webkit-keyframes iziM-fadeOutUp{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-100px,0);transform:translate3d(0,-100px,0)}}@keyframes iziM-fadeOutUp{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-100px,0);transform:translate3d(0,-100px,0)}}@-webkit-keyframes iziM-fadeInLeft{from{opacity:0;-webkit-transform:translate3d(-200px,0,0);transform:translate3d(-200px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes iziM-fadeInLeft{from{opacity:0;-webkit-transform:translate3d(-200px,0,0);transform:translate3d(-200px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-webkit-keyframes iziM-fadeOutLeft{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(-200px,0,0);transform:translate3d(-200px,0,0)}}@keyframes iziM-fadeOutLeft{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(-200px,0,0);transform:translate3d(-200px,0,0)}}@-webkit-keyframes iziM-fadeInRight{from{opacity:0;-webkit-transform:translate3d(200px,0,0);transform:translate3d(200px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes iziM-fadeInRight{from{opacity:0;-webkit-transform:translate3d(200px,0,0);transform:translate3d(200px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-webkit-keyframes iziM-fadeOutRight{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(200px,0,0);transform:translate3d(200px,0,0)}}@keyframes iziM-fadeOutRight{from{opacity:1}to{opacity:0;-webkit-transform:translate3d(200px,0,0);transform:translate3d(200px,0,0)}}@-webkit-keyframes iziM-flipInX{0%{-webkit-transform:perspective(400px) rotateX(60deg);opacity:0}40%{-webkit-transform:perspective(400px) rotateX(-10deg)}70%{-webkit-transform:perspective(400px) rotateX(10deg)}100%{-webkit-transform:perspective(400px) rotateX(0);opacity:1}}@keyframes iziM-flipInX{0%{transform:perspective(400px) rotateX(60deg);opacity:0}40%{transform:perspective(400px) rotateX(-10deg)}70%{transform:perspective(400px) rotateX(10deg)}100%{transform:perspective(400px) rotateX(0);opacity:1}}@-webkit-keyframes iziM-flipOutX{from{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}to{-webkit-transform:perspective(400px) rotate3d(1,0,0,40deg);transform:perspective(400px) rotate3d(1,0,0,40deg);opacity:0}}@keyframes iziM-flipOutX{from{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}to{-webkit-transform:perspective(400px) rotate3d(1,0,0,40deg);transform:perspective(400px) rotate3d(1,0,0,40deg);opacity:0}} \ No newline at end of file diff --git a/assets/css/range-selector.css b/assets/css/range-selector.css new file mode 100644 index 0000000..b659d64 --- /dev/null +++ b/assets/css/range-selector.css @@ -0,0 +1,68 @@ +.ui-corner-all { + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; +} + + +/*.ui-widget-content { + background: linear-gradient(#e9e9e9,#fff); + border-color: #1c3050; + color: #fff +}*/ + +.ui-slider-horizontal { + height: .8em; +} + +.ui-slider { + position: relative; + text-align: left; + margin-right: 64px; + margin-left: 10px; + /*margin-top: 5px;*/ +} + +.ui-state-default, +.ui-widget-content .ui-state-default, +.ui-widget-header .ui-state-default { + border-color: #1c3050; + background: linear-gradient(#284776, #1c3050); + color: #fff; +} + +.ui-slider-horizontal .ui-slider-handle { + top: -.3em; + margin-left: -.6em; +} + +.ui-slider .ui-slider-handle { + position: absolute; + z-index: 2; + min-width: 1.2em; + min-height: 1.2em; + cursor: grab; + padding: 2px 6px; + margin-top: -2px; + display: table; + text-wrap: nowrap; +} + +.ui-slider .ui-slider-handle:hover { + text-decoration: underline; +} + +#selected_capital_range.ui-slider { + /* margin-right: 86px; */ + margin-right: 0; +} + +.ui-slider .ui-slider-handle.ui-state-focus { + border: none; + outline: none; +} + +.ui-slider .ui-slider-handle.ui-state-focus .slider_capital_box { + /* box-sizing: border-box; + border: 3px solid #fff; */ +} \ No newline at end of file diff --git a/assets/css/societes-credit-manager.css b/assets/css/societes-credit-manager.css new file mode 100644 index 0000000..bd50534 --- /dev/null +++ b/assets/css/societes-credit-manager.css @@ -0,0 +1,307 @@ +/* ======================================== + SOCIETES CREDIT MANAGER - STYLES + ======================================== */ + +/* Actions Header */ +.credit-actions-header { + margin: 20px 0; +} + +.credit-actions-header .button { + display: inline-flex; + align-items: center; + gap: 5px; +} + +/* Table Styles */ +#societes-table { + margin-top: 20px; +} + +#societes-table th { + font-weight: 600; +} + +#societes-table td { + vertical-align: middle; +} + +/* Status Badges */ +.badge-active, +.badge-inactive { + display: inline-block; + padding: 4px 12px; + border-radius: 12px; + font-size: 12px; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.badge-active { + background-color: #46b450; + color: white; +} + +.badge-inactive { + background-color: #dc3232; + color: white; +} + +/* Action Buttons */ +.button-small { + padding: 4px 8px; + height: auto; + font-size: 12px; + line-height: 1.5; +} + +.button-link-delete { + color: #b32d2e; +} + +.button-link-delete:hover { + color: #dc3232; + border-color: #dc3232; +} + +/* Modal Styles */ +.societe-modal { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 999999; + display: none; + animation: fadeIn 0.3s ease-out; +} + +.societe-modal.show { + display: flex; + align-items: center; + justify-content: center; + animation: fadeIn 0.3s ease-out; +} + +.credit-modal-overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: linear-gradient(135deg, rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.8)); + backdrop-filter: blur(5px); + animation: fadeIn 0.3s ease-out; +} + +.credit-modal-content { + position: relative; + background: linear-gradient(145deg, #ffffff, #f8f9fa); + margin: 0; + width: 90%; + max-width: 600px; + max-height: 90vh; + overflow-y: auto; + border-radius: 20px; + box-shadow: + 0 20px 60px rgba(0, 0, 0, 0.3), + 0 0 0 1px rgba(255, 255, 255, 0.1), + inset 0 1px 0 rgba(255, 255, 255, 0.2); + padding: 0; + transform: scale(0.9); + animation: modalSlideIn 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards; + border: 1px solid rgba(255, 255, 255, 0.2); +} + +.credit-modal-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 25px 30px; + border-bottom: 1px solid rgba(0, 0, 0, 0.1); + background: linear-gradient(135deg, #001954 0%, #003580 100%); + border-radius: 20px 20px 0 0; + position: relative; + overflow: hidden; +} + +.credit-modal-header::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: linear-gradient(135deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.05)); + pointer-events: none; +} + +.credit-modal-header h2 { + margin: 0; + font-size: 24px; + font-weight: 600; + color: white; + position: relative; + z-index: 1; +} + +.credit-modal-close { + position: relative; + z-index: 1; + font-size: 32px; + font-weight: 300; + color: white; + cursor: pointer; + line-height: 1; + transition: all 0.3s ease; + opacity: 0.8; +} + +.credit-modal-close:hover { + opacity: 1; + transform: rotate(90deg); +} + +/* Form Styles */ +.credit-form { + padding: 30px; +} + +.form-group-full { + margin-bottom: 20px; +} + +.form-group-full label { + display: block; + font-weight: 600; + margin-bottom: 8px; + color: #23282d; + font-size: 14px; +} + +.form-group-full input[type="text"] { + width: 100%; + padding: 12px; + border: 2px solid #ddd; + border-radius: 8px; + font-size: 14px; + transition: all 0.3s ease; +} + +.form-group-full input[type="text"]:focus { + outline: none; + border-color: #0073aa; + box-shadow: 0 0 0 3px rgba(0, 115, 170, 0.1); +} + +.form-group-full input[type="checkbox"] { + margin-right: 8px; + width: 18px; + height: 18px; + vertical-align: middle; +} + +.required { + color: #dc3232; + font-weight: 700; +} + +.description { + margin-top: 5px; + margin-bottom: 0; + font-size: 12px; + color: #666; + font-style: italic; +} + +/* Form Actions */ +.form-actions { + display: flex; + gap: 10px; + justify-content: flex-end; + padding-top: 20px; + border-top: 1px solid #ddd; +} + +.form-actions .button { + display: inline-flex; + align-items: center; + gap: 5px; + padding: 10px 20px; + font-size: 14px; +} + +.form-actions .button-primary { + background: linear-gradient(135deg, #0073aa 0%, #005a87 100%); + border: none; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); +} + +.form-actions .button-primary:hover { + background: linear-gradient(135deg, #005a87 0%, #004466 100%); +} + +/* Animations */ +@keyframes fadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +@keyframes modalSlideIn { + from { + transform: scale(0.9); + opacity: 0; + } + to { + transform: scale(1); + opacity: 1; + } +} + +/* Responsive */ +@media (max-width: 768px) { + .credit-modal-content { + width: 95%; + max-width: 100%; + } + + .credit-modal-header { + padding: 20px; + } + + .credit-modal-header h2 { + font-size: 20px; + } + + .credit-form { + padding: 20px; + } + + .form-actions { + flex-direction: column; + } + + .form-actions .button { + width: 100%; + justify-content: center; + } +} + +/* DataTables Customization */ +.dataTables_wrapper .dataTables_filter input { + border: 2px solid #ddd; + border-radius: 4px; + padding: 6px 10px; +} + +.dataTables_wrapper .dataTables_length select { + border: 2px solid #ddd; + border-radius: 4px; + padding: 6px 10px; +} + diff --git a/assets/img/blug-abstract-bg.png b/assets/img/blug-abstract-bg.png new file mode 100644 index 0000000..963bd49 Binary files /dev/null and b/assets/img/blug-abstract-bg.png differ diff --git a/assets/img/cd-bullet.png b/assets/img/cd-bullet.png new file mode 100644 index 0000000..7360778 Binary files /dev/null and b/assets/img/cd-bullet.png differ diff --git a/assets/img/cred_banniere.jpg b/assets/img/cred_banniere.jpg new file mode 100644 index 0000000..9f0a468 Binary files /dev/null and b/assets/img/cred_banniere.jpg differ diff --git a/assets/img/credit-direct-embleme.png b/assets/img/credit-direct-embleme.png new file mode 100644 index 0000000..9121415 Binary files /dev/null and b/assets/img/credit-direct-embleme.png differ diff --git a/assets/img/footer-bg.jpg b/assets/img/footer-bg.jpg new file mode 100644 index 0000000..d7216f3 Binary files /dev/null and b/assets/img/footer-bg.jpg differ diff --git a/assets/img/header-bullet.png b/assets/img/header-bullet.png new file mode 100644 index 0000000..6e3e149 Binary files /dev/null and b/assets/img/header-bullet.png differ diff --git a/assets/img/icon-telephone-dk.png b/assets/img/icon-telephone-dk.png new file mode 100644 index 0000000..eef0dad Binary files /dev/null and b/assets/img/icon-telephone-dk.png differ diff --git a/assets/img/icon-telephone.png b/assets/img/icon-telephone.png new file mode 100644 index 0000000..28998fc Binary files /dev/null and b/assets/img/icon-telephone.png differ diff --git a/assets/js/README.md b/assets/js/README.md new file mode 100644 index 0000000..b97a828 --- /dev/null +++ b/assets/js/README.md @@ -0,0 +1,117 @@ +# README – cd_main.js + +## 1. Fonctions principales + +### Fonctions de calcul de crédit +- **calculate_pat, calculate_am, calculate_ph, calculate_fin_neuve, calculate_pao_m_3, calculate_pao_p_3, calculate_mobilhome, calculate_regroupement_de_credit, calculate_frais_notaire, calculate_but_immo, calculate_mono_rate_bt_10_30** + - Calculent les paramètres d'un crédit (durée min/max, taux, etc.) selon le type de prêt et les valeurs saisies (capital, durée). + - Chaque fonction correspond à un type de crédit spécifique. + +### Fonctions d'orchestration et d'UI +- **onchange_loan_type** + - Fonction centrale appelée lors du changement de type de crédit (sélecteur, radio, sous-type). + - Met à jour les sliders, les valeurs par défaut, l'affichage des champs, et déclenche le recalcul des mensualités. +- **calculate_mensualite** + - Calcule la mensualité et met à jour l'affichage (montant, durée, taux, etc.) selon les valeurs courantes. + - Appelée à chaque modification pertinente (type, capital, durée). +- **change_capital_slider, change_month_slider** + - Initialisent et mettent à jour les sliders de capital et de durée, avec gestion des bornes, des steps, et de l'affichage dynamique. +- **change_duree** + - Met à jour la liste des durées disponibles selon le type de crédit et le capital. +- **update_capital_input** + - Met à jour les bornes et la valeur du champ capital lors d'un changement de type de crédit. + +### Fonctions utilitaires +- **number_format** + - Formate les nombres pour l'affichage (séparateurs, décimales). +- **validate_months_input, delayed_capital_chnage, delayed_months_change** + - Gèrent la validation et l'arrondi des valeurs saisies dans les champs capital et durée. + +### Gestionnaires d'événements +- De nombreux gestionnaires jQuery déclenchent les fonctions ci-dessus lors des interactions utilisateur (changement de type, capital, durée, clics sur les boutons, etc.). + +## 2. Scénarios d'interaction et enchaînement des fonctions + +### Changement de type de crédit +- L'utilisateur change le type de crédit (sélecteur ou radio). +- **onchange_loan_type** est appelée : + - Met à jour le type sélectionné. + - Met à jour les sliders (capital, durée) via **change_capital_slider** et **change_month_slider**. + - Met à jour l'affichage des champs spécifiques. + - Appelle **calculate_mensualite** pour recalculer la mensualité. + +### Changement du capital +- L'utilisateur modifie le capital (slider ou input). +- **on_slider_value_change** est appelée (directement ou via un timeout). + - Appelle **calculate_mensualite** pour recalculer la mensualité. + - Peut aussi mettre à jour la durée maximale possible via **change_duree** ou **change_month_slider**. + +### Changement de la durée +- L'utilisateur modifie la durée (slider, input, ou boutons + / -). +- **calculate_mensualite** est appelée pour recalculer la mensualité. +- **change_duree** ou **change_month_slider** peuvent être appelées pour ajuster les bornes et l'affichage. + +### Changement de sous-type ou d'option spécifique +- Peut déclencher **onchange_loan_type** ou des fonctions de calcul spécifiques selon le contexte. + +### Soumission du formulaire +- Validation via jQuery Validate. +- Envoi AJAX, affichage d'un message de confirmation ou d'erreur. + +### Autres interactions +- De nombreux champs conditionnels (ex : profession, co-emprunteur, allocations) affichent ou masquent dynamiquement des sections du formulaire selon les choix de l'utilisateur. + +--- + +## 3. Schéma des interactions principales + +```mermaid +flowchart TD + A["Utilisateur interagit avec l'UI"] + A --> B{"Type d'action"} + B -->|Change le type de crédit| C[onchange_loan_type] + B -->|Change le capital| D[on_slider_value_change] + B -->|Change la durée| E[validate_months_input] + C --> F[change_capital_slider] + C --> G[change_month_slider] + C --> H[calculate_mensualite] + D --> H + E --> H + H --> I{"Type de crédit"} + I -->|pat| J[calculate_pat] + I -->|am| K[calculate_am] + I -->|ph| L[calculate_ph] + I -->|fin_neuve| M[calculate_fin_neuve] + I -->|fin_occ_m3a| N[calculate_pao_m_3] + I -->|fin_occ_p3a| O[calculate_pao_p_3] + I -->|mobil_carav| P[calculate_mobilhome] + I -->|regroup_cred| Q[calculate_regroupement_de_credit] + I -->|frais_notaire| R[calculate_frais_notaire] + I -->|but_immo| S[calculate_but_immo] + I -->|amr/cdp/cied| T[calculate_mono_rate_bt_10_30] + J --> U[Résultats de calcul] + K --> U + L --> U + M --> U + N --> U + O --> U + P --> U + Q --> U + R --> U + S --> U + T --> U + U --> V[Affichage des résultats] + V --> W[UI mise à jour] +``` + +--- + +**Remarques :** +- Le cœur de la logique métier repose sur l'enchaînement `onchange_loan_type` → `calculate_mensualite` → fonctions de calcul selon le type. +- Les sliders et les champs sont synchronisés à chaque changement pour garantir la cohérence des valeurs. +- Le code est fortement couplé à l'UI jQuery et à la structure HTML du simulateur. + +**Questions restantes :** +- Souhaitez-vous un schéma visuel des interactions ? +- Faut-il détailler chaque fonction de calcul ou ce niveau de synthèse suffit-il ? +- Voulez-vous une section sur l'extension AJAX et la structure des réponses serveur ? \ No newline at end of file diff --git a/assets/js/buildings-manager.js b/assets/js/buildings-manager.js new file mode 100644 index 0000000..6cad0aa --- /dev/null +++ b/assets/js/buildings-manager.js @@ -0,0 +1,179 @@ +/** + * Gestion des bâtiments et crédits associés + * Pour le formulaire credit-one-step.php + */ + +jQuery(document).ready(function($) { + var buildingIndex = 0; + var loanIndex = 0; + + // Toggle de la section bâtiments + $('input[name="isowner"]').on('change', function() { + if ($(this).val() === '1') { + $('.wpcf-buildings-section').removeClass('d-none'); + } else { + $('.wpcf-buildings-section').addClass('d-none'); + $('#buildings-container').empty(); + $('#IDnumberofbuildings').val(''); + buildingIndex = 0; + } + }); + + // Génération des bâtiments selon le nombre sélectionné + $('#IDnumberofbuildings').on('change', function() { + var numberOfBuildings = parseInt($(this).val()); + var container = $('#buildings-container'); + + // Vider le container + container.empty(); + buildingIndex = 0; + + // Générer les bâtiments + for (var i = 1; i <= numberOfBuildings; i++) { + addBuilding(i); + } + }); + + // Fonction pour ajouter un bâtiment + function addBuilding(index) { + var template = $('#building-template').html(); + template = template.replace(/__INDEX__/g, index); + + var $building = $(template); + $building.removeClass('d-none'); + + // S'assurer que tous les champs clonés sont activés (pas disabled) + $building.find('input, select, textarea').prop('disabled', false); + + $('#buildings-container').append($building); + + // Attacher les événements pour ce bâtiment + attachBuildingEvents(index); + } + + // Attacher les événements spécifiques à un bâtiment + function attachBuildingEvents(index) { + // Gestion de l'affichage du select pays + $('input[name="building[' + index + '][inbelgium]"]').on('change', function() { + var $block = $(this).closest('.building-block'); + var $countrySelect = $block.find('.building-country-select'); + + if ($(this).val() === '0') { + $countrySelect.removeClass('d-none'); + } else { + $countrySelect.addClass('d-none'); + } + }); + + // Gestion de l'affichage du montant des revenus locatifs + $('input[name="building[' + index + '][hasrentalincome]"]').on('change', function() { + var $block = $(this).closest('.building-block'); + var $rentalAmount = $block.find('.building-rental-amount'); + + if ($(this).val() === '1') { + $rentalAmount.removeClass('d-none'); + } else { + $rentalAmount.addClass('d-none'); + } + }); + } + + // Toggle de la section crédits pour bâtiments + $('input[name="hasbuildingloans"]').on('change', function() { + if ($(this).val() === '1') { + $('.wpcf-buildingloans').removeClass('d-none'); + + // Si le container est vide, ajouter automatiquement un premier crédit + if ($('#building-loans-container').children().length === 0) { + loanIndex = 1; + addBuildingLoan(loanIndex); + } + } else { + $('.wpcf-buildingloans').addClass('d-none'); + $('#building-loans-container').empty(); + loanIndex = 0; + } + }); + + // Ajouter un crédit + $('.wpcf-buildingloan-add').on('click', function(e) { + e.preventDefault(); + loanIndex++; + addBuildingLoan(loanIndex); + }); + + // Fonction pour ajouter un crédit + function addBuildingLoan(index) { + var template = $('#building-loan-template').html(); + template = template.replace(/__LOANINDEX__/g, index); + + var $loan = $(template); + $loan.removeClass('d-none'); + + // S'assurer que tous les champs clonés sont activés (pas disabled) + $loan.find('input, select, textarea').prop('disabled', false); + + $('#building-loans-container').append($loan); + + // Attacher l'événement de suppression + $loan.find('.wpcf-buildingloan-remove').on('click', function(e) { + e.preventDefault(); + + if (confirm('Êtes-vous sûr de vouloir retirer ce crédit ?')) { + var $loanBlock = $(this).closest('.building-loan-block'); + var kuid = $loanBlock.find('input[name*="[kuid]"]').val(); + + if (kuid) { + // Ajouter le kuid à la liste des suppressions + var delList = $('input[name="delbuildingloans"]').val(); + delList = delList ? delList + ',' + kuid : kuid; + $('input[name="delbuildingloans"]').val(delList); + } + + $loanBlock.remove(); + } + }); + } + + // Si des crédits existent déjà (en cas de modification), initialiser loanIndex + var existingLoans = $('.building-loan-block').length; + if (existingLoans > 0) { + loanIndex = existingLoans; + } + + // Si hasbuildingloans est déjà coché au chargement et qu'aucun crédit n'existe, en ajouter un + if ($('input[name="hasbuildingloans"]:checked').val() === '1' && $('#building-loans-container').children().length === 0) { + loanIndex = 1; + addBuildingLoan(loanIndex); + } + + // Animation et style pour les sections + $('.building-block').each(function() { + $(this).css({ + 'background-color': '#f8f9fa', + 'border-radius': '8px', + 'margin-bottom': '20px', + 'padding': '20px', + 'box-shadow': '0 2px 4px rgba(0,0,0,0.1)' + }); + }); + + // Style pour les labels des bâtiments + $('.building-label').css({ + 'color': '#ff6b35', + 'font-weight': 'bold' + }); + + // Désactiver tous les champs des templates pour éviter leur soumission + // Les templates contiennent __INDEX__ et __LOANINDEX__ dans les noms de champs + $('#building-template input, #building-template select, #building-template textarea').prop('disabled', true); + $('#building-loan-template input, #building-loan-template select, #building-loan-template textarea').prop('disabled', true); + + // S'assurer que les templates restent désactivés avant chaque soumission + $('form.form-submit').on('submit', function(e) { + // Désactiver tous les champs contenant __INDEX__ ou __LOANINDEX__ dans leur nom + $(this).find('input[name*="__INDEX__"], select[name*="__INDEX__"], textarea[name*="__INDEX__"]').prop('disabled', true); + $(this).find('input[name*="__LOANINDEX__"], select[name*="__LOANINDEX__"], textarea[name*="__LOANINDEX__"]').prop('disabled', true); + }); +}); + diff --git a/assets/js/cd_main - Copie.js b/assets/js/cd_main - Copie.js new file mode 100644 index 0000000..194761c --- /dev/null +++ b/assets/js/cd_main - Copie.js @@ -0,0 +1,2874 @@ +console.log(cd_js); + +var duree_range = []; +var Timer; +var form_sliders = []; +var authorized_value = ['pat', 'fin_neuve', 'fin_occ_m3a', 'fin_occ_p3a', 'ph', 'am', 'frais_notaire', 'but_immo']; + +var map_values = { + 'purchasehouse': 'am', + 'construction': 'am', + 'regrouping': 'am', + 'refinancing': 'am', + 'purchaseabroad': 'am', + 'achat_maison_de_rapport': 'amr', + 'credit_pont': 'cdp', + 'independants_et_entreprises_en_difficultes': 'cied', + 'regroupement_de_credit__rachats_de_credits': 'regroup_cred', + 'mobilhome': 'mobil_carav', + 'financement_frais_de_notaire': 'frais_notaire', + 'fonds_roulement_independants' : 'cied' +}; + +//Crédit travaux / Rénovation / Energie +form_sliders['but_immo'] = { capital_selected: 20000, capital_max: 90000, capital_step: 100, capital_min: 2500, duree_min: 24, duree_max: 120, durees: [24, 30, 36, 42, 48, 60, 72, 84], pivot_value: 0, sub_pivot_value: 0, title: 'Crédit travaux / Rénovation / Energie', description: '

    Exemple représentatif : type de crédit = prêt à tempérament (travaux) / montant emprunté = 10.001€ / durée = 60 mois / mensualité = 179,09€ / coût total = 10.745,40€ / TAEG* = 2,90% / taux débiteur fixe = 2,90%.

    *TAEG = Taux Annuel Effectif Global = Taux Débiteur Fixe. Sous réserve de changement des taux et d\'acceptation de votre dossier par nos partenaires financiers.

    ' }; +//Financement véhicule NEUF +form_sliders['fin_neuve'] = { capital_selected: 20000, capital_max: 100000, capital_step: 500, capital_min: 5000, duree_min: 24, duree_max: 84, durees: [24, 30, 36, 42, 48, 60, 72, 84], pivot_value: 0, sub_pivot_value: 5000, title: 'Financement véhicule NEUF', description: '

    Exemple représentatif : type de crédit = prêt à tempérament (achat auto neuve) / montant emprunté = 15.000€ / durée = 60 mois / mensualité = 262,73€ / coût total = 15.763,80€ / TAEG* = 1,99% / taux débiteur fixe = 1,99%.

    *TAEG = Taux Annuel Effectif Global = Taux Débiteur Fixe. Sous réserve de changement des taux et d\'acceptation de votre dossier par nos partenaires financiers.

    ' }; +// Financement véhicule d'occasion PLUS de 3 ans +form_sliders['fin_occ_p3a'] = { capital_selected: 20000, capital_max: 100000, capital_step: 500, capital_min: 5000, duree_min: 24, duree_max: 60, durees: [24, 30, 36, 42, 48, 60], pivot_value: 0, sub_pivot_value: 5000, title: 'Financement véhicule d\'occasion PLUS de 3 ans', description: '

    Exemple représentatif : type de crédit = prêt à tempérament (achat auto plus de 3 ans) / montant emprunté = 7.501€ / durée = 48 mois / mensualité = 170,74€ / coût total = 8.195,52€ / TAEG* = 4,50% / taux débiteur fixe = 4,50%.

    *TAEG = Taux Annuel Effectif Global = Taux Débiteur Fixe. Sous réserve de changement des taux et d\'acceptation de votre dossier par nos partenaires financiers.

    ' }; +// Financement véhicule d'occasion MOINS de 3 ans +form_sliders['fin_occ_m3a'] = { capital_selected: 20000, capital_max: 100000, capital_step: 500, capital_min: 5000, duree_min: 24, duree_max: 84, durees: [24, 30, 36, 42, 48, 60, 72, 84], pivot_value: 0, sub_pivot_value: 5000, title: 'Financement véhicule d\'occasion MOINS de 3 ans', description: '

    Exemple représentatif : type de crédit = prêt à tempérament (achat auto moins de 3 ans) / montant emprunté = 10.001€ / durée = 60 mois / mensualité = 177,32€ / coût total = 10.639,20€ / TAEG* = 2,49% / taux débiteur fixe = 2,49%.

    *TAEG = Taux Annuel Effectif Global = Taux Débiteur Fixe. Sous réserve de changement des taux et d\'acceptation de votre dossier par nos partenaires financiers.

    ' }; +// Financement véhicule d'occasion MOINS de 3 ans +form_sliders['mobil_carav'] = { capital_selected: 20000, capital_max: 100000, capital_step: 500, capital_min: 10000, duree_min: 24, duree_max: 144, durees: [24, 30, 36, 42, 48, 60, 72, 84, 96, 108, 120, 144], pivot_value: 5000, sub_pivot_value: 0, title: 'Financement mobilhome et caravane', description: '

    Exemple représentatif : type de crédit = prêt à tempérament (achat auto moins de 3 ans) / montant emprunté = 10.001€ / durée = 60 mois / mensualité = 177,32€ / coût total = 10.639,20€ / TAEG* = 2,49% / taux débiteur fixe = 2,49%.

    *TAEG = Taux Annuel Effectif Global = Taux Débiteur Fixe. Sous réserve de changement des taux et d\'acceptation de votre dossier par nos partenaires financiers.

    ' }; +// Financement frais de notaire +form_sliders['frais_notaire'] = { capital_selected: 20000, capital_max: 40000, capital_step: 100, capital_min: 2500, duree_min: 24, duree_max: 120, durees: [24, 30, 36, 42, 48, 60, 72, 84, 96, 108, 120], pivot_value: 0, sub_pivot_value: 0, title: 'Financement frais de notaire', description: '

    Exemple représentatif : type de crédit = via la loi du crédit hypothécaire (sans prise d’hypothèque) / montant emprunté = 20.000€ / durée = 120 mois / mensualité = 211,94€ / coût total = 25.432,80€ / TAEG* = 5,10% / taux débiteur fixe = 5,10%.

    *TAEG = Taux Annuel Effectif Global = Taux Débiteur Fixe. Sous réserve de changement des taux et d’acceptation de votre dossier par nos partenaires financiers.
    Uniquement valable aux noms des parents.

    ' }; +// Prêt personnel : tous motifs, achats divers +form_sliders['pat'] = { capital_selected: 10000, capital_max: 200000, capital_min: 1500, capital_step: 100, duree_min: 24, duree_max: 240, durees: [24, 30, 36, 42, 48, 60, 72, 84, 96, 108, 120, 144, 180, 240], pivot_value: 75000, sub_pivot_value: 0, title: 'Prêt personnel / Tous motifs / Achats divers', description: '

    Exemple représentatif : type de crédit = prêt à tempérament (tous motifs) / montant emprunté = 12.500€ / durée = 60 mois / mensualité = 245,97€ / coût total = 14758,20€ / TAEG* = 6,95% / taux débiteur fixe = 6,95%.

    *TAEG = Taux Annuel Effectif Global = Taux Débiteur Fixe. Sous réserve de changement des taux et d\'acceptation de votre dossier par nos partenaires financiers.

    *Le taux appliqué est un taux réduit, susceptible d\'évoluer à la hausse ou à la baisse en fonction de votre situation et des conditions bancaires en vigueur.

    ' }; +// Crédit hypothécaire social (achat maison, construction) +form_sliders['ph'] = { capital_selected: 100000, capital_max: 1000000, capital_min: 25000, capital_step: 1000, duree_min: 10, duree_max: 30, durees: [5, 10, 15, 20, 25, 30], pivot_value: 0, sub_pivot_value: 0, title: 'Crédit hypothécaire', description: '

    Exemple représentatif : type de crédit = prêt hypothécaire (formule « social » / achat maison / avec frais de notaire) / prix de vente de la maison = 120.000€ / assurance vie = 2535€ (prime unique pour une personne née le 30/06/92) / frais de notaire = 15.075,12€ (achat + crédit) / frais de dossier = 150€ / frais d’expertise = 150€ / assurance incendie = 309,20€ (prime annuelle) / budget total = 137.910,12€ / fonds propres : 3.410,12€ / montant du crédit = 134.500€ / durée = 30 ans fixe / mensualité = 506,65€ / taux nominal annuel : 1% fixe / TAEG* indicatif = 1,8249% / coût total du crédit = 151.995€ / quotité = 110%

    *TAEG (Taux Annuel Effectif Global) indicatif est communiqué à titre informatif : le définitif sera intégré dans l’ESIS lors de l’émission de l’offre. Il est calculé suivant le montant de l’assurance vie et incendie, les frais de dossier, d’expertise et d’hypothèque. Sous réserve de changement des taux et d’acceptation de votre dossier par nos partenaires financiers.

    *Le taux calculé est donné à titre indicatif pour une quotité inférieure à 80 %. Il peut légèrement varier à la hausse ou à la baisse en fonction des fluctuations du marché et de la date d’application.

    ' }; +// Crédit hypothécaire classique (achat maison, construction, refinancement, regroupement, travaux, achat à l'étranger) +form_sliders['am'] = { capital_selected: 100000, capital_max: 1000000, capital_min: 25000, capital_step: 1000, duree_min: 10, duree_max: 30, durees: [10, 15, 20, 25, 30], pivot_value: 0, sub_pivot_value: 0, title: 'Crédit hypothécaire classique (achat maison, construction, refinancement, regroupement, travaux, achat à l\'étranger)', description: '

    Exemple représentatif : type de crédit = prêt hypothécaire (formule « classique » / achat maison / hors frais de notaire) / prix de vente de la maison = 150.000€ / assurance vie = 113,04€ (prime annuelle pour une personne née le 30/06/92) / frais de notaire = 18.570,70€ (achat + crédit) / frais de dossier = 350€ / frais d’expertise = 250€ / assurance incendie = 309,20€ (prime annuelle) / montant du crédit = 150.000€ / durée = 25 ans fixe / mensualité = 678,07€ / taux nominal annuel = 2,60% fixe / TAEG* indicatif = 3,31% / coût total du crédit = 203.421€ / quotité = 100%

    *TAEG (Taux Annuel Effectif Global) indicatif est communiqué à titre informatif : le définitif sera intégré dans l’ESIS lors de l’émission de l’offre. Il est calculé suivant le montant de l’assurance vie et incendie, les frais de dossier, d’expertise et d’hypothèque. Sous réserve de changement des taux et d’acceptation de votre dossier par nos partenaires financiers.

    *Le taux calculé est donné à titre indicatif pour une quotité inférieure à 80 %. Il peut légèrement varier à la hausse ou à la baisse en fonction des fluctuations du marché et de la date d’application.

    ' }; +// Crédit achat maison rapport +form_sliders['amr'] = { capital_selected: 100000, capital_max: 1000000, capital_min: 25000, capital_step: 1000, duree_min: 10, duree_max: 30, durees: [10, 15, 20, 25, 30], pivot_value: 0, sub_pivot_value: 0, title: 'Crédit hypothécaire maison rapport', description: '

    Exemple représentatif : type de crédit = prêt hypothécaire (formule « classique » / achat maison / hors frais de notaire) / prix de vente de la maison = 150.000€ / assurance vie = 113,04€ (prime annuelle pour une personne née le 30/06/92) / frais de notaire = 18.570,70€ (achat + crédit) / frais de dossier = 350€ / frais d’expertise = 250€ / assurance incendie = 309,20€ (prime annuelle) / montant du crédit = 150.000€ / durée = 25 ans fixe / mensualité = 678,07€ / taux nominal annuel = 2,60% fixe / TAEG* indicatif = 3,31% / coût total du crédit = 203.421€ / quotité = 100%

    *TAEG (Taux Annuel Effectif Global) indicatif est communiqué à titre informatif : le définitif sera intégré dans l’ESIS lors de l’émission de l’offre. Il est calculé suivant le montant de l’assurance vie et incendie, les frais de dossier, d’expertise et d’hypothèque. Sous réserve de changement des taux et d’acceptation de votre dossier par nos partenaires financiers.

    *Le taux calculé est donné à titre indicatif pour une quotité inférieure à 80 %. Il peut légèrement varier à la hausse ou à la baisse en fonction des fluctuations du marché et de la date d’application.

    ' }; +// Crédit pont +form_sliders['cdp'] = { capital_selected: 100000, capital_max: 1000000, capital_min: 25000, capital_step: 1000, duree_min: 10, duree_max: 30, durees: [10, 15, 20, 25, 30], pivot_value: 0, sub_pivot_value: 0, title: 'Crédit pont', description: '

    Exemple représentatif : type de crédit = prêt hypothécaire (formule « classique » / achat maison / hors frais de notaire) / prix de vente de la maison = 150.000€ / assurance vie = 113,04€ (prime annuelle pour une personne née le 30/06/92) / frais de notaire = 18.570,70€ (achat + crédit) / frais de dossier = 350€ / frais d’expertise = 250€ / assurance incendie = 309,20€ (prime annuelle) / montant du crédit = 150.000€ / durée = 25 ans fixe / mensualité = 678,07€ / taux nominal annuel = 2,60% fixe / TAEG* indicatif = 3,31% / coût total du crédit = 203.421€ / quotité = 100%

    *TAEG (Taux Annuel Effectif Global) indicatif est communiqué à titre informatif : le définitif sera intégré dans l’ESIS lors de l’émission de l’offre. Il est calculé suivant le montant de l’assurance vie et incendie, les frais de dossier, d’expertise et d’hypothèque. Sous réserve de changement des taux et d’acceptation de votre dossier par nos partenaires financiers.

    *Le taux calculé est donné à titre indicatif pour une quotité inférieure à 80 %. Il peut légèrement varier à la hausse ou à la baisse en fonction des fluctuations du marché et de la date d’application.

    ' }; +// Crédit Indépendants et entreprises en difficultés +form_sliders['cied'] = { capital_selected: 100000, capital_max: 1000000, capital_min: 25000, capital_step: 1000, duree_min: 10, duree_max: 30, durees: [10, 15, 20, 25, 30], pivot_value: 0, sub_pivot_value: 0, title: 'Crédit Indépendants et entreprises en difficultés', description: '

    Exemple représentatif : type de crédit = prêt hypothécaire (formule « classique » / achat maison / hors frais de notaire) / prix de vente de la maison = 150.000€ / assurance vie = 113,04€ (prime annuelle) / montant du crédit = 150.000€ / durée = 25 ans fixe / mensualité = 678,07€ / taux nominal annuel = 2,60% fixe / TAEG* indicatif = 3,31% / coût total du crédit = 203.421€ / quotité = 100%

    *TAEG (Taux Annuel Effectif Global) indicatif est communiqué à titre informatif : le définitif sera intégré dans l’ESIS lors de l’émission de l’offre. Il est calculé suivant le montant de l’assurance vie et incendie, les frais de dossier, d’expertise et d’hypothèque. Sous réserve de changement des taux et d’acceptation de votre dossier par nos partenaires financiers.

    *Le taux calculé est donné à titre indicatif pour une quotité inférieure à 80 %. Il peut légèrement varier à la hausse ou à la baisse en fonction des fluctuations du marché et de la date d’application.

    ' }; + +// Regroupement de crédit / rachat de crédit +form_sliders['regroup_cred'] = { capital_selected: 20000, capital_max: 200000, capital_step: 500, capital_min: 5000, duree_min: 24, duree_max: 144, durees: [24, 30, 36, 42, 48, 60, 72, 84, 96, 108, 120, 144], pivot_value: 75000, sub_pivot_value: 0, title: 'Regroupement de crédit / rachat de crédit', description: '

    Exemple représentatif : type de crédit = prêt à tempérament (achat auto moins de 3 ans) / montant emprunté = 10.001€ / durée = 60 mois / mensualité = 177,32€ / coût total = 10.639,20€ / TAEG* = 2,49% / taux débiteur fixe = 2,49%.

    *TAEG = Taux Annuel Effectif Global = Taux Débiteur Fixe. Sous réserve de changement des taux et d\'acceptation de votre dossier par nos partenaires financiers.

    ' }; + + +// Intialize the stimulator on page load +jQuery(function($) { + if ($("#form_wizard").length) { + // onchange_loan_type(); + onchange_type_de_credit(); + } else if ($(".load_simulator").length) { + //Initialize capital slider + onchange_loan_type(); + } +}); + + +// Function to calculate Prêt personnel / Tous motifs / Achats divers +function calculate_pat(selected_capital, selected_duration) { + + let annual_rate, min_duration, max_duration, duree_in_range = true, display_observation_pat = false, + add_message = ''; + + min_duration = 24; + + console.log('selected_duration', selected_duration); + console.log('selected_capital', selected_capital); + + + if (1500 <= parseInt(selected_capital) && parseInt(selected_capital) <= 2500) { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers._1500_a_2500; + max_duration = 24; + } else if ((2500 < parseInt(selected_capital) && parseInt(selected_capital) <= 3700)) { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers._2501_a_3700; + max_duration = 30; + } else if ((3700 < parseInt(selected_capital) && parseInt(selected_capital) <= 5000)) { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers._3701_a_5000; + max_duration = 30; + } else if ((5000 < parseInt(selected_capital) && parseInt(selected_capital) <= 5600)) { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers._5001_a_5600; + max_duration = 36; + } else if ((5600 < parseInt(selected_capital) && parseInt(selected_capital) <= 7500)) { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers._5601_a_7500; + max_duration = 42; + } else if ((7500 < parseInt(selected_capital) && parseInt(selected_capital) <= 10000)) { + max_duration = 48; + + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) { + // + } else { + duree_in_range = false; + selected_duration = max_duration; + } + + if (selected_duration == 48) { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers._7501_a_10000_48_mois; + } else { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers._7501_a_10000_24_a_42_mois; + } + } else if ((10000 < parseInt(selected_capital) && parseInt(selected_capital) <= 15000)) { + + if (selected_duration < 48) { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers._10001_a_15000_24_a_42_mois; + } else { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers._10001_a_15000_48_a_60_mois; + } + max_duration = 60; + + } else if ((15000 < parseInt(selected_capital) && parseInt(selected_capital) <= 20000)) { + if (24 <= parseInt(selected_duration) && parseInt(selected_duration) <= 42) { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers.a_partir_de_15001_24_a_42_mois; + } else { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers.a_partir_de_15001_48_a_84_mois; + } + max_duration = 84; + } else if((20000 < parseInt(selected_capital) && parseInt(selected_capital) <= 75001)) { + + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers.a_partir_de_20001_a_75000; + + max_duration = 120; + } else if((75001 <= parseInt(selected_capital))) { + + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers.a_partir_de_75000; + + display_observation_pat = true; + + max_duration = 240; + selected_duration = 240; + } + + + /* else if ((20000 < parseInt(selected_capital) && parseInt(selected_capital) <= 29999)) { + if (24 <= parseInt(selected_duration) && parseInt(selected_duration) < 48) { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers.a_partir_de_20001_24_a_42_mois; + } else { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers.a_partir_de_20001_48_a_120_mois; + } + max_duration = 120; + } else if (parseInt(selected_capital) > 29999) { + max_duration = 120; + if (24 <= parseInt(selected_duration) && parseInt(selected_duration) < 48) { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers.a_partir_de_30001_24_a_42_mois; + } else { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers.a_partir_de_30001_48_a_120_mois; + } + } */ + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) { + + } else { + duree_in_range = false; + selected_duration = max_duration; + } + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message] + +} + +// Function to calculate Crédit hypothécaire +function calculate_ph(selected_capital, selected_duration) { + var annual_rate, min_duration, max_duration; + var duree_in_range = true; + var add_message = ''; + + min_duration = 5; + max_duration = 30; + annual_rate = cd_js.groups.credit_hypothecaire_social.de_10_a_30_ans; + + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + selected_duration = selected_duration * 12; + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message] +} + +// Function to calculate Crédit hypothécaire +function calculate_am(selected_capital, selected_duration) { + var annual_rate, min_duration, max_duration; + var duree_in_range = true; + var add_message = ''; + + for (var i = 10; i <= 30; i++) { + if (parseInt(selected_duration) == i) { + selector = 'credit_hypothecaire_classique.des_' + i + '_ans'; + + /* console.log(cd_js.groups.credit_hypothecaire_classique['des_' + i + '_ans']); */ + + annual_rate = cd_js.groups.credit_hypothecaire_classique['des_' + i + '_ans'] + } + } + min_duration = 10; + max_duration = 30; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + selected_duration = selected_duration * 12; + + console.log([min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message]); + + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message] +} + +//function to calculate credit with one type of rate between 10 to 30 years +function calculate_mono_rate_bt_10_30(selected_loan_type, selected_capital, selected_duration) { + + var annual_rate, min_duration, max_duration, add_message; + var duree_in_range = true; + + min_duration = 10; + max_duration = 30; + + console.log(selected_loan_type); + + annual_rate = cd_js.groups[selected_loan_type].de_10_a_30_ans; + + + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + + selected_duration = selected_duration * 12; + + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message] +} + +// Function to calculate Financement véhicule NEUF +function calculate_fin_neuve(selected_capital, selected_duration) { + var annual_rate, min_duration, max_duration, add_message; + var duree_in_range = true; + min_duration = 24; + if (2500 == parseInt(selected_capital)) { + annual_rate = cd_js.groups.financement_vehicule_neuf._2500_24_mois; + max_duration = 24; + } else if ((2500 < parseInt(selected_capital) && parseInt(selected_capital) <= 3700)) { + annual_rate = cd_js.groups.financement_vehicule_neuf._2501_a_3700_24_a_30_mois; + max_duration = 30; + } else if ((3700 < parseInt(selected_capital) && parseInt(selected_capital) <= 5600)) { + annual_rate = cd_js.groups.financement_vehicule_neuf._3701_a_5600_24_a_36_mois; + max_duration = 36; + } else if ((5600 < parseInt(selected_capital) && parseInt(selected_capital) <= 7500)) { + annual_rate = cd_js.groups.financement_vehicule_neuf._5601_a_7500_24_a_42_mois; + max_duration = 42; + } else if ((7500 < parseInt(selected_capital) && parseInt(selected_capital) <= 10000)) { + annual_rate = cd_js.groups.financement_vehicule_neuf._7501_a_10000_24_a_48_mois; + max_duration = 48; + } else if ((10000 < parseInt(selected_capital) && parseInt(selected_capital) <= 15000)) { + annual_rate = cd_js.groups.financement_vehicule_neuf.a_partir_de_10001_24_a_60_mois; + max_duration = 60; + } else if ((15000 < parseInt(selected_capital) && parseInt(selected_capital) <= 100000)) { + max_duration = 84; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration < 72) { + annual_rate = cd_js.groups.financement_vehicule_neuf.a_partir_de_15001_24_a_60_mois; + } else { + annual_rate = cd_js.groups.financement_vehicule_neuf.a_partir_de_15001_72_a_84_mois; + } + } + + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message] +} + +// Function to calculate prêt auto occasion - de 3 ans +function calculate_pao_m_3(selected_capital, selected_duration) { + var annual_rate, min_duration, max_duration; + var duree_in_range = true; + var add_message = ''; + + min_duration = 24; + if (2500 == parseInt(selected_capital)) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_moins_de_3_ans._2500_24_mois; + max_duration = 24; + } else if ((2500 < parseInt(selected_capital) && parseInt(selected_capital) <= 3700)) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_moins_de_3_ans._2501_a_3700_24_a_30_mois; + max_duration = 30; + } else if ((3700 < parseInt(selected_capital) && parseInt(selected_capital) <= 5600)) { + annual_rate = cd_js.groups.financement_vehicule_neuf._3701_a_5600_24_a_36_mois; + max_duration = 36; + } else if ((5600 < parseInt(selected_capital) && parseInt(selected_capital) <= 7500)) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_moins_de_3_ans._5601_a_7500_24_a_42_mois; + max_duration = 42; + } else if ((7500 < parseInt(selected_capital) && parseInt(selected_capital) <= 10000)) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_moins_de_3_ans._7501_a_10000_24_a_48_mois; + max_duration = 48; + } else if ((10000 < parseInt(selected_capital) && parseInt(selected_capital) <= 15000)) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_moins_de_3_ans.a_partir_de_10001_24_a_60_mois; + max_duration = 60; + } else if ((15000 < parseInt(selected_capital) && parseInt(selected_capital) <= 100000)) { + max_duration = 84; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration < 60) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_moins_de_3_ans.a_partir_de_15001_24_a_60_mois; + } else { + annual_rate = cd_js.groups.financement_vehicule_doccasion_moins_de_3_ans.a_partir_de_15001_72_a_84_mois; + } + } + if (!(min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) { + duree_in_range = false; + selected_duration = max_duration; + } + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message] +} + +// Function to calculate prêt auto occasion + de 3 ans +function calculate_pao_p_3(selected_capital, selected_duration) { + var annual_rate, min_duration, max_duration; + var duree_in_range = true; + var add_message = ''; + + min_duration = 24; + if (parseInt(selected_capital) <= 2500) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._2500_24_mois; + max_duration = 24; + } else if ((2500 < parseInt(selected_capital) && parseInt(selected_capital) <= 3700)) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._2501_a_3700_24_a_30_mois; + max_duration = 30; + } else if ((3700 < parseInt(selected_capital) && parseInt(selected_capital) <= 5000)) { + max_duration = 36; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration == 36) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._3701_a_5000_36_mois; + } else { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._3701_a_5000_24_a_30_mois; + } + } else if ((5000 < parseInt(selected_capital) && parseInt(selected_capital) <= 5600)) { + max_duration = 36; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration == 36) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._5001_a_5600_36_mois; + } else { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._5001_a_5600_24_a_30_mois; + } + } else if ((5600 < parseInt(selected_capital) && parseInt(selected_capital) <= 7500)) { + max_duration = 42; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration == 36) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._5601_a_7500_36_mois; + } else if (selected_duration == 42) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._5601_a_7500_42_mois; + } else { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._5601_a_7500_24_a_30_mois; + } + } else if ((7500 < parseInt(selected_capital) && parseInt(selected_capital) <= 10000)) { + max_duration = 48; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration < 36) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._7501_a_10000_24_a_30_mois; + } else if (selected_duration < 42) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._7501_a_10000_36_mois; + } else { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._7501_a_10000_42_a_48_mois; + } + } else if ((10000 < parseInt(selected_capital) && parseInt(selected_capital) <= 100000)) { + max_duration = 60; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration < 36) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans.a_partir_de_10001_24_a_30_mois; + } else if (selected_duration < 42) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans.a_partir_de_10001_36_mois; + } else { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans.a_partir_de_10001_42_a_48_mois; + } + } + + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + console.log('dureeee', selected_duration); + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message] +} + +// function to calculate mobilhome +function calculate_mobilhome(selected_capital, selected_duration) { + var annual_rate, min_duration, max_duration; + var duree_in_range = true; + var add_message = ''; + min_duration = 24; + + if(selected_capital <= 10000){ + annual_rate = cd_js.groups.financement_mobilhome_et_caravane_de_moins_de_3_ans.max_10000; + max_duration = 48; + } else if(selected_capital > 10000 && selected_capital <= 15000){ + annual_rate = cd_js.groups.financement_mobilhome_et_caravane_de_moins_de_3_ans.de_10001_a_15000; + max_duration = 60; + } else if(selected_capital > 15000 && selected_capital <= 37000){ + annual_rate = cd_js.groups.financement_mobilhome_et_caravane_de_moins_de_3_ans.de_15001_a_37000; + max_duration = 120; + } else if(selected_capital > 37000 && selected_capital <= 100000){ + annual_rate = cd_js.groups.financement_mobilhome_et_caravane_de_moins_de_3_ans.de_37001_a_100000; + max_duration = 144; + } + + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message]; + +} + +//function to calculate regroupement de credit +function calculate_regroupement_de_credit(selected_capital, selected_duration) { + var annual_rate, min_duration, max_duration; + var duree_in_range = true; + var add_message = ''; + min_duration = 24; + + if(selected_capital >= 5000 && selected_capital <= 5600){ + annual_rate = cd_js.groups.regroupement_de_credit__rachats_de_credits.de_5000_a_5600; + max_duration = 36; + } else if(selected_capital > 5600 && selected_capital <= 7500){ + annual_rate = cd_js.groups.regroupement_de_credit__rachats_de_credits.de_5601_a_7500; + max_duration = 42; + } else if(selected_capital > 7500 && selected_capital <= 10000){ + annual_rate = cd_js.groups.regroupement_de_credit__rachats_de_credits.de_7501_a_10000; + max_duration = 48; + } else if(selected_capital > 10000 && selected_capital <= 15000){ + annual_rate = cd_js.groups.regroupement_de_credit__rachats_de_credits.de_10001_a_15000; + max_duration = 60; + } else if(selected_capital > 15000 && selected_capital <= 20000){ + annual_rate = cd_js.groups.regroupement_de_credit__rachats_de_credits.de_15001_a_20000; + max_duration = 84; + } else if(selected_capital > 20000 && selected_capital <= 60000){ + annual_rate = cd_js.groups.regroupement_de_credit__rachats_de_credits.de_20001_a_60000; + max_duration = 120; + } else if(selected_capital > 60000 && selected_capital <= 75000){ + annual_rate = cd_js.groups.regroupement_de_credit__rachats_de_credits.de_60001_a_75000; + max_duration = 120; + } else if(selected_capital > 75000 && selected_capital <= 100000){ + annual_rate = cd_js.groups.regroupement_de_credit__rachats_de_credits.de_75001_a_100000; + max_duration = 144; + } + + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message]; +} + +// Function to calculate Financement frais de notaire +function calculate_frais_notaire(selected_capital, selected_duration) { + var annual_rate, min_duration, max_duration; + var duree_in_range = true; + var add_message = ''; + min_duration = 24; + if ((2500 < parseInt(selected_capital) && parseInt(selected_capital) <= 15000)) { + annual_rate = cd_js.groups.financement_frais_de_notaire.de_2500_a_15000_24_a_60_mois; + max_duration = 60; + } else if ((15000 < parseInt(selected_capital) && parseInt(selected_capital) <= 40000)) { + annual_rate = cd_js.groups.financement_frais_de_notaire.de_15001_a_40000_24_a_120_mois; + max_duration = 120; + } + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message] +} +// Function to calculate travaux / Rénovation / Energie +function calculate_but_immo(selected_capital, selected_duration) { + var annual_rate, min_duration, max_duration; + var duree_in_range = true; + var add_message = ''; + min_duration = 24; + if (2500 == parseInt(selected_capital)) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._2500_24_mois; + max_duration = 24; + } else if ((2500 < parseInt(selected_capital) && parseInt(selected_capital) <= 3700)) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._2501_a_3700_24_a_30_mois; + max_duration = 30; + } else if ((3700 < parseInt(selected_capital) && parseInt(selected_capital) <= 5600)) { + max_duration = 36; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration == 36) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._3701_a_5600_36_mois; + } else { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._3701_a_5600_24_a_30_mois; + } + } else if ((5600 < parseInt(selected_capital) && parseInt(selected_capital) <= 7500)) { + max_duration = 42; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration == 42) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._5601_a_7500_42_mois; + } else if (selected_duration == 36) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._3701_a_5600_36_mois; + } else { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._5601_a_7500_24_a_30_mois; + } + } else if ((7500 < parseInt(selected_capital) && parseInt(selected_capital) <= 10000)) { + max_duration = 48; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration < 36) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._7501_a_10000_24_a_30_mois; + } else if (selected_duration < 42) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._7501_a_10000_36_mois; + } else { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._7501_a_10000_42_a_48_mois; + } + } else if ((10000 < parseInt(selected_capital) && parseInt(selected_capital) <= 15000)) { + max_duration = 60; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration < 36) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._10001_a_15000_24_a_30_mois; + } else if (selected_duration < 42) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._10001_a_15000_36_mois; + } else { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._10001_a_15000_42_a_60_mois; + } + } else if ((15000 < parseInt(selected_capital) && parseInt(selected_capital) <= 20000)) { + max_duration = 84; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration < 36) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie.a_partir_de_15001_24_a_30_mois; + } else if (selected_duration < 42) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._a_partir_de_15001_36_mois; + } else if (selected_duration < 72) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._a_partir_de_15001_42_a_60_mois; + } else { + annual_rate = cd_js.groups.credit_travaux__renovation__energie.a_partir_de_15001_72_a_84_mois; + } + } else if ((20000) < parseInt(selected_capital)) { + max_duration = 120; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration < 36) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie.a_partir_de_20001_24_a_30_mois; + } else if (selected_duration < 42) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie.a_partir_de_20001_36_mois; + } else if (selected_duration < 72) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie.a_partir_de_20001_42_a_60_mois; + } else if (selected_duration < 96) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie.a_partir_de_20001_72_a_84_mois; + } else { + annual_rate = cd_js.groups.credit_travaux__renovation__energie.a_partir_de_20001_96_a_120_mois; + } + } + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message] +} +//Function to calculate mensulate for all forms +function calculate_mensualite() { + var selected_duration, selected_capital; + selected_duration = jQuery('#selected_months').val(); + selected_capital = jQuery('#selected_capital').val(); + var results, stimulator_value, min_duration, max_duration, duree_in_range, annual_rate, add_messages, loan_type, sub_loan_radio_type; + loan_type = jQuery('#loan_type').val(), + loan_radio_type = jQuery('.loan_type:checked').length ? jQuery('.loan_type:checked').val() : '', + sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : '', + sub_auto_radio_type = jQuery('.sub_auto_loan_type:checked').length ? jQuery('.sub_auto_loan_type:checked').val() : ''; + + /* if (sub_loan_radio_type != '') + loan_type = loan_radio_type; */ + + if (sub_loan_radio_type != '' && authorized_value.includes(sub_loan_radio_type)) { + loan_type = sub_loan_radio_type; + } else if (map_values[sub_loan_radio_type] !== 'undefined') { + loan_type = map_values[sub_loan_radio_type]; + } + + if (sub_auto_radio_type != '') + loan_type = sub_auto_radio_type; + + /* console.log(selected_capital); + console.log(JSON.stringify(selected_duration)); */ + + + switch (loan_type) { + case 'pat': + results = calculate_pat(selected_capital, selected_duration); + break; + case 'fin_neuve': + results = calculate_fin_neuve(selected_capital, selected_duration); + break; + case 'fin_occ_m3a': + results = calculate_pao_m_3(selected_capital, selected_duration); + break; + case 'fin_occ_p3a': + results = calculate_pao_p_3(selected_capital, selected_duration); + break; + case 'ph': + results = calculate_ph(selected_capital, selected_duration); + break; + case 'am': + results = calculate_am(selected_capital, selected_duration); + break; + case 'frais_notaire': + results = calculate_frais_notaire(selected_capital, selected_duration); + break; + case 'but_immo': + results = calculate_but_immo(selected_capital, selected_duration); + break; + case 'amr': + case 'cdp': + case 'cied': + results = calculate_mono_rate_bt_10_30(sub_loan_radio_type, selected_capital, selected_duration); + break; + case 'mobil_carav': + results = calculate_mobilhome(selected_capital, selected_duration); + break; + case 'regroup_cred': + results = calculate_regroupement_de_credit(selected_capital, selected_duration); + break; + } + /* console.log(loan_type); */ + console.log('results', results); + + min_duration = results[0]; + max_duration = results[1]; + selected_duration = results[2]; + duree_in_range = results[3]; + annual_rate = parseFloat(results[4]); + add_messages = results[5]; + + function calc_mens(mnt, dur, taeg) { + // Pour le crédit pont, on ne calcule que les intérêts + if (loan_type === 'cdp') { + var t100 = taeg / 100; + var mens = (mnt * t100) / 12; // Calcul des intérêts mensuels uniquement + return Math.floor(mens * 100) / 100; + } + + // Pour les autres types de crédit, calcul normal + var dur12 = dur / 12; + var t100 = taeg / 100; + var t101 = 1 + t100; + var d12 = 1 / 12; + var buf1 = Math.pow(t101, d12); + var buf2 = Math.pow(1 / t101, dur12); + var mens = (mnt * (buf1 - 1)) / (1 - buf2), + ag = (mens * dur) - mnt; + var tauxc = (ag * 100) / (mnt * dur); + + console.log(dur); + + if (loan_type == 'am') { + console.log(dur + ' : ' + buf2); + } + + return Math.floor(mens * 100) / 100; + } + + function get_credit_infos(selected_capital, duration) { + + let rtr_array = {}; + + switch (loan_type) { + case 'pat': + results_info = calculate_pat(selected_capital, duration); + break; + case 'fin_neuve': + results_info = calculate_fin_neuve(selected_capital, duration); + break; + case 'fin_occ_m3a': + results_info = calculate_pao_m_3(selected_capital, duration); + break; + case 'fin_occ_p3a': + results_info = calculate_pao_p_3(selected_capital, duration); + break; + case 'ph': + results_info = calculate_ph(selected_capital, duration); + break; + case 'am': + results_info = calculate_am(selected_capital, duration); + break; + case 'frais_notaire': + results_info = calculate_frais_notaire(selected_capital, duration); + break; + case 'but_immo': + results_info = calculate_but_immo(selected_capital, duration); + break; + case 'cied': + case 'cdp': + case 'amr': + results_info = calculate_mono_rate_bt_10_30(sub_loan_radio_type, selected_capital, duration); + break; + } + + rtr_array['min_duration'] = results_info[0]; + rtr_array['max_duration'] = results_info[1]; + rtr_array['annual_rate'] = parseFloat(results_info[4]); + + return parseFloat(rtr_array['annual_rate']); + } + + function calc_mens_all(mnt) { + + let mens_array = {}, + duree = form_sliders[loan_type]['durees']; + var loan_type_in_years = ['am', 'amr', 'cdp', 'cied', 'ph']; + + min_duration = form_sliders[loan_type]['duree_min']; + max_duration = form_sliders[loan_type]['duree_max']; + + for (i = 0; i < duree.length; i++) { + + if (duree[i] >= min_duration && duree[i] <= max_duration) { + + var duree_in_month = duree[i]; + + global_annual_rate = get_credit_infos(mnt, duree[i]); + + /* if (loan_type == 'am') */ + if(loan_type_in_years.includes(loan_type)) + duree_in_month = duree_in_month * 12; + + mens_array[duree[i]] = calc_mens(mnt, duree_in_month, global_annual_rate); + } + + } + + return mens_array; + + } + + + stimulator_value = calc_mens(selected_capital, selected_duration, annual_rate); + //Adjust the month duration selector to minimum or maximum allowed amount + stimulator_value = stimulator_value.toFixed(2); + + console.log(stimulator_value); + + /* console.log(selected_capital); + console.log(selected_duration); + console.log(annual_rate); */ + + let simulateur_all_mensualite = calc_mens_all(selected_capital); + var loan_type_in_years = ['am', 'amr', 'cdp', 'cied', 'ph']; + + if (loan_type_in_years.includes(loan_type)) { + var selected_duration_fortmated = selected_duration / 12; + /* if(loan_type == 'ph' || loan_type == 'am') + var selected_duration_fortmated = selected_duration / 12; + else + var selected_duration_fortmated = selected_duration; */ + + + var duree_suffix = " ans"; + jQuery('label[for="selected_months"]').html('Durée choisie (nombre d\'années)'); + + } else { + var selected_duration_fortmated = selected_duration; + var duree_suffix = " mois"; + jQuery('label[for="selected_months"]').html('Durée choisie (nombre de mensualités)'); + } + + if (jQuery(".mini-stimulator").length) {} else { + console.log('selected_duration_fortmated', selected_duration_fortmated); + change_duree(min_duration, max_duration, selected_duration_fortmated); + } + + let duree_value = jQuery('.limit-warning').length ? '--' : selected_duration_fortmated + duree_suffix; + + jQuery('.montant_value').html(number_format(selected_capital, 0, ',', '.')); + jQuery('.duree_value').html(duree_value); + jQuery('.montant_total_value').html(number_format(stimulator_value, 2, ',', '.')); + jQuery('.cout_total_value').html(number_format((stimulator_value * selected_duration), 2, ',', '.')); + jQuery('.taeg_value').html(annual_rate.toFixed(2) + ' %'); + /* jQuery('#taeg_value_2').html(annual_rate.toFixed(2) + '%'); */ + jQuery('.taux_debiteur_fixe_value').html(annual_rate.toFixed(2) + ' %'); + /* jQuery('#additional_messages').html(add_messages); */ + + if (jQuery('#loan_type').length) { + jQuery('#loan_type').val(loan_type); + } + + if (jQuery('#hidden_montant_total_value').length) { + jQuery('#hidden_montant_total_value').val(number_format(stimulator_value, 2, ',', '.')); + } + + if (jQuery('#hidden_cout_total_value').length) { + jQuery('#hidden_cout_total_value').val(number_format((stimulator_value * selected_duration), 2, ',', '.')); + } + + if (jQuery('#hidden_taeg_value').length) { + jQuery('#hidden_taeg_value').val(annual_rate.toFixed(2) + '%'); + } + + if (jQuery('#estateloantype').length) { + jQuery('#estateloantype').val(sub_loan_radio_type); + } + + /**print all mensualite for the different period */ + for (property in simulateur_all_mensualite) { + + /* class_name = loan_type == 'am' ? property + '_ans' : 'mens_' + property; */ + class_name = loan_type_in_years.includes(loan_type) ? property + '_ans' : 'mens_' + property; + + jQuery('.date-range-buttons .' + class_name).text(simulateur_all_mensualite[property] + ' €'); + } +} + +//Create an onchange event for Type de prêt +jQuery(document).on('change', '#loan_type, .loan_type, .sub_loan_type', function() { + console.log('change'); + + onchange_loan_type(); +}); + +jQuery(document).on('change', '.sub_auto_loan_type', function(e) { + console.log('sub-change'); + onchange_loan_type(); +}); + +/* jQuery('.loan_type').change(function() { + onchange_loan_type(); +}); */ + +jQuery('#credit-direct-accordion').accordion({ + collapsible: true, + active: false, + heightStyle: "content" +}); + +jQuery("#credit-direct-accordion .ui-accordion-header").click(function() { + jQuery(this) + .children("i") + .toggleClass("fa-plus-circle fa-minus-circle"); + + jQuery(".ui-accordion-header") + .not(jQuery(this)) + .children("i") + .removeClass("fa-minus-circle"); + jQuery(".ui-accordion-header") + .not(jQuery(this)) + .children("i") + .addClass("fa-plus-circle"); +}); + +// Function to perform when loan is changed +function onchange_loan_type(type = 'select') { + + var form_data = []; + var form_desc = []; + var selected = jQuery('#loan_type').val(), + loan_radio_type = jQuery('.loan_type:checked').length ? jQuery('.loan_type:checked').val() : '', + sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : '', + sub_auto_radio_type = jQuery('.sub_auto_loan_type:checked').length ? jQuery('.sub_auto_loan_type:checked').val() : '', + input_label = '', + sub_input_label; + + jQuery('.sub_loan_type, .sub_auto_loan_type').parent('.form_check').find('.form-check-label').removeClass('active'); + + if (jQuery('.sub_loan_type:checked').parent('.form_check').find('.form-check-label').length) { + input_label = jQuery('.sub_loan_type:checked, .sub_auto_loan_type:checked').parent('.form_check').find('.form-check-label'); + + if (!input_label.hasClass('active')) + input_label.addClass('active'); + } + + if (loan_radio_type != '') { + /* console.log(loan_radio_type); */ + selected = loan_radio_type; + } + + if (sub_loan_radio_type != '') { + + if (authorized_value.includes(sub_loan_radio_type)) { + selected = sub_loan_radio_type; + } else if (map_values[sub_loan_radio_type] !== 'undefined') { + selected = map_values[sub_loan_radio_type]; + } + + } + + /* if (sub_auto_radio_type != '') + selected = sub_auto_radio_type; */ + + //Define slider values + + console.log(form_sliders.selected); + + duree_range = form_sliders[selected].durees; + + jQuery('.disclaimer').html(form_sliders[selected].description); + if (jQuery(".mini-stimulator").length) { + jQuery('.type_pret_value').html(form_sliders[selected].title); + } else { + if ((selected == "ph") || (selected == "am")) { + change_duree(form_sliders[selected].duree_min, form_sliders[selected].duree_max, form_sliders[selected].duree_max); + jQuery('#selected_months').val(30); + } else { + change_duree(form_sliders[selected].duree_min, form_sliders[selected].duree_max, form_sliders[selected].duree_max); + jQuery('#selected_months').val(form_sliders[selected].duree_max); + } + console.log(jQuery('#selected_months').val()); + change_capital_slider(form_sliders[selected].capital_min, form_sliders[selected].capital_max, form_sliders[selected].capital_selected); + change_month_slider(form_sliders[selected].duree_min, form_sliders[selected].duree_max, form_sliders[selected].duree_max); + update_capital_input(); + //if ((selected == "ph") || (selected == "am") || (selected =="frais_notaire")) { + if ((selected == "ph") || (selected == "am")) { + jQuery('.disclaimer-results').html('

    TAEG : suite à la nouvelle législation en vigueur depuis le 01/04/2017, le TAEG (Taux Annuel Effectif Global) devra vous être communiqué dans le cadre d’une demande de crédit hypothécaire. Il sera calculé en fonction des frais liés au crédit. Le TAEG vous sera communiqué à votre demande, ou lors de la réception de votre demande de crédit. Informations complètes via ce lien.

    '); + jQuery('#stimulator_label_tdf_1').hide(); + jQuery('#stimulator_label_tdf_2').show(); + + jQuery('.but_credit_immo').slideDown(); + + + } else { + jQuery('.disclaimer-results').html(''); + jQuery('#stimulator_label_tdf_1').show(); + jQuery('#stimulator_label_tdf_2').hide(); + + if (jQuery('.but_credit_immo').is(':visible')) + jQuery('.but_credit_immo').slideUp(); + + } + + if (selected == 'fin_neuve' || selected == 'fin_occ_m3a' || selected == 'fin_occ_p3a' || selected == 'mobilhome') { + + /* let sub_auto_elem = '
    ' + + '
    ' + + '' + + '' + + '
    ' + + '
    ' + + '' + + '' + + '
    ' + + '
    ' + + '' + + '' + + '
    ' + + '
    '; */ + + /* let sub_auto_elem = jQuery('#select_subradio_auto'); + + if (!jQuery('.sub_auto').length) { + + console.log('auto!!!'); + + jQuery(sub_auto_elem).insertAfter('.loan_type_radio'); + } else if (!jQuery('.sub_auto').is(':visible')) { + jQuery('.sub_auto').slideDown(); + } */ + + /* jQuery('.sub_auto').slideDown(); */ + + } else { + console.log('bhbj'); + if (jQuery('.sub_auto').is(':visible')) { + /* jQuery('.sub_auto').slideUp(); */ + jQuery('.sub_auto_loan_type').prop('checked', false); + } + } + + if ((selected == "ph") || (selected == "am")) { + change_month_slider(5, 30, jQuery('#selected_months').val()); + /*jQuery("#duree_slider").css("display", "block"); + jQuery("#date-range-selector").css("display", "none"); */ + } else { + + console.log(jQuery('#selected_months').val()); + + /* jQuery("#duree_slider").css("display", "none"); */ + /* jQuery("#date-range-selector").css("display", "block"); */ + jQuery('#selected_months').val(jQuery('#selected_months').val()); + } + + } + + /* + * display the info for the different loan type + */ + + //get the group of the selected loan type + var group = form_sliders[selected].group; + var info = []; + + console.log('info', info); + console.log('selected', cd_js.groups[sub_loan_radio_type]); + console.log('loan_type', sub_loan_radio_type); + + /** + * if loan type has infos, show the credit_infos div + */ + if(cd_js.groups[sub_loan_radio_type] && cd_js.groups[sub_loan_radio_type].infos){ + info = cd_js.groups[sub_loan_radio_type].infos; + + jQuery('.credit_infos .notice-info').html(info); + jQuery('.credit_infos').slideDown(); + } else { + if(jQuery('.credit_infos').is(':visible')){ + jQuery('.credit_infos .notice-info').html(''); + jQuery('.credit_infos').slideUp(); + } + } + + + + + calculate_mensualite(); +} + +// Detect capital change +jQuery('#selected_capital').on('input', function(e) { + jQuery('#selected_capital').on('keyup', function() { + clearTimeout(Timer); + + sel_val = jQuery('#selected_capital').val(); + + /* jQuery('#selected_capital').val(sel_val + 1); */ + + Timer = setTimeout(delayed_capital_chnage, 20); + }); +}); + +jQuery('#selected_capital').on('blur', function() { + display_alert_capital(); +}); + +// Action to do on capital value change +function on_slider_value_change() { + console.log('cgcgh'); + var selected = jQuery('#loan_type').val(); + var loan_radio_type = jQuery('.loan_type:checked').length ? jQuery('.loan_type:checked').val() : '', + sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : ''; + + if (loan_radio_type != '') + selected = loan_radio_type; + + if (sub_loan_radio_type != '') { + + if (authorized_value.includes(sub_loan_radio_type)) { + selected = sub_loan_radio_type; + } else if (map_values[sub_loan_radio_type] !== 'undefined') { + selected = map_values[sub_loan_radio_type]; + } + + } + + var capital_min = form_sliders[selected].capital_min; + var capital_max = form_sliders[selected].capital_max; + var selected_capital = jQuery('#selected_capital').val(); + if (!(selected == 'ph' || selected == 'am')) { + jQuery('#selected_months').val(200); + } + calculate_mensualite(); + /* change_duree(form_sliders[selected].duree_min, form_sliders[selected].duree_max, form_sliders[selected].duree_max) */ + change_capital_slider(capital_min, capital_max, selected_capital); +} + +function display_alert_capital() { + + var selected_capital = jQuery('#selected_capital').val(); + var selected = jQuery('#loan_type').val(), + selected_radio = jQuery('.loan_type:checked').length ? jQuery('.loan_type:checked').val() : '', + sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : '';; + + if (selected_radio != '') + selected = selected_radio; + + if (sub_loan_radio_type != '') { + + if (authorized_value.includes(sub_loan_radio_type)) { + selected = sub_loan_radio_type; + } else if (map_values[sub_loan_radio_type] !== 'undefined') { + selected = map_values[sub_loan_radio_type]; + } + + } + + var capital_max = form_sliders[selected].capital_max; + var capital_min = form_sliders[selected].capital_min; + + if (jQuery('.limit-warning').length) { + jQuery('.limit-warning').slideUp(); + jQuery('.limit-warning').remove(); + } + + if (!((selected_capital > capital_min) && (selected_capital < capital_max))) { + if ((selected_capital <= capital_min)) { + + jQuery('.second-col').prepend('
    Le montant minimum requis est de ' + capital_min + '€
    '); + } else { + + jQuery('.second-col').prepend('
    Le montant maximum est de ' + capital_max + '€
    '); + } + + } +} + +// Get keystroke stop on capital value +function delayed_capital_chnage() { + var selected_capital_range = '#selected_capital_range'; + var selected = jQuery('#loan_type').val(), + loan_radio_type = jQuery('.loan_type:checked').length ? jQuery('.loan_type:checked').val() : '', + sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : ''; + var selected_capital = jQuery('#selected_capital').val(); + + if (loan_radio_type != '') { + selected = loan_radio_type; + } + + if (sub_loan_radio_type != '') { + + if (authorized_value.includes(sub_loan_radio_type)) { + selected = sub_loan_radio_type; + } else if (map_values[sub_loan_radio_type] !== 'undefined') { + selected = map_values[sub_loan_radio_type]; + } + + } + + var capital_max = form_sliders[selected].capital_max; + var capital_min = form_sliders[selected].capital_min; + var simu_button = document.querySelector('.stimulator_result_btn'); + + + if (jQuery('.limit-warning').length) { + jQuery('.limit-warning').slideUp(); + jQuery('.limit-warning').remove(); + } + + if ((selected_capital >= capital_min) && (selected_capital <= capital_max)) { + + if (jQuery('.stimulator_result_btn').is(':disabled')) + jQuery('.stimulator_result_btn').removeAttr('disabled'); + + on_slider_value_change(); + } else { + if (!((selected_capital > capital_min) && (selected_capital < capital_max))) { + if ((selected_capital <= capital_min)) { + if (!(selected == 'ph' || selected == 'am')) { + /* jQuery('#selected_capital').val(capital_min); */ + /* jQuery('.second-col').prepend('
    Le montant minimum requis est de ' + capital_min + '€
    '); */ + let elem = '

    Le montant minimum requis est de ' + capital_min + '€

    '; + + jQuery(elem).insertBefore('.stimulator_result_btn'); + + /* jQuery(('

    Le montant minimum requis est de ' + capital_min + '€

    ').insertBefore('.stimulator_result_btn')); */ + } + } else { + /* jQuery('#selected_capital').val(capital_max); */ + /* jQuery('.second-col').prepend('
    Le montant maximum est de ' + capital_max + '€
    '); */ + + jQuery('

    Le montant maximum requis est de ' + capital_max + '€

    ').insertBefore('.stimulator_result_btn'); + } + + jQuery('.stimulator_result_btn').prop('disabled', true); + + on_slider_value_change(); + } + } +} + +// Check if duration changed +jQuery(function() { + jQuery(document).on('click', '.duree-btn', function() { + if (jQuery(this).hasClass('months-active')) { + jQuery('#selected_months').val(jQuery(this).data('duree')); + calculate_mensualite(); + } + }); +}); + +//Change month values +function change_duree(default_min, default_max, selected_value) { + var list = ''; + var list_class = '', + loan_type = jQuery('#loan_type').val(), + loan_radio_type = jQuery('.loan_type:checked').length ? jQuery('.loan_type:checked').val() : '', + sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : '', + class_name = 'mens_', + selected_capital = jQuery('#selected_capital').val(), + monthly_low = 0, + monthly_high = 0, + capital_min = 0, + capital_max = 0; + + // Déplacer la définition de loan_type_in_years ici, en dehors de la boucle + var loan_type_in_years = ['am', 'amr', 'cdp', 'cied']; + + if (loan_radio_type != '') + loan_type = loan_radio_type; + + if (selected_capital == '') { + + selected_capital = form_sliders[loan_type]['capital_selected']; + } + + if (sub_loan_radio_type != '') { + + if (authorized_value.includes(sub_loan_radio_type)) { + loan_type = sub_loan_radio_type; + } else if (map_values[sub_loan_radio_type] !== 'undefined') { + loan_type = map_values[sub_loan_radio_type]; + } + + } + + capital_min = form_sliders[loan_type]['capital_min']; + capital_max = form_sliders[loan_type]['capital_max']; + + + switch (loan_type) { + case 'pat': + results = calculate_pat(selected_capital, selected_value); + break; + case 'fin_neuve': + results = calculate_fin_neuve(selected_capital, selected_value); + break; + case 'fin_occ_m3a': + results = calculate_pao_m_3(selected_capital, selected_value); + break; + case 'fin_occ_p3a': + results = calculate_pao_p_3(selected_capital, selected_value); + break; + case 'ph': + results = calculate_ph(selected_capital, selected_value); + break; + case 'am': + results = calculate_am(selected_capital, selected_value); + break; + case 'frais_notaire': + results = calculate_frais_notaire(selected_capital, selected_value); + break; + case 'but_immo': + results = calculate_but_immo(selected_capital, selected_value); + break; + case 'mobil_carav': + results = calculate_mobilhome(selected_capital, selected_value); + break; + case 'regroup_cred': + results = calculate_regroupement_de_credit(selected_capital, selected_value); + break; + } + + + monthly_low = results[0]; + monthly_high = results[1]; + + console.log('monthly_low', monthly_low); + console.log('monthly_high', monthly_high); + + var validDurees = []; + + // Filtrer d'abord les durées valides + for (var j = 0; j < duree_range.length; j++) { + + + if ((monthly_low <= parseInt(duree_range[j]) && parseInt(duree_range[j]) <= monthly_high)) { + validDurees.push(duree_range[j]); + } + } + + var startIndex = Math.max(0, validDurees.length - 4); + + console.log(duree_range[startIndex]); + + console.log(selected_capital); + console.log(results); + console.log(startIndex); + console.log(validDurees); + console.log('default_max', default_max); + console.log('default_min', default_min); + console.log('sel duree', selected_value); + + + if (jQuery('#selected_capital').val() < capital_min) { + list = '
  • La somme minimale est de ' + capital_min + '€
  • '; + } else if (jQuery('#selected_capital').val() > capital_max) { + list = '
  • La somme maximale est de ' + capital_max + '€
  • '; + } else { + /* for (var i = 0; i < duree_range.length; i++) { */ + for (var i = startIndex; i < validDurees.length; i++) { + + var periodicite = ' mois'; + + // Supprimer la redéfinition de loan_type_in_years ici + + if (loan_type_in_years.includes(loan_type)) { + + class_name = validDurees[i] + '_ans'; + periodicite = ' ans'; + } else { + + class_name = 'mens_' + validDurees[i]; + } + + /* console.log('2' + selected_value); */ + + if ((default_min <= parseInt(validDurees[i]) && parseInt(validDurees[i]) <= default_max)) { + if (selected_value == validDurees[i]) { + list_class = ' selected'; + } + + if (validDurees[i] <= monthly_high) { + list = list + '
  • ' + validDurees[i] + periodicite + '
  • '; + } + } else { + list = list + ''; + } + list_class = ''; + } + } + + /* console.log(duree_range); */ + console.log(monthly_high); + console.log(monthly_low); + jQuery('#date-range-selector').html(list); + + // Mise à jour du slider_duree_box avec la bonne périodicité + var periodicite = loan_type_in_years.includes(loan_type) ? ' ans' : ' mois'; + jQuery('.slider_duree_box').text(selected_value + periodicite); + + /* var selected_months_range = '#selected_months_range'; + var selected_months = '#selected_months'; + jQuery(selected_months_range).slider({ + value: selected_value, + min: default_min, + max: default_max, + step: 1, + slide: function(event, ui) { + console.log('duree slider', ui.value); + jQuery(selected_months).val(ui.value); + jQuery(selected_months_range).children("span").text(ui.value + ' ans'); + }, + stop: function(event, ui) { + calculate_mensualite(); + } + }); */ + + // Ajout de l'initialisation de la valeur par défaut + /* jQuery(selected_months).val(selected_value); + jQuery(selected_months_range).children("span").text(selected_value + ' ans'); */ + + /* console.log(jQuery(selected_months_range).slider("option", "value")); + + jQuery(selected_months).val(jQuery(selected_months_range).slider('value')); + jQuery(selected_months_range).children("span").text(jQuery(selected_months_range).slider('value') + ' ans'); */ +} + +//Change capital slider values +function change_capital_slider(default_min, default_max, default_selected_value) { + var selected_capital_range = '#selected_capital_range'; + var selected_capital = '#selected_capital'; + var stepUpdateTimeout = null; + var isInputChange = false; + + var loan_type = jQuery('#loan_type').val(), + loan_radio_type = jQuery('.loan_type:checked').length ? jQuery('.loan_type:checked').val() : '', + sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : ''; + + if (loan_radio_type != '') + loan_type = loan_radio_type; + + if (sub_loan_radio_type != '') { + + if (authorized_value.includes(sub_loan_radio_type)) { + loan_type = sub_loan_radio_type; + } else if (map_values[sub_loan_radio_type] !== 'undefined') { + loan_type = map_values[sub_loan_radio_type]; + } + + } + + var pivot_value = form_sliders[loan_type].pivot_value; + var sub_pivot_value = form_sliders[loan_type].sub_pivot_value; + var pivot_percent = ((pivot_value - default_min) / (default_max - default_min)) * 100; + var sub_pivot_percent = ((sub_pivot_value - default_min) / (default_max - default_min)) * 100; + + console.log('default_min', default_min); + console.log('default_max', default_max); + console.log('pivot_value', pivot_value); + console.log('sub_pivot_value', sub_pivot_value); + console.log('pivot_percent', pivot_percent); + console.log('sub_pivot_percent', sub_pivot_percent); + + // Supprime l'ancienne zone pivot si elle existe + jQuery('.pivot-zone').remove(); + + // Crée la nouvelle zone pivot si pivot_value > 0 + if (pivot_value > 0) { + var pivotZone = jQuery('
    '); + pivotZone.css({ + 'position': 'absolute', + 'left': pivot_percent + '%', + 'right': '0', + 'top': '0', + 'bottom': '0', + 'background-color': 'rgba(255, 0, 0, 0.2)', + 'pointer-events': 'none' + }); + jQuery(selected_capital_range).append(pivotZone); + } + + // Fonction pour calculer le step en fonction de la valeur + function calculateStep(value) { + return value < 10000 ? 500 : 250; + } + + // Fonction pour arrondir au step le plus proche + function roundToStep(value) { + var step = calculateStep(value); + return Math.round(value / step) * step; + } + + // Configuration du champ input + jQuery(selected_capital) + .attr('step', calculateStep(default_selected_value)) + .on('input', function() { + var $input = jQuery(this); + var value = Number($input.val()); + + // Si la valeur est vide ou non numérique, ne rien faire + if (!value) return; + + // Annuler le timeout précédent s'il existe + if (stepUpdateTimeout) { + clearTimeout(stepUpdateTimeout); + } + + // Programmer la mise à jour du step après un délai + stepUpdateTimeout = setTimeout(function() { + var newStep = calculateStep(value); + $input.attr('step', newStep); + }, 500); // Délai de 500ms + + // Indiquer que le changement vient de l'input + isInputChange = true; + + // Mettre à jour le slider avec la valeur exacte + jQuery(selected_capital_range).slider('value', value); + + // Mise à jour de l'affichage + jQuery(selected_capital_range).find(".slider_capital_box") + .text(number_format(value, 2, ',', '.') + ' €'); + + // Mise à jour des min/max du slider de durée + update_duration_slider_min_max(value); + }); + + + jQuery(selected_capital_range).slider({ + min: default_min, + max: default_max, + value: default_selected_value, + step: calculateStep(default_selected_value), + slide: function(event, ui) { + + if (isInputChange) return; + + var orange_bar = jQuery('.slider_capital_wrapper .after_bar'), + elem = jQuery(ui.handle), + left_css = parseInt(elem.css('left'), 10); + + console.log('left_css', left_css); + + orange_bar.css('width', left_css + 10); + + // Met à jour la couleur du texte en fonction de la position par rapport au pivot + if (pivot_value > 0 && ui.value >= pivot_value) { + jQuery(selected_capital_range).find(".slider_capital_box").addClass('pivot-value'); + + if (!jQuery('#acceptConditions').is(':checked')) { + jQuery('.stimulator_result_btn').prop('disabled', true).addClass('disabled'); + } + } else { + jQuery(selected_capital_range).find(".slider_capital_box").removeClass('pivot-value'); + jQuery('.stimulator_result_btn').prop('disabled', false).removeClass('disabled'); + } + + jQuery(selected_capital).val(ui.value); + /* jQuery(selected_capital_range).children("span").text(number_format((ui.value), 2, ',', '.') + ' €'); */ + jQuery(selected_capital_range).find(".slider_capital_box").text(number_format((ui.value), 2, ',', '.') + ' €'); + + // Gestion de l'affichage de la notice en fonction du pivot + if (pivot_value > 0) { + if (ui.value >= pivot_value) { + jQuery('.pat_plus75000').slideDown(300); // Animation douce pour l'affichage + /* jQuery(selected_capital_range).find(".slider_capital_box").addClass('pivot-value'); */ + } else { + jQuery('.pat_plus75000').slideUp(300); // Animation douce pour le masquage + /* jQuery(selected_capital_range).find(".slider_capital_box").removeClass('pivot-value'); */ + } + } else { + jQuery('.pat_plus75000').hide(); + } + }, + stop: function(event, ui) { + + if (((loan_type == "am") && jQuery('#selected_capital').val() > 100000) || ((loan_type == "ph") && jQuery('#selected_capital').val() > 100000)) { + jQuery('#selected_months').val(30); + } + var selected = jQuery('#loan_type').val(); + if (!(selected == 'ph' || selected == 'am')) { + jQuery('#selected_months').val(200); + } + + var orange_bar = jQuery('.slider_capital_wrapper .after_bar'), + elem = jQuery(ui.handle), + left_css = parseInt(elem.css('left'), 10); + + orange_bar.css('width', left_css + 10); + + calculate_mensualite(); + }, + change: function(event, ui) { + var orange_bar = jQuery('.slider_capital_wrapper .after_bar'), + elem = jQuery(ui.handle), + left_css = parseInt(elem.css('left'), 10); + + orange_bar.css('width', left_css + 10); + } + }); + + // Gestion du changement d'état de la case à cocher + jQuery('#acceptConditions').on('change', function() { + var currentValue = jQuery(selected_capital).val(); + if (pivot_value > 0 && currentValue >= pivot_value) { + if (jQuery(this).is(':checked')) { + jQuery('.stimulator_result_btn').prop('disabled', false).removeClass('disabled'); + } else { + jQuery('.stimulator_result_btn').prop('disabled', true).addClass('disabled'); + } + } + }); + + var appended_elem = 'test'; + /* jQuery(selected_capital).val(jQuery(selected_capital_range).slider('value')); */ + if (!jQuery('.ui-slider-handle .fa-angle-right').length) + jQuery(selected_capital_range).find(".ui-slider-handle").append(''); + + //if element is not present, append it + if (!jQuery(selected_capital_range).find('.slider_capital_box').length) { + jQuery(selected_capital_range).find('.ui-slider-handle').append(appended_elem); + } + jQuery(selected_capital_range).find(".slider_capital_box").text(number_format((jQuery(selected_capital_range).slider('value')), 2, ',', '.') + ' €'); + + if (sub_pivot_value > 0) { + var subPivotZone = jQuery('
    '); + subPivotZone.css({ + 'position': 'absolute', + 'left': '0', + 'width': sub_pivot_percent + '%', + 'top': '0', + 'bottom': '0', + 'background-color': 'rgba(0, 0, 255, 0.15)', // Par exemple, bleu clair + 'pointer-events': 'none' + }); + + if(jQuery('.sub-pivot-zone').length == 0) + jQuery(selected_capital_range).append(subPivotZone); + } +} + +//Change month slider values +function change_month_slider(default_min, default_max, default_selected_value) { + + var selected_months_range = '#selected_months_range'; + var selected_months = '#selected_months'; + var loan_type_in_years = ['am', 'amr', 'cdp', 'cied', 'ph']; + var sel_duree = jQuery(selected_months).val() + + // Récupérer le type de crédit de la même manière que dans change_duree + var loan_type = jQuery('#loan_type').val(), + loan_radio_type = jQuery('.loan_type:checked').length ? jQuery('.loan_type:checked').val() : '', + sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : ''; + + if (loan_radio_type != '') + loan_type = loan_radio_type; + + if (sub_loan_radio_type != '') { + if (authorized_value.includes(sub_loan_radio_type)) { + loan_type = sub_loan_radio_type; + } else if (map_values[sub_loan_radio_type] !== 'undefined') { + loan_type = map_values[sub_loan_radio_type]; + } + } + + // Récupérer le capital actuel + var selected_capital = jQuery('#selected_capital').val(); + + console.log('selected_capital', selected_capital); + console.log('loan_type', loan_type); + console.log('sel_duree', sel_duree); + + // Calculer la durée maximale en fonction du capital + var results = []; + switch (loan_type) { + case 'pat': + results = calculate_pat(selected_capital, sel_duree); + break; + case 'fin_neuve': + results = calculate_fin_neuve(selected_capital, sel_duree); + break; + case 'fin_occ_m3a': + results = calculate_pao_m_3(selected_capital, sel_duree); + break; + case 'fin_occ_p3a': + results = calculate_pao_p_3(selected_capital, sel_duree); + break; + case 'ph': + results = calculate_ph(selected_capital, sel_duree); + break; + case 'am': + results = calculate_am(selected_capital, sel_duree); + break; + case 'frais_notaire': + results = calculate_frais_notaire(selected_capital, sel_duree); + break; + case 'but_immo': + results = calculate_but_immo(selected_capital, sel_duree); + break; + case 'mobil_carav': + results = calculate_mobilhome(selected_capital, sel_duree); + break; + case 'regroup_cred': + results = calculate_regroupement_de_credit(selected_capital, sel_duree); + break; + } + + console.log('results', results); + + // Vérifier si les résultats sont valides + /* if (!results || results.length < 2 || typeof results[1] === 'undefined') { + console.error('Résultats invalides pour le type de prêt:', loan_type); + return; + } */ + + // Utiliser max_duration (index 1) comme limite maximale + var max_duration = results[1]; + var dynamic_max = default_max; + + // Trouver la durée maximale valide dans les durées du type de prêt + var available_durations = form_sliders[loan_type].durees; + /* if (!available_durations || !Array.isArray(available_durations)) { + console.error('Durées non disponibles pour le type de prêt:', loan_type); + return; + } */ + + for (var i = available_durations.length - 1; i >= 0; i--) { + if (available_durations[i] <= max_duration) { + dynamic_max = available_durations[i]; + break; + } + } + + console.log('dynamic_max', dynamic_max); + + function getStepForValue(loan_type,value) { + let dynamic_step = 1; + + if (loan_type_in_years.includes(loan_type)) { + dynamic_step = 1; // Step de 1 an pour les prêts en années + } else { + if (value <= 48) { + dynamic_step = 6; // Step de 6 mois jusqu'à 48 mois + } else { + dynamic_step = 12; // Step de 12 mois au-delà de 48 mois + } + } + + return dynamic_step; + } + + // Mettre à jour le slider avec la nouvelle limite maximale + jQuery(selected_months_range).slider({ + min: default_min, + max: dynamic_max, + value: Math.min(default_selected_value, dynamic_max), + step: getStepForValue(loan_type, default_selected_value), + slide: function(event, ui) { + var newStep = getStepForValue(loan_type, ui.value); + + if (newStep !== jQuery(this).slider('option', 'step')) { + jQuery(this).slider('option', 'step', newStep); + } + + var orange_bar = jQuery('.slider_duree_wrapper .after_bar_month'), + elem = jQuery(ui.handle), + left_css = parseInt(elem.css('left'), 10); + + orange_bar.css('width', left_css + 10); + jQuery(selected_months).val(ui.value); + + if (loan_type_in_years.includes(loan_type)) { + jQuery(selected_months_range).find(".slider_duree_box").text(ui.value + ' ans'); + } else { + jQuery(selected_months_range).find(".slider_duree_box").text(ui.value + ' mois'); + } + }, + stop: function(event, ui) { + var orange_bar = jQuery('.slider_duree_wrapper .after_bar_month'), + elem = jQuery(ui.handle), + left_css = parseInt(elem.css('left'), 10); + + orange_bar.css('width', left_css + 10); + calculate_mensualite(); + }, + change: function(event, ui) { + var orange_bar = jQuery('.slider_duree_wrapper .after_bar_month'), + elem = jQuery(ui.handle), + left_css = parseInt(elem.css('left'), 10); + + orange_bar.css('width', left_css + 10); + } + }); + + jQuery(selected_months).val(jQuery(selected_months_range).slider('value')); + + var periodicite = loan_type_in_years.includes(loan_type) ? ' ans' : ' mois'; + var appended_elem = '' + jQuery(selected_months_range).slider('value') + periodicite + ''; + + if (!jQuery(selected_months_range).find('.ui-slider-handle .fa-angle-right').length) { + jQuery(selected_months_range).find(".ui-slider-handle").append(''); + } + + if (!jQuery(selected_months_range).find('.slider_duree_box').length) { + jQuery(selected_months_range).find('.ui-slider-handle').append(appended_elem); + } +} + +// Create plus and minus buttons for slider +jQuery(".stimulator-slider-control.capital-minus").on('click', function() { + var selected_capital_range = '#selected_capital_range'; + var selected_capital = (+jQuery('#selected_capital').val() + -100); + var selected = jQuery('#loan_type').val(); + + var selected_radio = jQuery('.loan_type:checked').length ? jQuery('.loan_type:checked').val() : '', + sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : ''; + + if (selected_radio != '') + selected = selected_radio; + + if (sub_loan_radio_type != '') { + + if (authorized_value.includes(sub_loan_radio_type)) { + selected = sub_loan_radio_type; + } else if (map_values[sub_loan_radio_type] !== 'undefined') { + selected = map_values[sub_loan_radio_type]; + } + + } + + if ((selected_capital >= form_sliders[selected].capital_min) && (selected_capital <= form_sliders[selected].capital_max)) { + jQuery(selected_capital_range).slider({ + value: selected_capital + }); + + if (((selected == "am") && jQuery('#selected_capital').val() > 100000) || ((selected == "ph") && jQuery('#selected_capital').val() > 100000)) { + jQuery('#selected_months').val(30); + } else { + jQuery('#selected_months').val(200); + } + jQuery('#selected_capital').val(selected_capital); + calculate_mensualite(); + jQuery(selected_capital_range).find(".ui-slider-handle").append(''); + jQuery(selected_capital_range).find('.ui-slider-handle').append(appended_elem); + jQuery(selected_capital_range).find(".slider_capital_box").text(number_format((jQuery(selected_capital_range).slider('value')), 2, ',', '.') + ' €'); + } +}); + +jQuery(".stimulator-slider-control.capital-plus").on('click', function() { + var selected_capital_range = '#selected_capital_range'; + var selected_capital = (+jQuery('#selected_capital').val() + +100); + var selected = jQuery('#loan_type').val(); + + var selected_radio = jQuery('.loan_type:checked').length ? jQuery('.loan_type:checked').val() : '', + sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : ''; + + if (selected_radio != '') + selected = selected_radio; + + if (sub_loan_radio_type != '') { + + if (sub_loan_radio_type != '' && authorized_value.includes(sub_loan_radio_type)) { + selected = sub_loan_radio_type; + } else if (map_values[sub_loan_radio_type] !== 'undefined') { + selected = map_values[sub_loan_radio_type]; + } + + } + + if ((selected_capital >= form_sliders[selected].capital_min) && (selected_capital <= form_sliders[selected].capital_max)) { + jQuery(selected_capital_range).slider({ + + value: selected_capital + }); + + if (((selected == "am") && jQuery('#selected_capital').val() > 100000) || ((selected == "ph") && jQuery('#selected_capital').val() > 100000)) { + jQuery('#selected_months').val(30); + } else { + jQuery('#selected_months').val(200); + } + jQuery('#selected_capital').val(selected_capital); + calculate_mensualite(); + jQuery(selected_capital_range).find(".ui-slider-handle").append(''); + jQuery(selected_capital_range).find('.ui-slider-handle').append(appended_elem); + jQuery(selected_capital_range).find(".slider_capital_box").text(number_format((jQuery(selected_capital_range).slider('value')), 2, ',', '.') + ' €'); + } +}); + +// 2. 5 Step form + +// Accordian for content pages +jQuery(".ac-toggle-button").on('click', function(e) { + e.preventDefault(); + jQuery(".ac-text-block").slideToggle("slow"); +}); + +// Show link list when link is clicked +jQuery(".agency-menu-link").children("a").on('click', function() { + if (jQuery(".agency-menu-link").hasClass('agencies-active-link')) { + jQuery(".footer-locations").css("display", "none"); + jQuery(".agency-menu-link").removeClass('agencies-active-link'); + } else { + jQuery(".footer-locations").css("display", "inherit"); + jQuery(".agency-menu-link").addClass('agencies-active-link'); + } +}); + +jQuery('#co-emprunteur').on('change', function() { + if (jQuery('[name="co-emprunteur"]:checked').val() == "avec un co-emprunteur") { + jQuery(".co-emprunteur-fields").css('display', 'block'); + jQuery("#co-emprunteur-step2").val(1); + jQuery("#co-emprunteur-step3").val(1); + jQuery("#co-emprunteur-step4").val(1); + } else { + jQuery(".co-emprunteur-fields").css('display', 'none'); + jQuery(".co-emprunteur-fields input").val(""); + jQuery("#co-emprunteur-step2").val(0); + jQuery("#co-emprunteur-step3").val(0); + jQuery("#co-emprunteur-step4").val(0); + + } +}); + +jQuery('#je-suis-resident').on('change', function() { + if (jQuery('[name="je-suis-resident"]:checked').val() == "en Belgique") { + jQuery(".field-numero-national").show(); + } else { + jQuery(".field-numero-national").hide(); + } +}); +jQuery('#co-je-suis-resident').on('change', function() { + if (jQuery('[name="co-je-suis-resident"]:checked').val() == "en Belgique") { + jQuery(".field-co-numero-national").show(); + } else { + jQuery(".field-co-numero-national").hide(); + } +}); + +jQuery('#habitation').on('change', function() { + var fields = ["montant-du-loyer-a-payer", "credit-hypothecaire-en-cours", "vous-habitez"]; + for (var i = 0; i < fields.length; i++) { + jQuery(".field-" + fields[i]).hide(); + } + switch (jQuery('#habitation').val()) { + case 'locataire': + jQuery(".field-montant-du-loyer-a-payer").show(); + break; + case 'propriétaire': + jQuery(".field-credit-hypothecaire-en-cours").show(); + break; + case 'sans charge locative': + jQuery(".field-vous-habitez").show(); + break; + } +}); + +jQuery('#habitation-co-emprunteur').on('change', function() { + var fields = ["montant-du-loyer-a-payer-co-emprunteur", "credit-hypothecaire-en-cours-co-emprunteur", "vous-habitez-co-emprunteur"]; + for (var i = 0; i < fields.length; i++) { + jQuery(".field-" + fields[i]).hide(); + } + switch (jQuery('#habitation-co-emprunteur').val()) { + case 'locataire': + jQuery(".field-montant-du-loyer-a-payer-co-emprunteur").show(); + break; + + case 'propriétaire': + jQuery(".field-credit-hypothecaire-en-cours-co-emprunteur").show(); + break; + + case 'sans charge locative': + jQuery(".field-vous-habitez-co-emprunteur").show(); + break; + } +}); +jQuery('#nombre-d-enfant-s-a-charge').on('change', function() { + if (jQuery("#nombre-d-enfant-s-a-charge").val() == 0) { + jQuery(".field-montant-allocations-familiales").hide(); + jQuery(".field-montant-pension-alimentaire-recue").hide(); + } else { + jQuery(".field-montant-allocations-familiales").show(); + jQuery(".field-montant-pension-alimentaire-recue").show(); + } +}); +jQuery('#nombre-d-enfant-s-a-charge-co-emprunteur').on('change', function() { + if (jQuery("#nombre-d-enfant-s-a-charge-co-emprunteur").val() == 0) { + jQuery(".field-co-montant-allocations-familiales").hide(); + jQuery(".field-co-montant-pension-alimentaire-recue").hide(); + } else { + jQuery(".field-co-montant-allocations-familiales").show(); + jQuery(".field-co-montant-pension-alimentaire-recue").show(); + } +}); +jQuery('#profession').on('change', function() { + var ordered_fields; + jQuery("#autres-revenus-cheques-repas").val('non'); + on_chnage_autres_revenus_cheques(''); + jQuery('#valeur-du-cheque-repas').val(''); + var fields = ['type-de-contrat', 'nom-de-l-employeur', 'adresse-rue-numero', 'code-postal', 'localite', 'engage-depuis-quant', 'salaire-net-mensuel', 'nom-de-l-organisme-de-paiement', 'paye-depuis-quand', 'montant-net-mensuel-de-l-allocation', 'depuis-quand', 'numero-d-entreprise', 'domaine-de-l-activite', 'revenus-imposables-annuels', 'revenus-locatifs', 'autres-revenus-cheques-repas', 'allocation-supplementaire']; + for (var i = 0; i < fields.length; i++) { + jQuery(".field-" + fields[i]).hide(); + } + var allowed_fields; + var selected = jQuery("#profession").val(); + jQuery("#tab4 .emprunteur-primary").removeClass('flex-ordered'); + + if ((selected == "ouvrier") || (selected == "employé") || (selected == "fonctionnaire") || (selected == "militaire") || (selected == "policier") || (selected == "enseignant")) { + allowed_fields = ['type-de-contrat', 'nom-de-l-employeur', 'adresse-rue-numero', 'code-postal', 'localite', 'engage-depuis-quant', 'salaire-net-mensuel', 'revenus-locatifs', 'autres-revenus-cheques-repas', 'allocation-supplementaire']; + } else if (selected == "chômeur") { + allowed_fields = ['nom-de-l-organisme-de-paiement', 'adresse-rue-numero', 'code-postal', 'localite', 'paye-depuis-quand', 'montant-net-mensuel-de-l-allocation', 'revenus-locatifs', 'allocation-supplementaire', 'repeat-block', 'ajouter-dautres-revenus']; + ordered_fields = ['nom-de-l-organisme-de-paiement', 'adresse-rue-numero', 'code-postal', 'localite', 'paye-depuis-quand', 'montant-net-mensuel-de-l-allocation', 'revenus-locatifs', 'montant-total-des-revenus-locatifs', 'allocation-supplementaire', 'valeur-du-cheque-repas', 'montant-net-mensuel', 'repeat-block', 'ajouter-dautres-revenus']; + jQuery("#tab4 .emprunteur-primary").addClass('flex-ordered'); + var order = 1; + for (var i = 0; i < ordered_fields.length; i++) { + jQuery(".field-" + ordered_fields[i]).css('order', order); + order++; + } + } else if ((selected == "invalide")) { + allowed_fields = ['nom-de-l-organisme-de-paiement', 'adresse-rue-numero', 'code-postal', 'localite', 'paye-depuis-quand', 'montant-net-mensuel-de-l-allocation', 'revenus-locatifs', 'allocation-supplementaire']; + } else if ((selected == "pensionné") || (selected == "prépensionné")) { + allowed_fields = ['nom-de-l-organisme-de-paiement', 'adresse-rue-numero', 'code-postal', 'localite', 'paye-depuis-quand', 'montant-net-mensuel-de-l-allocation', 'revenus-locatifs', 'allocation-supplementaire']; + } else if ((selected == "indépendant")) { + allowed_fields = ['depuis-quand', 'numero-d-entreprise', 'domaine-de-l-activite', 'adresse-rue-numero', 'code-postal', 'localite', 'revenus-imposables-annuels', 'revenus-locatifs', 'autres-revenus-cheques-repas', 'allocation-supplementaire', 'repeat-block', 'ajouter-dautres-revenus']; + ordered_fields = ['depuis-quand', 'numero-d-entreprise', 'domaine-de-l-activite', 'adresse-rue-numero', 'code-postal', 'localite', 'revenus-imposables-annuels', 'revenus-locatifs', 'montant-total-des-revenus-locatifs', 'autres-revenus-cheques-repas', 'valeur-du-cheque-repas', 'allocation-supplementaire', 'repeat-block', 'ajouter-dautres-revenus']; + jQuery("#tab4 .emprunteur-primary").addClass('flex-ordered'); + var order = 1; + for (var i = 0; i < ordered_fields.length; i++) { + jQuery(".field-" + ordered_fields[i]).css('order', order); + order++; + } + } else if (selected == "sans profession") { + allowed_fields = ['revenus-locatifs']; + } + for (var i = 0; i < allowed_fields.length; i++) { + jQuery(".field-" + allowed_fields[i]).show(); + } +}); + +jQuery('#profession-co-emprunteur').on('change', function() { + var ordered_fields; + jQuery("#autres-revenus-cheques-repas-co-emprunteur").val('non'); + on_chnage_autres_revenus_cheques('co-'); + var fields = ['type-de-contrat', 'nom-de-l-employeur', 'adresse-rue-numero', 'code-postal', 'localite', 'engage-depuis-quant', 'salaire-net-mensuel', 'nom-de-l-organisme-de-paiement', 'paye-depuis-quand', 'montant-net-mensuel-de-l-allocation', 'depuis-quand', 'numero-d-entreprise', 'domaine-de-l-activite', 'revenus-imposables-annuels', 'revenus-locatifs', 'autres-revenus-cheques-repas', 'allocation-supplementaire']; + for (var i = 0; i < fields.length; i++) { + jQuery(".field-co-" + fields[i]).hide(); + } + var allowed_fields; + var selected = jQuery("#profession-co-emprunteur").val(); + + jQuery("#tab4 .co-emprunteur-fields").removeClass('flex-ordered'); + + if ((selected == "ouvrier") || (selected == "employé") || (selected == "fonctionnaire") || (selected == "militaire") || (selected == "policier") || (selected == "enseignant")) { + allowed_fields = ['type-de-contrat', 'nom-de-l-employeur', 'adresse-rue-numero', 'code-postal', 'localite', 'engage-depuis-quant', 'salaire-net-mensuel', 'revenus-locatifs', 'autres-revenus-cheques-repas', 'allocation-supplementaire']; + } else if (selected == "chômeur") { + allowed_fields = ['nom-de-l-organisme-de-paiement', 'adresse-rue-numero', 'code-postal', 'localite', 'paye-depuis-quand', 'montant-net-mensuel-de-l-allocation', 'revenus-locatifs', 'allocation-supplementaire', 'repeat-block', 'ajouter-dautres-revenus']; + ordered_fields = ['nom-de-l-organisme-de-paiement', 'adresse-rue-numero', 'code-postal', 'localite', 'paye-depuis-quand', 'montant-net-mensuel-de-l-allocation', 'revenus-locatifs', 'montant-total-des-revenus-locatifs', 'allocation-supplementaire', 'valeur-du-cheque-repas', 'montant-net-mensuel', 'repeat-block', 'ajouter-dautres-revenus']; + jQuery("#tab4 .co-emprunteur-fields").addClass('flex-ordered'); + var order = 1; + for (var i = 0; i < ordered_fields.length; i++) { + jQuery(".field-co-" + ordered_fields[i]).css('order', order); + order++; + } + } else if ((selected == "invalide")) { + allowed_fields = ['nom-de-l-organisme-de-paiement', 'adresse-rue-numero', 'code-postal', 'localite', 'paye-depuis-quand', 'montant-net-mensuel-de-l-allocation', 'revenus-locatifs', 'allocation-supplementaire']; + } else if ((selected == "pensionné") || (selected == "prépensionné")) { + allowed_fields = ['nom-de-l-organisme-de-paiement', 'adresse-rue-numero', 'code-postal', 'localite', 'paye-depuis-quand', 'montant-net-mensuel-de-l-allocation', 'revenus-locatifs', 'allocation-supplementaire']; + } else if ((selected == "indépendant")) { + allowed_fields = ['depuis-quand', 'numero-d-entreprise', 'domaine-de-l-activite', 'adresse-rue-numero', 'code-postal', 'localite', 'revenus-imposables-annuels', 'revenus-locatifs', 'autres-revenus-cheques-repas', 'allocation-supplementaire', 'repeat-block', 'ajouter-dautres-revenus']; + ordered_fields = ['depuis-quand', 'numero-d-entreprise', 'domaine-de-l-activite', 'adresse-rue-numero', 'code-postal', 'localite', 'revenus-imposables-annuels', 'revenus-locatifs', 'montant-total-des-revenus-locatifs', 'autres-revenus-cheques-repas', 'valeur-du-cheque-repas', 'allocation-supplementaire', 'repeat-block', 'ajouter-dautres-revenus']; + jQuery("#tab4 .co-emprunteur-fields").addClass('flex-ordered'); + var order = 1; + for (var i = 0; i < ordered_fields.length; i++) { + jQuery(".field-co-" + ordered_fields[i]).css('order', order); + order++; + } + } else if (selected == "sans profession") { + allowed_fields = ['revenus-locatifs']; + } + for (var i = 0; i < allowed_fields.length; i++) { + jQuery(".field-co-" + allowed_fields[i]).show(); + } +}); + +jQuery('#allocation-supplementaire').on('change', function() { + if (jQuery('#allocation-supplementaire').val() != "---") { + jQuery(".field-paye-depuis-quand-2").show(); + jQuery(".field-montant-net-mensuel-de-l-allocation-2").show(); + jQuery(".field-nom-de-l-organisme-de-paiement").show(); + } else { + jQuery(".field-paye-depuis-quand-2").hide(); + jQuery(".field-montant-net-mensuel-de-l-allocation-2").hide(); + jQuery(".field-nom-de-l-organisme-de-paiement").hide(); + } +}); + +jQuery('#allocation-supplementaire-co-emprunteur').on('change', function() { + if (jQuery('#allocation-supplementaire-co-emprunteur').val() == "oui") { + jQuery(".field-co-paye-depuis-quand-2").show(); + jQuery(".field-co-montant-net-mensuel-de-l-allocation-2").show(); + jQuery(".field-co-nom-de-l-organisme-de-paiement").show(); + } else { + jQuery(".field-co-montant-net-mensuel-de-l-allocation-2").hide(); + jQuery(".field-co-paye-depuis-quand-2").hide(); + jQuery(".field-co-nom-de-l-organisme-de-paiement").hide(); + + } +}); + +function on_chnage_autres_revenus_cheques(prefix) { + var prefix_extended = ''; + if (prefix == "co-") { prefix_extended = "-co-emprunteur" } + var selected = jQuery("#profession" + prefix_extended).val(); + jQuery(".field-" + prefix + "valeur-du-cheque-repas").hide(); + jQuery(".field-" + prefix + "montant-net-mensuel").hide(); + if (jQuery("#autres-revenus-cheques-repas" + prefix_extended).val() == "oui") { + jQuery(".field-" + prefix + "valeur-du-cheque-repas").show(); + if ((selected == "ouvrier") || (selected == "employé") || (selected == "fonctionnaire") || (selected == "militaire") || (selected == "policier") || (selected == "enseignant") || (selected == "indépendant")) {} else { + jQuery(".field-" + prefix + "montant-net-mensuel").show(); + } + } +} + +jQuery('#autres-revenus-cheques-repas').on('change', function() { + on_chnage_autres_revenus_cheques(''); +}); + +jQuery('#autres-revenus-cheques-repas-co-emprunteur').on('change', function() { + on_chnage_autres_revenus_cheques('co-'); +}); + +jQuery('#revenus-locatifs').on('change', function() { + if (jQuery('#revenus-locatifs').val() == "oui") { + jQuery(".field-montant-total-des-revenus-locatifs").show(); + } else { + jQuery(".field-montant-total-des-revenus-locatifs").hide(); + } +}); + +jQuery('#revenus-locatifs-co-emprunteur').on('change', function() { + if (jQuery('#revenus-locatifs-co-emprunteur').val() == "oui") { + jQuery(".field-co-montant-total-des-revenus-locatifs").show(); + } else { + jQuery(".field-co-montant-total-des-revenus-locatifs").hide(); + } +}); + +function onchange_type_de_credit() { + var fields = ['fonds-propres', 'type-des-frais-de-notaire', 'prix-d-achat', 'prix-de-la-construction-tvac', 'prix-d-achat', 'compromis-signe', 'valeur-du-batiment', 'montant-du-revenu-cadastral', 'marque-modele-du-vehicule', 'date-1ere-immatriculation', 'nom-du-vendeur', 'adresse-du-vendeur', 'prix-d-achat-du-vehicule', 'type-des-frais-de-notaire', 'type-des-travaux', 'montant-a-emprunter', 'duree']; + for (var i = 0; i < fields.length; i++) { + jQuery(".field-" + fields[i]).hide(); + } + var allowed_fields; + + switch (jQuery('#type-de-credit').val()) { + case 'Prêt Hypothécaire (Achat Maison)': + allowed_fields = ['prix-d-achat', 'fonds-propres', 'compromis-signe', 'montant-du-revenu-cadastral', 'montant-a-emprunter', 'duree']; + break; + case 'Prêt Hypothécaire (Construction)': + allowed_fields = ['prix-de-la-construction-tvac', 'fonds-propres', 'montant-a-emprunter', 'duree']; + break; + case 'Prêt Hypothécaire (Refinancement)': + allowed_fields = ['valeur-du-batiment', 'montant-a-emprunter', 'duree']; + break; + case 'Prêt Hypothécaire (Regroupement)': + allowed_fields = ['valeur-du-batiment', 'montant-a-emprunter', 'duree']; + break; + case 'Prêt Hypothécaire (Achat à L\'étranger)': + allowed_fields = ['prix-d-achat', 'fonds-propres', 'compromis-signe', 'montant-a-emprunter', 'duree']; + break; + case 'Prêt à Tempérament (Tous Motifs)': + allowed_fields = ['montant-a-emprunter', 'duree']; + break; + case 'Financement Véhicule Neuf': + allowed_fields = ['marque-modele-du-vehicule', 'date-1ere-immatriculation', 'nom-du-vendeur', 'adresse-du-vendeur', 'prix-d-achat-du-vehicule', 'montant-a-emprunter', 'duree']; + break; + case 'Financement Véhicule D\'occasion': + allowed_fields = ['marque-modele-du-vehicule', 'date-1ere-immatriculation', 'nom-du-vendeur', 'adresse-du-vendeur', 'prix-d-achat-du-vehicule', 'montant-a-emprunter', 'duree']; + break; + case 'Crédit Travaux / Rénovation / Energie': + allowed_fields = ['type-des-travaux', 'montant-a-emprunter', 'duree']; + break; + case 'Frais De Notaire': + allowed_fields = ['type-des-frais-de-notaire', 'montant-a-emprunter', 'duree']; + break; + default: + allowed_fields = ['montant-a-emprunter', 'duree']; + break; + } + for (var i = 0; i < allowed_fields.length; i++) { + jQuery(".field-" + allowed_fields[i]).show(); + } + onchange_loan_type(); + +}; + +jQuery(".stimulator-slider-control.duree-plus").on('click', function() { + var selected_months_range = '#selected_months_range'; + var selected_months = '#selected_months'; + var selected = jQuery('#loan_type').val(); + if ((jQuery(selected_months).val() >= form_sliders[selected].duree_min) && (jQuery(selected_months).val() <= form_sliders[selected].duree_max)) { + jQuery(selected_months).val(+jQuery(selected_months).val() + +1); + change_duree(form_sliders[selected].duree_min, form_sliders[selected].duree_max, jQuery(selected_months).val()) + calculate_mensualite(); + } +}); +jQuery(".stimulator-slider-control.duree-minus").on('click', function() { + var selected_months_range = '#selected_months_range'; + var selected_months = '#selected_months'; + var selected = jQuery('#loan_type').val(); + if ((jQuery(selected_months).val() >= form_sliders[selected].duree_min) && (jQuery(selected_months).val() <= form_sliders[selected].duree_max)) { + jQuery(selected_months).val(+jQuery(selected_months).val() + -1); + change_duree(form_sliders[selected].duree_min, form_sliders[selected].duree_max, jQuery(selected_months).val()) + calculate_mensualite(); + } +}); + +jQuery('.dautres-credit').on('click', function() { + if (jQuery('[name="dautres-credit[]"]').is(":checked")) { + jQuery(".dautres-credit-fields").css('display', 'block'); + var n = jQuery(".repeater-fields-step-5").length; + if (n == "") { n = 0 }; + n++; + var form_step_5 = '
    X
    oui
    '; + jQuery("#step-5-repeat-block").append(form_step_5); + } else { + var repeater_id = jQuery(".repeater-fields-step-5").length; + jQuery(".rf-g-cours-" + repeater_id).remove(); + jQuery(".dautres-credit-fields").css('display', 'none'); + } +}); + +jQuery(document).on('click', '.dautres-credit-repeater', function() { + var block_5 = jQuery(this).data("repeated"); + if (jQuery(this).is(":checked")) { + jQuery(".dautres-credit-fields-" + block_5).show(); + var n = jQuery(".repeater-fields-step-5").length; + if (n == "") { n = 0 }; + n++; + var form_step_5 = '
    X
    oui
    '; + jQuery("#step-5-repeat-block").append(form_step_5); + } else { + var repeater_id = jQuery(".repeater-fields-step-5").length; + jQuery(".rf-g-cours-" + repeater_id).remove(); + jQuery(".dautres-credit-fields-" + block_5).hide(); + } +}); + +jQuery(document).on('click', '.remove_rf_revenus', function() { + var repeater_id = jQuery(this).data("repeated"); + jQuery(".rf-g-revenus-" + repeater_id).remove(); +}); +jQuery(document).on('click', '.remove_rf_en_cours', function() { + var repeater_id = jQuery(this).data("repeated"); + jQuery(".rf-g-cours-" + repeater_id).remove(); +}); +jQuery(document).on("keypress", "form", function(event) { + return event.keyCode != 13; +}); + +jQuery('.mini-stimulator #loan_type, .mini-stimulator .loan_type').change(function() { + var hidden_fields, allowed_fields; + var changeTo = ''; + hidden_fields = []; + + var loan_type = jQuery('.mini-stimulator #loan_type').val(), + loan_radio_type = jQuery('.mini-stimulator .loan_type:checked').length ? jQuery('.mini-stimulator .loan_type:checked').val() : ''; + + if (loan_radio_type != '') + loan_type = loan_radio_type; + + jQuery(".field-type-des-travaux").hide(); + allowed_fields = ['fonds-propres', 'type-des-frais-de-notaire']; + for (var i = 0; i < allowed_fields.length; i++) { jQuery(".field-" + allowed_fields[i]).show(); } + switch (loan_type) { + case 'pat': + changeTo = "Prêt à Tempérament (Personnel / Tous Motifs / Achats Divers)"; + hidden_fields = ['fonds-propres', 'type-des-frais-de-notaire']; + break; + + case 'frais_notaire': + hidden_fields = ['fonds-propres']; + changeTo = "Frais De Notaire"; + break; + + case 'but_immo': + hidden_fields = ['fonds-propres', 'type-des-frais-de-notaire']; + jQuery(".field-type-des-travaux").show(); + changeTo = "Crédit Travaux / Rénovation / Energie"; + break; + + case 'fin_neuve': + changeTo = "Financement Véhicule Neuf"; + hidden_fields = ['type-des-frais-de-notaire']; + break; + + case 'fin_occ_m3a': + hidden_fields = ['fonds-propres', 'type-des-frais-de-notaire']; + changeTo = "Financement Véhicule D'occasion"; + break; + + case 'fin_occ_p3a': + hidden_fields = ['fonds-propres', 'type-des-frais-de-notaire']; + changeTo = "Financement Véhicule D'occasion"; + break; + + case 'am': + changeTo = "Prêt Hypothécaire (Achat Maison)"; + break; + + case 'ph': + changeTo = "Prêt Hypothécaire (Achat Maison)"; + break; + } + // Change all pre de credit to veuillez sélectionner votre type de prêt + changeTo = ''; + for (var i = 0; i < hidden_fields.length; i++) { jQuery(".field-" + hidden_fields[i]).hide(); } + jQuery('#type-de-credit').val(changeTo); + onchange_type_de_credit(); +}); + +jQuery('#type-de-credit').change(function() { + var changeTo = ''; + var changeYes = false; + + var loan_type = jQuery('.mini-stimulator #loan_type').val(), + loan_radio_type = jQuery('.mini-stimulator .loan_type:checked').length ? jQuery('.mini-stimulator .loan_type:checked').val() : ''; + + if (loan_radio_type != '') + loan_type = loan_radio_type; + + switch (jQuery('#type-de-credit').val()) { + case "Frais De Notaire": + changeTo = 'frais_notaire'; + changeYes = true; + break; + + case "Crédit Travaux / Rénovation / Energie": + changeYes = true; + changeTo = 'but_immo'; + break; + + case "Financement Véhicule Neuf": + changeYes = true; + changeTo = 'fin_neuve'; + break; + + case "Financement Véhicule D'occasion": + changeYes = true; + changeTo = 'fin_occ_m3a'; + break; + case "Prêt Hypothécaire (Achat Maison)": + changeYes = true; + changeTo = 'am'; + break; + + case "Prêt Hypothécaire (Construction)": + changeYes = true; + changeTo = 'ph'; + break; + case "Prêt Hypothécaire (Refinancement)": + changeYes = true; + changeTo = 'am'; + break; + case "Prêt Hypothécaire (Regroupement)": + changeYes = true; + changeTo = 'am'; + break; + case "Prêt Hypothécaire (Achat à L'étranger)": + changeYes = true; + changeTo = 'am'; + break; + case "Prêt à Tempérament (Personnel / Tous Motifs / Achats Divers)": + changeYes = true; + changeTo = 'pat'; + break; + } + if ((changeYes == true) && (loan_type != changeTo)) { + jQuery('.mini-stimulator #loan_type').val(changeTo); + jQuery('.mini-stimulator input#' + changeTo).prop('checked', true); + jQuery('#selected_months').val(200); + } + onchange_type_de_credit(); +}); + +// 3. General +"use strict"; + + +/* form handling */ +jQuery(function() { + jQuery('.field-repeat-block').repeater({ + show: function() { + changeYesjQuery(this).slideDown(); + }, + hide: function(deleteElement) { + if (confirm('Êtes-vous sûr de vouloir supprimer cet élément?')) { + jQuery(this).slideUp(deleteElement); + } + }, + ready: function(setIndexes) { + + } + }); + // Config + var form = jQuery('#formulaire_form'); + var wizard = jQuery('#form_wizard'); + var error = jQuery('.alert-danger', form); + var success = jQuery('.alert-success', form); + jQuery.validator.addClassRules({ + number_field: { + number: true + }, + email_field: { + email: true + } + }); + jQuery.validator.messages.required = "Ce champs est requis."; + jQuery.validator.messages.email = "Veuillez insérer une adresse mail valide." + form.validate({ + doNotHideMessage: true, + focusInvalid: false, + invalidHandler: function(event, validator) { + success.hide(); + error.show(); + }, + submitHandler: function(form) { + success.show(); + error.hide(); + jQuery(form).submit(); + }, + }); + + + // Functions + var displayConfirm = function() { + jQuery('#tab6 .form-control-static', form).each(function() { + var input = jQuery('[name="' + jQuery(this).attr("data-display") + '"]', form); + + if (input.is(":text") || input.is("textarea")) { + jQuery(this).html(input.val()); + } else if (input.is("select")) { + jQuery(this).html(input.find('option:selected').text()); + } else if (input.is(":radio") && input.is(":checked")) { + jQuery(this).html(input.attr("data-title")); + } + }); + } + + var handleTitle = function(tab, navigation, index) { + var total = navigation.find('li').length; + var current = index + 1; + + // Set widget title + jQuery('.step-title', wizard).text('Step ' + (index + 1) + ' of ' + total); + + // Set done steps + jQuery('li', wizard).removeClass("done"); + + var li_list = navigation.find('li'); + for (var i = 0; i < index; i++) { + jQuery(li_list[i]).addClass("done"); + } + + if (current == 1) { + wizard.find('.button-previous').hide(); + } else { + wizard.find('.button-previous').show(); + } + + if (current >= total) { + wizard.find('.button-next').hide(); + wizard.find('.button-submit').show(); + displayConfirm(); + } else { + wizard.find('.button-next').show(); + wizard.find('.button-submit').hide(); + } + } + + // Form wizard example + wizard.bootstrapWizard({ + 'nextSelector': '.button-next', + 'previousSelector': '.button-previous', + onTabClick: function(tab, navigation, index, clickedIndex) { + success.hide(); + error.hide(); + + if (form.valid() == false) { + return false; + } else { + + dataLayer.push({ 'event': 'pageview', 'virtualUrl': 'subscription-step' + (index + 1) + '-completed.html' }); + } + + handleTitle(tab, navigation, clickedIndex); + }, + onNext: function(tab, navigation, index) { + success.hide(); + error.hide(); + + if (form.valid() == false) { + return false; + } else { + dataLayer.push({ 'event': 'pageview', 'virtualUrl': 'subscription-step' + (index + 1) + '-completed.html' }); + } + handleTitle(tab, navigation, index); + + }, + onPrevious: function(tab, navigation, index) { + success.hide(); + error.hide(); + + handleTitle(tab, navigation, index); + }, + onTabShow: function(tab, navigation, index) { + // To set progressbar width + var total = navigation.find('li').length; + var current = index + 1; + if (current > 1) { jQuery('.page-formulaire-seletors').hide(); } else { jQuery('.page-formulaire-seletors').show(); } + var $percent = (current / total) * 100; + wizard.find('.progress-bar').css({ + width: $percent + '%' + }); + jQuery('html, body').animate({ + scrollTop: jQuery("#form_wizard").offset().top + }, 1000); + } + }); + + wizard.find('.button-previous').hide(); + jQuery('#form_wizard .button-submit').click(function() {}).hide(); +}); + +function number_format(number, decimals, decPoint, thousandsSep) { // eslint-disable-line camelcase + + number = (number + '').replace(/[^0-9+\-Ee.]/g, '') + var n = !isFinite(+number) ? 0 : +number + var prec = !isFinite(+decimals) ? 0 : Math.abs(decimals) + var sep = (typeof thousandsSep === 'undefined') ? ',' : thousandsSep + var dec = (typeof decPoint === 'undefined') ? '.' : decPoint + var s = '' + + var toFixedFix = function(n, prec) { + var k = Math.pow(10, prec) + return '' + (Math.round(n * k) / k) + .toFixed(prec) + } + + // @todo: for IE parseFloat(0.55).toFixed(0) = 0; + s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.') + if (s[0].length > 3) { + s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep) + } + if ((s[1] || '').length < prec) { + s[1] = s[1] || '' + s[1] += new Array(prec - s[1].length + 1).join('0') + } + + return s.join(dec) +} + +function update_capital_input() { + if (jQuery('#selected_capital').length) { + + var selected = jQuery('#loan_type').val(), + selected_radio = jQuery('.loan_type:checked').length ? jQuery('.loan_type:checked').val() : '', + sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : ''; + + if (selected_radio != '') + selected = selected_radio; + + if (sub_loan_radio_type != '' && authorized_value.includes(sub_loan_radio_type)) { + selected = sub_loan_radio_type; + } else if (map_values[sub_loan_radio_type] !== 'undefined') { + selected = map_values[sub_loan_radio_type]; + } + + var capital_max = form_sliders[selected].capital_max; + var capital_min = form_sliders[selected].capital_min; + var capital_selected = form_sliders[selected].capital_selected; + + jQuery('#selected_capital').prop('min', capital_min); + jQuery('#selected_capital').prop('max', capital_max); + jQuery('#selected_capital').val(capital_selected); + } +} + + +/* allocation selector */ +jQuery(document).on('change', '.allocation-supplementaire-repeater', function() { + var block_4 = jQuery(this).data("repeated"); + if ((jQuery(this)).val() != "---") { + jQuery(this).parents(".repeater-fields-step-4").children(".add-repeater-fields").show(); + } else { + jQuery(this).parents(".repeater-fields-step-4").children(".add-repeater-fields").hide(); + } +}); + +jQuery(function() { + var is_sending = false, + failure_message = 'Whoops, looks like there was a problem. Please try again later.'; + + jQuery('#forumulair-submit').on('click', function(e) { + + e.preventDefault(); // Prevent the default form submit + var $this = jQuery('#formulaire_form'); // Cache this + jQuery.ajax({ + url: cd_ajax_url.ajaxUrl, + type: 'post', + dataType: 'JSON', // Set this so we don't need to decode the response... + data: $this.serialize(), // One-liner form data prep... + beforeSend: function() { + is_sending = true; + // You could do an animation here... + }, + error: function(data) { + + }, + success: function(data) { + if (data.status === 'success') { + var message = + "

    Votre demande de crédit nous est bien parvenue et nous vous en remercions. Une suite vous sera assurée dans les plus brefs délais (vous allez d'ailleurs recevoir un accusé de réception de notre part, par e-mail)

    Nous vous informons qu'il est toujours préférable de ne pas introduire votre demande auprès de plusieurs sociétés de crédit en même temps. Nous travaillons avec la plupart des banques et sociétés de crédit, ce qui signifie que si votre dossier venait à être refusé la 1ère fois, nous le réintroduirons automatiquement ailleurs afin d'avoir un maximum de chances d'acceptation.

    Crédit Direct SPRL

    Retour vers la page d'accueil
    "; + jQuery('#formulaire_form').html(message); + window.setTimeout(function() { window.location.href = cd_ajax_url.site_url; }, 15000); + } else { + // handleFormError(); // If we don't get the expected response, it's an error... + } + } + }); + }); + + function handleFormError() { + is_sending = false; // Reset the is_sending var so they can try again... + alert(failure_message); + } +}); +// Create plus and minus buttons for slider +jQuery("#show_contact_num").click(function() { + jQuery('.header-top-contacts').slideToggle(); +}); + +jQuery('#rgpdID').on('click', function() { + + if (jQuery(this).is(':checked')) { + jQuery('[type="submit"]').removeAttr('disabled'); + } else { + jQuery('[type="submit"]').prop('disabled', true); + } + +}); + +jQuery('[name="hascoborrower"]').each(function() { + jQuery(this).on('click', function(e) { + + let val = jQuery(this).val(); + + if (val == 1) { + jQuery('.co-emprunteur').slideDown(); + jQuery('.isRequired').prop('required', true); + } else if (val == 0) { + jQuery('.co-emprunteur').slideUp(); + jQuery('.isRequired').removeAttr('required'); + } + + }); +}); + +/* jQuery('#selected_capital_range').on('slide, change', function(event, ui) { + + var css_left_span = jQuery('#selected_capital_range').find('span').css('left'), + orange_bar = jQuery('.slider-count-wrapper .after_bar'); + + if (!orange_bar.hasClass('active')) + orange_bar.addClass('active'); + + + if (css_left_span < 90) + css_left_span += 10; + + orange_bar.css('width', css_left_span); + +}); */ + +/*jQuery('#selected_capital_range').on('slidechange', function(event, ui) { + + var css_left_span = jQuery('#selected_capital_range').find('span').css('left'), + orange_bar = jQuery('.slider-count-wrapper .after_bar'); + + if (!orange_bar.hasClass('active')) + orange_bar.addClass('active'); + + + if (css_left_span < 90) + css_left_span += 10; + + orange_bar.css('width', css_left_span); + +});*/ + +jQuery('#selected_capital_range').on('slidecreate', function(event, ui) { + + var css_left_span = jQuery('#selected_capital_range').find('span').css('left'), + orange_bar = jQuery('.slider-count-wrapper .after_bar'); + + if (!orange_bar.hasClass('active')) + orange_bar.addClass('active'); + + + orange_bar.css('width', css_left_span); + +}); + +jQuery(document).ready(function($) { + // Gestion du changement d'état de la case à cocher avec effet de slide + $('#switch_duration_type').on('change', function() { + if ($(this).is(':checked')) { + $('.determined_choices').slideUp(300, function() { + $('.free_choice').slideDown(300); + }); + } else { + $('.free_choice').slideUp(300, function() { + $('.determined_choices').slideDown(300); + }); + } + }); +}); + +// Gestion des boutons de type de crédit +jQuery(document).ready(function($) { + $('.credit-type-selector').on('click', function(e) { + e.preventDefault(); + + const type = $(this).data('type'); + const $container = $('.load_simulator').parent(); + + // Ajout d'un indicateur de chargement + $container.addClass('loading'); + + // Requête AJAX + $.ajax({ + url: cd_js.ajaxUrl, + type: 'POST', + data: { + action: 'ajax_regenerate_simulator', + type: type, + nonce: cd_js.nonce + }, + success: function(response) { + if (response.success) { + // Mise à jour du contenu + $container.html(response.data.html); + + // Réinitialisation des événements + if (typeof on_slider_value_change === 'function') { + on_slider_value_change(); + } + } else { + console.error('Erreur lors de la régénération du simulateur:', response.data.message); + } + }, + error: function(xhr, status, error) { + console.error('Erreur AJAX:', error); + $container.removeClass('loading'); + }, + complete: function() { + $container.removeClass('loading'); + } + }); + }); +}); + +function handleCreditTypeClick() { + jQuery('#cred-hypo, #cred-pat').on('click', function(e) { + e.preventDefault(); + // Ajout gestion classe active_btn + jQuery('#cred-hypo, #cred-pat').removeClass('active_btn'); + jQuery(this).addClass('active_btn'); + + const type = jQuery(this).attr('id') === 'cred-hypo' ? 'am' : 'pat'; + const container = jQuery('.home-simu-holder > .fusion-column-wrapper'); + const parentContainer = container.parent(); + + // Sauvegarder la hauteur actuelle + const currentHeight = container.outerHeight(); + + jQuery.ajax({ + url: cd_js.ajaxUrl, + type: 'POST', + data: { + action: 'ajax_regenerate_simulator', + type: type, + nonce: cd_js.nonce + }, + beforeSend: function() { + // Ajouter le spinner + const loadingSpinner = jQuery('
    '); + parentContainer.append(loadingSpinner); + // Définir la hauteur minimale du parent + parentContainer.css('min-height', currentHeight + 'px'); + // Animation de sortie + container.addClass('animate-slide-out-down'); + // Enregistrer le temps de début du spinner + parentContainer.data('spinnerStart', Date.now()); + }, + success: function(response) { + if (response.success) { + // Mise à jour du contenu avec animation + container.html(response.data.html); + + // Séquence d'animations d'entrée + setTimeout(function() { + container.removeClass('animate-slide-out-down').addClass('animate-slide-in-up'); + + // Réinitialisation des événements après l'animation + setTimeout(function() { + if (typeof on_slider_value_change === 'function') { + on_slider_value_change(); + } + + // Réinitialisation des sliders + if (typeof change_capital_slider === 'function') { + const capitalSlider = jQuery('#selected_capital_range'); + if (capitalSlider.length) { + const min = parseInt(capitalSlider.data('min')); + const max = parseInt(capitalSlider.data('max')); + const value = parseInt(capitalSlider.data('value')); + change_capital_slider(min, max, value); + + // Initialisation de la barre orange pour le capital + const capitalOrangeBar = jQuery('.slider-count-wrapper .after_bar'); + if (capitalOrangeBar.length) { + const cssLeftSpan = capitalSlider.find('span').css('left'); + capitalOrangeBar.addClass('active'); + capitalOrangeBar.css('width', cssLeftSpan); + } + } + } + + if (typeof change_month_slider === 'function') { + const monthSlider = jQuery('#selected_month_range'); + if (monthSlider.length) { + const min = parseInt(monthSlider.data('min')); + const max = parseInt(monthSlider.data('max')); + const value = parseInt(monthSlider.data('value')); + change_month_slider(min, max, value); + + // Initialisation de la barre orange pour la durée + const monthOrangeBar = jQuery('.slider-month-wrapper .after_bar'); + if (monthOrangeBar.length) { + const cssLeftSpan = monthSlider.find('span').css('left'); + monthOrangeBar.addClass('active'); + monthOrangeBar.css('width', cssLeftSpan); + } + } + } + + // Réinitialisation des calculs + if (typeof calculate_mensualite === 'function') { + calculate_mensualite(); + } + + // Réinitialisation des événements de formulaire + if (typeof onchange_loan_type === 'function') { + onchange_loan_type('radio'); + } + + // Réinitialiser la hauteur minimale après l'animation + parentContainer.css('min-height', ''); + }, 500); // Attendre la fin de l'animation slideInUp + }, 500); // Attendre la fin de l'animation slideOutDown + } else { + console.error('Erreur lors de la régénération du simulateur:', response.data.message); + container.removeClass('animate-slide-out-down').addClass('animate-slide-in-up'); + parentContainer.css('min-height', ''); + } + }, + error: function(xhr, status, error) { + console.error('Erreur AJAX:', error); + container.removeClass('animate-slide-out-down').addClass('animate-slide-in-up'); + parentContainer.css('min-height', ''); + }, + complete: function() { + // Supprimer le spinner après au moins 800 ms + var spinnerStart = parentContainer.data('spinnerStart') || Date.now(); + var elapsed = Date.now() - spinnerStart; + var minDuration = 800; + var removeSpinner = function() { + parentContainer.find('.cd-loading-spinner').remove(); + }; + if (elapsed < minDuration) { + setTimeout(removeSpinner, minDuration - elapsed); + } else { + removeSpinner(); + } + } + }); + }); +} + +// Appeler la fonction lors du chargement du document +jQuery(document).ready(function() { + handleCreditTypeClick(); +}); + +// Initialisation de la modal de rappel de crédit +document.addEventListener('DOMContentLoaded', function() { + var creditReminderBtn = document.querySelector('.credit-reminder-btn'); + if (creditReminderBtn) { + creditReminderBtn.addEventListener('click', function() { + var modal = new bootstrap.Modal(document.getElementById('creditReminderModal')); + modal.show(); + }); + } +}); \ No newline at end of file diff --git a/assets/js/cd_main.js b/assets/js/cd_main.js new file mode 100644 index 0000000..f647f62 --- /dev/null +++ b/assets/js/cd_main.js @@ -0,0 +1,3873 @@ +console.log(cd_js); + +var duree_range = []; +var Timer; +var form_sliders = []; +var authorized_value = ['pat', 'fin_neuve', 'fin_occ_m3a', 'fin_occ_p3a', 'ph', 'am', 'frais_notaire', 'but_immo', 'mobil_carav', 'regroup_cred']; +var loan_type_in_years = ['am', 'amr', 'cied', 'ph']; + +//reprende les credits de $houseCreditTypes +var houseCreditTypes = ['purchasehouse', 'construction', 'regrouping_immo', 'refinancing', 'purchaseabroad', 'achat_maison_de_rapport', 'credit_pont', 'independants_et_entreprises_en_difficultes', 'regroupement_de_credit__rachats_de_credits', 'mobilhome', 'financement_frais_de_notaire', 'fonds_roulement_independants', 'but_immo_hypo']; + +var patCreditTypes = ['pat', 'regrouping','fin_neuve', 'fin_occ_m3a', 'fin_occ_p3a', 'mobil_carav','but_immo','reno_energie']; + + +var map_values = { + 'purchasehouse': 'am', + 'construction': 'am', + 'regrouping_immo': 'am', + 'regrouping': 'regroup_cred', + 'refinancing': 'am', + 'purchaseabroad': 'am', + 'achat_maison_de_rapport': 'amr', + 'credit_pont': 'cdp', + 'independants_et_entreprises_en_difficultes': 'cied', + 'regroupement_de_credit__rachats_de_credits': 'am', + 'mobilhome': 'mobil_carav', + 'financement_frais_de_notaire': 'frais_notaire', + 'fonds_roulement_independants' : 'cied', + 'reno_energie' : 'but_immo', + 'but_immo_hypo' : 'am' +}; + +//Crédit travaux / Rénovation / Energie +form_sliders['but_immo'] = { capital_selected: 20000, capital_max: 90000, capital_step: 100, capital_min: 2500, duree_min: 24, duree_max: 180, durees: [24, 30, 36, 42, 48, 60, 72, 84, 96, 108, 120, 132, 144, 156, 168, 180], pivot_value: 0, sub_pivot_value: 0, title: 'Crédit travaux / Rénovation / Energie', description: cd_js.groups.credit_travaux__renovation__energie.exemple_et_infos }; +//Financement véhicule NEUF +form_sliders['fin_neuve'] = { capital_selected: 20000, capital_max: 100000, capital_step: 500, capital_min: 5000, duree_min: 24, duree_max: 84, durees: [24, 30, 36, 42, 48, 60, 72, 84], pivot_value: 0, sub_pivot_value: 5000, title: 'Financement véhicule NEUF', description: cd_js.groups.financement_vehicule_neuf.exemple_et_infos }; +// Financement véhicule d'occasion PLUS de 3 ans +form_sliders['fin_occ_p3a'] = { capital_selected: 20000, capital_max: 100000, capital_step: 500, capital_min: 5000, duree_min: 24, duree_max: 60, durees: [24, 30, 36, 42, 48, 60], pivot_value: 0, sub_pivot_value: 5000, title: 'Financement véhicule d\'occasion PLUS de 3 ans', description: cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans.exemple_et_infos }; +// Financement véhicule d'occasion MOINS de 3 ans +form_sliders['fin_occ_m3a'] = { capital_selected: 20000, capital_max: 100000, capital_step: 500, capital_min: 5000, duree_min: 24, duree_max: 84, durees: [24, 30, 36, 42, 48, 60, 72, 84], pivot_value: 0, sub_pivot_value: 5000, title: 'Financement véhicule d\'occasion MOINS de 3 ans', description: cd_js.groups.financement_vehicule_doccasion_moins_de_3_ans.exemple_et_infos }; +// Financement véhicule d'occasion MOINS de 3 ans +form_sliders['mobil_carav'] = { capital_selected: 20000, capital_max: 100000, capital_step: 500, capital_min: 10000, duree_min: 24, duree_max: 144, durees: [24, 30, 36, 42, 48, 60, 72, 84, 96, 108, 120, 144], pivot_value: 75000, sub_pivot_value: 0, title: 'Financement mobilhome et caravane', description: cd_js.groups.financement_mobilhome_et_caravane_de_moins_de_3_ans.exemple_et_infos }; +// Financement frais de notaire +form_sliders['frais_notaire'] = { capital_selected: 20000, capital_max: 50000, capital_step: 500, capital_min: 10000, duree_min: 60, duree_max: 120, durees: [60, 72, 84, 96, 108, 120], pivot_value: 0, sub_pivot_value: 0, title: 'Financement frais de notaire', description: cd_js.groups.financement_frais_de_notaire.exemple_et_infos }; +// Prêt personnel : tous motifs, achats divers +form_sliders['pat'] = { capital_selected: 10000, capital_max: 200000, capital_min: 1500, capital_step: 250, duree_min: 24, duree_max: 240, durees: [24, 30, 36, 42, 48, 60, 72, 84, 96, 108, 120, 144, 180, 240], pivot_value: 75000, sub_pivot_value: 0, title: 'Prêt personnel / Tous motifs / Achats divers', description: cd_js.groups.pret_personnel__tous_motifs__achats_divers.exemple_et_infos }; +// Crédit hypothécaire social (achat maison, construction) +form_sliders['ph'] = { capital_selected: 100000, capital_max: 1000000, capital_min: 25000, capital_step: 250, duree_min: 10, duree_max: 30, durees: [5, 10, 15, 20, 25, 30], pivot_value: 0, sub_pivot_value: 0, title: 'Crédit hypothécaire', description: cd_js.groups.credit_hypothecaire_social.exemple_et_infos }; +// Crédit hypothécaire classique (achat maison, construction, refinancement, regroupement, travaux, achat à l'étranger) +form_sliders['am'] = { capital_selected: 100000, capital_max: 1000000, capital_min: 25000, capital_step: 250, duree_min: 10, duree_max: 30, durees: [10, 15, 20, 25, 30], pivot_value: 0, sub_pivot_value: 0, title: 'Crédit hypothécaire classique (achat maison, construction, refinancement, regroupement, travaux, achat à l\'étranger)', description: cd_js.groups.credit_hypothecaire_classique.exemple_et_infos }; +// Crédit achat maison rapport +form_sliders['amr'] = { capital_selected: 100000, capital_max: 1000000, capital_min: 25000, capital_step: 250, duree_min: 10, duree_max: 30, durees: [10, 15, 20, 25, 30], pivot_value: 0, sub_pivot_value: 0, title: 'Crédit hypothécaire maison rapport', description: cd_js.groups.achat_maison_de_rapport.exemple_et_infos }; +// Crédit pont +form_sliders['cdp'] = { capital_selected: 100000, capital_max: 1000000, capital_min: 25000, capital_step: 250, duree_min: 1, duree_max: 24, durees: [6,12,18,24], pivot_value: 0, sub_pivot_value: 0, title: 'Crédit pont', description: cd_js.groups.credit_pont.exemple_et_infos }; +// Crédit Indépendants et entreprises en difficultés +form_sliders['cied'] = { capital_selected: 100000, capital_max: 1000000, capital_min: 25000, capital_step: 250, duree_min: 10, duree_max: 30, durees: [10, 15, 20, 25, 30], pivot_value: 0, sub_pivot_value: 0, title: 'Crédit Indépendants et entreprises en difficultés', description: cd_js.groups.independants_et_entreprises_en_difficultes.exemple_et_infos }; +// Regroupement de crédit / rachat de crédit +form_sliders['regroup_cred'] = { capital_selected: 20000, capital_max: 200000, capital_step: 500, capital_min: 5000, duree_min: 24, duree_max: 144, durees: [24, 30, 36, 42, 48, 60, 72, 84, 96, 108, 120, 144], pivot_value: 75000, sub_pivot_value: 0, title: 'Regroupement de crédit / rachat de crédit', description: cd_js.groups.regroupement_de_credit__rachats_de_credits.exemple_et_infos }; + + +// Intialize the stimulator on page load +jQuery(function($) { + if ($("#form_wizard").length) { + // onchange_loan_type(); + onchange_type_de_credit(); + } else if ($(".load_simulator").length) { + //Initialize capital slider + onchange_loan_type(); + } +}); + + +// Function to calculate Prêt personnel / Tous motifs / Achats divers +function calculate_pat(selected_capital, selected_duration='') { + + let annual_rate, min_duration, max_duration, duree_in_range = true, display_observation_pat = false, + add_message = ''; + + min_duration = 24; + + /* console.log('selected_duration', selected_duration); + console.log('selected_capital', selected_capital); */ + + + if (1500 <= parseInt(selected_capital) && parseInt(selected_capital) <= 2500) { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers._1500_a_2500; + max_duration = 24; + } else if ((2500 < parseInt(selected_capital) && parseInt(selected_capital) <= 3700)) { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers._2501_a_3700; + max_duration = 30; + } else if ((3700 < parseInt(selected_capital) && parseInt(selected_capital) <= 5000)) { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers._3701_a_5000; + max_duration = 30; + } else if ((5000 < parseInt(selected_capital) && parseInt(selected_capital) <= 5600)) { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers._5001_a_5600; + max_duration = 36; + } else if ((5600 < parseInt(selected_capital) && parseInt(selected_capital) <= 7500)) { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers._5601_a_7500; + max_duration = 42; + } else if ((7500 < parseInt(selected_capital) && parseInt(selected_capital) <= 10000)) { + max_duration = 48; + + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) { + // + } else { + duree_in_range = false; + selected_duration = max_duration; + } + + if (selected_duration == 48) { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers._7501_a_10000_48_mois; + } else { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers._7501_a_10000_24_a_42_mois; + } + } else if ((10000 < parseInt(selected_capital) && parseInt(selected_capital) <= 15000)) { + + if (selected_duration < 48) { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers._10001_a_15000_24_a_42_mois; + } else { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers._10001_a_15000_48_a_60_mois; + } + max_duration = 60; + + } else if ((15000 < parseInt(selected_capital) && parseInt(selected_capital) <= 20000)) { + if (24 <= parseInt(selected_duration) && parseInt(selected_duration) <= 42) { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers.a_partir_de_15001_24_a_42_mois; + } else { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers.a_partir_de_15001_48_a_84_mois; + } + max_duration = 84; + } else if((20000 < parseInt(selected_capital) && parseInt(selected_capital) <= 75001)) { + + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers.a_partir_de_20001_a_75000; + + max_duration = 120; + } else if((75001 <= parseInt(selected_capital))) { + + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers.a_partir_de_75000; + + display_observation_pat = true; + + max_duration = 240; + selected_duration = 240; + } + + + /* else if ((20000 < parseInt(selected_capital) && parseInt(selected_capital) <= 29999)) { + if (24 <= parseInt(selected_duration) && parseInt(selected_duration) < 48) { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers.a_partir_de_20001_24_a_42_mois; + } else { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers.a_partir_de_20001_48_a_120_mois; + } + max_duration = 120; + } else if (parseInt(selected_capital) > 29999) { + max_duration = 120; + if (24 <= parseInt(selected_duration) && parseInt(selected_duration) < 48) { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers.a_partir_de_30001_24_a_42_mois; + } else { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers.a_partir_de_30001_48_a_120_mois; + } + } */ + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) { + + } else { + duree_in_range = false; + selected_duration = max_duration; + } + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message] + +} + +// Function to calculate Crédit hypothécaire +function calculate_ph(selected_capital, selected_duration) { + var annual_rate, min_duration, max_duration; + var duree_in_range = true; + var add_message = ''; + + min_duration = 5; + max_duration = 30; + annual_rate = cd_js.groups.credit_hypothecaire_social.de_10_a_30_ans; + + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + selected_duration = selected_duration * 12; + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message] +} + +// Function to calculate Crédit hypothécaire +function calculate_am(selected_capital, selected_duration) { + var annual_rate, min_duration, max_duration; + var duree_in_range = true; + var add_message = ''; + + for (var i = 10; i <= 30; i++) { + if (parseInt(selected_duration) == i) { + selector = 'credit_hypothecaire_classique.des_' + i + '_ans'; + + /* console.log(cd_js.groups.credit_hypothecaire_classique['des_' + i + '_ans']); */ + + annual_rate = cd_js.groups.credit_hypothecaire_classique['des_' + i + '_ans'] + } + } + min_duration = 10; + max_duration = 30; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + selected_duration = selected_duration * 12; + + /* console.log([min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message]); */ + + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message] +} + +//function to calculate credit with one type of rate between 10 to 30 years +function calculate_mono_rate_bt_10_30(selected_loan_type, selected_capital, selected_duration) { + var annual_rate, min_duration, max_duration, add_message; + var duree_in_range = true; + + min_duration = 10; + max_duration = 30; + + /* console.log('calculate_mono_rate_bt_10_30 - Type reçu:', selected_loan_type); */ + + // Fonction pour trouver le taux dans cd_js.groups + function findRate(type) { + if (cd_js.groups[type] && cd_js.groups[type].de_10_a_30_ans) { + return cd_js.groups[type].de_10_a_30_ans; + } + return null; + } + + // Essayer différentes variations du type pour trouver le taux + var possible_types = [ + selected_loan_type, // Type original + map_values[selected_loan_type], // Type mappé + selected_loan_type.toLowerCase(), // Type en minuscules + selected_loan_type.replace(/_/g, ''), // Type sans underscore + selected_loan_type.replace(/^credit_/, '') // Type sans préfixe 'credit_' + ]; + + // Filtrer les types undefined et null + possible_types = possible_types.filter(type => type); + + // Essayer chaque type possible + for (var type of possible_types) { + var rate = findRate(type); + if (rate !== null) { + annual_rate = rate; + /* console.log('calculate_mono_rate_bt_10_30 - Taux trouvé pour le type:', type, annual_rate); */ + break; + } + } + + // Si aucun taux n'est trouvé + if (annual_rate === undefined) { + console.error('Type de crédit non trouvé:', { + selected_loan_type, + possible_types, + available_groups: Object.keys(cd_js.groups) + }); + return [min_duration, max_duration, selected_duration * 12, false, 0, 'Type de crédit non disponible']; + } + + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) { + /* console.log('calculate_mono_rate_bt_10_30 - Durée dans la plage'); */ + } else { + duree_in_range = false; + selected_duration = max_duration; + /* console.log('calculate_mono_rate_bt_10_30 - Durée ajustée à:', selected_duration); */ + } + + selected_duration = selected_duration * 12; + /* console.log('calculate_mono_rate_bt_10_30 - Sortie:', { min_duration, max_duration, selected_duration, duree_in_range, annual_rate }); */ + + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message]; +} + +// Function to calculate Financement véhicule NEUF +function calculate_fin_neuve(selected_capital, selected_duration) { + var annual_rate, min_duration, max_duration, add_message; + var duree_in_range = true; + min_duration = 24; + if (2500 == parseInt(selected_capital)) { + annual_rate = cd_js.groups.financement_vehicule_neuf._2500_24_mois; + max_duration = 24; + } else if ((2500 < parseInt(selected_capital) && parseInt(selected_capital) <= 3700)) { + annual_rate = cd_js.groups.financement_vehicule_neuf._2501_a_3700_24_a_30_mois; + max_duration = 30; + } else if ((3700 < parseInt(selected_capital) && parseInt(selected_capital) <= 5600)) { + annual_rate = cd_js.groups.financement_vehicule_neuf._3701_a_5600_24_a_36_mois; + max_duration = 36; + } else if ((5600 < parseInt(selected_capital) && parseInt(selected_capital) <= 7500)) { + annual_rate = cd_js.groups.financement_vehicule_neuf._5601_a_7500_24_a_42_mois; + max_duration = 42; + } else if ((7500 < parseInt(selected_capital) && parseInt(selected_capital) <= 10000)) { + annual_rate = cd_js.groups.financement_vehicule_neuf._7501_a_10000_24_a_48_mois; + max_duration = 48; + } else if ((10000 < parseInt(selected_capital) && parseInt(selected_capital) <= 15000)) { + annual_rate = cd_js.groups.financement_vehicule_neuf.a_partir_de_10001_24_a_60_mois; + max_duration = 60; + } else if ((15000 < parseInt(selected_capital) && parseInt(selected_capital) <= 100000)) { + max_duration = 84; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration < 72) { + annual_rate = cd_js.groups.financement_vehicule_neuf.a_partir_de_15001_24_a_60_mois; + } else { + annual_rate = cd_js.groups.financement_vehicule_neuf.a_partir_de_15001_72_a_84_mois; + } + } + + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message] +} + +// Function to calculate prêt auto occasion - de 3 ans +function calculate_pao_m_3(selected_capital, selected_duration) { + var annual_rate, min_duration, max_duration; + var duree_in_range = true; + var add_message = ''; + + min_duration = 24; + if (2500 == parseInt(selected_capital)) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_moins_de_3_ans._2500_24_mois; + max_duration = 24; + } else if ((2500 < parseInt(selected_capital) && parseInt(selected_capital) <= 3700)) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_moins_de_3_ans._2501_a_3700_24_a_30_mois; + max_duration = 30; + } else if ((3700 < parseInt(selected_capital) && parseInt(selected_capital) <= 5600)) { + annual_rate = cd_js.groups.financement_vehicule_neuf._3701_a_5600_24_a_36_mois; + max_duration = 36; + } else if ((5600 < parseInt(selected_capital) && parseInt(selected_capital) <= 7500)) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_moins_de_3_ans._5601_a_7500_24_a_42_mois; + max_duration = 42; + } else if ((7500 < parseInt(selected_capital) && parseInt(selected_capital) <= 10000)) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_moins_de_3_ans._7501_a_10000_24_a_48_mois; + max_duration = 48; + } else if ((10000 < parseInt(selected_capital) && parseInt(selected_capital) <= 15000)) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_moins_de_3_ans.a_partir_de_10001_24_a_60_mois; + max_duration = 60; + } else if ((15000 < parseInt(selected_capital) && parseInt(selected_capital) <= 100000)) { + max_duration = 84; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration < 60) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_moins_de_3_ans.a_partir_de_15001_24_a_60_mois; + } else { + annual_rate = cd_js.groups.financement_vehicule_doccasion_moins_de_3_ans.a_partir_de_15001_72_a_84_mois; + } + } + if (!(min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) { + duree_in_range = false; + selected_duration = max_duration; + } + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message] +} + +// Function to calculate prêt auto occasion + de 3 ans +function calculate_pao_p_3(selected_capital, selected_duration) { + var annual_rate, min_duration, max_duration; + var duree_in_range = true; + var add_message = ''; + + min_duration = 24; + if (parseInt(selected_capital) <= 2500) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._2500_24_mois; + max_duration = 24; + } else if ((2500 < parseInt(selected_capital) && parseInt(selected_capital) <= 3700)) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._2501_a_3700_24_a_30_mois; + max_duration = 30; + } else if ((3700 < parseInt(selected_capital) && parseInt(selected_capital) <= 5000)) { + max_duration = 36; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration == 36) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._3701_a_5000_36_mois; + } else { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._3701_a_5000_24_a_30_mois; + } + } else if ((5000 < parseInt(selected_capital) && parseInt(selected_capital) <= 5600)) { + max_duration = 36; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration == 36) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._5001_a_5600_36_mois; + } else { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._5001_a_5600_24_a_30_mois; + } + } else if ((5600 < parseInt(selected_capital) && parseInt(selected_capital) <= 7500)) { + max_duration = 42; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration == 36) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._5601_a_7500_36_mois; + } else if (selected_duration == 42) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._5601_a_7500_42_mois; + } else { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._5601_a_7500_24_a_30_mois; + } + } else if ((7500 < parseInt(selected_capital) && parseInt(selected_capital) <= 10000)) { + max_duration = 48; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration < 36) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._7501_a_10000_24_a_30_mois; + } else if (selected_duration < 42) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._7501_a_10000_36_mois; + } else { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._7501_a_10000_42_a_48_mois; + } + } else if ((10000 < parseInt(selected_capital) && parseInt(selected_capital) <= 100000)) { + max_duration = 60; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration < 36) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans.a_partir_de_10001_24_a_30_mois; + } else if (selected_duration < 42) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans.a_partir_de_10001_36_mois; + } else { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans.a_partir_de_10001_42_a_48_mois; + } + } + + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + /* console.log('dureeee', selected_duration); */ + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message] +} + +// function to calculate mobilhome +function calculate_mobilhome(selected_capital, selected_duration) { + var annual_rate, min_duration, max_duration; + var duree_in_range = true; + var add_message = ''; + min_duration = 24; + + if(selected_capital <= 10000){ + annual_rate = cd_js.groups.financement_mobilhome_et_caravane_de_moins_de_3_ans.max_10000; + max_duration = 48; + } else if(selected_capital > 10000 && selected_capital <= 15000){ + annual_rate = cd_js.groups.financement_mobilhome_et_caravane_de_moins_de_3_ans.de_10001_a_15000; + max_duration = 60; + } else if(selected_capital > 15000 && selected_capital <= 37000){ + annual_rate = cd_js.groups.financement_mobilhome_et_caravane_de_moins_de_3_ans.de_15001_a_37000; + max_duration = 120; + } else if(selected_capital > 37000 && selected_capital <= 100000){ + annual_rate = cd_js.groups.financement_mobilhome_et_caravane_de_moins_de_3_ans.de_37001_a_10000; + max_duration = 144; + } + + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message]; + +} + +//function to calculate regroupement de credit +function calculate_regroupement_de_credit(selected_capital, selected_duration) { + var annual_rate, min_duration, max_duration; + var duree_in_range = true; + var add_message = ''; + min_duration = 24; + + if(selected_capital >= 5000 && selected_capital <= 5600){ + annual_rate = cd_js.groups.regroupement_de_credit__rachats_de_credits.de_5000_a_5600; + max_duration = 36; + } else if(selected_capital > 5600 && selected_capital <= 7500){ + annual_rate = cd_js.groups.regroupement_de_credit__rachats_de_credits.de_5601_a_7500; + max_duration = 42; + } else if(selected_capital > 7500 && selected_capital <= 10000){ + annual_rate = cd_js.groups.regroupement_de_credit__rachats_de_credits.de_7501_a_10000; + max_duration = 48; + } else if(selected_capital > 10000 && selected_capital <= 15000){ + annual_rate = cd_js.groups.regroupement_de_credit__rachats_de_credits.de_10001_a_15000; + max_duration = 60; + } else if(selected_capital > 15000 && selected_capital <= 20000){ + annual_rate = cd_js.groups.regroupement_de_credit__rachats_de_credits.de_15001_a_20000; + max_duration = 84; + } else if(selected_capital > 20000 && selected_capital <= 60000){ + annual_rate = cd_js.groups.regroupement_de_credit__rachats_de_credits.de_20001_a_60000; + max_duration = 120; + } else if(selected_capital > 60000 && selected_capital <= 75000){ + annual_rate = cd_js.groups.regroupement_de_credit__rachats_de_credits.de_60001_a_75000; + max_duration = 120; + } else if(selected_capital > 75000 && selected_capital <= 100000){ + annual_rate = cd_js.groups.regroupement_de_credit__rachats_de_credits.de_75001_a_100000; + max_duration = 144; + } + + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message]; +} + +// Function to calculate Financement frais de notaire +function calculate_frais_notaire(selected_capital, selected_duration) { + var annual_rate, min_duration, max_duration; + var duree_in_range = true; + var add_message = ''; + min_duration = 60; + + if ((10001 <= parseInt(selected_capital) && parseInt(selected_capital) <= 15000)) { + annual_rate = cd_js.groups.financement_frais_de_notaire.de_10000_a_15000; + max_duration = 60; + } else if ((15000 < parseInt(selected_capital) && parseInt(selected_capital) <= 20000)) { + annual_rate = cd_js.groups.financement_frais_de_notaire.de_15000_a_20000; + max_duration = 84; + } else if ((15000 < parseInt(selected_capital) && parseInt(selected_capital) <= 50000)) { + annual_rate = cd_js.groups.financement_frais_de_notaire.de_20000_a_50000; + max_duration = 120; + } + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message] +} +// Function to calculate travaux / Rénovation / Energie +function calculate_but_immo(selected_capital, selected_duration) { + var annual_rate, min_duration, max_duration; + var duree_in_range = true; + var add_message = ''; + min_duration = 24; + if (2500 == parseInt(selected_capital)) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._2500_24_mois; + max_duration = 24; + } else if ((2500 < parseInt(selected_capital) && parseInt(selected_capital) <= 3700)) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._2501_a_3700_24_a_30_mois; + max_duration = 30; + } else if ((3700 < parseInt(selected_capital) && parseInt(selected_capital) <= 5600)) { + max_duration = 36; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration == 36) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._3701_a_5600_36_mois; + } else { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._3701_a_5600_24_a_30_mois; + } + } else if ((5600 < parseInt(selected_capital) && parseInt(selected_capital) <= 7500)) { + max_duration = 42; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration == 42) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._5601_a_7500_42_mois; + } else if (selected_duration == 36) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._3701_a_5600_36_mois; + } else { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._5601_a_7500_24_a_30_mois; + } + } else if ((7500 < parseInt(selected_capital) && parseInt(selected_capital) <= 10000)) { + max_duration = 48; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration < 36) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._7501_a_10000_24_a_30_mois; + } else if (selected_duration < 42) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._7501_a_10000_36_mois; + } else { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._7501_a_10000_42_a_48_mois; + } + } else if ((10000 < parseInt(selected_capital) && parseInt(selected_capital) <= 15000)) { + max_duration = 60; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration < 36) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._10001_a_15000_24_a_30_mois; + } else if (selected_duration < 42) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._10001_a_15000_36_mois; + } else { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._10001_a_15000_42_a_60_mois; + } + } else if ((15000 < parseInt(selected_capital) && parseInt(selected_capital) <= 20000)) { + max_duration = 84; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration < 36) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie.a_partir_de_15001_24_a_30_mois; + } else if (selected_duration < 42) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._a_partir_de_15001_36_mois; + } else if (selected_duration < 72) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._a_partir_de_15001_42_a_60_mois; + } else { + annual_rate = cd_js.groups.credit_travaux__renovation__energie.a_partir_de_15001_72_a_84_mois; + } + } else if ((20000) < parseInt(selected_capital)) { + max_duration = 120; + + if(37001 <= parseInt(selected_capital)) { + max_duration = 180; + } + + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration < 36) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie.a_partir_de_20001_24_a_30_mois; + } else if (selected_duration < 42) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie.a_partir_de_20001_36_mois; + } else if (selected_duration < 72) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie.a_partir_de_20001_42_a_60_mois; + } else if (selected_duration < 96) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie.a_partir_de_20001_72_a_84_mois; + } else if (selected_duration > 120) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie.a_partir_de_20001_120_a_180_mois; + } else { + annual_rate = cd_js.groups.credit_travaux__renovation__energie.a_partir_de_20001_96_a_120_mois; + } + } + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message] +} + +// Function to calculate crédit pont +function calculate_cdp(selected_capital, selected_duration) { + var annual_rate, min_duration, max_duration, add_message; + var duree_in_range = true; + + min_duration = 1; // En mois + max_duration = 24; // En mois + + // Récupération du taux pour le crédit pont avec le nouveau sélecteur + annual_rate = cd_js.groups.credit_pont.de_1_a_24_mois; + + + // Vérification si la durée est dans la plage + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + /* console.log('selected_duration', selected_duration); */ + + + // Pas besoin de convertir la durée en mois car elle est déjà en mois + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message]; +} + +//Function to calculate mensulate for all forms +function calculate_mensualite() { + console.log('🧮 CALCULATE_MENSUALITE - Fonction appelée'); + var selected_duration, selected_capital; + selected_duration = jQuery('#selected_months').val(); + selected_capital = jQuery('#selected_capital').val(); + var results, stimulator_value, min_duration, max_duration, duree_in_range, annual_rate, add_messages, loan_type, sub_loan_radio_type; + loan_type = jQuery('#loan_type').val(), + loan_radio_type = jQuery('.loan_type:checked').length ? jQuery('.loan_type:checked').val() : '', + sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : '', + sub_auto_radio_type = jQuery('.sub_auto_loan_type:checked').length ? jQuery('.sub_auto_loan_type:checked').val() : ''; + + + /* console.log('selected_capital++', selected_capital); + console.log('selected_duration++', selected_duration); */ + + /* if (sub_loan_radio_type != '') + loan_type = loan_radio_type; */ + + if (sub_loan_radio_type != '' && authorized_value.includes(sub_loan_radio_type)) { + loan_type = sub_loan_radio_type; + } else if (map_values[sub_loan_radio_type] !== 'undefined') { + loan_type = map_values[sub_loan_radio_type]; + } + + if (sub_auto_radio_type != '') + loan_type = sub_auto_radio_type; + + /* console.log(selected_capital); + console.log(JSON.stringify(selected_duration)); */ + + + switch (loan_type) { + case 'pat': + results = calculate_pat(selected_capital, selected_duration); + break; + case 'fin_neuve': + results = calculate_fin_neuve(selected_capital, selected_duration); + break; + case 'fin_occ_m3a': + results = calculate_pao_m_3(selected_capital, selected_duration); + break; + case 'fin_occ_p3a': + results = calculate_pao_p_3(selected_capital, selected_duration); + break; + case 'ph': + results = calculate_ph(selected_capital, selected_duration); + break; + case 'am': + results = calculate_am(selected_capital, selected_duration); + break; + case 'frais_notaire': + results = calculate_frais_notaire(selected_capital, selected_duration); + break; + case 'but_immo': + results = calculate_but_immo(selected_capital, selected_duration); + break; + case 'cdp': + results = calculate_cdp(selected_capital, selected_duration); + break; + case 'amr': + case 'cied': + results = calculate_mono_rate_bt_10_30(sub_loan_radio_type, selected_capital, selected_duration); + break; + case 'mobil_carav': + results = calculate_mobilhome(selected_capital, selected_duration); + break; + case 'regroup_cred': + results = calculate_regroupement_de_credit(selected_capital, selected_duration); + break; + } + /* console.log(loan_type); */ + /* console.log('results', results); */ + + min_duration = results[0]; + max_duration = results[1]; + selected_duration = results[2]; + duree_in_range = results[3]; + annual_rate = parseFloat(results[4]); + add_messages = results[5]; + + function calc_mens(mnt, dur, taeg) { + // Pour le crédit pont, on ne calcule que les intérêts mensuels + if (loan_type === 'cdp') { + var t100 = taeg / 100; + // Calcul des intérêts mensuels uniquement : (capital * taux_annuel) / 12 + var mens = (mnt * t100) / 12; + return Math.floor(mens * 100) / 100; + } + + // Pour les autres types de crédit, calcul normal + var dur12 = dur / 12; + var t100 = taeg / 100; + var t101 = 1 + t100; + var d12 = 1 / 12; + var buf1 = Math.pow(t101, d12); + var buf2 = Math.pow(1 / t101, dur12); + var mens = (mnt * (buf1 - 1)) / (1 - buf2), + ag = (mens * dur) - mnt; + var tauxc = (ag * 100) / (mnt * dur); + + /* console.log(dur); */ + + if (loan_type == 'am') { + /* console.log(dur + ' : ' + buf2); */ + } + + return Math.floor(mens * 100) / 100; + } + + function get_credit_infos(selected_capital, duration) { + + let rtr_array = {}; + + switch (loan_type) { + case 'pat': + results_info = calculate_pat(selected_capital, duration); + break; + case 'fin_neuve': + results_info = calculate_fin_neuve(selected_capital, duration); + break; + case 'fin_occ_m3a': + results_info = calculate_pao_m_3(selected_capital, duration); + break; + case 'fin_occ_p3a': + results_info = calculate_pao_p_3(selected_capital, duration); + break; + case 'ph': + results_info = calculate_ph(selected_capital, duration); + break; + case 'am': + results_info = calculate_am(selected_capital, duration); + break; + case 'frais_notaire': + results_info = calculate_frais_notaire(selected_capital, duration); + break; + case 'but_immo': + results_info = calculate_but_immo(selected_capital, duration); + break; + case 'cdp': + results_info = calculate_cdp(selected_capital, duration); + break; + case 'amr': + case 'cied': + results_info = calculate_mono_rate_bt_10_30(sub_loan_radio_type, selected_capital, duration); + break; + case 'mobil_carav': + results_info = calculate_mobilhome(selected_capital, duration); + break; + case 'regroup_cred': + results_info = calculate_regroupement_de_credit(selected_capital, duration); + break; + } + + rtr_array['min_duration'] = results_info[0]; + rtr_array['max_duration'] = results_info[1]; + rtr_array['annual_rate'] = parseFloat(results_info[4]); + + return parseFloat(rtr_array['annual_rate']); + } + + function calc_mens_all(mnt) { + let mens_array = {}, + duree = form_sliders[loan_type]['durees']; + var loan_type_in_years = ['am', 'amr', 'cied', 'ph']; + var global_annual_rate, + sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : ''; + + min_duration = form_sliders[loan_type]['duree_min']; + max_duration = form_sliders[loan_type]['duree_max']; + + // Correction : initialiser le taux global pour tous les types en années + if (loan_type_in_years.includes(loan_type)) { + global_annual_rate = get_credit_infos(mnt, duree[0]); // On prend le premier taux comme référence + } + + for (i = 0; i < duree.length; i++) { + if (duree[i] >= min_duration && duree[i] <= max_duration) { + var duree_in_month = duree[i]; + + if (!loan_type_in_years.includes(loan_type)) { + global_annual_rate = get_credit_infos(mnt, duree[i]); + } + + if(loan_type_in_years.includes(loan_type)) { + duree_in_month = duree_in_month * 12; + } + + /* console.log('mt', mnt); + console.log('duree_in_month', duree_in_month); + console.log('global_annual_rate', global_annual_rate); */ + + mens_array[duree[i]] = calc_mens(mnt, duree_in_month, global_annual_rate); + } + } + + /* console.log('mens_array', mens_array); */ + + return mens_array; + } + + + stimulator_value = calc_mens(selected_capital, selected_duration, annual_rate); + //Adjust the month duration selector to minimum or maximum allowed amount + stimulator_value = stimulator_value.toFixed(2); + + /* console.log(stimulator_value); */ + + /* console.log(selected_capital); + console.log(selected_duration); + console.log(annual_rate); */ + + let simulateur_all_mensualite = calc_mens_all(selected_capital); + var loan_type_in_years = ['am', 'amr', 'cied', 'ph']; + + if (loan_type_in_years.includes(loan_type)) { + var selected_duration_fortmated = selected_duration / 12; + /* if(loan_type == 'ph' || loan_type == 'am') + var selected_duration_fortmated = selected_duration / 12; + else + var selected_duration_fortmated = selected_duration; */ + + + var duree_suffix = " ans"; + jQuery('label[for="selected_months"]').html('Durée choisie (nombre d\'années)'); + + } else { + var selected_duration_fortmated = selected_duration; + var duree_suffix = " mois"; + jQuery('label[for="selected_months"]').html('Durée choisie (nombre de mensualités)'); + } + + if (jQuery(".mini-stimulator").length) {} else { + /* console.log('selected_duration_fortmated', selected_duration_fortmated); */ + change_duree(min_duration, max_duration, selected_duration_fortmated); + } + + let duree_value = jQuery('.limit-warning').length ? '--' : selected_duration_fortmated + duree_suffix; + + /* console.log('duree_value_bis', selected_capital); */ + + jQuery('.montant_value').html(number_format(selected_capital, 0, ',', '.')); + jQuery('.duree_value').html(duree_value); + jQuery('.montant_total_value').html(number_format(stimulator_value, 2, ',', '.')); + jQuery('.cout_total_value').html(number_format((stimulator_value * selected_duration), 2, ',', '.')); + jQuery('.taux_debiteur_fixe_value').html(annual_rate.toFixed(2) + ' %'); + /* jQuery('#taeg_value_2').html(annual_rate.toFixed(2) + '%'); */ + + // Calcul du taux débiteur en fonction du type de crédit + let tauxDebiteur = annual_rate; + if (houseCreditTypes.includes(sub_loan_radio_type)) { + tauxDebiteur = annual_rate + (annual_rate * 0.11); + } + jQuery('.taeg_value').html(tauxDebiteur.toFixed(2) + ' %'); + + /* jQuery('#additional_messages').html(add_messages); */ + + if (jQuery('#loan_type').length) { + jQuery('#loan_type').val(loan_type); + } + + if (jQuery('#hidden_montant_total_value').length) { + jQuery('#hidden_montant_total_value').val(number_format(stimulator_value, 2, ',', '.')); + } + + if (jQuery('#hidden_cout_total_value').length) { + jQuery('#hidden_cout_total_value').val(number_format((stimulator_value * selected_duration), 2, ',', '.')); + } + + if (jQuery('#hidden_taeg_value').length) { + jQuery('#hidden_taeg_value').val(annual_rate.toFixed(2) + '%'); + } + + if (jQuery('#estateloantype').length) { + jQuery('#estateloantype').val(sub_loan_radio_type); + } + + /**print all mensualite for the different period */ + for (property in simulateur_all_mensualite) { + + /* class_name = loan_type == 'am' ? property + '_ans' : 'mens_' + property; */ + class_name = loan_type_in_years.includes(loan_type) ? property + '_ans' : 'mens_' + property; + + jQuery('.date-range-buttons .' + class_name).text(simulateur_all_mensualite[property] + ' €'); + } +} + +//Create an onchange event for Type de prêt +jQuery(document).on('change', '#loan_type, .loan_type, .sub_loan_type', function() { + /* console.log('change'); */ + + onchange_loan_type(); +}); + +jQuery(document).on('change', '.sub_auto_loan_type', function(e) { + /* console.log('sub-change'); */ + onchange_loan_type(); +}); + +/* jQuery('.loan_type').change(function() { + onchange_loan_type(); +}); */ + +jQuery('#credit-direct-accordion').accordion({ + collapsible: true, + active: false, + heightStyle: "content" +}); + +jQuery("#credit-direct-accordion .ui-accordion-header").click(function() { + jQuery(this) + .children("i") + .toggleClass("fa-plus-circle fa-minus-circle"); + + jQuery(".ui-accordion-header") + .not(jQuery(this)) + .children("i") + .removeClass("fa-minus-circle"); + jQuery(".ui-accordion-header") + .not(jQuery(this)) + .children("i") + .addClass("fa-plus-circle"); +}); + +// Function to perform when loan is changed +function onchange_loan_type(type = 'select') { + + var form_data = []; + var form_desc = []; + var selected = jQuery('#loan_type').val(), + loan_type = jQuery('#loan_type').val(), + loan_radio_type = jQuery('.loan_type:checked').length ? jQuery('.loan_type:checked').val() : '', + sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : '', + sub_auto_radio_type = jQuery('.sub_auto_loan_type:checked').length ? jQuery('.sub_auto_loan_type:checked').val() : '', + input_label = '', + sub_input_label; + + /* console.log('Initial loan_type:', loan_type); + console.log('Initial selected:', selected); */ + + // Mise à jour du type sélectionné en fonction des boutons radio + if (loan_radio_type !== '') { + selected = loan_radio_type; + loan_type = loan_radio_type; + } + + // Mise à jour du type sélectionné en fonction des sous-types + if (sub_loan_radio_type !== '') { + if (authorized_value.includes(sub_loan_radio_type)) { + selected = sub_loan_radio_type; + loan_type = sub_loan_radio_type; + } else if (map_values[sub_loan_radio_type]) { + selected = map_values[sub_loan_radio_type]; + loan_type = map_values[sub_loan_radio_type]; + } + } + + // Réinitialisation du capital à la valeur par défaut lors d'un changement de type de crédit + if (jQuery('#selected_capital').length) { + var default_capital = form_sliders[loan_type] ? form_sliders[loan_type].capital_selected : null; + if (default_capital !== null) { + jQuery('#selected_capital').val(default_capital); + } + } + + var sel_duree = jQuery('#selected_months').val(), + selected_capital = jQuery('#selected_capital').val(); + + /* console.log('Final loan_type:', loan_type); + console.log('Final selected:', selected); */ + + // Mise à jour des classes actives + jQuery('.sub_loan_type, .sub_auto_loan_type').parent('.form_check').find('.form-check-label').removeClass('active'); + if (jQuery('.sub_loan_type:checked').parent('.form_check').find('.form-check-label').length) { + input_label = jQuery('.sub_loan_type:checked, .sub_auto_loan_type:checked').parent('.form_check').find('.form-check-label'); + if (!input_label.hasClass('active')) { + input_label.addClass('active'); + } + } + + // Calcul des résultats en fonction du type de crédit + var results; + switch(loan_type) { + case 'pat': + results = calculate_pat(selected_capital, sel_duree); + break; + case 'fin_neuve': + results = calculate_fin_neuve(selected_capital, sel_duree); + break; + case 'fin_occ_m3a': + results = calculate_pao_m_3(selected_capital, sel_duree); + break; + case 'fin_occ_p3a': + results = calculate_pao_p_3(selected_capital, sel_duree); + break; + case 'ph': + results = calculate_ph(selected_capital, sel_duree); + break; + case 'am': + results = calculate_am(selected_capital, sel_duree); + break; + case 'frais_notaire': + results = calculate_frais_notaire(selected_capital, sel_duree); + break; + case 'but_immo': + results = calculate_but_immo(selected_capital, sel_duree); + break; + case 'cdp': + results = calculate_cdp(selected_capital, sel_duree); + break; + case 'amr': + case 'cied': + results = calculate_mono_rate_bt_10_30(sub_loan_radio_type, selected_capital, sel_duree); + break; + case 'mobil_carav': + results = calculate_mobilhome(selected_capital, sel_duree); + break; + case 'regroup_cred': + results = calculate_regroupement_de_credit(selected_capital, sel_duree); + break; + } + + // Mise à jour des sliders et des valeurs + let dynamic_start_max = results[1]; + let dynamic_start_min = results[0]; + + let info_parent = jQuery('.credit_infos').parents('.stimulated-results'); + + /* console.log('dynamic_start_max', dynamic_start_max); */ + + duree_range = form_sliders[selected].durees; + jQuery('.disclaimer').html(form_sliders[selected].description); + + if (jQuery(".mini-stimulator").length) { + jQuery('.type_pret_value').html(form_sliders[selected].title); + } else { + if ((selected == "ph") || (selected == "am")) { + change_duree(dynamic_start_min, dynamic_start_max, dynamic_start_max); + jQuery('#selected_months').val(30); + } else { + change_duree(dynamic_start_min, dynamic_start_max, dynamic_start_max); + + /* console.log('form_sliders[selected].duree_max', form_sliders[selected].duree_max); */ + + jQuery('#selected_months').val(form_sliders[selected].duree_max); + } + change_capital_slider(form_sliders[selected].capital_min, form_sliders[selected].capital_max, form_sliders[selected].capital_selected); + change_month_slider(form_sliders[selected].duree_min, form_sliders[selected].duree_max, form_sliders[selected].duree_max); + update_capital_input(); + } + + // Affichage des informations du crédit + var group = form_sliders[selected].group; + var info = []; + + if(cd_js.groups[sub_loan_radio_type] && cd_js.groups[sub_loan_radio_type].infos) { + info = cd_js.groups[sub_loan_radio_type].infos; + jQuery('.credit_infos .notice-info').html(info); + jQuery('.credit_infos').slideDown(); + info_parent.addClass('info_active'); + } else { + if(jQuery('.credit_infos').is(':visible')) { + jQuery('.credit_infos .notice-info').html(''); + jQuery('.credit_infos').slideUp(); + info_parent.removeClass('info_active'); + } + } + + calculate_mensualite(); + + // Ajout : fonction pour mettre à jour l'unité de durée à côté de #selected_months + updateSelectedMonthsUnit(); + + // Mettre à jour l'état des boutons de durée après changement de type de crédit + updateDurationButtonsState(); +} + +// Detect capital change +jQuery(document).on('input', '#selected_capital', function(e) { + jQuery('#selected_capital').on('keyup', function() { + clearTimeout(Timer); + + sel_val = jQuery('#selected_capital').val(); + + /* jQuery('#selected_capital').val(sel_val + 1); */ + + // Ne plus appeler delayed_capital_chnage ici pour éviter la correction automatique pendant la saisie + // Timer = setTimeout(delayed_capital_chnage, 20); + }); +}); + +// Detect months change +jQuery(document).on('input', '#selected_months', function(e) { + jQuery('#selected_months').on('keyup', function() { + clearTimeout(Timer); + + sel_val = jQuery('#selected_months').val(); + + Timer = setTimeout(validate_months_input, 5000); // Délai de 0.5s + }); +}); + +jQuery(document).on('blur', '#selected_capital', function() { + display_alert_capital(); + // Appeler delayed_capital_chnage au onblur pour corriger la valeur seulement quand l'utilisateur quitte le champ + delayed_capital_chnage(); +}); + +jQuery(document).on('blur', '#selected_months', function() { + // Vérifier si le champ est vide ou contient une valeur invalide + var value = jQuery(this).val(); + if (value === '' || isNaN(value)) { + // Remettre une valeur par défaut ou afficher un message + jQuery(this).val(''); // ou une valeur par défaut + // Optionnel : afficher un message d'alerte + } else { + // Appeler la validation normale + validate_months_input(); + } +}); + +// Action to do on capital value change +function on_slider_value_change() { + console.log('🔄 ON_SLIDER_VALUE_CHANGE - Fonction appelée'); + var selected = jQuery('#loan_type').val(); + var loan_radio_type = jQuery('.loan_type:checked').length ? jQuery('.loan_type:checked').val() : '', + sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : ''; + + if (loan_radio_type != '') + selected = loan_radio_type; + + if (sub_loan_radio_type != '') { + + if (authorized_value.includes(sub_loan_radio_type)) { + selected = sub_loan_radio_type; + } else if (map_values[sub_loan_radio_type] !== 'undefined') { + selected = map_values[sub_loan_radio_type]; + } + + } + + var capital_min = form_sliders[selected].capital_min; + var capital_max = form_sliders[selected].capital_max; + var selected_capital = jQuery('#selected_capital').val(); + if (!(selected == 'ph' || selected == 'am')) { + /* jQuery('#selected_months').val(200); */ + } + console.log('🔄 ON_SLIDER_VALUE_CHANGE - Appel calculate_mensualite()'); + calculate_mensualite(); + /* change_duree(form_sliders[selected].duree_min, form_sliders[selected].duree_max, form_sliders[selected].duree_max); */ + /* change_capital_slider(capital_min, capital_max, selected_capital); */ + +} + +function display_alert_capital() { + + var selected_capital = jQuery('#selected_capital').val(); + var selected = jQuery('#loan_type').val(), + selected_radio = jQuery('.loan_type:checked').length ? jQuery('.loan_type:checked').val() : '', + sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : '';; + + if (selected_radio != '') + selected = selected_radio; + + if (sub_loan_radio_type != '') { + + if (authorized_value.includes(sub_loan_radio_type)) { + selected = sub_loan_radio_type; + } else if (map_values[sub_loan_radio_type] !== 'undefined') { + selected = map_values[sub_loan_radio_type]; + } + + } + + var capital_max = form_sliders[selected].capital_max; + var capital_min = form_sliders[selected].capital_min; + + if (jQuery('.limit-warning').length) { + jQuery('.limit-warning').slideUp(); + jQuery('.limit-warning').remove(); + } + + if (!((selected_capital > capital_min) && (selected_capital < capital_max))) { + if ((selected_capital <= capital_min)) { + + jQuery('.second-col').prepend('
    Le montant minimum requis est de ' + capital_min + '€
    '); + } else { + + jQuery('.second-col').prepend('
    Le montant maximum est de ' + capital_max + '€
    '); + } + + } +} + +// Get keystroke stop on capital value +function delayed_capital_chnage() { + var selected_capital_range = '#selected_capital_range'; + var selected = jQuery('#loan_type').val(), + loan_radio_type = jQuery('.loan_type:checked').length ? jQuery('.loan_type:checked').val() : '', + sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : ''; + var selected_capital = parseFloat(jQuery('#selected_capital').val()); + + if (loan_radio_type != '') { + selected = loan_radio_type; + } + + if (sub_loan_radio_type != '') { + if (authorized_value.includes(sub_loan_radio_type)) { + selected = sub_loan_radio_type; + } else if (map_values[sub_loan_radio_type] !== 'undefined') { + selected = map_values[sub_loan_radio_type]; + } + } + + var capital_max = form_sliders[selected].capital_max; + var capital_min = form_sliders[selected].capital_min; + var simu_button = document.querySelector('.stimulator_result_btn'); + + // Suppression de tout message d'alerte + if (jQuery('.limit-warning').length) { + jQuery('.limit-warning').slideUp(); + jQuery('.limit-warning').remove(); + } + + // Recalculer la durée max dynamiquement en fonction du capital AVANT la correction + console.log('🔄 DELAYED_CAPITAL_CHANGE - Recalcul de la durée max pour capital:', selected_capital); + + // Utiliser la fonction centralisée + var results = calculateDynamicLimits(selected, sub_loan_radio_type, selected_capital, ''); + + if (results && results.length > 1) { + var new_max_duration = results[1]; + var current_duration = jQuery('#selected_months').val(); + + console.log('🔄 DELAYED_CAPITAL_CHANGE - Durée actuelle:', current_duration); + console.log('🔄 DELAYED_CAPITAL_CHANGE - Durée max recalculée:', new_max_duration); + + // Si la durée actuelle dépasse le nouveau max, ajuster à la nouvelle durée max + if (parseInt(current_duration) > parseInt(new_max_duration)) { + console.log('🔄 DELAYED_CAPITAL_CHANGE - Ajustement de la durée à:', new_max_duration); + jQuery('#selected_months').val(new_max_duration); + change_month_slider(form_sliders[selected].duree_min, form_sliders[selected].duree_max, new_max_duration); + } else { + // Sinon, garder la durée actuelle mais mettre à jour les limites du slider + console.log('🔄 DELAYED_CAPITAL_CHANGE - Durée conservée, mise à jour du slider'); + change_month_slider(form_sliders[selected].duree_min, form_sliders[selected].duree_max, current_duration); + } + } + + // Correction automatique si hors bornes + if (selected_capital < capital_min) { + jQuery('#selected_capital').val(capital_min); + jQuery(selected_capital_range).slider('value', capital_min); + // Déclencher l'événement slide pour maintenir la synchronisation + jQuery(selected_capital_range).slider('option', 'slide').call(jQuery(selected_capital_range)[0], null, {value: capital_min}); + // Mise à jour affichage + var selected_capital_box = jQuery(selected_capital_range).parents('.selected_capital'); + jQuery(selected_capital_range).find('.slider_capital_box').text(number_format(capital_min, 2, ',', '.') + ' €'); + selected_capital_box.find('.outside_box').text(number_format(capital_min, 2, ',', '.') + ' €'); + if (simu_button) simu_button.disabled = false; + } else if (selected_capital > capital_max) { + jQuery('#selected_capital').val(capital_max); + jQuery(selected_capital_range).slider('value', capital_max); + // Déclencher l'événement slide pour maintenir la synchronisation + jQuery(selected_capital_range).slider('option', 'slide').call(jQuery(selected_capital_range)[0], null, {value: capital_max}); + // Mise à jour affichage + var selected_capital_box = jQuery(selected_capital_range).parents('.selected_capital'); + jQuery(selected_capital_range).find('.slider_capital_box').text(number_format(capital_max, 2, ',', '.') + ' €'); + selected_capital_box.find('.outside_box').text(number_format(capital_max, 2, ',', '.') + ' €'); + if (simu_button) simu_button.disabled = false; + } else { + if (simu_button && simu_button.disabled) simu_button.disabled = false; + } + + // Appeler calculate_mensualite() pour tout recalculer (change_duree + mensualités) + calculate_mensualite(); + + // Mettre à jour l'état des boutons de durée + updateDurationButtonsState(); +} + +// Get keystroke stop on months value +function delayed_months_change() { + var selected_months_range = '#selected_months_range'; + var selected = jQuery('#loan_type').val(), + loan_radio_type = jQuery('.loan_type:checked').length ? jQuery('.loan_type:checked').val() : '', + sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : ''; + var selected_months = jQuery('#selected_months').val(); + var selected_duree_box = jQuery(selected_months_range).parents('.selected_duree'); + + if (loan_radio_type != '') { + selected = loan_radio_type; + } + + if (sub_loan_radio_type != '') { + if (authorized_value.includes(sub_loan_radio_type)) { + selected = sub_loan_radio_type; + } else if (map_values[sub_loan_radio_type] !== 'undefined') { + selected = map_values[sub_loan_radio_type]; + } + } + + var duree_max = form_sliders[selected].duree_max; + var duree_min = form_sliders[selected].duree_min; + + if ((selected_months >= duree_min) && (selected_months <= duree_max)) { + jQuery(selected_months_range).slider({ + value: selected_months + }); + + var loan_type_in_years = ['am', 'amr', 'cied', 'ph']; + var periodicite = loan_type_in_years.includes(selected) ? ' ans' : ' mois'; + jQuery(selected_months_range).find(".slider_duree_box").text(selected_months + periodicite); + jQuery(selected_duree_box).find(".outside_slider_duree_box").text(selected_months + periodicite); + + calculate_mensualite(); + } +} + +// Check if duration changed +jQuery(function() { + jQuery(document).on('click', '.duree-btn', function() { + var $this = jQuery(this); + if ($this.length && $this.hasClass('months-active')) { + var selected_duree = $this.data('duree'); + var loan_type = jQuery('#loan_type').val(); + var selected_capital = jQuery('#selected_capital').val(); + + // Récupérer les limites originales du slider + var results = calculate_pat(selected_capital, selected_duree); + var max_duration = results[1]; + + // Mettre à jour la valeur sélectionnée + jQuery('#selected_months').val(selected_duree); + + // Mettre à jour le slider avec la nouvelle valeur mais en préservant la limite maximale + var $slider = jQuery('#selected_months_range'); + if ($slider.length) { + $slider.slider('option', 'value', selected_duree); + } + + calculate_mensualite(); + } + }); +}); + +//Change month values +function change_duree(default_min, default_max, selected_value) { + var list = ''; + var list_class = '', + loan_type = jQuery('#loan_type').val(), + loan_radio_type = jQuery('.loan_type:checked').length ? jQuery('.loan_type:checked').val() : '', + sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : '', + class_name = 'mens_', + selected_capital = jQuery('#selected_capital').val(), + monthly_low = 0, + monthly_high = 0, + capital_min = 0, + capital_max = 0, + selected_duree_box = jQuery('#selected_months_range').parents('.selected_duree'); + + // Déplacer la définition de loan_type_in_years ici, en dehors de la boucle + var loan_type_in_years = ['am', 'amr', 'cied', 'ph']; + + if (loan_radio_type != '') + loan_type = loan_radio_type; + + if (selected_capital == '') { + + selected_capital = form_sliders[loan_type]['capital_selected']; + } + + if (sub_loan_radio_type != '') { + + if (authorized_value.includes(sub_loan_radio_type)) { + loan_type = sub_loan_radio_type; + } else if (map_values[sub_loan_radio_type] !== 'undefined') { + loan_type = map_values[sub_loan_radio_type]; + } + + } + + /* console.log('loan_type-bis', loan_type); + console.log('loan_radio_type', loan_radio_type); + console.log('sub_loan_radio_type', sub_loan_radio_type); + console.log('selected_capital-bis', selected_capital); */ + capital_min = form_sliders[loan_type]['capital_min']; + capital_max = form_sliders[loan_type]['capital_max']; + + // Utiliser la fonction centralisée pour calculer les limites + results = calculateDynamicLimits(loan_type, sub_loan_radio_type, selected_capital, selected_value); + + /* console.log('results-bis', results); */ + + monthly_low = results[0]; + monthly_high = results[1]; + + /* console.log('monthly_low', monthly_low); + console.log('monthly_high', monthly_high); */ + + var validDurees = []; + + // Filtrer d'abord les durées valides + for (var j = 0; j < duree_range.length; j++) { + + + if ((monthly_low <= parseInt(duree_range[j]) && parseInt(duree_range[j]) <= monthly_high)) { + validDurees.push(duree_range[j]); + } + } + + var startIndex = Math.max(0, validDurees.length - 4); + + /* console.log(duree_range[startIndex]); + + console.log(selected_capital); + console.log(results); + console.log(startIndex); + console.log(validDurees); + console.log('default_max', default_max); + console.log('default_min', default_min); + console.log('sel duree', selected_value); */ + + + if (jQuery('#selected_capital').val() < capital_min) { + list = '
  • La somme minimale est de ' + capital_min + '€
  • '; + } else if (jQuery('#selected_capital').val() > capital_max) { + list = '
  • La somme maximale est de ' + capital_max + '€
  • '; + } else { + /* for (var i = 0; i < duree_range.length; i++) { */ + for (var i = startIndex; i < validDurees.length; i++) { + + var periodicite = ' mois'; + + // Supprimer la redéfinition de loan_type_in_years ici + + if (loan_type_in_years.includes(loan_type)) { + + class_name = validDurees[i] + '_ans'; + periodicite = ' ans'; + } else { + + class_name = 'mens_' + validDurees[i]; + } + + /* console.log('2' + selected_value); */ + + if ((default_min <= parseInt(validDurees[i]) && parseInt(validDurees[i]) <= default_max)) { + if (selected_value == validDurees[i]) { + list_class = ' selected'; + } + + if (validDurees[i] <= monthly_high) { + list = list + '
  • ' + validDurees[i] + periodicite + '
  • '; + } + } else { + list = list + ''; + } + list_class = ''; + } + } + + /* console.log(duree_range); */ + /* console.log(monthly_high); + console.log(monthly_low); */ + jQuery('#date-range-selector').html(list); + + // Mise à jour du slider_duree_box avec la bonne périodicité + var periodicite = loan_type_in_years.includes(loan_type) ? ' ans' : ' mois'; + jQuery('.slider_duree_box').text(selected_value + periodicite); + jQuery(selected_duree_box).find(".outside_slider_duree_box").text(selected_value + periodicite); + + /* var selected_months_range = '#selected_months_range'; + var selected_months = '#selected_months'; + jQuery(selected_months_range).slider({ + value: selected_value, + min: default_min, + max: default_max, + step: 1, + slide: function(event, ui) { + console.log('duree slider', ui.value); + jQuery(selected_months).val(ui.value); + jQuery(selected_months_range).children("span").text(ui.value + ' ans'); + }, + stop: function(event, ui) { + calculate_mensualite(); + } + }); */ + + // Ajout de l'initialisation de la valeur par défaut + /* jQuery(selected_months).val(selected_value); + jQuery(selected_months_range).children("span").text(selected_value + ' ans'); */ + + /* console.log(jQuery(selected_months_range).slider("option", "value")); + + jQuery(selected_months).val(jQuery(selected_months_range).slider('value')); + jQuery(selected_months_range).children("span").text(jQuery(selected_months_range).slider('value') + ' ans'); */ +} + +//Change capital slider values +function change_capital_slider(default_min, default_max, default_selected_value) { + var selected_capital_range = '#selected_capital_range'; + var selected_capital = '#selected_capital'; + var selected_capital_box = jQuery(selected_capital_range).parents('.selected_capital'); + var stepUpdateTimeout = null; + var isInputChange = false; + var fromSlider = false; + + var loan_type = jQuery('#loan_type').val(), + loan_radio_type = jQuery('.loan_type:checked').length ? jQuery('.loan_type:checked').val() : '', + sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : ''; + + if (loan_radio_type != '') + loan_type = loan_radio_type; + + if (sub_loan_radio_type != '') { + + if (authorized_value.includes(sub_loan_radio_type)) { + loan_type = sub_loan_radio_type; + } else if (map_values[sub_loan_radio_type] !== 'undefined') { + loan_type = map_values[sub_loan_radio_type]; + } + + } + + var pivot_value = form_sliders[loan_type].pivot_value; + var sub_pivot_value = form_sliders[loan_type].sub_pivot_value; + var pivot_percent = ((pivot_value - default_min) / (default_max - default_min)) * 100; + var sub_pivot_percent = ((sub_pivot_value - default_min) / (default_max - default_min)) * 100; + + /* console.log('default_min', default_min); + console.log('default_max', default_max); + console.log('pivot_value', pivot_value); + console.log('sub_pivot_value', sub_pivot_value); + console.log('pivot_percent', pivot_percent); + console.log('sub_pivot_percent', sub_pivot_percent); */ + + // Supprime l'ancienne zone pivot si elle existe + jQuery('.pivot-zone').remove(); + + // Crée la nouvelle zone pivot si pivot_value > 0 + if (pivot_value > 0) { + var pivotZone = jQuery('
    '); + /* var textPivot = cd_js.groups[loan_type].depassement_montant !== undefined ? cd_js.groups[loan_type].depassement_montant : ''; */ + /* console.log('textPivot', textPivot); */ + pivotZone.css({ + 'position': 'absolute', + 'left': pivot_percent + '%', + 'right': '0', + 'top': '0', + 'bottom': '0', + 'background-color': 'rgba(255, 0, 0, 0.2)', + 'pointer-events': 'none' + }); + jQuery(selected_capital_range).append(pivotZone); + } + + // Fonction pour calculer le step en fonction de la valeur + function calculateStep(value) { + return value < 10000 ? 500 : 250; + } + + // Fonction pour arrondir au step le plus proche + function roundToStep(value) { + var step = calculateStep(value); + return Math.round(value / step) * step; + } + + // Configuration du champ input + jQuery(selected_capital) + .attr('step', '1') + .on('input', function() { + var $input = jQuery(this); + var value = Number($input.val()); + + console.log('⌨️ INPUT CHANGE - Valeur saisie:', value); + console.log('⌨️ INPUT CHANGE - État des flags avant:', { fromSlider, isInputChange }); + + // Si la valeur est vide ou non numérique, ne rien faire + if (!value) return; + + // Annuler le timeout précédent s'il existe + if (stepUpdateTimeout) { + clearTimeout(stepUpdateTimeout); + } + + // Programmer la mise à jour du step après un délai + stepUpdateTimeout = setTimeout(function() { + /* var newStep = calculateStep(value); */ + $input.attr('step', '1'); + }, 500); // Délai de 500ms + + // Indiquer que le changement vient de l'input + isInputChange = true; + + console.log('⌨️ INPUT CHANGE - Mise à jour slider avec:', value); + // Mettre à jour le slider avec la valeur exacte + jQuery(selected_capital_range).slider('value', value); + + console.log('⌨️ INPUT CHANGE - Mise à jour slider_capital_box avec:', number_format(value, 2, ',', '.') + ' €'); + // Mise à jour de l'affichage + jQuery(selected_capital_range).find(".slider_capital_box") + .text(number_format(value, 2, ',', '.') + ' €'); + + /* console.log('selected_capital_box', selected_capital_box.find('.outside_box')); */ + + console.log('⌨️ INPUT CHANGE - Mise à jour outside_box avec:', number_format(value, 2, ',', '.') + ' €'); + selected_capital_box.find('.outside_box').text(number_format(value, 2, ',', '.') + ' €'); + + // Mise à jour des min/max du slider de durée + /* update_duration_slider_min_max(value); */ + }); + + + jQuery(selected_capital_range).slider({ + min: default_min, + max: default_max, + value: default_selected_value, + step: calculateStep(default_selected_value), + slide: function(event, ui) { + + // Reset des flags au début de slide si on vient d'un changement manuel + if (isInputChange) { + console.log('🔄 SLIDER SLIDE - Reset des flags car changement manuel détecté'); + isInputChange = false; + fromSlider = false; + } + + fromSlider = true; + console.log('🔄 SLIDER SLIDE - Valeur:', ui.value); + console.log('🔄 SLIDER SLIDE - État des flags après:', { fromSlider, isInputChange }); + + var orange_bar = jQuery('.slider_capital_wrapper .after_bar'), + elem = jQuery(ui.handle), + left_css = parseInt(elem.css('left'), 10); + + /* console.log('left_css', left_css); */ + + orange_bar.css('width', left_css + 10); + + // Gestion du pivot + if (pivot_value > 0 && ui.value >= pivot_value) { + jQuery(selected_capital_range).find(".slider_capital_box").addClass('pivot-value'); + if (!jQuery('#acceptConditions').is(':checked')) { + jQuery('.stimulator_result_btn').prop('disabled', true).addClass('disabled'); + } + } else { + jQuery(selected_capital_range).find(".slider_capital_box").removeClass('pivot-value'); + jQuery('.stimulator_result_btn').prop('disabled', false).removeClass('disabled'); + } + + console.log('📝 SLIDER SLIDE - Mise à jour input capital avec:', ui.value); + // ✅ Mise à jour de l'input + jQuery(selected_capital).val(ui.value); + + console.log('📝 SLIDER SLIDE - Mise à jour slider_capital_box avec:', number_format(ui.value, 2, ',', '.') + ' €'); + // ✅ Mise à jour du span du slider + jQuery(selected_capital_range).find(".slider_capital_box").text(number_format(ui.value, 2, ',', '.') + ' €'); + + console.log('📝 SLIDER SLIDE - Mise à jour outside_box avec:', number_format(ui.value, 2, ',', '.') + ' €'); + // ✅ AJOUTER CETTE LIGNE pour le span outside + selected_capital_box.find('.outside_box').text(number_format(ui.value, 2, ',', '.') + ' €'); + + let pivot_info_parent = jQuery('.pat_plus75000').parents('.stimulated-results'); + + // Gestion de l'affichage de la notice + if (pivot_value > 0) { + if (ui.value >= pivot_value) { + jQuery('.pat_plus75000').slideDown(300); + pivot_info_parent.addClass('info_active'); + } else { + jQuery('.pat_plus75000').slideUp(300); + pivot_info_parent.removeClass('info_active'); + } + } else { + jQuery('.pat_plus75000').hide(); + } + }, + stop: function(event, ui) { + + console.log('🛑 SLIDER STOP - Valeur finale:', ui.value); + console.log('🛑 SLIDER STOP - fromSlider:', fromSlider); + console.log('🛑 SLIDER STOP - isInputChange:', isInputChange); + + // Mise à jour sécurisée de l'input capital + if (!isInputChange) { + console.log('🛑 SLIDER STOP - Mise à jour input capital avec:', ui.value); + jQuery(selected_capital).val(ui.value); + } else { + console.log('🛑 SLIDER STOP - Vérification synchronisation input/slider'); + var currentInputValue = jQuery(selected_capital).val(); + if (currentInputValue != ui.value) { + console.log('🛑 SLIDER STOP - Désynchronisation détectée! Input:', currentInputValue, 'Slider:', ui.value); + console.log('🛑 SLIDER STOP - Correction de l\'input avec:', ui.value); + jQuery(selected_capital).val(ui.value); + } else { + console.log('🛑 SLIDER STOP - Input et slider synchronisés'); + } + } + + var selected = jQuery('#loan_type').val(); + var loan_radio_type = jQuery('.loan_type:checked').length ? jQuery('.loan_type:checked').val() : ''; + var sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : ''; + var selected_capital = jQuery('#selected_capital').val(); + + if (loan_radio_type != '') selected = loan_radio_type; + if (sub_loan_radio_type != '') { + if (authorized_value.includes(sub_loan_radio_type)) { + selected = sub_loan_radio_type; + } else if (map_values[sub_loan_radio_type]) { + selected = map_values[sub_loan_radio_type]; + } + } + + // Cas particuliers déjà gérés + if (((selected == "am") && selected_capital > 100000) || ((selected == "ph") && selected_capital > 100000)) { + jQuery('#selected_months').val(30); + change_duree(form_sliders[selected].duree_min, form_sliders[selected].duree_max, 30); + } else { + // Calcul de la nouvelle durée max selon le type de prêt via la fonction centralisée + var results = calculateDynamicLimits(selected, sub_loan_radio_type, selected_capital, ''); + console.log('🛑 SLIDER STOP - Results:', results); + console.log('🛑 SLIDER STOP - Results type:', typeof results); + console.log('🛑 SLIDER STOP - Results length:', results ? results.length : 'undefined'); + + if (results && results.length > 1) { + var new_max_duration = results[1]; + + console.log('🛑 SLIDER STOP - Durée max recalculée:', new_max_duration); + jQuery('#selected_months').val(new_max_duration); + change_month_slider(form_sliders[selected].duree_min, form_sliders[selected].duree_max, new_max_duration); + } else { + console.log('🛑 SLIDER STOP - Pas de recalcul nécessaire'); + } + } + + var orange_bar = jQuery('.slider_capital_wrapper .after_bar'), + elem = jQuery(ui.handle), + left_css = parseInt(elem.css('left'), 10); + + orange_bar.css('width', left_css + 10); + + console.log('🛑 SLIDER STOP - Mise à jour outside_box avec:', number_format(ui.value, 2, ',', '.') + ' €'); + selected_capital_box.find('.outside_box').text(number_format(ui.value, 2, ',', '.') + ' €'); + + console.log('🛑 SLIDER STOP - Appel calculate_mensualite()'); + // calculate_mensualite() va appeler change_duree() et remplir les mensualités + calculate_mensualite(); + + // Mettre à jour l'état des boutons de durée après changement de capital + updateDurationButtonsState(); + + // Reset des flags APRÈS tous les traitements + console.log('🛑 SLIDER STOP - Reset des flags'); + fromSlider = false; + isInputChange = false; + }, + change: function(event, ui) { + var orange_bar = jQuery('.slider_capital_wrapper .after_bar'), + elem = jQuery(ui.handle), + left_css = parseInt(elem.css('left'), 10); + + orange_bar.css('width', left_css + 10); + } + }); + + // Gestion du changement d'état de la case à cocher + jQuery('#acceptConditions').on('change', function() { + var currentValue = jQuery(selected_capital).val(); + if (pivot_value > 0 && currentValue >= pivot_value) { + if (jQuery(this).is(':checked')) { + jQuery('.stimulator_result_btn').prop('disabled', false).removeClass('disabled'); + } else { + jQuery('.stimulator_result_btn').prop('disabled', true).addClass('disabled'); + } + } + }); + + var appended_elem = 'test'; + /* jQuery(selected_capital).val(jQuery(selected_capital_range).slider('value')); */ + if (!jQuery('.ui-slider-handle .fa-angle-right').length) + jQuery(selected_capital_range).find(".ui-slider-handle").append(''); + + //if element is not present, append it + if (!jQuery(selected_capital_range).find('.slider_capital_box').length) { + jQuery(selected_capital_range).find('.ui-slider-handle').append(appended_elem); + } + jQuery(selected_capital_range).find(".slider_capital_box").text(number_format((jQuery(selected_capital_range).slider('value')), 2, ',', '.') + ' €'); + selected_capital_box.find('.outside_box').text(number_format((jQuery(selected_capital_range).slider('value')), 2, ',', '.') + ' €'); + + if (sub_pivot_value > 0) { + var subPivotZone = jQuery('
    '); + subPivotZone.css({ + 'position': 'absolute', + 'left': '0', + 'width': sub_pivot_percent + '%', + 'top': '0', + 'bottom': '0', + 'background-color': 'rgba(0, 0, 255, 0.15)', // Par exemple, bleu clair + 'pointer-events': 'none' + }); + + if(jQuery('.sub-pivot-zone').length == 0) + jQuery(selected_capital_range).append(subPivotZone); + } +} + +//Change month slider values +function change_month_slider(default_min, default_max, default_selected_value) { + var selected_months_range = '#selected_months_range'; + var selected_months = '#selected_months'; + var loan_type_in_years = ['am', 'amr', 'cied', 'ph']; + var sel_duree = jQuery(selected_months).val(), + selected_duree_box = jQuery(selected_months_range).parents('.selected_duree'); + + // Récupérer le type de crédit + var loan_type = jQuery('#loan_type').val(), + loan_radio_type = jQuery('.loan_type:checked').length ? jQuery('.loan_type:checked').val() : '', + sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : ''; + + if (loan_radio_type != '') + loan_type = loan_radio_type; + + if (sub_loan_radio_type != '') { + if (authorized_value.includes(sub_loan_radio_type)) { + loan_type = sub_loan_radio_type; + } else if (map_values[sub_loan_radio_type] !== 'undefined') { + loan_type = map_values[sub_loan_radio_type]; + } + } + + // Récupérer le capital actuel + var selected_capital = jQuery('#selected_capital').val(); + + if (selected_capital == '') + selected_capital = form_sliders[loan_type]['capital_selected']; + + /* console.log('selected_capital', selected_capital); + console.log('loan_type', loan_type); + console.log('sel_duree', sel_duree); */ + + // Calculer la durée maximale en fonction du capital via la fonction centralisée + var results = calculateDynamicLimits(loan_type, sub_loan_radio_type, selected_capital, sel_duree); + + // Utiliser max_duration (index 1) comme limite maximale + var max_duration = results[1]; + var dynamic_max = max_duration; + + // Trouver la durée maximale valide dans les durées du type de prêt + var available_durations = form_sliders[loan_type].durees; + + for (var i = available_durations.length - 1; i >= 0; i--) { + if (available_durations[i] <= max_duration) { + dynamic_max = available_durations[i]; + break; + } + } + + /* console.log('available_durations', results); + + console.log('dynamic_max', dynamic_max); + console.log('duration max', max_duration); + console.log('loan_type', loan_type); + console.log('available_durations array', available_durations); */ + + function getStepForValue(loan_type, value) { + let dynamic_step = 1; + + if (loan_type_in_years.includes(loan_type)) { + dynamic_step = 1; // Step de 1 an pour les prêts en années + } else if (loan_type === 'cdp') { + dynamic_step = 1; // Step de 1 mois pour le crédit pont + } else { + if (value <= 48) { + dynamic_step = 6; // Step de 6 mois jusqu'à 48 mois + } else { + dynamic_step = 12; // Step de 12 mois au-delà de 48 mois + } + } + + return dynamic_step; + } + + // Mettre à jour le slider avec la nouvelle limite maximale + jQuery(selected_months_range).slider({ + min: default_min, + max: dynamic_max, + value: dynamic_max, // Utiliser la valeur maximale comme valeur initiale + step: getStepForValue(loan_type, dynamic_max), + slide: function(event, ui) { + var newStep = getStepForValue(loan_type, ui.value); + + if (newStep !== jQuery(this).slider('option', 'step')) { + jQuery(this).slider('option', 'step', newStep); + } + + var orange_bar = jQuery('.slider_duree_wrapper .after_bar_month'), + elem = jQuery(ui.handle), + left_css = parseInt(elem.css('left'), 10); + + orange_bar.css('width', left_css + 10); + jQuery(selected_months).val(ui.value); + + if (loan_type_in_years.includes(loan_type)) { + jQuery(selected_months_range).find(".slider_duree_box").text(ui.value + ' ans'); + jQuery(selected_duree_box).find(".outside_slider_duree_box").text(ui.value + ' ans'); + } else { + jQuery(selected_months_range).find(".slider_duree_box").text(ui.value + ' mois'); + jQuery(selected_duree_box).find(".outside_slider_duree_box").text(ui.value + ' mois'); + } + }, + stop: function(event, ui) { + var orange_bar = jQuery('.slider_duree_wrapper .after_bar_month'), + elem = jQuery(ui.handle), + left_css = parseInt(elem.css('left'), 10); + + orange_bar.css('width', left_css + 10); + calculate_mensualite(); + + // Mettre à jour l'état des boutons de durée après mouvement du slider + updateDurationButtonsState(); + }, + change: function(event, ui) { + var orange_bar = jQuery('.slider_duree_wrapper .after_bar_month'), + elem = jQuery(ui.handle), + left_css = parseInt(elem.css('left'), 10); + + orange_bar.css('width', left_css + 10); + } + }); + + jQuery(selected_months).val(jQuery(selected_months_range).slider('value')); + + var periodicite = loan_type_in_years.includes(loan_type) ? ' ans' : ' mois'; + var appended_elem = '' + jQuery(selected_months_range).slider('value') + periodicite + ''; + selected_duree_box.find(".outside_slider_duree_box").text(jQuery(selected_months_range).slider('value') + periodicite); + + if (!jQuery(selected_months_range).find('.ui-slider-handle .fa-angle-right').length) { + jQuery(selected_months_range).find(".ui-slider-handle").append(''); + } + + if (!jQuery(selected_months_range).find('.slider_duree_box').length) { + jQuery(selected_months_range).find('.ui-slider-handle').append(appended_elem); + } +} + +// Create plus and minus buttons for slider + +jQuery(document).on('click', ".stimulator-slider-control.capital-minus, .stimulator-slider-control.capital-plus", function() { + var selected_capital_range = '#selected_capital_range'; + var selected_capital_box = jQuery(selected_capital_range).parents('.selected_capital'); + var selected = jQuery('#loan_type').val(); + + /* console.log('selected_capital_box', selected_capital_box); */ + + var selected_radio = jQuery('.loan_type:checked').length ? jQuery('.loan_type:checked').val() : '', + sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : ''; + + if (selected_radio != '') + selected = selected_radio; + + if (sub_loan_radio_type != '') { + + if (sub_loan_radio_type != '' && authorized_value.includes(sub_loan_radio_type)) { + selected = sub_loan_radio_type; + } else if (map_values[sub_loan_radio_type] !== 'undefined') { + selected = map_values[sub_loan_radio_type]; + } + + } + + var current_step = form_sliders[selected].capital_step; + var is_plus = jQuery(this).hasClass('capital-plus'); + var selected_capital = is_plus ? + (+jQuery('#selected_capital').val() + current_step) : + (+jQuery('#selected_capital').val() - current_step); + + if ((selected_capital >= form_sliders[selected].capital_min) && (selected_capital <= form_sliders[selected].capital_max)) { + jQuery(selected_capital_range).slider({ + value: selected_capital + }); + + // Mise à jour du capital + jQuery('#selected_capital').val(selected_capital); + + console.log('🔘 BOUTON CAPITAL - Type de crédit:', selected); + console.log('🔘 BOUTON CAPITAL - Nouveau capital:', selected_capital); + + // Cas particuliers déjà gérés + if (((selected == "am") && selected_capital > 100000) || ((selected == "ph") && selected_capital > 100000)) { + jQuery('#selected_months').val(30); + change_duree(form_sliders[selected].duree_min, form_sliders[selected].duree_max, 30); + } else { + // Recalculer la durée max dynamiquement en fonction du nouveau capital via la fonction centralisée + var results = calculateDynamicLimits(selected, sub_loan_radio_type, selected_capital, ''); + + console.log('🔘 BOUTON CAPITAL - Results:', results); + + if (results && results.length > 1) { + var new_max_duration = results[1]; + var current_duration = jQuery('#selected_months').val(); + + console.log('🔘 BOUTON CAPITAL - Durée actuelle:', current_duration); + console.log('🔘 BOUTON CAPITAL - Durée max recalculée:', new_max_duration); + + // Si la durée actuelle dépasse le nouveau max, ajuster à la nouvelle durée max + if (parseInt(current_duration) > parseInt(new_max_duration)) { + console.log('🔘 BOUTON CAPITAL - Ajustement de la durée à:', new_max_duration); + jQuery('#selected_months').val(new_max_duration); + change_month_slider(form_sliders[selected].duree_min, form_sliders[selected].duree_max, new_max_duration); + } else { + // Sinon, garder la durée actuelle mais mettre à jour les limites du slider + console.log('🔘 BOUTON CAPITAL - Durée conservée, mise à jour du slider'); + change_month_slider(form_sliders[selected].duree_min, form_sliders[selected].duree_max, current_duration); + } + } + } + + // calculate_mensualite() va appeler change_duree() et remplir les mensualités + calculate_mensualite(); + + // Mettre à jour l'état des boutons de durée après changement de capital + updateDurationButtonsState(); + + /* jQuery(selected_capital_range).find(".ui-slider-handle").append(''); + jQuery(selected_capital_range).find('.ui-slider-handle').append(appended_elem); */ + jQuery('.range_selector.selected_capital .outside_box').text(number_format((jQuery(selected_capital_range).slider('value')), 2, ',', '.') + ' €'); + jQuery(selected_capital_range).find(".slider_capital_box").text(number_format((jQuery(selected_capital_range).slider('value')), 2, ',', '.') + ' €'); + } +}); + +// 2. 5 Step form + +// Accordian for content pages +jQuery(".ac-toggle-button").on('click', function(e) { + e.preventDefault(); + jQuery(".ac-text-block").slideToggle("slow"); +}); + +// Show link list when link is clicked +jQuery(".agency-menu-link").children("a").on('click', function() { + if (jQuery(".agency-menu-link").hasClass('agencies-active-link')) { + jQuery(".footer-locations").css("display", "none"); + jQuery(".agency-menu-link").removeClass('agencies-active-link'); + } else { + jQuery(".footer-locations").css("display", "inherit"); + jQuery(".agency-menu-link").addClass('agencies-active-link'); + } +}); + +jQuery('#co-emprunteur').on('change', function() { + if (jQuery('[name="co-emprunteur"]:checked').val() == "avec un co-emprunteur") { + jQuery(".co-emprunteur-fields").css('display', 'block'); + jQuery("#co-emprunteur-step2").val(1); + jQuery("#co-emprunteur-step3").val(1); + jQuery("#co-emprunteur-step4").val(1); + } else { + jQuery(".co-emprunteur-fields").css('display', 'none'); + jQuery(".co-emprunteur-fields input").val(""); + jQuery("#co-emprunteur-step2").val(0); + jQuery("#co-emprunteur-step3").val(0); + jQuery("#co-emprunteur-step4").val(0); + + } +}); + +jQuery('#je-suis-resident').on('change', function() { + if (jQuery('[name="je-suis-resident"]:checked').val() == "en Belgique") { + jQuery(".field-numero-national").show(); + } else { + jQuery(".field-numero-national").hide(); + } +}); +jQuery('#co-je-suis-resident').on('change', function() { + if (jQuery('[name="co-je-suis-resident"]:checked').val() == "en Belgique") { + jQuery(".field-co-numero-national").show(); + } else { + jQuery(".field-co-numero-national").hide(); + } +}); + +jQuery('#habitation').on('change', function() { + var fields = ["montant-du-loyer-a-payer", "credit-hypothecaire-en-cours", "vous-habitez"]; + for (var i = 0; i < fields.length; i++) { + jQuery(".field-" + fields[i]).hide(); + } + switch (jQuery('#habitation').val()) { + case 'locataire': + jQuery(".field-montant-du-loyer-a-payer").show(); + break; + case 'propriétaire': + jQuery(".field-credit-hypothecaire-en-cours").show(); + break; + case 'sans charge locative': + jQuery(".field-vous-habitez").show(); + break; + } +}); + +jQuery('#habitation-co-emprunteur').on('change', function() { + var fields = ["montant-du-loyer-a-payer-co-emprunteur", "credit-hypothecaire-en-cours-co-emprunteur", "vous-habitez-co-emprunteur"]; + for (var i = 0; i < fields.length; i++) { + jQuery(".field-" + fields[i]).hide(); + } + switch (jQuery('#habitation-co-emprunteur').val()) { + case 'locataire': + jQuery(".field-montant-du-loyer-a-payer-co-emprunteur").show(); + break; + + case 'propriétaire': + jQuery(".field-credit-hypothecaire-en-cours-co-emprunteur").show(); + break; + + case 'sans charge locative': + jQuery(".field-vous-habitez-co-emprunteur").show(); + break; + } +}); +jQuery('#nombre-d-enfant-s-a-charge').on('change', function() { + if (jQuery("#nombre-d-enfant-s-a-charge").val() == 0) { + jQuery(".field-montant-allocations-familiales").hide(); + jQuery(".field-montant-pension-alimentaire-recue").hide(); + } else { + jQuery(".field-montant-allocations-familiales").show(); + jQuery(".field-montant-pension-alimentaire-recue").show(); + } +}); +jQuery('#nombre-d-enfant-s-a-charge-co-emprunteur').on('change', function() { + if (jQuery("#nombre-d-enfant-s-a-charge-co-emprunteur").val() == 0) { + jQuery(".field-co-montant-allocations-familiales").hide(); + jQuery(".field-co-montant-pension-alimentaire-recue").hide(); + } else { + jQuery(".field-co-montant-allocations-familiales").show(); + jQuery(".field-co-montant-pension-alimentaire-recue").show(); + } +}); +jQuery('#profession').on('change', function() { + var ordered_fields; + jQuery("#autres-revenus-cheques-repas").val('non'); + on_chnage_autres_revenus_cheques(''); + jQuery('#valeur-du-cheque-repas').val(''); + var fields = ['type-de-contrat', 'nom-de-l-employeur', 'adresse-rue-numero', 'code-postal', 'localite', 'engage-depuis-quant', 'salaire-net-mensuel', 'nom-de-l-organisme-de-paiement', 'paye-depuis-quand', 'montant-net-mensuel-de-l-allocation', 'depuis-quand', 'numero-d-entreprise', 'domaine-de-l-activite', 'revenus-imposables-annuels', 'revenus-locatifs', 'autres-revenus-cheques-repas', 'allocation-supplementaire']; + for (var i = 0; i < fields.length; i++) { + jQuery(".field-" + fields[i]).hide(); + } + var allowed_fields; + var selected = jQuery("#profession").val(); + jQuery("#tab4 .emprunteur-primary").removeClass('flex-ordered'); + + if ((selected == "ouvrier") || (selected == "employé") || (selected == "fonctionnaire") || (selected == "militaire") || (selected == "policier") || (selected == "enseignant")) { + allowed_fields = ['type-de-contrat', 'nom-de-l-employeur', 'adresse-rue-numero', 'code-postal', 'localite', 'engage-depuis-quant', 'salaire-net-mensuel', 'revenus-locatifs', 'autres-revenus-cheques-repas', 'allocation-supplementaire']; + } else if (selected == "chômeur") { + allowed_fields = ['nom-de-l-organisme-de-paiement', 'adresse-rue-numero', 'code-postal', 'localite', 'paye-depuis-quand', 'montant-net-mensuel-de-l-allocation', 'revenus-locatifs', 'allocation-supplementaire', 'repeat-block', 'ajouter-dautres-revenus']; + ordered_fields = ['nom-de-l-organisme-de-paiement', 'adresse-rue-numero', 'code-postal', 'localite', 'paye-depuis-quand', 'montant-net-mensuel-de-l-allocation', 'revenus-locatifs', 'montant-total-des-revenus-locatifs', 'allocation-supplementaire', 'valeur-du-cheque-repas', 'montant-net-mensuel', 'repeat-block', 'ajouter-dautres-revenus']; + jQuery("#tab4 .emprunteur-primary").addClass('flex-ordered'); + var order = 1; + for (var i = 0; i < ordered_fields.length; i++) { + jQuery(".field-" + ordered_fields[i]).css('order', order); + order++; + } + } else if ((selected == "invalide")) { + allowed_fields = ['nom-de-l-organisme-de-paiement', 'adresse-rue-numero', 'code-postal', 'localite', 'paye-depuis-quand', 'montant-net-mensuel-de-l-allocation', 'revenus-locatifs', 'allocation-supplementaire']; + } else if ((selected == "pensionné") || (selected == "prépensionné")) { + allowed_fields = ['nom-de-l-organisme-de-paiement', 'adresse-rue-numero', 'code-postal', 'localite', 'paye-depuis-quand', 'montant-net-mensuel-de-l-allocation', 'revenus-locatifs', 'allocation-supplementaire']; + } else if ((selected == "indépendant")) { + allowed_fields = ['depuis-quand', 'numero-d-entreprise', 'domaine-de-l-activite', 'adresse-rue-numero', 'code-postal', 'localite', 'revenus-imposables-annuels', 'revenus-locatifs', 'autres-revenus-cheques-repas', 'allocation-supplementaire', 'repeat-block', 'ajouter-dautres-revenus']; + ordered_fields = ['depuis-quand', 'numero-d-entreprise', 'domaine-de-l-activite', 'adresse-rue-numero', 'code-postal', 'localite', 'revenus-imposables-annuels', 'revenus-locatifs', 'montant-total-des-revenus-locatifs', 'autres-revenus-cheques-repas', 'valeur-du-cheque-repas', 'allocation-supplementaire', 'repeat-block', 'ajouter-dautres-revenus']; + jQuery("#tab4 .emprunteur-primary").addClass('flex-ordered'); + var order = 1; + for (var i = 0; i < ordered_fields.length; i++) { + jQuery(".field-" + ordered_fields[i]).css('order', order); + order++; + } + } else if (selected == "sans profession") { + allowed_fields = ['revenus-locatifs']; + } + for (var i = 0; i < allowed_fields.length; i++) { + jQuery(".field-" + allowed_fields[i]).show(); + } +}); + +jQuery('#profession-co-emprunteur').on('change', function() { + var ordered_fields; + jQuery("#autres-revenus-cheques-repas-co-emprunteur").val('non'); + on_chnage_autres_revenus_cheques('co-'); + var fields = ['type-de-contrat', 'nom-de-l-employeur', 'adresse-rue-numero', 'code-postal', 'localite', 'engage-depuis-quant', 'salaire-net-mensuel', 'nom-de-l-organisme-de-paiement', 'paye-depuis-quand', 'montant-net-mensuel-de-l-allocation', 'depuis-quand', 'numero-d-entreprise', 'domaine-de-l-activite', 'revenus-imposables-annuels', 'revenus-locatifs', 'autres-revenus-cheques-repas', 'allocation-supplementaire']; + for (var i = 0; i < fields.length; i++) { + jQuery(".field-co-" + fields[i]).hide(); + } + var allowed_fields; + var selected = jQuery("#profession-co-emprunteur").val(); + + jQuery("#tab4 .co-emprunteur-fields").removeClass('flex-ordered'); + + if ((selected == "ouvrier") || (selected == "employé") || (selected == "fonctionnaire") || (selected == "militaire") || (selected == "policier") || (selected == "enseignant")) { + allowed_fields = ['type-de-contrat', 'nom-de-l-employeur', 'adresse-rue-numero', 'code-postal', 'localite', 'engage-depuis-quant', 'salaire-net-mensuel', 'revenus-locatifs', 'autres-revenus-cheques-repas', 'allocation-supplementaire']; + } else if (selected == "chômeur") { + allowed_fields = ['nom-de-l-organisme-de-paiement', 'adresse-rue-numero', 'code-postal', 'localite', 'paye-depuis-quand', 'montant-net-mensuel-de-l-allocation', 'revenus-locatifs', 'allocation-supplementaire', 'repeat-block', 'ajouter-dautres-revenus']; + ordered_fields = ['nom-de-l-organisme-de-paiement', 'adresse-rue-numero', 'code-postal', 'localite', 'paye-depuis-quand', 'montant-net-mensuel-de-l-allocation', 'revenus-locatifs', 'montant-total-des-revenus-locatifs', 'allocation-supplementaire', 'valeur-du-cheque-repas', 'montant-net-mensuel', 'repeat-block', 'ajouter-dautres-revenus']; + jQuery("#tab4 .co-emprunteur-fields").addClass('flex-ordered'); + var order = 1; + for (var i = 0; i < ordered_fields.length; i++) { + jQuery(".field-co-" + ordered_fields[i]).css('order', order); + order++; + } + } else if ((selected == "invalide")) { + allowed_fields = ['nom-de-l-organisme-de-paiement', 'adresse-rue-numero', 'code-postal', 'localite', 'paye-depuis-quand', 'montant-net-mensuel-de-l-allocation', 'revenus-locatifs', 'allocation-supplementaire']; + } else if ((selected == "pensionné") || (selected == "prépensionné")) { + allowed_fields = ['nom-de-l-organisme-de-paiement', 'adresse-rue-numero', 'code-postal', 'localite', 'paye-depuis-quand', 'montant-net-mensuel-de-l-allocation', 'revenus-locatifs', 'allocation-supplementaire']; + } else if ((selected == "indépendant")) { + allowed_fields = ['depuis-quand', 'numero-d-entreprise', 'domaine-de-l-activite', 'adresse-rue-numero', 'code-postal', 'localite', 'revenus-imposables-annuels', 'revenus-locatifs', 'autres-revenus-cheques-repas', 'allocation-supplementaire', 'repeat-block', 'ajouter-dautres-revenus']; + ordered_fields = ['depuis-quand', 'numero-d-entreprise', 'domaine-de-l-activite', 'adresse-rue-numero', 'code-postal', 'localite', 'revenus-imposables-annuels', 'revenus-locatifs', 'montant-total-des-revenus-locatifs', 'autres-revenus-cheques-repas', 'valeur-du-cheque-repas', 'allocation-supplementaire', 'repeat-block', 'ajouter-dautres-revenus']; + jQuery("#tab4 .co-emprunteur-fields").addClass('flex-ordered'); + var order = 1; + for (var i = 0; i < ordered_fields.length; i++) { + jQuery(".field-co-" + ordered_fields[i]).css('order', order); + order++; + } + } else if (selected == "sans profession") { + allowed_fields = ['revenus-locatifs']; + } + for (var i = 0; i < allowed_fields.length; i++) { + jQuery(".field-co-" + allowed_fields[i]).show(); + } +}); + +jQuery('#allocation-supplementaire').on('change', function() { + if (jQuery('#allocation-supplementaire').val() != "---") { + jQuery(".field-paye-depuis-quand-2").show(); + jQuery(".field-montant-net-mensuel-de-l-allocation-2").show(); + jQuery(".field-nom-de-l-organisme-de-paiement").show(); + } else { + jQuery(".field-paye-depuis-quand-2").hide(); + jQuery(".field-montant-net-mensuel-de-l-allocation-2").hide(); + jQuery(".field-nom-de-l-organisme-de-paiement").hide(); + } +}); + +jQuery('#allocation-supplementaire-co-emprunteur').on('change', function() { + if (jQuery('#allocation-supplementaire-co-emprunteur').val() == "oui") { + jQuery(".field-co-paye-depuis-quand-2").show(); + jQuery(".field-co-montant-net-mensuel-de-l-allocation-2").show(); + jQuery(".field-co-nom-de-l-organisme-de-paiement").show(); + } else { + jQuery(".field-co-montant-net-mensuel-de-l-allocation-2").hide(); + jQuery(".field-co-paye-depuis-quand-2").hide(); + jQuery(".field-co-nom-de-l-organisme-de-paiement").hide(); + + } +}); + +function on_chnage_autres_revenus_cheques(prefix) { + var prefix_extended = ''; + if (prefix == "co-") { prefix_extended = "-co-emprunteur" } + var selected = jQuery("#profession" + prefix_extended).val(); + jQuery(".field-" + prefix + "valeur-du-cheque-repas").hide(); + jQuery(".field-" + prefix + "montant-net-mensuel").hide(); + if (jQuery("#autres-revenus-cheques-repas" + prefix_extended).val() == "oui") { + jQuery(".field-" + prefix + "valeur-du-cheque-repas").show(); + if ((selected == "ouvrier") || (selected == "employé") || (selected == "fonctionnaire") || (selected == "militaire") || (selected == "policier") || (selected == "enseignant") || (selected == "indépendant")) {} else { + jQuery(".field-" + prefix + "montant-net-mensuel").show(); + } + } +} + +jQuery('#autres-revenus-cheques-repas').on('change', function() { + on_chnage_autres_revenus_cheques(''); +}); + +jQuery('#autres-revenus-cheques-repas-co-emprunteur').on('change', function() { + on_chnage_autres_revenus_cheques('co-'); +}); + +jQuery('#revenus-locatifs').on('change', function() { + if (jQuery('#revenus-locatifs').val() == "oui") { + jQuery(".field-montant-total-des-revenus-locatifs").show(); + } else { + jQuery(".field-montant-total-des-revenus-locatifs").hide(); + } +}); + +jQuery('#revenus-locatifs-co-emprunteur').on('change', function() { + if (jQuery('#revenus-locatifs-co-emprunteur').val() == "oui") { + jQuery(".field-co-montant-total-des-revenus-locatifs").show(); + } else { + jQuery(".field-co-montant-total-des-revenus-locatifs").hide(); + } +}); + +function onchange_type_de_credit() { + var fields = ['fonds-propres', 'type-des-frais-de-notaire', 'prix-d-achat', 'prix-de-la-construction-tvac', 'prix-d-achat', 'compromis-signe', 'valeur-du-batiment', 'montant-du-revenu-cadastral', 'marque-modele-du-vehicule', 'date-1ere-immatriculation', 'nom-du-vendeur', 'adresse-du-vendeur', 'prix-d-achat-du-vehicule', 'type-des-frais-de-notaire', 'type-des-travaux', 'montant-a-emprunter', 'duree']; + for (var i = 0; i < fields.length; i++) { + jQuery(".field-" + fields[i]).hide(); + } + var allowed_fields; + + switch (jQuery('#type-de-credit').val()) { + case 'Prêt Hypothécaire (Achat Maison)': + allowed_fields = ['prix-d-achat', 'fonds-propres', 'compromis-signe', 'montant-du-revenu-cadastral', 'montant-a-emprunter', 'duree']; + break; + case 'Prêt Hypothécaire (Construction)': + allowed_fields = ['prix-de-la-construction-tvac', 'fonds-propres', 'montant-a-emprunter', 'duree']; + break; + case 'Prêt Hypothécaire (Refinancement)': + allowed_fields = ['valeur-du-batiment', 'montant-a-emprunter', 'duree']; + break; + case 'Prêt Hypothécaire (Regroupement)': + allowed_fields = ['valeur-du-batiment', 'montant-a-emprunter', 'duree']; + break; + case 'Prêt Hypothécaire (Achat à L\'étranger)': + allowed_fields = ['prix-d-achat', 'fonds-propres', 'compromis-signe', 'montant-a-emprunter', 'duree']; + break; + case 'Prêt à Tempérament (Tous Motifs)': + allowed_fields = ['montant-a-emprunter', 'duree']; + break; + case 'Financement Véhicule Neuf': + allowed_fields = ['marque-modele-du-vehicule', 'date-1ere-immatriculation', 'nom-du-vendeur', 'adresse-du-vendeur', 'prix-d-achat-du-vehicule', 'montant-a-emprunter', 'duree']; + break; + case 'Financement Véhicule D\'occasion': + allowed_fields = ['marque-modele-du-vehicule', 'date-1ere-immatriculation', 'nom-du-vendeur', 'adresse-du-vendeur', 'prix-d-achat-du-vehicule', 'montant-a-emprunter', 'duree']; + break; + case 'Crédit Travaux / Rénovation / Energie': + allowed_fields = ['type-des-travaux', 'montant-a-emprunter', 'duree']; + break; + case 'Frais De Notaire': + allowed_fields = ['type-des-frais-de-notaire', 'montant-a-emprunter', 'duree']; + break; + default: + allowed_fields = ['montant-a-emprunter', 'duree']; + break; + } + for (var i = 0; i < allowed_fields.length; i++) { + jQuery(".field-" + allowed_fields[i]).show(); + } + onchange_loan_type(); + +}; + +// Fonction centralisée pour calculer les limites dynamiques en fonction du type de crédit et du capital +function calculateDynamicLimits(loan_type, sub_loan_radio_type, capital, duration) { + var results; + + switch (loan_type) { + case 'pat': + results = calculate_pat(capital, duration); + break; + case 'fin_neuve': + results = calculate_fin_neuve(capital, duration); + break; + case 'fin_occ_m3a': + results = calculate_pao_m_3(capital, duration); + break; + case 'fin_occ_p3a': + results = calculate_pao_p_3(capital, duration); + break; + case 'ph': + results = calculate_ph(capital, duration); + break; + case 'am': + results = calculate_am(capital, duration); + break; + case 'frais_notaire': + results = calculate_frais_notaire(capital, duration); + break; + case 'but_immo': + results = calculate_but_immo(capital, duration); + break; + case 'cdp': + results = calculate_cdp(capital, duration); + break; + case 'amr': + case 'cied': + results = calculate_mono_rate_bt_10_30(sub_loan_radio_type, capital, duration); + break; + case 'mobil_carav': + results = calculate_mobilhome(capital, duration); + break; + case 'regroup_cred': + results = calculate_regroupement_de_credit(capital, duration); + break; + default: + // Si le type n'est pas reconnu, utiliser les valeurs par défaut + results = [ + form_sliders[loan_type] ? form_sliders[loan_type].duree_min : 24, + form_sliders[loan_type] ? form_sliders[loan_type].duree_max : 240, + duration || 0, + true, + 0, + '' + ]; + break; + } + + return results; +} + +// Fonction pour activer/désactiver les boutons de durée en fonction des limites dynamiques +function updateDurationButtonsState() { + var selected = jQuery('#loan_type').val(); + var selected_radio = jQuery('.loan_type:checked').length ? jQuery('.loan_type:checked').val() : ''; + var sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : ''; + var loan_type_in_years = ['am', 'amr', 'cied', 'ph','cdp']; + + if (selected_radio != '') + selected = selected_radio; + + if (sub_loan_radio_type != '') { + if (authorized_value.includes(sub_loan_radio_type)) { + selected = sub_loan_radio_type; + } else if (map_values[sub_loan_radio_type] !== 'undefined') { + selected = map_values[sub_loan_radio_type]; + } + } + + var selected_capital = jQuery('#selected_capital').val(); + var current_value = +jQuery('#selected_months').val(); + + // Calculer les limites dynamiques via la fonction centralisée + var results = calculateDynamicLimits(selected, sub_loan_radio_type, selected_capital, current_value); + + var duree_min = results[0]; + var duree_max = results[1]; + + // Fonction pour calculer le step + function getStepForValue(loan_type, value) { + let dynamic_step = 1; + if (loan_type_in_years.includes(loan_type)) { + dynamic_step = 1; + } else if (loan_type === 'cdp') { + dynamic_step = 1; + } else { + if (value <= 48) { + dynamic_step = 6; + } else { + dynamic_step = 12; + } + } + return dynamic_step; + } + + var current_step = getStepForValue(selected, current_value); + + // Calculer les valeurs potentielles + var next_value = current_value + current_step; + var prev_value = current_value - current_step; + + // Ajouter une transition CSS pour un effet fluide (une seule fois) + if (!jQuery('.stimulator-slider-control.duree-plus').data('transition-added')) { + jQuery('.stimulator-slider-control.duree-plus, .stimulator-slider-control.duree-minus').css({ + 'transition': 'opacity 0.3s ease', + 'cursor': 'pointer' + }); + jQuery('.stimulator-slider-control.duree-plus, .stimulator-slider-control.duree-minus').data('transition-added', true); + } + + // Activer/désactiver le bouton plus + if (next_value > duree_max) { + jQuery('.stimulator-slider-control.duree-plus').addClass('disabled').prop('disabled', true).css({ + 'opacity': '0.4', + 'cursor': 'not-allowed' + }); + console.log('🔒 Bouton durée+ désactivé (next:', next_value, '> max:', duree_max, ')'); + } else { + jQuery('.stimulator-slider-control.duree-plus').removeClass('disabled').prop('disabled', false).css({ + 'opacity': '1', + 'cursor': 'pointer' + }); + console.log('🔓 Bouton durée+ activé'); + } + + // Activer/désactiver le bouton moins + if (prev_value < duree_min) { + jQuery('.stimulator-slider-control.duree-minus').addClass('disabled').prop('disabled', true).css({ + 'opacity': '0.4', + 'cursor': 'not-allowed' + }); + console.log('🔒 Bouton durée- désactivé (prev:', prev_value, '< min:', duree_min, ')'); + } else { + jQuery('.stimulator-slider-control.duree-minus').removeClass('disabled').prop('disabled', false).css({ + 'opacity': '1', + 'cursor': 'pointer' + }); + console.log('🔓 Bouton durée- activé'); + } +} + +jQuery(document).on('click', ".stimulator-slider-control.duree-plus, .stimulator-slider-control.duree-minus", function() { + var selected_months_range = '#selected_months_range'; + var selected_months = '#selected_months'; + var selected = jQuery('#loan_type').val(); + var loan_type_in_years = ['am', 'amr', 'cied', 'ph','cdp']; + + var selected_radio = jQuery('.loan_type:checked').length ? jQuery('.loan_type:checked').val() : '', + sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : ''; + + if (selected_radio != '') + selected = selected_radio; + + if (sub_loan_radio_type != '') { + if (sub_loan_radio_type != '' && authorized_value.includes(sub_loan_radio_type)) { + selected = sub_loan_radio_type; + } else if (map_values[sub_loan_radio_type] !== 'undefined') { + selected = map_values[sub_loan_radio_type]; + } + } + + // Récupérer le capital actuel pour calculer les limites dynamiques + var selected_capital = jQuery('#selected_capital').val(); + var current_value = +jQuery(selected_months).val(); + + // Calculer les limites dynamiques en fonction du capital via la fonction centralisée + var results = calculateDynamicLimits(selected, sub_loan_radio_type, selected_capital, current_value); + + var duree_min = results[0]; + var duree_max = results[1]; + + console.log('🔘 BOUTON DURÉE - Capital:', selected_capital); + console.log('🔘 BOUTON DURÉE - Limites dynamiques: min =', duree_min, ', max =', duree_max); + console.log('🔘 BOUTON DURÉE - Valeur actuelle:', current_value); + + var is_plus = jQuery(this).hasClass('duree-plus'); + + // Utiliser la fonction getStepForValue pour déterminer le step approprié + function getStepForValue(loan_type, value) { + let dynamic_step = 1; + + if (loan_type_in_years.includes(loan_type)) { + dynamic_step = 1; // Step de 1 an pour les prêts en années + } else if (loan_type === 'cdp') { + dynamic_step = 1; // Step de 1 mois pour le crédit pont + } else { + if (value <= 48) { + dynamic_step = 6; // Step de 6 mois jusqu'à 48 mois + } else { + dynamic_step = 12; // Step de 12 mois au-delà de 48 mois + } + } + + return dynamic_step; + } + + // Calculer le step approprié pour la valeur actuelle + var current_step = getStepForValue(selected, current_value); + + // Calculer la nouvelle valeur + var new_value; + if (is_plus) { + new_value = current_value + current_step; + } else { + new_value = current_value - current_step; + } + + console.log('🔘 BOUTON DURÉE - Nouvelle valeur:', new_value); + + // Vérifier que la nouvelle valeur est dans les limites DYNAMIQUES + if ((new_value >= duree_min) && (new_value <= duree_max)) { + jQuery(selected_months).val(new_value); + jQuery(selected_months_range).slider({ + value: new_value + }); + change_duree(form_sliders[selected].duree_min, form_sliders[selected].duree_max, new_value); + calculate_mensualite(); + + console.log('✅ Bouton durée - Valeur mise à jour'); + } else { + console.log('⚠️ Bouton durée - Valeur hors limites dynamiques'); + } + + // Mettre à jour l'état des boutons après le changement + updateDurationButtonsState(); +}); + +jQuery('.dautres-credit').on('click', function() { + if (jQuery('[name="dautres-credit[]"]').is(":checked")) { + jQuery(".dautres-credit-fields").css('display', 'block'); + var n = jQuery(".repeater-fields-step-5").length; + if (n == "") { n = 0 }; + n++; + var form_step_5 = '
    X
    oui
    '; + jQuery("#step-5-repeat-block").append(form_step_5); + } else { + var repeater_id = jQuery(".repeater-fields-step-5").length; + jQuery(".rf-g-cours-" + repeater_id).remove(); + jQuery(".dautres-credit-fields").css('display', 'none'); + } +}); + +jQuery(document).on('click', '.dautres-credit-repeater', function() { + var block_5 = jQuery(this).data("repeated"); + if (jQuery(this).is(":checked")) { + jQuery(".dautres-credit-fields-" + block_5).show(); + var n = jQuery(".repeater-fields-step-5").length; + if (n == "") { n = 0 }; + n++; + var form_step_5 = '
    X
    oui
    '; + jQuery("#step-5-repeat-block").append(form_step_5); + } else { + var repeater_id = jQuery(".repeater-fields-step-5").length; + jQuery(".rf-g-cours-" + repeater_id).remove(); + jQuery(".dautres-credit-fields-" + block_5).hide(); + } +}); + +jQuery(document).on('click', '.remove_rf_revenus', function() { + var repeater_id = jQuery(this).data("repeated"); + jQuery(".rf-g-revenus-" + repeater_id).remove(); +}); +jQuery(document).on('click', '.remove_rf_en_cours', function() { + var repeater_id = jQuery(this).data("repeated"); + jQuery(".rf-g-cours-" + repeater_id).remove(); +}); +jQuery(document).on("keypress", "form", function(event) { + return event.keyCode != 13; +}); + +jQuery('.mini-stimulator #loan_type, .mini-stimulator .loan_type').change(function() { + var hidden_fields, allowed_fields; + var changeTo = ''; + hidden_fields = []; + + var loan_type = jQuery('.mini-stimulator #loan_type').val(), + loan_radio_type = jQuery('.mini-stimulator .loan_type:checked').length ? jQuery('.mini-stimulator .loan_type:checked').val() : ''; + + if (loan_radio_type != '') + loan_type = loan_radio_type; + + jQuery(".field-type-des-travaux").hide(); + allowed_fields = ['fonds-propres', 'type-des-frais-de-notaire']; + for (var i = 0; i < allowed_fields.length; i++) { jQuery(".field-" + allowed_fields[i]).show(); } + switch (loan_type) { + case 'pat': + changeTo = "Prêt à Tempérament (Personnel / Tous Motifs / Achats Divers)"; + hidden_fields = ['fonds-propres', 'type-des-frais-de-notaire']; + break; + + case 'frais_notaire': + hidden_fields = ['fonds-propres']; + changeTo = "Frais De Notaire"; + break; + + case 'but_immo': + hidden_fields = ['fonds-propres', 'type-des-frais-de-notaire']; + jQuery(".field-type-des-travaux").show(); + changeTo = "Crédit Travaux / Rénovation / Energie"; + break; + + case 'fin_neuve': + changeTo = "Financement Véhicule Neuf"; + hidden_fields = ['type-des-frais-de-notaire']; + break; + + case 'fin_occ_m3a': + hidden_fields = ['fonds-propres', 'type-des-frais-de-notaire']; + changeTo = "Financement Véhicule D'occasion"; + break; + + case 'fin_occ_p3a': + hidden_fields = ['fonds-propres', 'type-des-frais-de-notaire']; + changeTo = "Financement Véhicule D'occasion"; + break; + + case 'am': + changeTo = "Prêt Hypothécaire (Achat Maison)"; + break; + + case 'ph': + changeTo = "Prêt Hypothécaire (Achat Maison)"; + break; + } + // Change all pre de credit to veuillez sélectionner votre type de prêt + changeTo = ''; + for (var i = 0; i < hidden_fields.length; i++) { jQuery(".field-" + hidden_fields[i]).hide(); } + jQuery('#type-de-credit').val(changeTo); + onchange_type_de_credit(); +}); + +jQuery('#type-de-credit').change(function() { + var changeTo = ''; + var changeYes = false; + + var loan_type = jQuery('.mini-stimulator #loan_type').val(), + loan_radio_type = jQuery('.mini-stimulator .loan_type:checked').length ? jQuery('.mini-stimulator .loan_type:checked').val() : ''; + + if (loan_radio_type != '') + loan_type = loan_radio_type; + + switch (jQuery('#type-de-credit').val()) { + case "Frais De Notaire": + changeTo = 'frais_notaire'; + changeYes = true; + break; + + case "Crédit Travaux / Rénovation / Energie": + changeYes = true; + changeTo = 'but_immo'; + break; + + case "Financement Véhicule Neuf": + changeYes = true; + changeTo = 'fin_neuve'; + break; + + case "Financement Véhicule D'occasion": + changeYes = true; + changeTo = 'fin_occ_m3a'; + break; + case "Prêt Hypothécaire (Achat Maison)": + changeYes = true; + changeTo = 'am'; + break; + + case "Prêt Hypothécaire (Construction)": + changeYes = true; + changeTo = 'ph'; + break; + case "Prêt Hypothécaire (Refinancement)": + changeYes = true; + changeTo = 'am'; + break; + case "Prêt Hypothécaire (Regroupement)": + changeYes = true; + changeTo = 'am'; + break; + case "Prêt Hypothécaire (Achat à L'étranger)": + changeYes = true; + changeTo = 'am'; + break; + case "Prêt à Tempérament (Personnel / Tous Motifs / Achats Divers)": + changeYes = true; + changeTo = 'pat'; + break; + } + if ((changeYes == true) && (loan_type != changeTo)) { + jQuery('.mini-stimulator #loan_type').val(changeTo); + jQuery('.mini-stimulator input#' + changeTo).prop('checked', true); + /* jQuery('#selected_months').val(200); */ + } + onchange_type_de_credit(); +}); + +// 3. General +"use strict"; + + +/* form handling */ +jQuery(function() { + jQuery('.field-repeat-block').repeater({ + show: function() { + changeYesjQuery(this).slideDown(); + }, + hide: function(deleteElement) { + if (confirm('Êtes-vous sûr de vouloir supprimer cet élément?')) { + jQuery(this).slideUp(deleteElement); + } + }, + ready: function(setIndexes) { + + } + }); + // Config + var form = jQuery('#formulaire_form'); + var wizard = jQuery('#form_wizard'); + var error = jQuery('.alert-danger', form); + var success = jQuery('.alert-success', form); + jQuery.validator.addClassRules({ + number_field: { + number: true + }, + email_field: { + email: true + } + }); + jQuery.validator.messages.required = "Ce champs est requis."; + jQuery.validator.messages.email = "Veuillez insérer une adresse mail valide." + form.validate({ + doNotHideMessage: true, + focusInvalid: false, + invalidHandler: function(event, validator) { + success.hide(); + error.show(); + }, + submitHandler: function(form) { + success.show(); + error.hide(); + jQuery(form).submit(); + }, + }); + + + // Functions + var displayConfirm = function() { + jQuery('#tab6 .form-control-static', form).each(function() { + var input = jQuery('[name="' + jQuery(this).attr("data-display") + '"]', form); + + if (input.is(":text") || input.is("textarea")) { + jQuery(this).html(input.val()); + } else if (input.is("select")) { + jQuery(this).html(input.find('option:selected').text()); + } else if (input.is(":radio") && input.is(":checked")) { + jQuery(this).html(input.attr("data-title")); + } + }); + } + + var handleTitle = function(tab, navigation, index) { + var total = navigation.find('li').length; + var current = index + 1; + + // Set widget title + jQuery('.step-title', wizard).text('Step ' + (index + 1) + ' of ' + total); + + // Set done steps + jQuery('li', wizard).removeClass("done"); + + var li_list = navigation.find('li'); + for (var i = 0; i < index; i++) { + jQuery(li_list[i]).addClass("done"); + } + + if (current == 1) { + wizard.find('.button-previous').hide(); + } else { + wizard.find('.button-previous').show(); + } + + if (current >= total) { + wizard.find('.button-next').hide(); + wizard.find('.button-submit').show(); + displayConfirm(); + } else { + wizard.find('.button-next').show(); + wizard.find('.button-submit').hide(); + } + } + + // Form wizard example + wizard.bootstrapWizard({ + 'nextSelector': '.button-next', + 'previousSelector': '.button-previous', + onTabClick: function(tab, navigation, index, clickedIndex) { + success.hide(); + error.hide(); + + if (form.valid() == false) { + return false; + } else { + + dataLayer.push({ 'event': 'pageview', 'virtualUrl': 'subscription-step' + (index + 1) + '-completed.html' }); + } + + handleTitle(tab, navigation, clickedIndex); + }, + onNext: function(tab, navigation, index) { + success.hide(); + error.hide(); + + if (form.valid() == false) { + return false; + } else { + dataLayer.push({ 'event': 'pageview', 'virtualUrl': 'subscription-step' + (index + 1) + '-completed.html' }); + } + handleTitle(tab, navigation, index); + + }, + onPrevious: function(tab, navigation, index) { + success.hide(); + error.hide(); + + handleTitle(tab, navigation, index); + }, + onTabShow: function(tab, navigation, index) { + // To set progressbar width + var total = navigation.find('li').length; + var current = index + 1; + if (current > 1) { jQuery('.page-formulaire-seletors').hide(); } else { jQuery('.page-formulaire-seletors').show(); } + var $percent = (current / total) * 100; + wizard.find('.progress-bar').css({ + width: $percent + '%' + }); + jQuery('html, body').animate({ + scrollTop: jQuery("#form_wizard").offset().top + }, 1000); + } + }); + + wizard.find('.button-previous').hide(); + jQuery('#form_wizard .button-submit').click(function() {}).hide(); +}); + +function number_format(number, decimals, decPoint, thousandsSep) { // eslint-disable-line camelcase + + number = (number + '').replace(/[^0-9+\-Ee.]/g, '') + var n = !isFinite(+number) ? 0 : +number + var prec = !isFinite(+decimals) ? 0 : Math.abs(decimals) + var sep = (typeof thousandsSep === 'undefined') ? ',' : thousandsSep + var dec = (typeof decPoint === 'undefined') ? '.' : decPoint + var s = '' + + var toFixedFix = function(n, prec) { + var k = Math.pow(10, prec) + return '' + (Math.round(n * k) / k) + .toFixed(prec) + } + + // @todo: for IE parseFloat(0.55).toFixed(0) = 0; + s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.') + if (s[0].length > 3) { + s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep) + } + if ((s[1] || '').length < prec) { + s[1] = s[1] || '' + s[1] += new Array(prec - s[1].length + 1).join('0') + } + + return s.join(dec) +} + +function update_capital_input() { + if (jQuery('#selected_capital').length) { + + var selected = jQuery('#loan_type').val(), + selected_radio = jQuery('.loan_type:checked').length ? jQuery('.loan_type:checked').val() : '', + sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : ''; + + if (selected_radio != '') + selected = selected_radio; + + if (sub_loan_radio_type != '' && authorized_value.includes(sub_loan_radio_type)) { + selected = sub_loan_radio_type; + } else if (map_values[sub_loan_radio_type] !== 'undefined') { + selected = map_values[sub_loan_radio_type]; + } + + var capital_max = form_sliders[selected].capital_max; + var capital_min = form_sliders[selected].capital_min; + var capital_selected = form_sliders[selected].capital_selected; + + jQuery('#selected_capital').prop('min', capital_min); + jQuery('#selected_capital').prop('max', capital_max); + jQuery('#selected_capital').val(capital_selected); + } +} + + +/* allocation selector */ +jQuery(document).on('change', '.allocation-supplementaire-repeater', function() { + var block_4 = jQuery(this).data("repeated"); + if ((jQuery(this)).val() != "---") { + jQuery(this).parents(".repeater-fields-step-4").children(".add-repeater-fields").show(); + } else { + jQuery(this).parents(".repeater-fields-step-4").children(".add-repeater-fields").hide(); + } +}); + +jQuery(function() { + var is_sending = false, + failure_message = 'Whoops, looks like there was a problem. Please try again later.'; + + jQuery('#forumulair-submit').on('click', function(e) { + + e.preventDefault(); // Prevent the default form submit + var $this = jQuery('#formulaire_form'); // Cache this + jQuery.ajax({ + url: cd_ajax_url.ajaxUrl, + type: 'post', + dataType: 'JSON', // Set this so we don't need to decode the response... + data: $this.serialize(), // One-liner form data prep... + beforeSend: function() { + is_sending = true; + // You could do an animation here... + }, + error: function(data) { + + }, + success: function(data) { + if (data.status === 'success') { + var message = + "

    Votre demande de crédit nous est bien parvenue et nous vous en remercions. Une suite vous sera assurée dans les plus brefs délais (vous allez d'ailleurs recevoir un accusé de réception de notre part, par e-mail)

    Nous vous informons qu'il est toujours préférable de ne pas introduire votre demande auprès de plusieurs sociétés de crédit en même temps. Nous travaillons avec la plupart des banques et sociétés de crédit, ce qui signifie que si votre dossier venait à être refusé la 1ère fois, nous le réintroduirons automatiquement ailleurs afin d'avoir un maximum de chances d'acceptation.

    Crédit Direct SPRL

    Retour vers la page d'accueil
    "; + jQuery('#formulaire_form').html(message); + window.setTimeout(function() { window.location.href = cd_ajax_url.site_url; }, 15000); + } else { + // handleFormError(); // If we don't get the expected response, it's an error... + } + } + }); + }); + + function handleFormError() { + is_sending = false; // Reset the is_sending var so they can try again... + alert(failure_message); + } +}); +// Create plus and minus buttons for slider +jQuery("#show_contact_num").click(function() { + jQuery('.header-top-contacts').slideToggle(); +}); + +jQuery('#rgpdID').on('click', function() { + + if (jQuery(this).is(':checked')) { + jQuery('[type="submit"]').removeAttr('disabled'); + } else { + jQuery('[type="submit"]').prop('disabled', true); + } + +}); + +jQuery('[name="hascoborrower"]').each(function() { + jQuery(this).on('click', function(e) { + + let val = jQuery(this).val(); + + if (val == 1) { + jQuery('.co-emprunteur').slideDown(); + jQuery('.isRequired').prop('required', true); + + // Gérer les patterns pour les champs date dans .co-emprunteur + // Vérifier si cojob = 5 pour gérer co-independent_section + var cojobValue = jQuery('select[name="cojob"]').val(); + var isCojobIndependent = cojobValue === '5'; + + // Activer les patterns pour tous les champs date sauf co-independent_section + jQuery('.co-emprunteur').find('input.input-date').each(function() { + var $field = jQuery(this); + var $container = $field.closest('.co-independent_section'); + + // Si le champ n'est pas dans co-independent_section, activer le pattern + if ($container.length === 0) { + var currentPattern = $field.attr('pattern'); + if (!$field.attr('data-initial-pattern') && typeof currentPattern !== 'undefined' && currentPattern !== '') { + $field.attr('data-initial-pattern', '1'); + $field.attr('data-initial-pattern-value', currentPattern); + } + + if ($field.attr('data-initial-pattern') === '1') { + $field.attr('pattern', $field.attr('data-initial-pattern-value')); + } else { + $field.attr('pattern', '\\d{1,2}/\\d{1,2}/\\d{4}'); + } + } else { + // Si dans co-independent_section, activer uniquement si cojob = 5 + if (isCojobIndependent) { + var currentPattern = $field.attr('pattern'); + if (!$field.attr('data-initial-pattern') && typeof currentPattern !== 'undefined' && currentPattern !== '') { + $field.attr('data-initial-pattern', '1'); + $field.attr('data-initial-pattern-value', currentPattern); + } + + if ($field.attr('data-initial-pattern') === '1') { + $field.attr('pattern', $field.attr('data-initial-pattern-value')); + } else { + $field.attr('pattern', '\\d{1,2}/\\d{1,2}/\\d{4}'); + } + } else { + $field.removeAttr('pattern'); + } + } + }); + } else if (val == 0) { + jQuery('.co-emprunteur').slideUp(); + jQuery('.isRequired').removeAttr('required'); + + // Retirer les patterns quand le co-emprunteur est désactivé + jQuery('.co-emprunteur').find('input.input-date').each(function() { + jQuery(this).removeAttr('pattern'); + }); + } + + }); +}); + +// Gestionnaire pour le changement de cojob dans le formulaire one-step +// Mettre à jour les patterns des champs date dans co-independent_section +jQuery('body').on('change', 'select[name="cojob"]', function() { + var cojobValue = jQuery(this).val(); + var isCojobIndependent = cojobValue === '5'; + var hasCoBorrower = jQuery('input[name="hascoborrower"]:checked').length > 0 && + jQuery('input[name="hascoborrower"]:checked').val() == 1; + + // Mettre à jour les patterns uniquement si le co-emprunteur est activé + if (hasCoBorrower) { + jQuery('.co-emprunteur').find('.co-independent_section input.input-date').each(function() { + var $field = jQuery(this); + + if (isCojobIndependent) { + // Activer le pattern si cojob = 5 + var currentPattern = $field.attr('pattern'); + if (!$field.attr('data-initial-pattern') && typeof currentPattern !== 'undefined' && currentPattern !== '') { + $field.attr('data-initial-pattern', '1'); + $field.attr('data-initial-pattern-value', currentPattern); + } + + if ($field.attr('data-initial-pattern') === '1') { + $field.attr('pattern', $field.attr('data-initial-pattern-value')); + } else { + $field.attr('pattern', '\\d{1,2}/\\d{1,2}/\\d{4}'); + } + } else { + // Retirer le pattern si cojob ≠ 5 + $field.removeAttr('pattern'); + } + }); + } +}); + +/* jQuery('#selected_capital_range').on('slide, change', function(event, ui) { + + var css_left_span = jQuery('#selected_capital_range').find('span').css('left'), + orange_bar = jQuery('.slider-count-wrapper .after_bar'); + + if (!orange_bar.hasClass('active')) + orange_bar.addClass('active'); + + + if (css_left_span < 90) + css_left_span += 10; + + orange_bar.css('width', css_left_span); + +}); */ + +/*jQuery('#selected_capital_range').on('slidechange', function(event, ui) { + + var css_left_span = jQuery('#selected_capital_range').find('span').css('left'), + orange_bar = jQuery('.slider-count-wrapper .after_bar'); + + if (!orange_bar.hasClass('active')) + orange_bar.addClass('active'); + + + if (css_left_span < 90) + css_left_span += 10; + + orange_bar.css('width', css_left_span); + +});*/ + +jQuery('#selected_capital_range').on('slidecreate', function(event, ui) { + + var css_left_span = jQuery('#selected_capital_range').find('span').css('left'), + orange_bar = jQuery('.slider-count-wrapper .after_bar'); + + if (!orange_bar.hasClass('active')) + orange_bar.addClass('active'); + + + orange_bar.css('width', css_left_span); + +}); + +jQuery(document).ready(function($) { + // Gestion du changement d'état de la case à cocher avec effet de slide + $('#switch_duration_type').on('change', function() { + if ($(this).is(':checked')) { + $('.determined_choices').slideUp(300, function() { + $('.free_choice').slideDown(300); + }); + } else { + $('.free_choice').slideUp(300, function() { + $('.determined_choices').slideDown(300); + }); + } + }); +}); + +// Gestion des boutons de type de crédit +jQuery(document).ready(function($) { + $('.credit-type-selector').on('click', function(e) { + e.preventDefault(); + + const type = $(this).data('type'); + const $container = $('.load_simulator').parent(); + + // Ajout d'un indicateur de chargement + $container.addClass('loading'); + + // Requête AJAX + $.ajax({ + url: cd_js.ajaxUrl, + type: 'POST', + data: { + action: 'ajax_regenerate_simulator', + type: type, + nonce: cd_js.nonce + }, + success: function(response) { + if (response.success) { + // Mise à jour du contenu + $container.html(response.data.html); + + // Réinitialisation des événements + if (typeof on_slider_value_change === 'function') { + on_slider_value_change(); + } + } else { + console.error('Erreur lors de la régénération du simulateur:', response.data.message); + } + }, + error: function(xhr, status, error) { + console.error('Erreur AJAX:', error); + $container.removeClass('loading'); + }, + complete: function() { + $container.removeClass('loading'); + } + }); + }); +}); + +function handleCreditTypeClick() { + jQuery('#cred-hypo, #cred-pat').on('click', function(e) { + e.preventDefault(); + // Ajout gestion classe active_btn + jQuery('#cred-hypo, #cred-pat').removeClass('active_btn'); + jQuery(this).addClass('active_btn'); + + const type = jQuery(this).attr('id') === 'cred-hypo' ? 'am' : 'pat'; + const container = jQuery('.home-simu-holder > .fusion-column-wrapper'); + const parentContainer = container.parent(); + + // Sauvegarder la hauteur actuelle + const currentHeight = container.outerHeight(); + + jQuery.ajax({ + url: cd_js.ajaxUrl, + type: 'POST', + data: { + action: 'ajax_regenerate_simulator', + type: type, + nonce: cd_js.nonce + }, + beforeSend: function() { + // Ajouter le spinner + const loadingSpinner = jQuery('
    '); + parentContainer.append(loadingSpinner); + // Définir la hauteur minimale du parent + parentContainer.css('min-height', currentHeight + 'px'); + // Animation de sortie + container.addClass('animate-slide-out-down'); + // Enregistrer le temps de début du spinner + parentContainer.data('spinnerStart', Date.now()); + }, + success: function(response) { + if (response.success) { + // Mise à jour du contenu avec animation + container.html(response.data.html); + + // Séquence d'animations d'entrée + setTimeout(function() { + container.removeClass('animate-slide-out-down').addClass('animate-slide-in-up'); + + // Réinitialisation des événements après l'animation + setTimeout(function() { + if (typeof on_slider_value_change === 'function') { + on_slider_value_change(); + } + + // Réinitialisation des sliders + if (typeof change_capital_slider === 'function') { + const capitalSlider = jQuery('#selected_capital_range'); + if (capitalSlider.length) { + const min = parseInt(capitalSlider.data('min')); + const max = parseInt(capitalSlider.data('max')); + const value = parseInt(capitalSlider.data('value')); + change_capital_slider(min, max, value); + + // Initialisation de la barre orange pour le capital + const capitalOrangeBar = jQuery('.slider-count-wrapper .after_bar'); + if (capitalOrangeBar.length) { + const cssLeftSpan = capitalSlider.find('span').css('left'); + capitalOrangeBar.addClass('active'); + capitalOrangeBar.css('width', cssLeftSpan); + } + } + } + + if (typeof change_month_slider === 'function') { + const monthSlider = jQuery('#selected_month_range'); + if (monthSlider.length) { + const min = parseInt(monthSlider.data('min')); + const max = parseInt(monthSlider.data('max')); + const value = parseInt(monthSlider.data('value')); + change_month_slider(min, max, value); + + // Initialisation de la barre orange pour la durée + const monthOrangeBar = jQuery('.slider-month-wrapper .after_bar'); + if (monthOrangeBar.length) { + const cssLeftSpan = monthSlider.find('span').css('left'); + monthOrangeBar.addClass('active'); + monthOrangeBar.css('width', cssLeftSpan); + } + } + } + + // Réinitialisation des calculs + if (typeof calculate_mensualite === 'function') { + calculate_mensualite(); + } + + // Réinitialisation des événements de formulaire + if (typeof onchange_loan_type === 'function') { + onchange_loan_type('radio'); + } + + // Réinitialiser la hauteur minimale après l'animation + parentContainer.css('min-height', ''); + }, 500); // Attendre la fin de l'animation slideInUp + }, 500); // Attendre la fin de l'animation slideOutDown + } else { + console.error('Erreur lors de la régénération du simulateur:', response.data.message); + container.removeClass('animate-slide-out-down').addClass('animate-slide-in-up'); + parentContainer.css('min-height', ''); + } + }, + error: function(xhr, status, error) { + console.error('Erreur AJAX:', error); + container.removeClass('animate-slide-out-down').addClass('animate-slide-in-up'); + parentContainer.css('min-height', ''); + }, + complete: function() { + // Supprimer le spinner après au moins 800 ms + var spinnerStart = parentContainer.data('spinnerStart') || Date.now(); + var elapsed = Date.now() - spinnerStart; + var minDuration = 800; + var removeSpinner = function() { + parentContainer.find('.cd-loading-spinner').remove(); + }; + if (elapsed < minDuration) { + setTimeout(removeSpinner, minDuration - elapsed); + } else { + removeSpinner(); + } + } + }); + }); +} + +// Appeler la fonction lors du chargement du document +jQuery(document).ready(function() { + handleCreditTypeClick(); +}); + +// Initialisation de la modal de rappel de crédit +/* document.addEventListener('DOMContentLoaded', function() { + var creditReminderBtn = document.querySelector('.credit-reminder-btn'); + var modal = new bootstrap.Modal(document.getElementById('creditReminderModal')); + + console.log('modal', modal); + + if (creditReminderBtn) { + + creditReminderBtn.addEventListener('click', function() { + console.log('bjkbjbnjjnk'); + modal.show(); + }); + } +}); */ + +// Initialisation de la modal iziModal +jQuery("#creditReminderModal").iziModal({ + width: 600, + overlayClose: true, + closeOnEscape: true, + headerColor: '#fe8c1e', // Orange pour l'en-tête + title: 'Vous avez une demande de crédit en cours', + subtitle: '', + padding: 20, + radius: 5, + zindex: 999, + iframe: false, + iframeHeight: 400, + iframeURL: null, + focusInput: false, + group: '', + loop: false, + navigateCaption: true, + navigateArrows: true, + history: false, + restoreDefaultContent: false, + autoOpen: false, + bodyOverflow: false, + fullscreen: false, + openFullscreen: false, + closeOnOverlayClick: true, + overlay: true, + overlayColor: 'rgba(0, 0, 0, 0.4)', + timeout: false, + timeoutProgressbar: false, + onOpening: function(){ + // Callback avant l'ouverture + }, + onOpened: function(){ + // Callback après l'ouverture + // Personnalisation des couleurs après l'ouverture + jQuery('.iziModal-header').css({ + 'background-color': '#fe8c1e', + 'color': '#fff' + }); + jQuery('.iziModal-header.inner-header').css({ + 'background-color': '#fff', + 'color': '#fff', + 'box-shadow': 'none' + }); + jQuery('.iziModal-close').css({ + 'color': '#fff' + }); + jQuery('.iziModal-content').css({ + 'border-top': '3px solid #fe8c1e' + }); + jQuery('.btn-primary').css({ + 'background-color': '#1c3050', + 'border-color': '#fe8c1e' + }); + jQuery('.btn-primary:hover').css({ + 'background-color': '#e67e17', + 'border-color': '#e67e17' + }); + }, + onClosing: function(){ + // Callback avant la fermeture + }, + onClosed: function(){ + // Callback après la fermeture + } +}); + +/* jQuery('#IDjob,#IDcojob').on('change', function() { + let job = jQuery(this).val(), + hascoborrower = jQuery('#hascoborrower').val(), + independent_section = jQuery('.independent_section'), + employee_section = jQuery('.employee_section'), + co_independent_section = jQuery('.co-emprunteur .independent_section'), + co_employee_section = jQuery('.co-emprunteur .employee_section'); + + if(job == 'independent') { + if(hascoborrower == 0) { + independent_section.fadeIn().removeClass('hidden'); + employee_section.fadeOut().addClass('hidden'); + } else { + co_independent_section.fadeIn().removeClass('hidden'); + co_employee_section.fadeOut().addClass('hidden'); + } + } else { + employee_section.fadeIn().removeClass('hidden'); + if(hascoborrower == 0) { + independent_section.fadeIn().removeClass('hidden'); + employee_section.fadeOut().addClass('hidden'); + } else { + co_independent_section.fadeIn().removeClass('hidden'); + co_employee_section.fadeOut().addClass('hidden'); + } + } +}); */ + +/** + * Valide et arrondit la valeur saisie dans le champ selected_months + * en fonction des limites min/max et du step du slider + */ +function validate_months_input() { + var selected_months_range = '#selected_months_range'; + var selected_months = '#selected_months'; + var selected = jQuery('#loan_type').val(), + loan_radio_type = jQuery('.loan_type:checked').length ? jQuery('.loan_type:checked').val() : '', + sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : '', + selected_duree_box = jQuery(selected_months_range).parents('.selected_duree'); + + if (loan_radio_type != '') { + selected = loan_radio_type; + } + + if (sub_loan_radio_type != '') { + if (authorized_value.includes(sub_loan_radio_type)) { + selected = sub_loan_radio_type; + } else if (map_values[sub_loan_radio_type] !== 'undefined') { + selected = map_values[sub_loan_radio_type]; + } + } + + // Récupérer le capital actuel pour calculer le max dynamique + var selected_capital = jQuery('#selected_capital').val(); + var current_value = jQuery(selected_months).val() ? parseInt(jQuery(selected_months).val()) : 0; + + // Calculer les limites dynamiques en fonction du capital et du type de crédit via la fonction centralisée + var results = calculateDynamicLimits(selected, sub_loan_radio_type, selected_capital, current_value); + + // Extraire les limites dynamiques + var duree_min = results[0]; + var duree_max = results[1]; + var loan_type_in_years = ['am', 'amr', 'cied', 'ph','cdp']; + + // Recalculer current_value si nécessaire + if (!current_value || current_value === 0) { + current_value = parseInt(duree_min); + } + + console.log('🔍 VALIDATE_MONTHS_INPUT - Type de crédit:', selected); + console.log('🔍 VALIDATE_MONTHS_INPUT - Capital:', selected_capital); + console.log('🔍 VALIDATE_MONTHS_INPUT - Durée min dynamique:', duree_min); + console.log('🔍 VALIDATE_MONTHS_INPUT - Durée max dynamique:', duree_max); + + // Utiliser la fonction getStepForValue existante + var step = getStepForValue(selected, current_value); + + + // Arrondir à la valeur la plus proche selon le step + var rounded_value = Math.round(current_value / step) * step; + + console.log('🔍 VALIDATE_MONTHS_INPUT - Valeur saisie:', current_value); + console.log('🔍 VALIDATE_MONTHS_INPUT - Step:', step); + console.log('🔍 VALIDATE_MONTHS_INPUT - Valeur arrondie:', rounded_value); + + // Appliquer les limites min/max (SNAP) + if (rounded_value < duree_min) { + console.log('⚠️ SNAP appliqué : valeur trop basse (' + rounded_value + ') → min (' + duree_min + ')'); + rounded_value = duree_min; + } else if (rounded_value > duree_max) { + console.log('⚠️ SNAP appliqué : valeur trop haute (' + rounded_value + ') → max dynamique (' + duree_max + ')'); + rounded_value = duree_max; + } else { + console.log('✅ Valeur dans les limites, pas de snap nécessaire'); + } + + console.log('🎯 VALIDATE_MONTHS_INPUT - Valeur finale:', rounded_value); + + // Mettre à jour le champ et le slider + jQuery(selected_months).val(rounded_value); + jQuery(selected_months_range).slider('value', rounded_value); + + // Mettre à jour l'affichage + var periodicite = loan_type_in_years.includes(selected) ? ' ans' : ' mois'; + jQuery(selected_months_range).find(".slider_duree_box").text(rounded_value + periodicite); + jQuery(selected_duree_box).find(".outside_slider_duree_box").text(rounded_value + periodicite); + // Recalculer la mensualité + calculate_mensualite(); +} + +// Modifier l'événement input existant pour utiliser la nouvelle fonction +/* jQuery(document).on('input', '#selected_months', function(e) { + jQuery('#selected_months').on('keyup', function() { + if(jQuery('#selected_months').val() != '') { + clearTimeout(Timer); + Timer = setTimeout(validate_months_input, 500); // Délai de 0.5s + } + }); +}); */ + +function getStepForValue(loan_type, value) { + let dynamic_step = 1; + + if (loan_type_in_years.includes(loan_type)) { + dynamic_step = 1; // Step de 1 an pour les prêts en années + } else if (loan_type === 'cdp') { + dynamic_step = 1; // Step de 1 mois pour le crédit pont + } else { + if (value <= 48) { + dynamic_step = 6; // Step de 6 mois jusqu'à 48 mois + } else { + dynamic_step = 12; // Step de 12 mois au-delà de 48 mois + } + } + + return dynamic_step; +} + +function change_month_slider(default_min, default_max, default_selected_value) { + var selected_months_range = '#selected_months_range'; + var selected_months = '#selected_months'; + var loan_type_in_years = ['am', 'amr', 'cied', 'ph']; + var sel_duree = jQuery(selected_months).val(), + selected_duree_box = jQuery(selected_months_range).parents('.selected_duree'); + + // Récupérer le type de crédit + var loan_type = jQuery('#loan_type').val(), + loan_radio_type = jQuery('.loan_type:checked').length ? jQuery('.loan_type:checked').val() : '', + sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : ''; + + if (loan_radio_type != '') + loan_type = loan_radio_type; + + if (sub_loan_radio_type != '') { + if (authorized_value.includes(sub_loan_radio_type)) { + loan_type = sub_loan_radio_type; + } else if (map_values[sub_loan_radio_type] !== 'undefined') { + loan_type = map_values[sub_loan_radio_type]; + } + } + + // Récupérer le capital actuel + var selected_capital = jQuery('#selected_capital').val(); + + if (selected_capital == '') + selected_capital = form_sliders[loan_type]['capital_selected']; + + /* console.log('selected_capital', selected_capital); + console.log('loan_type', loan_type); + console.log('sel_duree', sel_duree); + */ + // Calculer la durée maximale en fonction du capital + var results = []; + switch (loan_type) { + case 'pat': + results = calculate_pat(selected_capital, sel_duree); + break; + case 'fin_neuve': + results = calculate_fin_neuve(selected_capital, sel_duree); + break; + case 'fin_occ_m3a': + results = calculate_pao_m_3(selected_capital, sel_duree); + break; + case 'fin_occ_p3a': + results = calculate_pao_p_3(selected_capital, sel_duree); + break; + case 'ph': + results = calculate_ph(selected_capital, sel_duree); + break; + case 'am': + results = calculate_am(selected_capital, sel_duree); + break; + case 'frais_notaire': + results = calculate_frais_notaire(selected_capital, sel_duree); + break; + case 'but_immo': + results = calculate_but_immo(selected_capital, sel_duree); + break; + case 'cdp': + results = calculate_cdp(selected_capital, sel_duree); + break; + case 'amr': + case 'cied': + results = calculate_mono_rate_bt_10_30(sub_loan_radio_type, selected_capital, sel_duree); + break; + case 'mobil_carav': + results = calculate_mobilhome(selected_capital, sel_duree); + break; + case 'regroup_cred': + results = calculate_regroupement_de_credit(selected_capital, sel_duree); + break; + } + + // Utiliser max_duration (index 1) comme limite maximale + var max_duration = results[1]; + var dynamic_max = max_duration; + + // Trouver la durée maximale valide dans les durées du type de prêt + var available_durations = form_sliders[loan_type].durees; + + for (var i = available_durations.length - 1; i >= 0; i--) { + if (available_durations[i] <= max_duration) { + dynamic_max = available_durations[i]; + break; + } + } + + /* console.log('available_durations', results); + + console.log('dynamic_max', dynamic_max); + console.log('duration max', max_duration); + console.log('loan_type', loan_type); + console.log('available_durations array', available_durations); */ + + function getStepForValue(loan_type, value) { + let dynamic_step = 1; + + if (loan_type_in_years.includes(loan_type)) { + dynamic_step = 1; // Step de 1 an pour les prêts en années + } else if (loan_type === 'cdp') { + dynamic_step = 1; // Step de 1 mois pour le crédit pont + } else { + if (value <= 48) { + dynamic_step = 6; // Step de 6 mois jusqu'à 48 mois + } else { + dynamic_step = 12; // Step de 12 mois au-delà de 48 mois + } + } + + return dynamic_step; + } + + // Mettre à jour le slider avec la nouvelle limite maximale + jQuery(selected_months_range).slider({ + min: default_min, + max: dynamic_max, + value: dynamic_max, // Utiliser la valeur maximale comme valeur initiale + step: getStepForValue(loan_type, dynamic_max), + slide: function(event, ui) { + var newStep = getStepForValue(loan_type, ui.value); + + if (newStep !== jQuery(this).slider('option', 'step')) { + jQuery(this).slider('option', 'step', newStep); + } + + var orange_bar = jQuery('.slider_duree_wrapper .after_bar_month'), + elem = jQuery(ui.handle), + left_css = parseInt(elem.css('left'), 10); + + orange_bar.css('width', left_css + 10); + jQuery(selected_months).val(ui.value); + + if (loan_type_in_years.includes(loan_type)) { + jQuery(selected_months_range).find(".slider_duree_box").text(ui.value + ' ans'); + jQuery(selected_duree_box).find(".outside_slider_duree_box").text(ui.value + ' ans'); + } else { + jQuery(selected_months_range).find(".slider_duree_box").text(ui.value + ' mois'); + jQuery(selected_duree_box).find(".outside_slider_duree_box").text(ui.value + ' mois'); + } + }, + stop: function(event, ui) { + var orange_bar = jQuery('.slider_duree_wrapper .after_bar_month'), + elem = jQuery(ui.handle), + left_css = parseInt(elem.css('left'), 10); + + orange_bar.css('width', left_css + 10); + calculate_mensualite(); + + // Mettre à jour l'état des boutons de durée après mouvement du slider + updateDurationButtonsState(); + }, + change: function(event, ui) { + var orange_bar = jQuery('.slider_duree_wrapper .after_bar_month'), + elem = jQuery(ui.handle), + left_css = parseInt(elem.css('left'), 10); + + orange_bar.css('width', left_css + 10); + } + }); + + jQuery(selected_months).val(jQuery(selected_months_range).slider('value')); + + var periodicite = loan_type_in_years.includes(loan_type) ? ' ans' : ' mois'; + var appended_elem = '' + jQuery(selected_months_range).slider('value') + periodicite + ''; + jQuery(selected_duree_box).find(".outside_slider_duree_box").text(jQuery(selected_months_range).slider('value') + periodicite); + + if (!jQuery(selected_months_range).find('.ui-slider-handle .fa-angle-right').length) { + jQuery(selected_months_range).find(".ui-slider-handle").append(''); + } + + if (!jQuery(selected_months_range).find('.slider_duree_box').length) { + jQuery(selected_months_range).find('.ui-slider-handle').append(appended_elem); + } +} + +// Ajout : fonction pour mettre à jour l'unité de durée à côté de #selected_months +function updateSelectedMonthsUnit() { + + + var loan_type = jQuery('#loan_type').val(); + var loan_type_in_years = ['am', 'amr', 'cied', 'ph']; + var unit = loan_type_in_years.includes(loan_type) ? 'Ans' : 'Mois'; + + var $inputGroup = jQuery('#selected_months').parents('.input-group').find('.input-group-append'); + + /* console.log('unit', unit); */ + + $inputGroup.find('.input-group-text').text(unit); + + /* console.log('inputGroup', $inputGroup); */ +} + +// Gestion de l'affichage du champ montant_allocation_familiale basé sur le nombre d'enfants +jQuery(document).ready(function() { + // Fonction pour gérer l'affichage du champ montant_allocation_familiale (emprunteur principal) + function toggleMontantAllocation() { + var nbEnfants = parseInt(jQuery('#IDdependentchildren').val()) || 0; + if (nbEnfants > 0) { + jQuery('#IDmontant_allocation_familiale').closest('.montant_allocation').removeClass('hidden').show(); + } else { + jQuery('#IDmontant_allocation_familiale').closest('.montant_allocation').addClass('hidden').hide(); + } + } + + // Fonction pour gérer l'affichage du champ montant_allocation_familiale (co-emprunteur) + function toggleCoMontantAllocation() { + var nbEnfantsCo = parseInt(jQuery('#IDcodependentchildren').val()) || 0; + if (nbEnfantsCo > 0) { + jQuery('#coIDmontant_allocation_familiale').closest('.montant_allocation').removeClass('hidden').show(); + } else { + jQuery('#coIDmontant_allocation_familiale').closest('.montant_allocation').addClass('hidden').hide(); + } + } + + // Événement sur le changement du nombre d'enfants (emprunteur principal) + jQuery('#IDdependentchildren').on('change', function() { + toggleMontantAllocation(); + }); + + // Événement sur le changement du nombre d'enfants (co-emprunteur) + jQuery('#IDcodependentchildren').on('change', function() { + toggleCoMontantAllocation(); + }); + + // Vérification initiale au chargement de la page + toggleMontantAllocation(); + toggleCoMontantAllocation(); +}); \ No newline at end of file diff --git a/assets/js/cred_js.php b/assets/js/cred_js.php new file mode 100644 index 0000000..7f12150 --- /dev/null +++ b/assets/js/cred_js.php @@ -0,0 +1,42 @@ + Excel', + className: 'btn-export-excel', + title: 'Export Crédits - ' + new Date().toLocaleDateString('fr-FR'), + exportOptions: { + columns: ':not(:last-child)' // Exclure la colonne Actions + } + }, + { + extend: 'csvHtml5', + text: ' CSV', + className: 'btn-export-csv', + title: 'Export Crédits', + exportOptions: { + columns: ':not(:last-child)' // Exclure la colonne Actions + } + } + ], + language: { + "sProcessing": "Traitement en cours...", + "sSearch": "Rechercher:", + "sLengthMenu": "Afficher _MENU_ éléments", + "sInfo": "Affichage de l'élément _START_ à _END_ sur _TOTAL_ éléments", + "sInfoEmpty": "Affichage de l'élément 0 à 0 sur 0 élément", + "sInfoFiltered": "(filtré de _MAX_ éléments au total)", + "sLoadingRecords": "Chargement en cours...", + "sZeroRecords": "Aucun élément à afficher", + "sEmptyTable": "Aucune donnée disponible dans le tableau", + "paginate": { + "sFirst": "Premier", + "sPrevious": "Précédent", + "sNext": "Suivant", + "sLast": "Dernier" + }, + "buttons": { + "excel": "Excel", + "csv": "CSV" + } + }, + columns: [ + { data: 'id', title: 'ID', defaultContent: '' }, + { data: 'type_credit', title: 'Type', defaultContent: '' }, + { data: 'nom', title: 'Nom', defaultContent: '' }, + { data: 'prenom', title: 'Prénom', defaultContent: '' }, + { data: 'adresse', title: 'Adresse', defaultContent: '' }, + { data: 'localite', title: 'Localité', defaultContent: '' }, + { data: 'email', title: 'Email', defaultContent: '' }, + { + data: null, + title: 'Téléphone/GSM', + render: function(data, type, row) { + let phones = []; + if (row.telephone) phones.push(row.telephone); + if (row.gsm) phones.push(row.gsm); + return phones.join('
    '); + } + }, + { data: 'societe_credit', title: 'Société', defaultContent: '' }, + { + data: 'montant', + title: 'Montant', + render: function(data, type, row) { + return formatCurrency(row.montant); + } + }, + { + data: 'date', + title: 'Date', + render: function(data, type, row) { + return formatDate(row.date); + } + }, + { data: 'date_signature', title: 'Date Signature', defaultContent: '' }, + { data: 'numero_dossier', title: 'N° Dossier', defaultContent: '' }, + { data: 'code', title: 'Code', defaultContent: '' }, + { + data: null, + title: 'Statut', + orderable: false, + searchable: false, + render: function(data, type, row) { + const map = { + '-1': { label: 'Refusé', cls: 'status-refused' }, + '0': { label: 'À valider', cls: 'status-pending' }, + '1': { label: 'Validé non signé', cls: 'status-accepted-unsigned' }, + '2': { label: 'Validé classé', cls: 'status-accepted-filed' } + }; + const key = String(row.status ?? '0'); + const conf = map[key] || map['0']; + return '' + conf.label + ''; + } + }, + { + data: null, + title: 'Actions', + orderable: false, + searchable: false, + render: function(data, type, row) { + // Récupérer le statut actuel + const currentStatus = parseInt(row.status ?? '0'); + + return ` +
    + + + + +
    + `; + } + } + ] + }); + } + + // Charger les données des crédits + function loadCredits(options = {}) { + const silent = !!options.silent; + // Vérifier que creditManagerAjax est défini + if (typeof creditManagerAjax === 'undefined') { + console.error('ERROR: creditManagerAjax is not defined!'); + showNotification('Erreur de configuration JavaScript', 'error'); + return; + } + + // Vérifier que le nonce est défini + if (!creditManagerAjax.nonce) { + console.error('ERROR: Nonce is not defined in creditManagerAjax!'); + console.log('creditManagerAjax object:', creditManagerAjax); + showNotification('Erreur: Nonce manquant', 'error'); + return; + } + + // Afficher une notification de chargement (si non silencieux) + if (!silent) { + showNotification('Chargement des crédits...', 'saving'); + } + + // Préparer les données avec les filtres + let ajaxData = { + action: 'credit_manager_list', + nonce: creditManagerAjax.nonce + }; + + // Ajouter les filtres s'ils existent + Object.assign(ajaxData, currentFilters); + + // Debug: Afficher les données envoyées + console.log('=== AJAX Request ==='); + console.log('URL:', creditManagerAjax.ajaxurl); + console.log('Nonce:', creditManagerAjax.nonce); + console.log('Filters:', currentFilters); + console.log('Ajax Data:', ajaxData); + + $.ajax({ + url: creditManagerAjax.ajaxurl, + type: 'POST', + data: ajaxData, + success: function(response) { + console.log('=== AJAX Response ==='); + console.log('Response:', response); + + if (response.success) { + console.log('Success! Credits count:', response.data.credits ? response.data.credits.length : 0); + console.log('Status counts:', response.data.status_counts); + + // Détruire la table existante si elle existe + if (creditsTable) { + creditsTable.destroy(); + } + + // Réinitialiser le tableau HTML + $('#credits-table tbody').empty(); + + // Réinitialiser DataTables + initDataTable(); + + // Ajouter les données + if (response.data.credits && response.data.credits.length > 0) { + // Assainir les lignes pour correspondre aux colonnes attendues + const requiredFields = ['id','type_credit','nom','prenom','adresse','localite','email','telephone','gsm','societe_credit','montant','date','date_signature','numero_dossier','code']; + const sanitized = response.data.credits.map(function(row, idx){ + if (typeof row !== 'object' || row === null) { + console.warn('Row is not an object at index', idx); + row = {}; + } + requiredFields.forEach(function(k){ + if (typeof row[k] === 'undefined') { + row[k] = (k === 'montant') ? 0 : ''; + } + }); + return row; + }); + creditsTable.clear(); + creditsTable.rows.add(sanitized); + creditsTable.draw(); + if (!silent) { + showNotification(response.data.credits.length + ' crédit(s) chargé(s)', 'success'); + } + } else { + if (!silent) { + showNotification('Aucun crédit trouvé', 'info'); + } + } + + // Mettre à jour les compteurs avec les données du serveur + if (response.data.status_counts) { + updateStatusCountsFromData(response.data.status_counts, response.data.total_all); + } + } else { + console.error('AJAX Error:', response.data); + showNotification('Erreur: ' + response.data, 'error'); + } + }, + error: function(xhr, status, error) { + console.error('=== AJAX Connection Error ==='); + console.error('Status:', status); + console.error('Error:', error); + console.error('Response:', xhr.responseText); + showNotification('Erreur de connexion: ' + error, 'error'); + } + }); + } + + // Formater la devise + function formatCurrency(amount) { + return new Intl.NumberFormat('fr-FR', { + style: 'currency', + currency: 'EUR' + }).format(amount || 0); + } + + // Formater la date + function formatDate(dateString) { + if (!dateString) return ''; + return new Date(dateString).toLocaleDateString('fr-FR'); + } + + /** + * Affiche une notification moderne (style toast) + * @param {string} message - Le message à afficher + * @param {string} type - Le type de notification: 'success', 'saving', 'error', 'info' + */ + function showNotification(message, type = 'success') { + let indicator = $('.auto-save-indicator'); + + // Créer l'indicateur s'il n'existe pas + if (indicator.length === 0) { + indicator = $('
    '); + $('body').append(indicator); + } + + // Mapper le type 'info' vers 'saving' pour une meilleure visibilité + if (type === 'info') { + type = 'saving'; + } + + // Retirer toutes les classes de type et ajouter la nouvelle + indicator.removeClass('show saving error').addClass('show ' + type); + indicator.text(message); + + // Masquer après 3 secondes (5 secondes pour les erreurs) + const duration = type === 'error' ? 5000 : 3000; + setTimeout(() => { + indicator.removeClass('show'); + }, duration); + } + + // Alias pour compatibilité avec l'ancien code + function showMessage(message, type) { + showNotification(message, type); + } + + // Ouvrir le modal + window.openCreditModal = function(creditId = null) { + currentCreditId = creditId; + + if (creditId) { + loadCreditData(creditId); + } else { + $('#credit-form')[0].reset(); + $('.credit-modal-header h2').text('Nouveau crédit'); + // Réinitialiser Select2 + $('#credit-type').val([]).trigger('change'); + } + + $('.credit-modal').addClass('show').show(); + // Réinitialiser Select2 après ouverture de la modal + setTimeout(function() { + if (typeof $.fn.select2 === 'function') { + // Détruire l'instance existante si elle existe + if ($('#credit-type').hasClass('select2-hidden-accessible')) { + $('#credit-type').select2('destroy'); + } + initSelect2(); + } + }, 100); + }; + + // Fermer le modal + window.closeCreditModal = function() { + $('.credit-modal').addClass('closing'); + + setTimeout(function() { + $('.credit-modal').removeClass('show closing').hide(); + currentCreditId = null; + }, 300); + }; + + // Charger les données d'un crédit + function loadCreditData(creditId) { + $.ajax({ + url: creditManagerAjax.ajaxurl, + type: 'POST', + data: { + action: 'credit_manager_get', + nonce: creditManagerAjax.nonce, + credit_id: creditId + }, + success: function(response) { + if (response.success) { + const credit = response.data.credit; + $('.credit-modal-header h2').text('Modifier le crédit'); + + // Remplir le formulaire + if (credit.type_credit) { + const typeCreditArray = typeof credit.type_credit === 'string' + ? credit.type_credit.split(',') + : credit.type_credit; + $('#credit-type').val(typeCreditArray); + } else { + $('#credit-type').val([]); + } + $('#credit-nom').val(credit.nom || ''); + $('#credit-prenom').val(credit.prenom || ''); + $('#credit-adresse').val(credit.adresse || ''); + $('#credit-localite').val(credit.localite || ''); + $('#credit-email').val(credit.email || ''); + $('#credit-telephone').val(credit.telephone || ''); + $('#credit-gsm').val(credit.gsm || ''); + $('#credit-type-habitation').val(credit.type_habitation || ''); + $('#credit-societe').val(credit.societe_credit || ''); + $('#credit-montant').val(credit.montant || ''); + $('#credit-date').val(credit.date || ''); + $('#credit-signature').val(credit.date_signature || ''); + $('#credit-numero-dossier').val(credit.numero_dossier || ''); + $('#credit-code').val(credit.code || ''); + $('#credit-remarques').val(credit.remarques || ''); + + showNotification('Crédit chargé avec succès', 'success'); + } else { + showNotification('✕ Erreur lors du chargement: ' + response.data, 'error'); + } + }, + error: function(xhr, status, error) { + showNotification('✕ Erreur de connexion lors du chargement: ' + error, 'error'); + } + }); + } + + // Sauvegarder le crédit + window.saveCredit = function() { + // Afficher la notification de sauvegarde + showNotification('Sauvegarde en cours...', 'saving'); + + const formData = { + action: currentCreditId ? 'credit_manager_update' : 'credit_manager_create', + nonce: creditManagerAjax.nonce, + type_credit: $('#credit-type').val(), + nom: $('#credit-nom').val(), + prenom: $('#credit-prenom').val(), + adresse: $('#credit-adresse').val(), + localite: $('#credit-localite').val(), + email: $('#credit-email').val(), + telephone: $('#credit-telephone').val(), + gsm: $('#credit-gsm').val(), + type_habitation: $('#credit-type-habitation').val(), + societe_credit: $('#credit-societe').val(), + montant: $('#credit-montant').val(), + date: $('#credit-date').val(), + signature: $('#credit-signature').val(), + numero_dossier: $('#credit-numero-dossier').val(), + code: $('#credit-code').val(), + remarques: $('#credit-remarques').val() + }; + + if (currentCreditId) { + formData.credit_id = currentCreditId; + } + + $.ajax({ + url: creditManagerAjax.ajaxurl, + type: 'POST', + data: formData, + success: function(response) { + if (response.success) { + showNotification('✓ ' + response.data.message, 'success'); + closeCreditModal(); + loadCredits({ silent: true }); + } else { + showNotification('✕ Erreur: ' + response.data, 'error'); + } + }, + error: function(xhr, status, error) { + showNotification('✕ Erreur de connexion: ' + error, 'error'); + } + }); + }; + + // Supprimer un crédit + window.deleteCredit = function(creditId) { + // Confirmation plus détaillée + const confirmMessage = '⚠️ ATTENTION ⚠️\n\n' + + 'Vous êtes sur le point de supprimer définitivement ce crédit.\n\n' + + 'Cette action est IRRÉVERSIBLE et supprimera toutes les données associées.\n\n' + + 'Êtes-vous absolument certain de vouloir continuer ?'; + + if (!confirm(confirmMessage)) { + return; + } + + // Double confirmation pour plus de sécurité + if (!confirm('Dernière chance !\n\nConfirmez-vous la suppression définitive de ce crédit ?')) { + return; + } + + // Afficher un message de chargement + showNotification('Suppression en cours...', 'saving'); + + $.ajax({ + url: creditManagerAjax.ajaxurl, + type: 'POST', + data: { + action: 'credit_manager_delete', + nonce: creditManagerAjax.nonce, + credit_id: creditId + }, + success: function(response) { + if (response.success) { + showNotification('✓ ' + response.data.message, 'success'); + loadCredits({ silent: true }); + } else { + showNotification('✕ Erreur: ' + response.data, 'error'); + } + }, + error: function(xhr, status, error) { + showNotification('✕ Erreur de connexion lors de la suppression: ' + error, 'error'); + } + }); + }; + + // Modifier un crédit + window.editCredit = function(creditId) { + openCreditModal(creditId); + }; + + // Mettre à jour le statut d'un crédit + window.updateCreditStatus = function(creditId, status) { + let statusLabel = ''; + let confirmMessage = ''; + + switch(status) { + case 'accepte_non_signe': + statusLabel = 'Accepté non signé'; + confirmMessage = 'Êtes-vous sûr de vouloir marquer ce crédit comme "Accepté non signé" ?'; + break; + case 'accepte_classe': + statusLabel = 'Accepté classé'; + confirmMessage = 'Êtes-vous sûr de vouloir marquer ce crédit comme "Accepté classé" ?'; + break; + case 'refuse': + statusLabel = 'Refusé'; + confirmMessage = 'Êtes-vous sûr de vouloir marquer ce crédit comme "Refusé" ?'; + break; + } + + if (!confirm(confirmMessage)) { + return; + } + + showNotification('Mise à jour du statut en cours...', 'saving'); + + $.ajax({ + url: creditManagerAjax.ajaxurl, + type: 'POST', + data: { + action: 'credit_manager_update_status', + nonce: creditManagerAjax.nonce, + credit_id: creditId, + status: status + }, + success: function(response) { + if (response.success) { + showNotification('✓ Statut mis à jour : ' + statusLabel, 'success'); + loadCredits({ silent: true }); + } else { + showNotification('✕ Erreur: ' + response.data, 'error'); + } + }, + error: function(xhr, status, error) { + showNotification('✕ Erreur de connexion lors de la mise à jour: ' + error, 'error'); + } + }); + }; + + + // Fermer le modal en cliquant à l'extérieur + $(document).on('click', '.credit-modal', function(e) { + if (e.target === this) { + closeCreditModal(); + } + }); + + // Toggle des filtres + $('#toggle-filters').on('click', function() { + $('#credit-filters-form').slideToggle(300); + $(this).find('.dashicons').toggleClass('dashicons-arrow-down-alt2 dashicons-arrow-up-alt2'); + }); + + // Soumission du formulaire de filtres + $('#credit-filters-form').on('submit', function(e) { + e.preventDefault(); + + // Récupérer les valeurs du formulaire + currentFilters = { + societe_credit: $('#filter-societe').val(), + code_postal: $('#filter-code-postal').val(), + status: $('#filter-status').val(), + type_credit: $('#filter-type').val(), + credit_code_select: $('#filter-credit-code').val(), + montant_min: $('#filter-montant-min').val(), + montant_max: $('#filter-montant-max').val(), + date_signature_debut: $('#filter-date-debut').val(), + date_signature_fin: $('#filter-date-fin').val() + }; + + // Compter le nombre de filtres actifs + let activeFiltersCount = 0; + Object.keys(currentFilters).forEach(key => { + if (currentFilters[key] !== '' && currentFilters[key] !== null) { + activeFiltersCount++; + } + }); + + if (activeFiltersCount > 0) { + showNotification('Application de ' + activeFiltersCount + ' filtre(s)...', 'saving'); + } + + // Recharger les données avec les filtres + loadCredits(); + }); + + // Réinitialiser les filtres + $('#reset-filters').on('click', function() { + $('#credit-filters-form')[0].reset(); + currentFilters = {}; + showNotification('Filtres réinitialisés', 'success'); + loadCredits(); + }); + + // Fonction pour mettre à jour les compteurs depuis les données du serveur + function updateStatusCountsFromData(statusCounts, totalAll) { + // Mettre à jour les affichages avec les compteurs reçus du serveur + $('[data-count-status="0"]').text('(' + (statusCounts['0'] || 0) + ')'); + $('[data-count-status="1"]').text('(' + (statusCounts['1'] || 0) + ')'); + $('[data-count-status="2"]').text('(' + (statusCounts['2'] || 0) + ')'); + $('[data-count-status="-1"]').text('(' + (statusCounts['-1'] || 0) + ')'); + $('#total-count').text('(' + (totalAll || 0) + ')'); + + console.log('Status counts updated from server:', statusCounts, 'Total:', totalAll); + } + + // Gestionnaire pour les boutons de filtre rapide par statut + $('.status-filter-btn').on('click', function() { + const status = $(this).data('status'); + + // Retirer la classe active de tous les boutons + $('.status-filter-btn').removeClass('active'); + + // Ajouter la classe active au bouton cliqué + $(this).addClass('active'); + + // Réinitialiser les autres filtres du formulaire + $('#credit-filters-form')[0].reset(); + + // Appliquer le filtre de statut + if (status === '') { + // Bouton "Tous" - réinitialiser les filtres + currentFilters = {}; + showNotification('Affichage de tous les crédits', 'success'); + } else { + // Filtre par statut spécifique + currentFilters = { + status: status + }; + + const statusLabels = { + '0': 'À valider', + '1': 'Validé non signé', + '2': 'Validé classé', + '-1': 'Refusé' + }; + + showNotification('Filtre : ' + statusLabels[status], 'saving'); + } + + // Recharger les crédits + loadCredits(); + }); + + // Mailchimp - tester la connexion (page admin Mailchimp) + $('#cred-mailchimp-test').on('click', function(e) { + e.preventDefault(); + var $out = $('#cred-mailchimp-test-result'); + if ($out.length) { + $out.text('Test en cours…'); + } else { + showNotification('Test de connexion en cours…', 'saving'); + } + $.post(creditManagerAjax.ajaxurl, { + action: 'cred_mailchimp_ping', + nonce: creditManagerAjax.mailchimpPingNonce || '' + }).done(function(resp){ + if ($out.length) { + $out.text(resp && resp.success ? 'Connexion OK' : ('Échec: ' + ((resp && resp.data && resp.data.message) ? resp.data.message : 'Error'))); + } else { + if (resp && resp.success) { + showNotification('Connexion Mailchimp OK', 'success'); + } else { + showNotification('Échec: ' + ((resp && resp.data && resp.data.message) ? resp.data.message : 'Error'), 'error'); + } + } + }).fail(function(xhr){ + var msg = (xhr && xhr.responseJSON && xhr.responseJSON.data && xhr.responseJSON.data.message) ? xhr.responseJSON.data.message : xhr.statusText; + if ($out.length) { + $out.text('Échec: ' + msg); + } else { + showNotification('Échec: ' + msg, 'error'); + } + }); + }); + + // Sendy - tester la connexion (page admin Sendy) + $('#cred-sendy-test').on('click', function(e) { + e.preventDefault(); + var $out = $('#cred-sendy-test-result'); + if ($out.length) { + $out.text('Test en cours…'); + } else { + showNotification('Test de connexion en cours…', 'saving'); + } + $.post(creditManagerAjax.ajaxurl, { + action: 'cred_sendy_ping', + nonce: creditManagerAjax.sendyPingNonce || '' + }).done(function(resp){ + if ($out.length) { + $out.text(resp && resp.success ? 'Connexion OK' : ('Échec: ' + ((resp && resp.data && resp.data.message) ? resp.data.message : 'Error'))); + } else { + if (resp && resp.success) { + showNotification('Connexion Sendy OK', 'success'); + } else { + showNotification('Échec: ' + ((resp && resp.data && resp.data.message) ? resp.data.message : 'Error'), 'error'); + } + } + }).fail(function(xhr){ + var msg = (xhr && xhr.responseJSON && xhr.responseJSON.data && xhr.responseJSON.data.message) ? xhr.responseJSON.data.message : xhr.statusText; + if ($out.length) { + $out.text('Échec: ' + msg); + } else { + showNotification('Échec: ' + msg, 'error'); + } + }); + }); + + // Initialiser uniquement sur la page Crédit (évite le chargement sur Mailchimp/Sendy) + if (jQuery('#credits-table').length > 0) { + loadCredits(); + } +}); diff --git a/assets/js/exp/README.md b/assets/js/exp/README.md new file mode 100644 index 0000000..1312b26 --- /dev/null +++ b/assets/js/exp/README.md @@ -0,0 +1,27 @@ +# README – Version modulaire du simulateur de crédit + +Ce dossier contient une version refactorisée et modulaire du simulateur, avec séparation claire des responsabilités. + +## Fichiers et logique + +- **calculs.js** : + Contient toutes les fonctions de calcul de crédit (calculate_pat, calculate_am, etc.). Chaque fonction prend en entrée le capital, la durée, et retourne les paramètres du crédit selon le type. + +- **utils.js** : + Fonctions utilitaires réutilisables (number_format, getStepForValue, etc.). + +- **ui.js** : + Gère l'affichage, les sliders, la synchronisation des champs, et les interactions utilisateur (change_capital_slider, change_month_slider, change_duree, update_capital_input, etc.). + +- **main.js** : + Point d'entrée du simulateur. Importe les modules, initialise l'application, gère les événements, et orchestre la logique entre calculs, UI et utilitaires. + +## Logique générale + +- La logique métier (calculs) est totalement séparée de la gestion de l'UI. +- Les utilitaires sont accessibles à tous les modules. +- Le fichier main.js centralise l'initialisation et la gestion des interactions. + +--- + +Pour toute évolution, ajoutez vos nouveaux modules dans ce dossier et documentez-les ici. \ No newline at end of file diff --git a/assets/js/exp/calculs.js b/assets/js/exp/calculs.js new file mode 100644 index 0000000..3fb2ec7 --- /dev/null +++ b/assets/js/exp/calculs.js @@ -0,0 +1,482 @@ +// Module des fonctions de calcul de crédit + +// On suppose que cd_js et map_values sont passés en paramètre ou importés dans main.js + +export function calculate_pat(cd_js, selected_capital, selected_duration = '') { + let annual_rate, min_duration, max_duration, duree_in_range = true, display_observation_pat = false, + add_message = ''; + min_duration = 24; + if (1500 <= parseInt(selected_capital) && parseInt(selected_capital) <= 2500) { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers._1500_a_2500; + max_duration = 24; + } else if ((2500 < parseInt(selected_capital) && parseInt(selected_capital) <= 3700)) { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers._2501_a_3700; + max_duration = 30; + } else if ((3700 < parseInt(selected_capital) && parseInt(selected_capital) <= 5000)) { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers._3701_a_5000; + max_duration = 30; + } else if ((5000 < parseInt(selected_capital) && parseInt(selected_capital) <= 5600)) { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers._5001_a_5600; + max_duration = 36; + } else if ((5600 < parseInt(selected_capital) && parseInt(selected_capital) <= 7500)) { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers._5601_a_7500; + max_duration = 42; + } else if ((7500 < parseInt(selected_capital) && parseInt(selected_capital) <= 10000)) { + max_duration = 48; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) { + } else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration == 48) { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers._7501_a_10000_48_mois; + } else { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers._7501_a_10000_24_a_42_mois; + } + } else if ((10000 < parseInt(selected_capital) && parseInt(selected_capital) <= 15000)) { + if (selected_duration < 48) { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers._10001_a_15000_24_a_42_mois; + } else { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers._10001_a_15000_48_a_60_mois; + } + max_duration = 60; + } else if ((15000 < parseInt(selected_capital) && parseInt(selected_capital) <= 20000)) { + if (24 <= parseInt(selected_duration) && parseInt(selected_duration) <= 42) { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers.a_partir_de_15001_24_a_42_mois; + } else { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers.a_partir_de_15001_48_a_84_mois; + } + max_duration = 84; + } else if((20000 < parseInt(selected_capital) && parseInt(selected_capital) <= 75001)) { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers.a_partir_de_20001_a_75000; + max_duration = 120; + } else if((75001 <= parseInt(selected_capital))) { + annual_rate = cd_js.groups.pret_personnel__tous_motifs__achats_divers.a_partir_de_75000; + display_observation_pat = true; + max_duration = 240; + selected_duration = 240; + } + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) { + } else { + duree_in_range = false; + selected_duration = max_duration; + } + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message]; +} + +export function calculate_ph(cd_js, selected_capital, selected_duration) { + var annual_rate, min_duration, max_duration; + var duree_in_range = true; + var add_message = ''; + min_duration = 5; + max_duration = 30; + annual_rate = cd_js.groups.credit_hypothecaire_social.de_10_a_30_ans; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + selected_duration = selected_duration * 12; + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message]; +} + +export function calculate_am(cd_js, selected_capital, selected_duration) { + var annual_rate, min_duration, max_duration; + var duree_in_range = true; + var add_message = ''; + for (var i = 10; i <= 30; i++) { + if (parseInt(selected_duration) == i) { + annual_rate = cd_js.groups.credit_hypothecaire_classique['des_' + i + '_ans']; + } + } + min_duration = 10; + max_duration = 30; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + selected_duration = selected_duration * 12; + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message]; +} + +export function calculate_mono_rate_bt_10_30(cd_js, map_values, selected_loan_type, selected_capital, selected_duration) { + var annual_rate, min_duration, max_duration, add_message; + var duree_in_range = true; + min_duration = 10; + max_duration = 30; + function findRate(type) { + if (cd_js.groups[type] && cd_js.groups[type].de_10_a_30_ans) { + return cd_js.groups[type].de_10_a_30_ans; + } + return null; + } + var possible_types = [ + selected_loan_type, + map_values[selected_loan_type], + selected_loan_type.toLowerCase(), + selected_loan_type.replace(/_/g, ''), + selected_loan_type.replace(/^credit_/, '') + ]; + possible_types = possible_types.filter(type => type); + for (var type of possible_types) { + var rate = findRate(type); + if (rate !== null) { + annual_rate = rate; + break; + } + } + if (annual_rate === undefined) { + return [min_duration, max_duration, selected_duration * 12, false, 0, 'Type de crédit non disponible']; + } + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) { + } else { + duree_in_range = false; + selected_duration = max_duration; + } + selected_duration = selected_duration * 12; + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message]; +} + +export function calculate_fin_neuve(cd_js, selected_capital, selected_duration) { + var annual_rate, min_duration, max_duration, add_message; + var duree_in_range = true; + min_duration = 24; + if (2500 == parseInt(selected_capital)) { + annual_rate = cd_js.groups.financement_vehicule_neuf._2500_24_mois; + max_duration = 24; + } else if ((2500 < parseInt(selected_capital) && parseInt(selected_capital) <= 3700)) { + annual_rate = cd_js.groups.financement_vehicule_neuf._2501_a_3700_24_a_30_mois; + max_duration = 30; + } else if ((3700 < parseInt(selected_capital) && parseInt(selected_capital) <= 5600)) { + annual_rate = cd_js.groups.financement_vehicule_neuf._3701_a_5600_24_a_36_mois; + max_duration = 36; + } else if ((5600 < parseInt(selected_capital) && parseInt(selected_capital) <= 7500)) { + annual_rate = cd_js.groups.financement_vehicule_neuf._5601_a_7500_24_a_42_mois; + max_duration = 42; + } else if ((7500 < parseInt(selected_capital) && parseInt(selected_capital) <= 10000)) { + annual_rate = cd_js.groups.financement_vehicule_neuf._7501_a_10000_24_a_48_mois; + max_duration = 48; + } else if ((10000 < parseInt(selected_capital) && parseInt(selected_capital) <= 15000)) { + annual_rate = cd_js.groups.financement_vehicule_neuf.a_partir_de_10001_24_a_60_mois; + max_duration = 60; + } else if ((15000 < parseInt(selected_capital) && parseInt(selected_capital) <= 100000)) { + max_duration = 84; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration < 72) { + annual_rate = cd_js.groups.financement_vehicule_neuf.a_partir_de_15001_24_a_60_mois; + } else { + annual_rate = cd_js.groups.financement_vehicule_neuf.a_partir_de_15001_72_a_84_mois; + } + } + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message]; +} + +export function calculate_pao_m_3(cd_js, selected_capital, selected_duration) { + var annual_rate, min_duration, max_duration; + var duree_in_range = true; + var add_message = ''; + min_duration = 24; + if (2500 == parseInt(selected_capital)) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_moins_de_3_ans._2500_24_mois; + max_duration = 24; + } else if ((2500 < parseInt(selected_capital) && parseInt(selected_capital) <= 3700)) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_moins_de_3_ans._2501_a_3700_24_a_30_mois; + max_duration = 30; + } else if ((3700 < parseInt(selected_capital) && parseInt(selected_capital) <= 5600)) { + annual_rate = cd_js.groups.financement_vehicule_neuf._3701_a_5600_24_a_36_mois; + max_duration = 36; + } else if ((5600 < parseInt(selected_capital) && parseInt(selected_capital) <= 7500)) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_moins_de_3_ans._5601_a_7500_24_a_42_mois; + max_duration = 42; + } else if ((7500 < parseInt(selected_capital) && parseInt(selected_capital) <= 10000)) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_moins_de_3_ans._7501_a_10000_24_a_48_mois; + max_duration = 48; + } else if ((10000 < parseInt(selected_capital) && parseInt(selected_capital) <= 15000)) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_moins_de_3_ans.a_partir_de_10001_24_a_60_mois; + max_duration = 60; + } else if ((15000 < parseInt(selected_capital) && parseInt(selected_capital) <= 100000)) { + max_duration = 84; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration < 60) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_moins_de_3_ans.a_partir_de_15001_24_a_60_mois; + } else { + annual_rate = cd_js.groups.financement_vehicule_doccasion_moins_de_3_ans.a_partir_de_15001_72_a_84_mois; + } + } + if (!(min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) { + duree_in_range = false; + selected_duration = max_duration; + } + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message]; +} + +export function calculate_pao_p_3(cd_js, selected_capital, selected_duration) { + var annual_rate, min_duration, max_duration; + var duree_in_range = true; + var add_message = ''; + min_duration = 24; + if (parseInt(selected_capital) <= 2500) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._2500_24_mois; + max_duration = 24; + } else if ((2500 < parseInt(selected_capital) && parseInt(selected_capital) <= 3700)) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._2501_a_3700_24_a_30_mois; + max_duration = 30; + } else if ((3700 < parseInt(selected_capital) && parseInt(selected_capital) <= 5000)) { + max_duration = 36; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration == 36) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._3701_a_5000_36_mois; + } else { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._3701_a_5000_24_a_30_mois; + } + } else if ((5000 < parseInt(selected_capital) && parseInt(selected_capital) <= 5600)) { + max_duration = 36; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration == 36) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._5001_a_5600_36_mois; + } else { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._5001_a_5600_24_a_30_mois; + } + } else if ((5600 < parseInt(selected_capital) && parseInt(selected_capital) <= 7500)) { + max_duration = 42; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration == 36) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._5601_a_7500_36_mois; + } else if (selected_duration == 42) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._5601_a_7500_42_mois; + } else { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._5601_a_7500_24_a_30_mois; + } + } else if ((7500 < parseInt(selected_capital) && parseInt(selected_capital) <= 10000)) { + max_duration = 48; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration < 36) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._7501_a_10000_24_a_30_mois; + } else if (selected_duration < 42) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._7501_a_10000_36_mois; + } else { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans._7501_a_10000_42_a_48_mois; + } + } else if ((10000 < parseInt(selected_capital) && parseInt(selected_capital) <= 100000)) { + max_duration = 60; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration < 36) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans.a_partir_de_10001_24_a_30_mois; + } else if (selected_duration < 42) { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans.a_partir_de_10001_36_mois; + } else { + annual_rate = cd_js.groups.financement_vehicule_doccasion_plus_de_3_ans.a_partir_de_10001_42_a_48_mois; + } + } + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message] +} + +export function calculate_mobilhome(cd_js, selected_capital, selected_duration) { + var annual_rate, min_duration, max_duration; + var duree_in_range = true; + var add_message = ''; + min_duration = 24; + if(selected_capital <= 10000){ + annual_rate = cd_js.groups.financement_mobilhome_et_caravane_de_moins_de_3_ans.max_10000; + max_duration = 48; + } else if(selected_capital > 10000 && selected_capital <= 15000){ + annual_rate = cd_js.groups.financement_mobilhome_et_caravane_de_moins_de_3_ans.de_10001_a_15000; + max_duration = 60; + } else if(selected_capital > 15000 && selected_capital <= 37000){ + annual_rate = cd_js.groups.financement_mobilhome_et_caravane_de_moins_de_3_ans.de_15001_a_37000; + max_duration = 120; + } else if(selected_capital > 37000 && selected_capital <= 100000){ + annual_rate = cd_js.groups.financement_mobilhome_et_caravane_de_moins_de_3_ans.de_37001_a_100000; + max_duration = 144; + } + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message]; +} + +export function calculate_regroupement_de_credit(cd_js, selected_capital, selected_duration) { + var annual_rate, min_duration, max_duration; + var duree_in_range = true; + var add_message = ''; + min_duration = 24; + if(selected_capital >= 5000 && selected_capital <= 5600){ + annual_rate = cd_js.groups.regroupement_de_credit__rachats_de_credits.de_5000_a_5600; + max_duration = 36; + } else if(selected_capital > 5600 && selected_capital <= 7500){ + annual_rate = cd_js.groups.regroupement_de_credit__rachats_de_credits.de_5601_a_7500; + max_duration = 42; + } else if(selected_capital > 7500 && selected_capital <= 10000){ + annual_rate = cd_js.groups.regroupement_de_credit__rachats_de_credits.de_7501_a_10000; + max_duration = 48; + } else if(selected_capital > 10000 && selected_capital <= 15000){ + annual_rate = cd_js.groups.regroupement_de_credit__rachats_de_credits.de_10001_a_15000; + max_duration = 60; + } else if(selected_capital > 15000 && selected_capital <= 20000){ + annual_rate = cd_js.groups.regroupement_de_credit__rachats_de_credits.de_15001_a_20000; + max_duration = 84; + } else if(selected_capital > 20000 && selected_capital <= 60000){ + annual_rate = cd_js.groups.regroupement_de_credit__rachats_de_credits.de_20001_a_60000; + max_duration = 120; + } else if(selected_capital > 60000 && selected_capital <= 75000){ + annual_rate = cd_js.groups.regroupement_de_credit__rachats_de_credits.de_60001_a_75000; + max_duration = 120; + } else if(selected_capital > 75000 && selected_capital <= 100000){ + annual_rate = cd_js.groups.regroupement_de_credit__rachats_de_credits.de_75001_a_100000; + max_duration = 144; + } + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message]; +} + +export function calculate_frais_notaire(cd_js, selected_capital, selected_duration) { + var annual_rate, min_duration, max_duration; + var duree_in_range = true; + var add_message = ''; + min_duration = 24; + if ((2500 < parseInt(selected_capital) && parseInt(selected_capital) <= 15000)) { + annual_rate = cd_js.groups.financement_frais_de_notaire.de_2500_a_15000_24_a_60_mois; + max_duration = 60; + } else if ((15000 < parseInt(selected_capital) && parseInt(selected_capital) <= 40000)) { + annual_rate = cd_js.groups.financement_frais_de_notaire.de_15001_a_40000_24_a_120_mois; + max_duration = 120; + } + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message]; +} + +export function calculate_but_immo(cd_js, selected_capital, selected_duration) { + var annual_rate, min_duration, max_duration; + var duree_in_range = true; + var add_message = ''; + min_duration = 24; + if (2500 == parseInt(selected_capital)) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._2500_24_mois; + max_duration = 24; + } else if ((2500 < parseInt(selected_capital) && parseInt(selected_capital) <= 3700)) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._2501_a_3700_24_a_30_mois; + max_duration = 30; + } else if ((3700 < parseInt(selected_capital) && parseInt(selected_capital) <= 5600)) { + max_duration = 36; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration == 36) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._3701_a_5600_36_mois; + } else { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._3701_a_5600_24_a_30_mois; + } + } else if ((5600 < parseInt(selected_capital) && parseInt(selected_capital) <= 7500)) { + max_duration = 42; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration == 42) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._5601_a_7500_42_mois; + } else if (selected_duration == 36) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._3701_a_5600_36_mois; + } else { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._5601_a_7500_24_a_30_mois; + } + } else if ((7500 < parseInt(selected_capital) && parseInt(selected_capital) <= 10000)) { + max_duration = 48; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration < 36) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._7501_a_10000_24_a_30_mois; + } else if (selected_duration < 42) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._7501_a_10000_36_mois; + } else { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._7501_a_10000_42_a_48_mois; + } + } else if ((10000 < parseInt(selected_capital) && parseInt(selected_capital) <= 15000)) { + max_duration = 60; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration < 36) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._10001_a_15000_24_a_30_mois; + } else if (selected_duration < 42) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._10001_a_15000_36_mois; + } else { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._10001_a_15000_42_a_60_mois; + } + } else if ((15000 < parseInt(selected_capital) && parseInt(selected_capital) <= 20000)) { + max_duration = 84; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration < 36) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie.a_partir_de_15001_24_a_30_mois; + } else if (selected_duration < 42) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._a_partir_de_15001_36_mois; + } else if (selected_duration < 72) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie._a_partir_de_15001_42_a_60_mois; + } else { + annual_rate = cd_js.groups.credit_travaux__renovation__energie.a_partir_de_15001_72_a_84_mois; + } + } else if ((20000) < parseInt(selected_capital)) { + max_duration = 120; + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + if (selected_duration < 36) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie.a_partir_de_20001_24_a_30_mois; + } else if (selected_duration < 42) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie.a_partir_de_20001_36_mois; + } else if (selected_duration < 72) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie.a_partir_de_20001_42_a_60_mois; + } else if (selected_duration < 96) { + annual_rate = cd_js.groups.credit_travaux__renovation__energie.a_partir_de_20001_72_a_84_mois; + } else { + annual_rate = cd_js.groups.credit_travaux__renovation__energie.a_partir_de_20001_96_a_120_mois; + } + } + if ((min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration)) {} else { + duree_in_range = false; + selected_duration = max_duration; + } + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message]; +} \ No newline at end of file diff --git a/assets/js/exp/main.js b/assets/js/exp/main.js new file mode 100644 index 0000000..3e6b7b8 --- /dev/null +++ b/assets/js/exp/main.js @@ -0,0 +1,153 @@ +// Point d'entrée du simulateur modulaire +import * as calculs from './calculs.js'; +import * as utils from './utils.js'; +import * as ui from './ui.js'; + +// --- Exemples de données (à remplacer par les vraies données dynamiques) --- +const form_sliders = { + but_immo: { capital_selected: 20000, capital_max: 90000, capital_step: 100, capital_min: 2500, duree_min: 24, duree_max: 120, durees: [24, 30, 36, 42, 48, 60, 72, 84], pivot_value: 0, sub_pivot_value: 0, title: 'Crédit travaux / Rénovation / Energie', description: 'Exemple crédit travaux.' }, + fin_neuve: { capital_selected: 20000, capital_max: 100000, capital_step: 500, capital_min: 5000, duree_min: 24, duree_max: 84, durees: [24, 30, 36, 42, 48, 60, 72, 84], pivot_value: 0, sub_pivot_value: 5000, title: 'Financement véhicule NEUF', description: 'Exemple véhicule neuf.' }, + fin_occ_p3a: { capital_selected: 20000, capital_max: 100000, capital_step: 500, capital_min: 5000, duree_min: 24, duree_max: 60, durees: [24, 30, 36, 42, 48, 60], pivot_value: 0, sub_pivot_value: 5000, title: 'Financement véhicule d\'occasion PLUS de 3 ans', description: 'Exemple véhicule +3 ans.' }, + fin_occ_m3a: { capital_selected: 20000, capital_max: 100000, capital_step: 500, capital_min: 5000, duree_min: 24, duree_max: 84, durees: [24, 30, 36, 42, 48, 60, 72, 84], pivot_value: 0, sub_pivot_value: 5000, title: 'Financement véhicule d\'occasion MOINS de 3 ans', description: 'Exemple véhicule -3 ans.' }, + mobil_carav: { capital_selected: 20000, capital_max: 100000, capital_step: 500, capital_min: 10000, duree_min: 24, duree_max: 144, durees: [24, 30, 36, 42, 48, 60, 72, 84, 96, 108, 120, 144], pivot_value: 75000, sub_pivot_value: 0, title: 'Financement mobilhome et caravane', description: 'Exemple mobilhome.' }, + frais_notaire: { capital_selected: 20000, capital_max: 40000, capital_step: 100, capital_min: 2500, duree_min: 24, duree_max: 120, durees: [24, 30, 36, 42, 48, 60, 72, 84, 96, 108, 120], pivot_value: 0, sub_pivot_value: 0, title: 'Financement frais de notaire', description: 'Exemple frais notaire.' }, + pat: { capital_selected: 10000, capital_max: 200000, capital_min: 1500, capital_step: 100, duree_min: 24, duree_max: 240, durees: [24, 30, 36, 42, 48, 60, 72, 84, 96, 108, 120, 144, 180, 240], pivot_value: 75000, sub_pivot_value: 0, title: 'Prêt personnel / Tous motifs / Achats divers', description: 'Exemple prêt personnel.' }, + ph: { capital_selected: 100000, capital_max: 1000000, capital_min: 25000, capital_step: 1000, duree_min: 10, duree_max: 30, durees: [5, 10, 15, 20, 25, 30], pivot_value: 0, sub_pivot_value: 0, title: 'Crédit hypothécaire', description: 'Exemple crédit hypo social.' }, + am: { capital_selected: 100000, capital_max: 1000000, capital_min: 25000, capital_step: 1000, duree_min: 10, duree_max: 30, durees: [10, 15, 20, 25, 30], pivot_value: 0, sub_pivot_value: 0, title: 'Crédit hypothécaire classique', description: 'Exemple crédit hypo classique.' }, + amr: { capital_selected: 100000, capital_max: 1000000, capital_min: 25000, capital_step: 1000, duree_min: 10, duree_max: 30, durees: [10, 15, 20, 25, 30], pivot_value: 0, sub_pivot_value: 0, title: 'Crédit hypothécaire maison rapport', description: 'Exemple maison rapport.' }, + cdp: { capital_selected: 100000, capital_max: 1000000, capital_min: 25000, capital_step: 1000, duree_min: 10, duree_max: 30, durees: [10, 15, 20, 25, 30], pivot_value: 0, sub_pivot_value: 0, title: 'Crédit pont', description: 'Exemple crédit pont.' }, + cied: { capital_selected: 100000, capital_max: 1000000, capital_min: 25000, capital_step: 1000, duree_min: 10, duree_max: 30, durees: [10, 15, 20, 25, 30], pivot_value: 0, sub_pivot_value: 0, title: 'Crédit Indépendants et entreprises en difficultés', description: 'Exemple crédit indépendants.' }, + regroup_cred: { capital_selected: 20000, capital_max: 200000, capital_step: 500, capital_min: 5000, duree_min: 24, duree_max: 144, durees: [24, 30, 36, 42, 48, 60, 72, 84, 96, 108, 120, 144], pivot_value: 75000, sub_pivot_value: 0, title: 'Regroupement de crédit / rachat de crédit', description: 'Exemple regroupement.' }, +}; +const map_values = { pat: 'pat', am: 'am' }; +const authorized_value = ['pat', 'am']; + +// --- Etat global du simulateur --- +let selected_type = 'pat'; +let selected_capital = form_sliders[selected_type].capital_selected; +let selected_duree = form_sliders[selected_type].duree_max; + +// --- Création des éléments d'affichage si besoin --- +function ensureResultElements() { + if (!document.getElementById('mensualite_result')) { + const res = document.createElement('div'); + res.id = 'mensualite_result'; + res.style.margin = '1em 0'; + document.body.appendChild(res); + } + if (!document.getElementById('taux_result')) { + const res = document.createElement('div'); + res.id = 'taux_result'; + res.style.margin = '1em 0'; + document.body.appendChild(res); + } + if (!document.getElementById('duree_result')) { + const res = document.createElement('div'); + res.id = 'duree_result'; + res.style.margin = '1em 0'; + document.body.appendChild(res); + } +} + +// --- Fonction de recalcul centralisée et affichage --- +function recalculate() { + let result; + switch (selected_type) { + case 'pat': + result = calculs.calculate_pat(form_sliders, selected_capital, selected_duree); + break; + case 'am': + result = calculs.calculate_am(form_sliders, selected_capital, selected_duree); + break; + case 'fin_neuve': + if (typeof calculs.calculate_fin_neuve === 'function') { + result = calculs.calculate_fin_neuve(form_sliders, selected_capital, selected_duree); + } + break; + case 'fin_occ_m3a': + if (typeof calculs.calculate_pao_m_3 === 'function') { + result = calculs.calculate_pao_m_3(form_sliders, selected_capital, selected_duree); + } + break; + case 'fin_occ_p3a': + if (typeof calculs.calculate_pao_p_3 === 'function') { + result = calculs.calculate_pao_p_3(form_sliders, selected_capital, selected_duree); + } + break; + case 'ph': + if (typeof calculs.calculate_ph === 'function') { + result = calculs.calculate_ph(form_sliders, selected_capital, selected_duree); + } + break; + case 'frais_notaire': + if (typeof calculs.calculate_frais_notaire === 'function') { + result = calculs.calculate_frais_notaire(form_sliders, selected_capital, selected_duree); + } + break; + case 'but_immo': + if (typeof calculs.calculate_but_immo === 'function') { + result = calculs.calculate_but_immo(form_sliders, selected_capital, selected_duree); + } + break; + case 'mobil_carav': + if (typeof calculs.calculate_mobilhome === 'function') { + result = calculs.calculate_mobilhome(form_sliders, selected_capital, selected_duree); + } + break; + case 'regroup_cred': + if (typeof calculs.calculate_regroupement_de_credit === 'function') { + result = calculs.calculate_regroupement_de_credit(form_sliders, selected_capital, selected_duree); + } + break; + // Ajouter ici d'autres types de crédits selon le module calculs.js + default: + result = null; + } + if (result) { + // result = [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message] + const mensualite = (selected_capital * (result[4] / 100) / 12).toFixed(2); // Simplifié pour démo + const taux = result[4]; + const duree = result[2]; + document.getElementById('mensualite_result').textContent = `Mensualité estimée : ${utils.number_format(mensualite, 2, ',', ' ')} €`; + document.getElementById('taux_result').textContent = `Taux annuel : ${taux} %`; + document.getElementById('duree_result').textContent = `Durée sélectionnée : ${duree}`; + } else { + document.getElementById('mensualite_result').textContent = 'Mensualité : --'; + document.getElementById('taux_result').textContent = 'Taux : --'; + document.getElementById('duree_result').textContent = 'Durée : --'; + } +} + +// --- Initialisation des sliders au chargement --- +document.addEventListener('DOMContentLoaded', () => { + ensureResultElements(); + // Initialisation sliders capital et durée + ui.change_capital_slider(form_sliders, map_values, authorized_value, utils.number_format, form_sliders[selected_type].capital_min, form_sliders[selected_type].capital_max, form_sliders[selected_type].capital_selected); + ui.change_month_slider(form_sliders, map_values, authorized_value, utils.number_format, ui.getStepForValue, form_sliders[selected_type].duree_min, form_sliders[selected_type].duree_max, form_sliders[selected_type].duree_max); + recalculate(); + + // --- Gestion des événements --- + document.getElementById('loan_type')?.addEventListener('change', (e) => { + selected_type = e.target.value; + selected_capital = form_sliders[selected_type].capital_selected; + selected_duree = form_sliders[selected_type].duree_max; + ui.change_capital_slider(form_sliders, map_values, authorized_value, utils.number_format, form_sliders[selected_type].capital_min, form_sliders[selected_type].capital_max, selected_capital); + ui.change_month_slider(form_sliders, map_values, authorized_value, utils.number_format, ui.getStepForValue, form_sliders[selected_type].duree_min, form_sliders[selected_type].duree_max, selected_duree); + recalculate(); + }); + document.getElementById('selected_capital')?.addEventListener('input', (e) => { + selected_capital = parseInt(e.target.value, 10) || form_sliders[selected_type].capital_selected; + recalculate(); + }); + document.getElementById('selected_months')?.addEventListener('input', (e) => { + selected_duree = parseInt(e.target.value, 10) || form_sliders[selected_type].duree_max; + recalculate(); + }); +}); + +// TODO : Gérer l'état global du simulateur, les valeurs sélectionnées, et l'intégration complète des modules + +// Ici, on gérera l'initialisation, les événements, et l'orchestration des modules +// Exemple : +// ui.change_capital_slider(...); +// calculs.calculate_pat(...); \ No newline at end of file diff --git a/assets/js/exp/ui.js b/assets/js/exp/ui.js new file mode 100644 index 0000000..ada7563 --- /dev/null +++ b/assets/js/exp/ui.js @@ -0,0 +1,489 @@ +// Module de gestion de l'UI et des sliders + +// Les fonctions ci-dessous supposent que form_sliders, map_values, authorized_value sont passés en paramètre ou importés + +export function change_duree(form_sliders, map_values, authorized_value, default_min, default_max, selected_value) { + var list = ''; + var list_class = '', + loan_type = jQuery('#loan_type').val(), + loan_radio_type = jQuery('.loan_type:checked').length ? jQuery('.loan_type:checked').val() : '', + sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : '', + class_name = 'mens_', + selected_capital = jQuery('#selected_capital').val(), + monthly_low = 0, + monthly_high = 0, + capital_min = 0, + capital_max = 0, + selected_duree_box = jQuery('#selected_months_range').parents('.selected_duree'); + + var loan_type_in_years = ['am', 'amr', 'cdp', 'cied']; + + if (loan_radio_type != '') + loan_type = loan_radio_type; + + if (selected_capital == '') { + selected_capital = form_sliders[loan_type]['capital_selected']; + } + + if (sub_loan_radio_type != '') { + if (authorized_value.includes(sub_loan_radio_type)) { + loan_type = sub_loan_radio_type; + } else if (map_values[sub_loan_radio_type] !== 'undefined') { + loan_type = map_values[sub_loan_radio_type]; + } + } + + capital_min = form_sliders[loan_type]['capital_min']; + capital_max = form_sliders[loan_type]['capital_max']; + + // Ici, il faudrait injecter les fonctions de calcul en paramètre ou via import + // Pour l'instant, on laisse un placeholder pour results + let results = [default_min, default_max]; + // ... (à compléter avec l'appel à la bonne fonction de calcul) + + monthly_low = results[0]; + monthly_high = results[1]; + + var validDurees = []; + for (var j = 0; j < duree_range.length; j++) { + if ((monthly_low <= parseInt(duree_range[j]) && parseInt(duree_range[j]) <= monthly_high)) { + validDurees.push(duree_range[j]); + } + } + var startIndex = Math.max(0, validDurees.length - 4); + + if (jQuery('#selected_capital').val() < capital_min) { + list = '
  • La somme minimale est de ' + capital_min + '€
  • '; + } else if (jQuery('#selected_capital').val() > capital_max) { + list = '
  • La somme maximale est de ' + capital_max + '€
  • '; + } else { + for (var i = startIndex; i < validDurees.length; i++) { + var periodicite = ' mois'; + if (loan_type_in_years.includes(loan_type)) { + class_name = validDurees[i] + '_ans'; + periodicite = ' ans'; + } else { + class_name = 'mens_' + validDurees[i]; + } + if ((default_min <= parseInt(validDurees[i]) && parseInt(validDurees[i]) <= default_max)) { + if (selected_value == validDurees[i]) { + list_class = ' selected'; + } + if (validDurees[i] <= monthly_high) { + list = list + '
  • ' + validDurees[i] + periodicite + '
  • '; + } + } else { + list = list + ''; + } + list_class = ''; + } + } + jQuery('#date-range-selector').html(list); + var periodicite = loan_type_in_years.includes(loan_type) ? ' ans' : ' mois'; + jQuery('.slider_duree_box').text(selected_value + periodicite); + jQuery(selected_duree_box).find('.outside_slider_duree_box').text(selected_value + periodicite); +} + +export function change_capital_slider(form_sliders, map_values, authorized_value, number_format, default_min, default_max, default_selected_value) { + var selected_capital_range = '#selected_capital_range'; + var selected_capital = '#selected_capital'; + var selected_capital_box = jQuery(selected_capital_range).parents('.selected_capital'); + var stepUpdateTimeout = null; + var isInputChange = false; + + var loan_type = jQuery('#loan_type').val(), + loan_radio_type = jQuery('.loan_type:checked').length ? jQuery('.loan_type:checked').val() : '', + sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : ''; + + if (loan_radio_type != '') + loan_type = loan_radio_type; + + if (sub_loan_radio_type != '') { + if (authorized_value.includes(sub_loan_radio_type)) { + loan_type = sub_loan_radio_type; + } else if (map_values[sub_loan_radio_type] !== 'undefined') { + loan_type = map_values[sub_loan_radio_type]; + } + } + + var pivot_value = form_sliders[loan_type].pivot_value; + var sub_pivot_value = form_sliders[loan_type].sub_pivot_value; + var pivot_percent = ((pivot_value - default_min) / (default_max - default_min)) * 100; + var sub_pivot_percent = ((sub_pivot_value - default_min) / (default_max - default_min)) * 100; + + jQuery('.pivot-zone').remove(); + if (pivot_value > 0) { + var pivotZone = jQuery('
    '); + pivotZone.css({ + 'position': 'absolute', + 'left': pivot_percent + '%', + 'right': '0', + 'top': '0', + 'bottom': '0', + 'background-color': 'rgba(255, 0, 0, 0.2)', + 'pointer-events': 'none' + }); + jQuery(selected_capital_range).append(pivotZone); + } + + function calculateStep(value) { + return value < 10000 ? 500 : 250; + } + function roundToStep(value) { + var step = calculateStep(value); + return Math.round(value / step) * step; + } + + jQuery(selected_capital) + .attr('step', calculateStep(default_selected_value)) + .on('input', function() { + var $input = jQuery(this); + var value = Number($input.val()); + if (!value) return; + if (stepUpdateTimeout) { + clearTimeout(stepUpdateTimeout); + } + stepUpdateTimeout = setTimeout(function() { + var newStep = calculateStep(value); + $input.attr('step', newStep); + }, 500); + isInputChange = true; + jQuery(selected_capital_range).slider('value', value); + jQuery(selected_capital_range).find('.slider_capital_box') + .text(number_format(value, 2, ',', '.') + ' €'); + selected_capital_box.find('.outside_box').text(number_format(value, 2, ',', '.') + ' €'); + }); + + jQuery(selected_capital_range).slider({ + min: default_min, + max: default_max, + value: default_selected_value, + step: calculateStep(default_selected_value), + slide: function(event, ui) { + if (isInputChange) return; + var orange_bar = jQuery('.slider_capital_wrapper .after_bar'), + elem = jQuery(ui.handle), + left_css = parseInt(elem.css('left'), 10); + orange_bar.css('width', left_css + 10); + if (pivot_value > 0 && ui.value >= pivot_value) { + jQuery(selected_capital_range).find('.slider_capital_box').addClass('pivot-value'); + if (!jQuery('#acceptConditions').is(':checked')) { + jQuery('.stimulator_result_btn').prop('disabled', true).addClass('disabled'); + } + } else { + jQuery(selected_capital_range).find('.slider_capital_box').removeClass('pivot-value'); + jQuery('.stimulator_result_btn').prop('disabled', false).removeClass('disabled'); + } + jQuery(selected_capital).val(ui.value); + jQuery(selected_capital_range).find('.slider_capital_box').text(number_format((ui.value), 2, ',', '.') + ' €'); + selected_capital_box.find('.outside_box').text(number_format(ui.value, 2, ',', '.') + ' €'); + if (pivot_value > 0) { + if (ui.value >= pivot_value) { + jQuery('.pat_plus75000').slideDown(300); + } else { + jQuery('.pat_plus75000').slideUp(300); + } + } else { + jQuery('.pat_plus75000').hide(); + } + }, + stop: function(event, ui) { + // Les callbacks de recalcul et de sliders seront injectés dans main.js + }, + change: function(event, ui) { + var orange_bar = jQuery('.slider_capital_wrapper .after_bar'), + elem = jQuery(ui.handle), + left_css = parseInt(elem.css('left'), 10); + orange_bar.css('width', left_css + 10); + } + }); + + jQuery('#acceptConditions').on('change', function() { + var currentValue = jQuery(selected_capital).val(); + if (pivot_value > 0 && currentValue >= pivot_value) { + if (jQuery(this).is(':checked')) { + jQuery('.stimulator_result_btn').prop('disabled', false).removeClass('disabled'); + } else { + jQuery('.stimulator_result_btn').prop('disabled', true).addClass('disabled'); + } + } + }); + + var appended_elem = 'test'; + if (!jQuery('.ui-slider-handle .fa-angle-right').length) + jQuery(selected_capital_range).find('.ui-slider-handle').append(''); + if (!jQuery(selected_capital_range).find('.slider_capital_box').length) { + jQuery(selected_capital_range).find('.ui-slider-handle').append(appended_elem); + } + jQuery(selected_capital_range).find('.slider_capital_box').text(number_format((jQuery(selected_capital_range).slider('value')), 2, ',', '.') + ' €'); + selected_capital_box.find('.outside_box').text(number_format((jQuery(selected_capital_range).slider('value')), 2, ',', '.') + ' €'); + + if (sub_pivot_value > 0) { + var subPivotZone = jQuery('
    '); + subPivotZone.css({ + 'position': 'absolute', + 'left': '0', + 'width': sub_pivot_percent + '%', + 'top': '0', + 'bottom': '0', + 'background-color': 'rgba(0, 0, 255, 0.15)', + 'pointer-events': 'none' + }); + if(jQuery('.sub-pivot-zone').length == 0) + jQuery(selected_capital_range).append(subPivotZone); + } +} + +export function change_month_slider(form_sliders, map_values, authorized_value, number_format, getStepForValue, default_min, default_max, default_selected_value) { + var selected_months_range = '#selected_months_range'; + var selected_months = '#selected_months'; + var loan_type_in_years = ['am', 'amr', 'cdp', 'cied', 'ph']; + var sel_duree = jQuery(selected_months).val(), + selected_duree_box = jQuery(selected_months_range).parents('.selected_duree'); + + var loan_type = jQuery('#loan_type').val(), + loan_radio_type = jQuery('.loan_type:checked').length ? jQuery('.loan_type:checked').val() : '', + sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : ''; + + if (loan_radio_type != '') + loan_type = loan_radio_type; + + if (sub_loan_radio_type != '') { + if (authorized_value.includes(sub_loan_radio_type)) { + loan_type = sub_loan_radio_type; + } else if (map_values[sub_loan_radio_type] !== 'undefined') { + loan_type = map_values[sub_loan_radio_type]; + } + } + + var selected_capital = jQuery('#selected_capital').val(); + if (selected_capital == '') + selected_capital = form_sliders[loan_type]['capital_selected']; + + // Les résultats de calcul sont à injecter via callback dans main.js si besoin + let results = [default_min, default_max]; // À remplacer par l'appel à la bonne fonction de calcul + var max_duration = results[1]; + var dynamic_max = max_duration; + var available_durations = form_sliders[loan_type].durees; + for (var i = available_durations.length - 1; i >= 0; i--) { + if (available_durations[i] <= max_duration) { + dynamic_max = available_durations[i]; + break; + } + } + + jQuery(selected_months_range).slider({ + min: default_min, + max: dynamic_max, + value: dynamic_max, + step: getStepForValue(loan_type, dynamic_max), + slide: function(event, ui) { + var newStep = getStepForValue(loan_type, ui.value); + if (newStep !== jQuery(this).slider('option', 'step')) { + jQuery(this).slider('option', 'step', newStep); + } + var orange_bar = jQuery('.slider_duree_wrapper .after_bar_month'), + elem = jQuery(ui.handle), + left_css = parseInt(elem.css('left'), 10); + orange_bar.css('width', left_css + 10); + jQuery(selected_months).val(ui.value); + if (loan_type_in_years.includes(loan_type)) { + jQuery(selected_months_range).find('.slider_duree_box').text(ui.value + ' ans'); + jQuery(selected_duree_box).find('.outside_slider_duree_box').text(ui.value + ' ans'); + } else { + jQuery(selected_months_range).find('.slider_duree_box').text(ui.value + ' mois'); + jQuery(selected_duree_box).find('.outside_slider_duree_box').text(ui.value + ' mois'); + } + }, + stop: function(event, ui) { + // Les callbacks de recalcul seront injectés dans main.js + }, + change: function(event, ui) { + var orange_bar = jQuery('.slider_duree_wrapper .after_bar_month'), + elem = jQuery(ui.handle), + left_css = parseInt(elem.css('left'), 10); + orange_bar.css('width', left_css + 10); + } + }); + + jQuery(selected_months).val(jQuery(selected_months_range).slider('value')); + var periodicite = loan_type_in_years.includes(loan_type) ? ' ans' : ' mois'; + var appended_elem = '' + jQuery(selected_months_range).slider('value') + periodicite + ''; + jQuery(selected_duree_box).find('.outside_slider_duree_box').text(jQuery(selected_months_range).slider('value') + periodicite); + if (!jQuery(selected_months_range).find('.ui-slider-handle .fa-angle-right').length) { + jQuery(selected_months_range).find('.ui-slider-handle').append(''); + } + if (!jQuery(selected_months_range).find('.slider_duree_box').length) { + jQuery(selected_months_range).find('.ui-slider-handle').append(appended_elem); + } +} + +export function update_capital_input(form_sliders, map_values, authorized_value) { + if (jQuery('#selected_capital').length) { + var selected = jQuery('#loan_type').val(), + selected_radio = jQuery('.loan_type:checked').length ? jQuery('.loan_type:checked').val() : '', + sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : ''; + + if (selected_radio != '') + selected = selected_radio; + + if (sub_loan_radio_type != '' && authorized_value.includes(sub_loan_radio_type)) { + selected = sub_loan_radio_type; + } else if (map_values[sub_loan_radio_type] !== 'undefined') { + selected = map_values[sub_loan_radio_type]; + } + + var capital_max = form_sliders[selected].capital_max; + var capital_min = form_sliders[selected].capital_min; + var capital_selected = form_sliders[selected].capital_selected; + + jQuery('#selected_capital').prop('min', capital_min); + jQuery('#selected_capital').prop('max', capital_max); + jQuery('#selected_capital').val(capital_selected); + } +} + +export function validate_months_input(form_sliders, map_values, authorized_value, getStepForValue, calculate_mensualite) { + var selected_months_range = '#selected_months_range'; + var selected_months = '#selected_months'; + var selected = jQuery('#loan_type').val(), + loan_radio_type = jQuery('.loan_type:checked').length ? jQuery('.loan_type:checked').val() : '', + sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : '', + selected_duree_box = jQuery(selected_months_range).parents('.selected_duree'); + + if (loan_radio_type != '') { + selected = loan_radio_type; + } + + if (sub_loan_radio_type != '') { + if (authorized_value.includes(sub_loan_radio_type)) { + selected = sub_loan_radio_type; + } else if (map_values[sub_loan_radio_type] !== 'undefined') { + selected = map_values[sub_loan_radio_type]; + } + } + + var duree_max = form_sliders[selected].duree_max; + var duree_min = form_sliders[selected].duree_min; + var loan_type_in_years = ['am', 'amr', 'cdp', 'cied', 'ph']; + var current_value = parseInt(jQuery(selected_months).val()); + + // Utiliser la fonction getStepForValue passée en paramètre + var step = getStepForValue(selected, current_value); + + // Arrondir à la valeur la plus proche selon le step + var rounded_value = Math.round(current_value / step) * step; + + // Appliquer les limites min/max + if (rounded_value < duree_min) { + rounded_value = duree_min; + } else if (rounded_value > duree_max) { + rounded_value = duree_max; + } + + // Mettre à jour le champ et le slider + jQuery(selected_months).val(rounded_value); + jQuery(selected_months_range).slider('value', rounded_value); + + // Mettre à jour l'affichage + var periodicite = loan_type_in_years.includes(selected) ? ' ans' : ' mois'; + jQuery(selected_months_range).find('.slider_duree_box').text(rounded_value + periodicite); + jQuery(selected_duree_box).find('.outside_slider_duree_box').text(rounded_value + periodicite); + // Recalculer la mensualité + calculate_mensualite(); +} + +export function getStepForValue(loan_type, value) { + let loan_type_in_years = ['am', 'amr', 'cdp', 'cied', 'ph']; + let dynamic_step = 1; + if (loan_type_in_years.includes(loan_type)) { + dynamic_step = 1; // Step de 1 an pour les prêts en années + } else { + if (value <= 48) { + dynamic_step = 6; // Step de 6 mois jusqu'à 48 mois + } else { + dynamic_step = 12; // Step de 12 mois au-delà de 48 mois + } + } + return dynamic_step; +} + +export function display_alert_capital(form_sliders, map_values, authorized_value) { + var selected_capital = jQuery('#selected_capital').val(); + var selected = jQuery('#loan_type').val(), + selected_radio = jQuery('.loan_type:checked').length ? jQuery('.loan_type:checked').val() : '', + sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : ''; + + if (selected_radio != '') + selected = selected_radio; + + if (sub_loan_radio_type != '') { + if (authorized_value.includes(sub_loan_radio_type)) { + selected = sub_loan_radio_type; + } else if (map_values[sub_loan_radio_type] !== 'undefined') { + selected = map_values[sub_loan_radio_type]; + } + } + + var capital_max = form_sliders[selected].capital_max; + var capital_min = form_sliders[selected].capital_min; + + if (jQuery('.limit-warning').length) { + jQuery('.limit-warning').slideUp(); + jQuery('.limit-warning').remove(); + } + + if (!((selected_capital > capital_min) && (selected_capital < capital_max))) { + if ((selected_capital <= capital_min)) { + jQuery('.second-col').prepend('
    Le montant minimum requis est de ' + capital_min + '€
    '); + } else { + jQuery('.second-col').prepend('
    Le montant maximum est de ' + capital_max + '€
    '); + } + } +} + +export function delayed_capital_chnage(form_sliders, map_values, authorized_value, on_slider_value_change) { + var selected_capital_range = '#selected_capital_range'; + var selected = jQuery('#loan_type').val(), + loan_radio_type = jQuery('.loan_type:checked').length ? jQuery('.loan_type:checked').val() : '', + sub_loan_radio_type = jQuery('.sub_loan_type:checked').length ? jQuery('.sub_loan_type:checked').val() : ''; + var selected_capital = jQuery('#selected_capital').val(); + + if (loan_radio_type != '') { + selected = loan_radio_type; + } + + if (sub_loan_radio_type != '') { + if (authorized_value.includes(sub_loan_radio_type)) { + selected = sub_loan_radio_type; + } else if (map_values[sub_loan_radio_type] !== 'undefined') { + selected = map_values[sub_loan_radio_type]; + } + } + + var capital_max = form_sliders[selected].capital_max; + var capital_min = form_sliders[selected].capital_min; + var simu_button = document.querySelector('.stimulator_result_btn'); + + if (jQuery('.limit-warning').length) { + jQuery('.limit-warning').slideUp(); + jQuery('.limit-warning').remove(); + } + + if ((selected_capital >= capital_min) && (selected_capital <= capital_max)) { + if (jQuery('.stimulator_result_btn').is(':disabled')) + jQuery('.stimulator_result_btn').removeAttr('disabled'); + on_slider_value_change(); + } else { + if (!((selected_capital > capital_min) && (selected_capital < capital_max))) { + if ((selected_capital <= capital_min)) { + let elem = '

    Le montant minimum requis est de ' + capital_min + '€

    '; + jQuery(elem).insertBefore('.stimulator_result_btn'); + } else { + jQuery('

    Le montant maximum requis est de ' + capital_max + '€

    ').insertBefore('.stimulator_result_btn'); + } + jQuery('.stimulator_result_btn').prop('disabled', true); + on_slider_value_change(); + } + } +} \ No newline at end of file diff --git a/assets/js/exp/utils.js b/assets/js/exp/utils.js new file mode 100644 index 0000000..1b06212 --- /dev/null +++ b/assets/js/exp/utils.js @@ -0,0 +1,32 @@ +// Module des fonctions utilitaires + +export function number_format(number, decimals, decPoint, thousandsSep) { + number = (number + '').replace(/[^0-9+\-Ee.]/g, '') + var n = !isFinite(+number) ? 0 : +number + var prec = !isFinite(+decimals) ? 0 : Math.abs(decimals) + var sep = (typeof thousandsSep === 'undefined') ? ',' : thousandsSep + var dec = (typeof decPoint === 'undefined') ? '.' : decPoint + var s = '' + + var toFixedFix = function(n, prec) { + var k = Math.pow(10, prec) + return '' + (Math.round(n * k) / k) + .toFixed(prec) + } + + // @todo: for IE parseFloat(0.55).toFixed(0) = 0; + s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.') + if (s[0].length > 3) { + s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep) + } + if ((s[1] || '').length < prec) { + s[1] = s[1] || '' + s[1] += new Array(prec - s[1].length + 1).join('0') + } + + return s.join(dec) +} + +export function getStepForValue(loan_type, value) { + // ... +} \ No newline at end of file diff --git a/assets/js/form_main.js b/assets/js/form_main.js new file mode 100644 index 0000000..b409d62 --- /dev/null +++ b/assets/js/form_main.js @@ -0,0 +1,2082 @@ +jQuery(function($) { + jQuery('form.load_simulator').each(function() { + jQuery(this).attr('action', window.location.origin + '/credit-step1') + }) + + /** + * Système de sauvegarde localStorage + */ + const FORM_STORAGE_KEY = 'credit_direct_form_data'; + const FORM_STORAGE_TIMESTAMP = 'credit_direct_form_timestamp'; + const STORAGE_EXPIRY_HOURS = 24; // Les données expirent après 24h + + /** + * Affiche l'indicateur de sauvegarde + */ + function showSaveIndicator(message, type = 'success') { + let indicator = jQuery('.auto-save-indicator'); + + if (indicator.length === 0) { + indicator = jQuery('
    '); + jQuery('body').append(indicator); + } + + indicator.removeClass('show saving error').addClass('show ' + type); + indicator.text(message); + + // Masquer après 3 secondes + setTimeout(() => { + indicator.removeClass('show'); + }, 3000); + } + + /** + * Sauvegarde les données du formulaire dans localStorage + */ + function saveFormData() { + // Afficher l'indicateur de sauvegarde + showSaveIndicator('Sauvegarde en cours...', 'saving'); + + const formData = {}; + const currentStep = getCurrentStep(); + + // Récupérer tous les champs du formulaire + jQuery('form.form-submit').find('input, select, textarea').each(function() { + const $field = jQuery(this); + const name = $field.attr('name'); + const type = $field.attr('type'); + + if (!name) return; + + let value = ''; + + switch (type) { + case 'checkbox': + value = $field.is(':checked') ? $field.val() : ''; + break; + case 'radio': + if ($field.is(':checked')) { + value = $field.val(); + } + break; + case 'file': + // Ne pas sauvegarder les fichiers + return; + default: + value = $field.val() || ''; + break; + } + + // Ne sauvegarder que si la valeur n'est pas vide + if (value !== '') { + formData[name] = value; + } + }); + + // Sauvegarder avec l'étape actuelle et le timestamp + const dataToSave = { + step: currentStep, + data: formData, + timestamp: Date.now() + }; + + try { + localStorage.setItem(FORM_STORAGE_KEY, JSON.stringify(dataToSave)); + localStorage.setItem(FORM_STORAGE_TIMESTAMP, Date.now().toString()); + console.log('Données sauvegardées dans localStorage:', dataToSave); + + // Afficher le succès + setTimeout(() => { + showSaveIndicator('Données sauvegardées', 'success'); + }, 500); + + } catch (e) { + console.error('Erreur lors de la sauvegarde localStorage:', e); + showSaveIndicator('Erreur de sauvegarde', 'error'); + } + } + + /** + * Restaure les données du formulaire depuis localStorage + */ + function restoreFormData() { + try { + const savedData = localStorage.getItem(FORM_STORAGE_KEY); + if (!savedData) return false; + + const parsedData = JSON.parse(savedData); + const now = Date.now(); + const savedTime = parsedData.timestamp || 0; + + console.log('parsedData', parsedData); + + // Vérifier si les données ne sont pas expirées + if (now - savedTime > STORAGE_EXPIRY_HOURS * 60 * 60 * 1000) { + console.log('Données localStorage expirées, suppression...'); + clearFormData(); + return false; + } + + const formData = parsedData.data || {}; + let restoredCount = 0; + + // Traiter d'abord les champs de crédits en cours + const currentLoansData = {}; + const coCurrentLoansData = {}; + + // Séparer les données des crédits en cours des autres champs + Object.keys(formData).forEach(name => { + if (name.startsWith('currentloans[')) { + const match = name.match(/currentloans\[(\d+)\]\[([^\]]+)\]/); + if (match) { + const index = parseInt(match[1]); + const field = match[2]; + if (!currentLoansData[index]) currentLoansData[index] = {}; + currentLoansData[index][field] = formData[name]; + } + } else if (name.startsWith('cocurrentloans[')) { + const match = name.match(/cocurrentloans\[(\d+)\]\[([^\]]+)\]/); + if (match) { + const index = parseInt(match[1]); + const field = match[2]; + if (!coCurrentLoansData[index]) coCurrentLoansData[index] = {}; + coCurrentLoansData[index][field] = formData[name]; + } + } + }); + + // Restaurer les valeurs des champs simples + Object.keys(formData).forEach(name => { + // Ignorer les champs de crédits en cours (traités séparément) + if (name.startsWith('currentloans[') || name.startsWith('cocurrentloans[')) { + return; + } + + const $field = jQuery('form.form-submit').find(`[name="${name}"]`); + if ($field.length === 0) return; + + const value = formData[name]; + const type = $field.attr('type'); + + switch (type) { + case 'checkbox': + if (value) { + $field.prop('checked', true); + } + break; + case 'radio': + $field.filter(`[value="${value}"]`).prop('checked', true); + break; + default: + $field.val(value); + break; + } + + // Ajouter un effet visuel temporaire + $field.addClass('field-restored'); + setTimeout(() => { + $field.removeClass('field-restored'); + }, 2000); + + restoredCount++; + }); + + // Restaurer les crédits en cours de l'emprunteur + Object.keys(currentLoansData).forEach(index => { + const loanData = currentLoansData[index]; + const blockIndex = parseInt(index); + + // Créer le bloc si nécessaire + while (jQuery('.wpcf-currentloan--block').length <= blockIndex) { + addCurrentLoan(); + } + + // Remplir les champs du bloc + const $block = jQuery('.wpcf-currentloan--block').eq(blockIndex); + Object.keys(loanData).forEach(field => { + const $field = $block.find(`[name="currentloans[${index}][${field}]"]`); + if ($field.length > 0) { + $field.val(loanData[field]); + $field.addClass('field-restored'); + setTimeout(() => { + $field.removeClass('field-restored'); + }, 2000); + restoredCount++; + } + }); + + // Appliquer la logique de désactivation du champ durationmonth selon le type de prêt + const loanType = loanData.loantype; + if (loanType === '1') { + const $durationField = $block.find('input[name*="durationmonth"]'); + if ($durationField.length > 0) { + $durationField.prop('readonly', true); + $durationField.addClass('readonly-field'); + } + + // Mettre à jour les labels selon le type de prêt + const $borrowedCapitalField = $block.find('input[name*="borrowedcapital"]'); + const $monthlyPaymentField = $block.find('input[name*="monthlypayment"]'); + + if ($borrowedCapitalField.length > 0) { + const $borrowedCapitalLabel = $borrowedCapitalField.closest('.form-group').find('label'); + if ($borrowedCapitalLabel.length > 0) { + $borrowedCapitalLabel.text('Plafond de la carte'); + } + } + + if ($monthlyPaymentField.length > 0) { + const $monthlyPaymentLabel = $monthlyPaymentField.closest('.form-group').find('label'); + if ($monthlyPaymentLabel.length > 0) { + $monthlyPaymentLabel.text('Remboursement mensuel'); + } + } + } + }); + + // Restaurer les crédits en cours du co-emprunteur + Object.keys(coCurrentLoansData).forEach(index => { + const loanData = coCurrentLoansData[index]; + const blockIndex = parseInt(index); + + // Créer le bloc si nécessaire + while (jQuery('.wpcf-cocurrentloan--block').length <= blockIndex) { + addCoCurrentLoan(); + } + + // Remplir les champs du bloc + const $block = jQuery('.wpcf-cocurrentloan--block').eq(blockIndex); + Object.keys(loanData).forEach(field => { + const $field = $block.find(`[name="cocurrentloans[${index}][${field}]"]`); + if ($field.length > 0) { + $field.val(loanData[field]); + $field.addClass('field-restored'); + setTimeout(() => { + $field.removeClass('field-restored'); + }, 2000); + restoredCount++; + } + }); + + // Appliquer la logique de désactivation du champ durationmonth selon le type de prêt + const loanType = loanData.loantype; + if (loanType === '1') { + const $durationField = $block.find('input[name*="durationmonth"]'); + if ($durationField.length > 0) { + $durationField.prop('readonly', true); + $durationField.addClass('readonly-field'); + } + + // Mettre à jour les labels selon le type de prêt + const $borrowedCapitalField = $block.find('input[name*="borrowedcapital"]'); + const $monthlyPaymentField = $block.find('input[name*="monthlypayment"]'); + + if ($borrowedCapitalField.length > 0) { + const $borrowedCapitalLabel = $borrowedCapitalField.closest('.form-group').find('label'); + if ($borrowedCapitalLabel.length > 0) { + $borrowedCapitalLabel.text('Plafond de la carte'); + } + } + + if ($monthlyPaymentField.length > 0) { + const $monthlyPaymentLabel = $monthlyPaymentField.closest('.form-group').find('label'); + if ($monthlyPaymentLabel.length > 0) { + $monthlyPaymentLabel.text('Remboursement mensuel'); + } + } + } + }); + + console.log(`${restoredCount} champs restaurés depuis localStorage`); + + if (restoredCount > 0) { + showSaveIndicator(`${restoredCount} champs restaurés`, 'success'); + } + + return restoredCount > 0; + + } catch (e) { + console.error('Erreur lors de la restauration localStorage:', e); + return false; + } + } + + /** + * Efface les données du formulaire du localStorage + */ + function clearFormData() { + try { + localStorage.removeItem(FORM_STORAGE_KEY); + localStorage.removeItem(FORM_STORAGE_TIMESTAMP); + console.log('Données localStorage effacées'); + + // Masquer le message d'information + jQuery('.localstorage-info').fadeOut(); + + // Afficher un message de confirmation + showSaveIndicator('Données effacées', 'success'); + + } catch (e) { + console.error('Erreur lors de l\'effacement localStorage:', e); + showSaveIndicator('Erreur lors de l\'effacement', 'error'); + } + } + + // Rendre la fonction accessible globalement + window.clearFormData = clearFormData; + + /** + * Détermine l'étape actuelle basée sur l'URL + */ + function getCurrentStep() { + const path = window.location.pathname; + if (path.includes('credit-step1')) return 'step1'; + if (path.includes('credit-step2')) return 'step2'; + if (path.includes('credit-step3')) return 'step3'; + if (path.includes('credit-step4')) return 'step4'; + if (path.includes('credit-step5')) return 'step5'; + return 'unknown'; + } + + /** + * Sauvegarde automatique lors de la modification des champs + */ + function setupAutoSave() { + // Sauvegarde sur clic du lien "previous-step" + jQuery('a.previous-step').on('click', function(e) { + /* e.preventDefault(); */ + saveFormData(); + }); + + // Sauvegarde sur changement de valeur (désactivé) + // jQuery('form.form-submit').on('change input', 'input, select, textarea', function() { + // // Debounce pour éviter trop de sauvegardes + // clearTimeout(window.autoSaveTimeout); + // window.autoSaveTimeout = setTimeout(saveFormData, 1000); + // }); + + // Sauvegarde sur clic des boutons radio/checkbox (désactivé) + // jQuery('form.form-submit').on('click', 'input[type="radio"], input[type="checkbox"]', function() { + // setTimeout(saveFormData, 100); + // }); + + // Sauvegarde avant soumission du formulaire (désactivé) + // jQuery('form.form-submit').on('submit', function() { + // saveFormData(); + // }); + + // Sauvegarde avant navigation (bouton étape précédente) (désactivé) + // jQuery('a[href*="credit-step"]').on('click', function() { + // saveFormData(); + // }); + + // Sauvegarde lors de l'ajout/suppression de crédits en cours (désactivé) + // $(document).on('currentLoanAdded currentLoanRemoved', function() { + // setTimeout(saveFormData, 500); + // }); + } + + /** + * Affiche le message d'information localStorage + */ + function showLocalStorageInfo() { + const savedData = localStorage.getItem(FORM_STORAGE_KEY); + if (!savedData) return; + + // Vérifier si le message existe déjà + if (jQuery('.localstorage-info').length > 0) return; + + const infoHtml = ` +
    + 💾 + Vos données sont sauvegardées automatiquement. + +
    + `; + + // Insérer au début du formulaire + jQuery('form.form-submit').prepend(infoHtml); + } + + /** + * Initialise le système de sauvegarde + */ + function initFormStorage() { + + if(hasCreditDirectToken()) + return; + + //check if localStorage is empty + /* if(localStorage.getItem(FORM_STORAGE_KEY) === null) + return; */ + + // Restaurer les données au chargement + const restored = restoreFormData(); + + // Configurer la sauvegarde automatique + setupAutoSave(); + + // Effacer les données après soumission réussie (optionnel) + jQuery(document).on('formSubmitted', function() { + clearFormData(); + }); + + // Si des données ont été restaurées, initialiser l'affichage des zones conditionnelles + if (restored) { + setTimeout(function() { + initializePreFilledValues(); + }, 200); + } + + // Afficher le message d'information + showLocalStorageInfo(); + + console.log('Système de sauvegarde localStorage initialisé'); + } + + function hasCreditDirectToken() { + return window.location.search.includes('credit-direct-token'); + } + + // Initialiser le système de sauvegarde UNIQUEMENT si le paramètre est présent dans l'URL + // (déplacé après la définition des fonctions addCurrentLoan et addCoCurrentLoan) + if (hasCreditDirectToken()) { + } + + /** + * General + */ + function empty(value) { return value == undefined || value == null || value == [] || value == ''; } + + function makeLabelRequired(containerSelector = 'body') { + if (jQuery(containerSelector).length > 0) { + jQuery(containerSelector).find('input:required, select:required, textarea:required').each(function() { + var labelId = jQuery(this).attr('id'); + var label = jQuery('label[for="' + labelId + '"]') + + if (label.length > 0 && label.html().charAt(label.html().length - 1) !== '*') { + label.html(label.html() + '*') + } + }) + } + } + + // Marque les champs initialement requis pour pouvoir restaurer l'attribut required quand on ré-affiche une zone + function markInitialRequired(containerSelector) { + if (jQuery(containerSelector).length > 0) { + jQuery(containerSelector).find('input, select, textarea').each(function() { + var $el = jQuery(this); + if ($el.is('[required]')) { + $el.attr('data-initial-required', '1'); + } + var pattern = $el.attr('pattern'); + if (typeof pattern !== 'undefined' && pattern !== null && pattern !== '') { + $el.attr('data-initial-pattern', '1'); + $el.attr('data-initial-pattern-value', pattern); + } + }); + } + } + + // Active/désactive l'attribut pattern pour les seuls champs date (input.input-date) du conteneur + function togglePatternForContainer($container, isVisible) { + if (!$container || $container.length === 0) { return; } + $container.find('input.input-date').each(function() { + var $el = jQuery(this); + var defaultDatePattern = '\\d{1,2}/\\d{1,2}/\\d{4}'; + // Capture paresseuse du pattern initial si non marqué mais présent + var currentPattern = $el.attr('pattern'); + if (!$el.attr('data-initial-pattern') && typeof currentPattern !== 'undefined' && currentPattern !== '') { + $el.attr('data-initial-pattern', '1'); + $el.attr('data-initial-pattern-value', currentPattern); + } + + if (isVisible) { + if ($el.attr('data-initial-pattern') === '1') { + $el.attr('pattern', $el.attr('data-initial-pattern-value')); + } else { + // Si aucun pattern initial, appliquer le pattern date par défaut + $el.attr('pattern', defaultDatePattern); + } + } else { + $el.removeAttr('pattern'); + } + }); + } + + // Retire l'attribut required de tous les champs dans les sections cachées + // Cette fonction est appelée avant la soumission du formulaire pour éviter l'erreur + // "An invalid form control with name='...' is not focusable" + function removeRequiredFromHiddenFields() { + // Retirer required uniquement des champs qui sont VRAIMENT cachés (display:none ou visibility:hidden) + // Ne pas toucher aux champs visibles même s'ils ont la classe d-none (qui peut être retirée dynamiquement) + jQuery('input, select, textarea').each(function() { + var $field = jQuery(this); + var $fieldElement = $field[0]; + + // Vérifier si le champ est vraiment caché (display:none ou dans un élément avec display:none) + var isReallyHidden = false; + + // Vérifier d'abord si l'élément lui-même est caché + if ($fieldElement.offsetParent === null && $field.css('display') === 'none') { + isReallyHidden = true; + } else { + // Vérifier si un parent est caché avec display:none ou a la classe 'hidden' + var $parent = $field.parent(); + while ($parent.length > 0 && !$parent.is('form') && !$parent.is('body')) { + // Ignorer les sections co-emprunteur qui pourraient être visibles + if ($parent.hasClass('wpcf-coborrower') || $parent.hasClass('co-borrower-section') || $parent.hasClass('co-emprunteur')) { + // Si la section co-emprunteur n'est pas vraiment cachée, ne pas retirer required + if ($parent.css('display') !== 'none' && $parent.is(':visible') && !$parent.hasClass('hidden')) { + break; + } + } + + // Vérifier aussi la classe 'hidden' pour les sections comme independent_section + if ($parent.css('display') === 'none' || !$parent.is(':visible') || $parent.hasClass('hidden')) { + isReallyHidden = true; + break; + } + $parent = $parent.parent(); + } + } + + // Retirer required seulement si vraiment caché ET que ce n'est pas un champ du co-emprunteur visible + if (isReallyHidden) { + // Exception : ne pas retirer required des champs du co-emprunteur si celui-ci est activé + // et que la section est visible (même si elle a la classe d-none) + var hasCoBorrower = jQuery('input[name="hascoborrower"]:checked').length > 0 && + jQuery('input[name="hascoborrower"]:checked').val() == '1'; + + if (hasCoBorrower) { + var $coSection = $field.closest('.wpcf-coborrower, .co-borrower-section, .co-emprunteur'); + if ($coSection.length > 0) { + // Vérifier si la section co-emprunteur est visible malgré la classe d-none/hidden + if ($coSection.is(':visible') && $coSection.css('display') !== 'none' && !$coSection.hasClass('hidden')) { + // Vérifier aussi si le champ est dans une sous-section cachée (comme independent_section) + var $hiddenSubSection = $field.closest('.hidden'); + if ($hiddenSubSection.length === 0) { + // Ne pas retirer required si la section est visible et pas dans une sous-section cachée + return; + } + } + } + } + + $field.removeAttr('required'); + } + }); + } + + if (jQuery('.wpcf-borrower').length > 0) { + makeLabelRequired('.wpcf-borrower') + } else { + makeLabelRequired('.form-submit') + } + + // Enregistrer l'état initial des champs requis/pattern (global + zones clés) + markInitialRequired('.form-submit'); + markInitialRequired('.co-borrower-section'); + markInitialRequired('.wpcf-coborrower'); + markInitialRequired('.isIndependant'); + + /** + * Step 2 + */ + function changeJobLabels(value, container) { + var jobLabels = { + independent: { + factory: 'de l\'entreprise', + salary: 'Revenu imposable annuel', + startDate: 'de début d\'activité' + }, + withoutEmployer: { + employer: 'de l\'employeur/organisme de paiement', + salary: 'Indemnités mensuelles', + startDate: 'd\'engagement' + }, + withEmployer: { + employer: 'de l\'employeur/organisme de paiement', + salary: 'Salaire net mensuel', + startDate: 'd\'engagement' + } + }, job = { + independent: 5, + withoutEmployer: ['1','6','9','12'] + }; + + console.log('job', value, job.independent); + + var prefix = container.find('#IDcofirstname').length > 0 ? 'co' : '' + var fields = ['emname', 'emaddress', 'emzip', 'emcity', 'emcountry', 'commitmentdate', 'salary'] + + fields.forEach(id => { + var labelText = null + + switch (id) { + case 'commitmentdate': + if(value === job.independent) { + labelText = jobLabels.independent.startDate + } else if(job.withoutEmployer.includes(value)) { + labelText = jobLabels.withoutEmployer.startDate + } else { + labelText = jobLabels.withEmployer.startDate + } + break; + + case 'salary': + + if(value === job.independent) { + labelText = jobLabels.independent.salary + } else if(job.withoutEmployer.includes(value)) { + labelText = jobLabels.withoutEmployer.salary + } else { + labelText = jobLabels.withEmployer.salary + } + break; + + default: + if(value === job.independent) { + labelText = jobLabels.independent.factory + } else if(job.withoutEmployer.includes(value)) { + labelText = jobLabels.withoutEmployer.employer + } else { + labelText = jobLabels.withEmployer.employer + } + break; + } + + container.find('label[for="ID' + prefix + id + '"] > span').text(labelText); + + console.log('labelText', labelText); + }); + + /* console.log('container', container); + console.log('prefix', container.find('.'+prefix+'independent_section')); */ + console.log('value', value); + + excludedFields = ['IDnotice_of_assessment', 'IDpaycheck', 'IDcopaycheck', 'IDconotice_of_assessment']; + + if(value == job.independent) { + container.find('.'+prefix+'independent_section').fadeIn().removeClass('hidden'); + //remove required attributes + container.find('.'+prefix+'employee_section').find('input, select').removeAttr('required'); + container.find('.'+prefix+'employee_section').fadeOut().addClass('hidden'); + container.find('.'+prefix+'independent_section').find('input, select').each(function() { + var fieldId = jQuery(this).attr('id'); + if (excludedFields.indexOf(fieldId) === -1) { + jQuery(this).attr('required', true); + } + }); + // Patterns: visible sur independent_section, masqué sur employee_section + togglePatternForContainer(container.find('.'+prefix+'independent_section'), true); + togglePatternForContainer(container.find('.'+prefix+'employee_section'), false); + } else if(job.withoutEmployer.includes(value)) { + container.find('.withemployer_section').fadeOut().addClass('hidden'); + container.find('.withemployer_section').find('input, select').removeAttr('required'); + togglePatternForContainer(container.find('.withemployer_section'), false); + + // Retirer aussi required des champs de la section indépendant (cas où on passe de indépendant à sans employeur) + container.find('.'+prefix+'independent_section').fadeOut().addClass('hidden'); + container.find('.'+prefix+'independent_section').find('input, select').removeAttr('required'); + togglePatternForContainer(container.find('.'+prefix+'independent_section'), false); + + console.log((jobLabels.withoutEmployer.salary)); + /* container.find('.'+prefix+'IDsalary').prev().text(jobLabels.withoutEmployer.salary); + + console.log(container.find('#'+prefix+'IDsalary').prev()); */ + } else { + container.find('.'+prefix+'independent_section').fadeOut().addClass('hidden'); + //not input field required + container.find('.'+prefix+'employee_section').find('input:not([type="file"]), select').attr('required', true); + container.find('.'+prefix+'employee_section').fadeIn().removeClass('hidden'); + + //except file inputs + container.find('.'+prefix+'independent_section').find('input, select').removeAttr('required'); + + if(jQuery('.withemployer_section').hasClass('hidden')) { + jQuery('.withemployer_section').fadeIn().removeClass('hidden'); + jQuery('.withemployer_section').find('input, select').attr('required', true); + togglePatternForContainer(jQuery('.withemployer_section'), true); + } + // Patterns: visible sur employee_section, masqué sur independent_section + togglePatternForContainer(container.find('.'+prefix+'employee_section'), true); + togglePatternForContainer(container.find('.'+prefix+'independent_section'), false); + } + + container + .find('#ID' + prefix + 'emnumber') + .attr('required', value === job.independent) + .parent() + .toggleClass('d-none', value !== job.independent) + + makeLabelRequired() + } + + // Ajouter un gestionnaire sur les boutons submit pour retirer required AVANT la validation HTML5 + jQuery('body').on('click', '.form-submit button[type="submit"]', function(e) { + // Retirer l'attribut required de tous les champs dans les sections cachées + // AVANT la validation HTML5 pour éviter l'erreur "not focusable" + removeRequiredFromHiddenFields(); + }); + + function displayCoBorrower() { + // Éviter les exécutions multiples + if (displayCoBorrower._isRunning) { + return; + } + displayCoBorrower._isRunning = true; + + var + excludedFieldsName = [ + 'cocontract_type', + 'coemname', + 'coemaddress', + 'coemzip', + 'coemcity', + 'coemcountry', + 'cocommitmentdate', + 'cooiamouthmealvoucher', + 'cooiamouthrentalincome', + 'cooiamouthunemployment', + 'cooiamouthother', + 'cooiothertext', + 'co_secteur_activite', + 'co_num_tva', + 'coMtn_loyer', + 'coHabitation_loyer' + ], + hasCoBorrower = + jQuery('input[name="hascoborrower"]:checked').length > 0 && + jQuery('input[name="hascoborrower"]:checked').val() == 1, + key = '.wpcf-coborrower', + cols_key = '.credit-cols'; + + console.log('hasCoBorrower', hasCoBorrower); + + // Gestion de l'affichage/masquage + jQuery(key).toggleClass('d-none', !hasCoBorrower); + jQuery('.co-borrower-section').toggleClass('d-none', !hasCoBorrower); + // Note: .co-emprunteur est géré dans cd_main.js pour le formulaire one-step + + // Gérer l'attribut required/pattern en fonction de la visibilité + var coContainers = jQuery(key).add('.co-borrower-section'); + var cojobValue = jQuery('select[name="cojob"]').val(); + var isCojobIndependent = cojobValue === '5'; + + if (hasCoBorrower) { + coContainers.find('input, select, textarea').each(function() { + var wasRequired = jQuery(this).attr('data-initial-required') === '1'; + if (wasRequired) { + jQuery(this).attr('required', true); + } else { + jQuery(this).removeAttr('required'); + } + }); + + // Gestion des patterns selon le statut indépendant du cojob + // Activer les patterns pour tous les conteneurs sauf co-independent_section / coindependent_section + togglePatternForContainer(coContainers.not('.co-independent_section, .coindependent_section'), true); + + // Pour co-independent_section / coindependent_section, activer le pattern uniquement si cojob = 5 + if (isCojobIndependent) { + togglePatternForContainer(jQuery('.co-independent_section, .coindependent_section'), true); + } else { + togglePatternForContainer(jQuery('.co-independent_section, .coindependent_section'), false); + } + } else { + coContainers.find('input, select, textarea').removeAttr('required'); + togglePatternForContainer(coContainers, false); + } + + makeLabelRequired(); + + // Gestion des colonnes + if (hasCoBorrower) { + // Mode deux colonnes + jQuery(cols_key).removeClass('col-md-12').addClass('col-md-6'); + + // Ajuster les colonnes internes + jQuery('.credit-cols [class*="col-md-"]').each(function() { + var classes = jQuery(this).attr('class').split(' '); + classes.forEach(function(className) { + if (className.startsWith('col-md-')) { + var currentSize = parseInt(className.replace('col-md-', '')); + console.log('currentSize', currentSize); + + // Sauvegarder la taille originale si ce n'est pas déjà fait + if (!jQuery(this).data('original-size')) { + jQuery(this).data('original-size', className); + } + + // Définir la nouvelle taille + jQuery(this).removeClass(className).addClass('col-md-12'); + } + }.bind(this)); + }); + + // Ajuster spécifiquement les colonnes dans .other-credit-cols et ses sous-éléments + jQuery('.other-credit-cols').find('[class*="col-md-"]').each(function() { + var classes = jQuery(this).attr('class').split(' '); + classes.forEach(function(className) { + if (className.startsWith('col-md-')) { + var currentSize = parseInt(className.replace('col-md-', '')); + console.log('currentSize other-credit-cols', currentSize); + + // Sauvegarder la taille originale si ce n'est pas déjà fait + if (!jQuery(this).data('original-size')) { + jQuery(this).data('original-size', className); + } + + // Définir la nouvelle taille pour .other-credit-cols et ses sous-éléments + jQuery(this).removeClass(className).addClass('col-md-6'); + } + }.bind(this)); + }); + } else { + // Mode une colonne + jQuery('.credit-cols .wpcf-borrower').removeClass('col-md-6'); + + if(!jQuery(cols_key).hasClass('col-md-12')) + jQuery(cols_key).addClass('col-md-12').removeClass('col-md-6'); + + // Restaurer les colonnes internes à leur taille d'origine + jQuery('.credit-cols [class*="col-md-"]').each(function() { + var originalSize = jQuery(this).data('original-size'); + + if (originalSize) { + // Supprimer toutes les classes col-md-* actuelles + var classes = jQuery(this).attr('class').split(' '); + classes.forEach(function(className) { + if (className.startsWith('col-md-')) { + jQuery(this).removeClass(className); + } + }.bind(this)); + + // Restaurer la taille originale + jQuery(this).addClass(originalSize); + } + }); + + // Pour .other-credit-cols, forcer une taille appropriée même sans co-emprunteur + jQuery('.other-credit-cols').find('[class*="col-md-"]').each(function() { + // Supprimer toutes les classes col-md-* actuelles + var classes = jQuery(this).attr('class').split(' '); + classes.forEach(function(className) { + if (className.startsWith('col-md-')) { + jQuery(this).removeClass(className); + } + }.bind(this)); + + // Toujours appliquer col-md-6 pour .other-credit-cols, même sans co-emprunteur + jQuery(this).addClass('col-md-6'); + }); + } + + // Gestion des champs requis + jQuery(key).find('input[type="text"], input[type="number"], input[type="date"], select, textarea').each(function() { + if (excludedFieldsName.indexOf(jQuery(this).attr('name')) < 0) { + jQuery(this).attr('required', hasCoBorrower) + } + }) + + if (!hasCoBorrower) { + jQuery(key).find('input[type="checkbox"]:checked, input[type="radio"][value="0"]').each(function() { + jQuery(this).prop('checked', jQuery(this).attr('type') === 'radio') + }) + + jQuery(key).find('input:not([type="checkbox"]):not([type="radio"]), select, textarea').each(function() { + jQuery(this).val('') + }) + } + + makeLabelRequired(key) + + // Afficher les autres revenus si nécessaire (même si cojob = 5) + displayOtherIncome( + hasCoBorrower && jQuery('input[name="cohasotherincome"]:checked').length > 0 && jQuery('input[name="cohasotherincome"]:checked').val() == 1, + '.co' + ); + + // Réinitialiser le flag après un court délai + setTimeout(function() { + displayCoBorrower._isRunning = false; + }, 50); + } + + function displayOtherIncome(show, key) { + var target = jQuery('.wpcf-otherincome' + key) + + if (target.length > 0) { + target.toggleClass('d-none', !show); + + if (!show) { + target.find('input[type="checkbox"]:checked, input[type="radio"][value="0"]').each(function() { + jQuery(this).prop('checked', jQuery(this).attr('type') === 'radio') + }) + } + + displayOtherIncomeSubFields(target.find('input[type="checkbox"], input[type="radio"]:checked')) + } + } + + function displayOtherIncomeSubFields(el) { + el.each(function() { + var subFields = jQuery(this).closest('.form-row').find('.form-group') + + if (subFields.length > 0) { + subFields.toggleClass('d-none', !jQuery(this).is(':checked')) + subFields.find('input').attr('required', jQuery(this).is(':checked')) + } + }) + } + + function initializePreFilledValues() { + // Gérer l'affichage des sections basé sur les valeurs pré-remplies + setTimeout(function() { + // Vérifier si hascoborrower est pré-rempli + var hasCoBorrowerChecked = jQuery('input[name="hascoborrower"]:checked'); + if (hasCoBorrowerChecked.length > 0) { + displayCoBorrower(); + } + + // Vérifier si hasotherincome est pré-rempli (emprunteur) + var hasOtherIncomeChecked = jQuery('input[name="hasotherincome"]:checked'); + if (hasOtherIncomeChecked.length > 0) { + displayOtherIncome(hasOtherIncomeChecked.val() == 1, '.em'); + } + + // Vérifier si cohasotherincome est pré-rempli (co-emprunteur) + var coHasOtherIncomeChecked = jQuery('input[name="cohasotherincome"]:checked'); + if (coHasOtherIncomeChecked.length > 0) { + displayOtherIncome(coHasOtherIncomeChecked.val() == 1, '.co'); + } + + // Vérifier si hascurrentloan est pré-rempli + var hasCurrentLoanChecked = jQuery('input[name="hascurrentloan"]:checked'); + if (hasCurrentLoanChecked.length > 0) { + var isChecked = hasCurrentLoanChecked.val() == '1'; + jQuery('.wpcf-currentloan').toggleClass('d-none', !isChecked); + } + + // Vérifier si cohascurrentloan est pré-rempli + var coHasCurrentLoanChecked = jQuery('input[name="cohascurrentloan"]:checked'); + if (coHasCurrentLoanChecked.length > 0) { + var isChecked = coHasCurrentLoanChecked.val() == '1'; + jQuery('.wpcf-cocurrentloan').toggleClass('d-none', !isChecked); + } + + // Gérer les champs autres revenus pré-remplis + jQuery('.wpcf-otherincome input[type="checkbox"]:checked').each(function() { + displayOtherIncomeSubFields(jQuery(this)); + }); + + // Gérer les champs indépendant pré-remplis + var jobSelect = jQuery('select[name="job"]'); + if (jobSelect.length > 0 && jobSelect.val()) { + changeJobLabels(jobSelect.val(), jobSelect.closest('fieldset')); + } + + var coJobSelect = jQuery('select[name="cojob"]'); + if (coJobSelect.length > 0 && coJobSelect.val()) { + changeJobLabels(coJobSelect.val(), coJobSelect.closest('fieldset')); + } + }, 100); // Petit délai pour s'assurer que le DOM est chargé + } + + var hasCoBorrowerField = jQuery('input[name="hascoborrower"]:checked') + + if (hasCoBorrowerField.length > 0) { + displayCoBorrower() + } + + if (jQuery('input[name="hasotherincome"]:checked').length > 0) { + displayOtherIncome(jQuery('input[name="hasotherincome"]:checked').val() == 1, '.em') + } + + // Initialisation pour les valeurs pré-remplies + initializePreFilledValues(); + + // Flag pour éviter les déclenchements multiples + var isProcessingJobChange = false; + + jQuery('body').on('change', 'input[name="hascoborrower"]', function() { + // Éviter les déclenchements multiples quand cojob = 5 + if (!isProcessingJobChange) { + displayCoBorrower(); + } + }); + + jQuery('body').on('change', 'input[name="hasotherincome"]', function() { + displayOtherIncome(jQuery(this).val() == 1, '.em') + }); + + jQuery('body').on('change', 'input.wpcf-otherincome--oitype', function(e) { + displayOtherIncomeSubFields(jQuery(e.target)) + }); + + jQuery('body').on('change', 'input[name="cohasotherincome"]', function() { + displayOtherIncome(jQuery(this).val() == 1, '.co') + }); + + jQuery('body').on('change', 'select[name="job"], select[name="cojob"]', function() { + var jobValue = jQuery(this).val(); + var isCojob = jQuery(this).attr('name') === 'cojob'; + var container = jQuery(this).closest('fieldset'); + + // Activer le flag pour éviter les déclenchements multiples + isProcessingJobChange = true; + + // Appeler changeJobLabels + changeJobLabels(jobValue, container); + + // Si c'est cojob, mettre à jour les patterns dans displayCoBorrower + if (isCojob) { + var hasCoBorrower = jQuery('input[name="hascoborrower"]:checked').length > 0 && + jQuery('input[name="hascoborrower"]:checked').val() == 1; + + if (hasCoBorrower) { + // Mettre à jour les patterns pour co-independent_section / coindependent_section selon la valeur + if (jobValue == '5') { + togglePatternForContainer(jQuery('.co-independent_section, .coindependent_section'), true); + } else { + togglePatternForContainer(jQuery('.co-independent_section, .coindependent_section'), false); + } + } + } + + // Si c'est cojob et valeur = 5, éviter de déclencher displayCoBorrower en cascade + if (isCojob && jobValue == '5') { + // Attendre un peu avant de réactiver pour éviter les cascades + setTimeout(function() { + isProcessingJobChange = false; + }, 100); + } else { + isProcessingJobChange = false; + } + }); + + /** + * Step 3 + */ + jQuery('body').on('change', 'select[name="hometype"], select[name="cohometype"]', function(e) { + var val = jQuery(this).val(), + c = 'd-none', + cname = 'wpcf-' + jQuery(this).attr('name') + '--complement-home' + val, + elements = jQuery('.wpcf-' + jQuery(this).attr('name') + '--complement .form-group'); + + elements.addClass(c); + + elements.each(function() { + if (jQuery(this).hasClass(cname)) { + jQuery('.' + cname).removeClass(c); + } + + jQuery(this).find('input, select').attr('required', !jQuery(this).hasClass(c)) + // Synchroniser aussi le pattern avec la visibilité (comme required) + togglePatternForContainer(jQuery(this), !jQuery(this).hasClass(c)) + makeLabelRequired(jQuery(this).context) + }) + + }); + + var currentLoanProto = jQuery('.wpcf-currentloan--block').length > 0 ? jQuery('.wpcf-currentloan--block') : null; + var currentLoanCount = 0; + + if (currentLoanProto !== null) { + currentLoanProto.removeClass('wpcf-prototype'); + currentLoanProto = currentLoanProto[0].outerHTML + jQuery('.wpcf-currentloan--block').remove() + } + + var coCurrentLoanProto = jQuery('.wpcf-cocurrentloan--block').length > 0 ? jQuery('.wpcf-cocurrentloan--block') : null; + var coCurrentLoanCount = 0; + + if (coCurrentLoanProto !== null) { + coCurrentLoanProto.removeClass('wpcf-prototype'); + coCurrentLoanProto = coCurrentLoanProto[0].outerHTML + jQuery('.wpcf-cocurrentloan--block').remove() + } + + jQuery('body').on('change', 'input[name="hascurrentloan"], input[name="cohascurrentloan"]', function(e) { + var selector = jQuery(this).attr('name') === 'hascurrentloan' ? '.wpcf-currentloan' : '.wpcf-cocurrentloan'; + var elem = jQuery(selector), + c = 'd-none'; + // Pour les radio, on vérifie la value sélectionnée + var isChecked = jQuery('input[name="' + jQuery(this).attr('name') + '"]:checked').val() == '1'; + elem.toggleClass(c, !isChecked); + if (!isChecked) { + jQuery(this).attr('name') === 'hascurrentloan' ? jQuery('.wpcf-currentloan--block').remove() : jQuery('.wpcf-cocurrentloan--block').remove(); + } else if (elem.find(selector + '--block').length < 1) { + jQuery(this).attr('name') === 'hascurrentloan' ? addCurrentLoan() : addCoCurrentLoan(); + } + }); + + // Affichage initial au chargement de la page + function updateCurrentLoanVisibility() { + var isChecked = jQuery('input[name="hascurrentloan"]:checked').val() == '1'; + jQuery('.wpcf-currentloan').toggleClass('d-none', !isChecked); + if (!isChecked) { + jQuery('.wpcf-currentloan--block').remove(); + } else if (jQuery('.wpcf-currentloan--block').length < 1) { + addCurrentLoan(); + } + var isCoChecked = jQuery('input[name="cohascurrentloan"]:checked').val() == '1'; + jQuery('.wpcf-cocurrentloan').toggleClass('d-none', !isCoChecked); + if (!isCoChecked) { + jQuery('.wpcf-cocurrentloan--block').remove(); + } else if (jQuery('.wpcf-cocurrentloan--block').length < 1) { + addCoCurrentLoan(); + } + } + // Appel au chargement + updateCurrentLoanVisibility(); + + // Initialiser l'état des champs durationmonth et labels selon les types de prêt existants + function initializeDurationMonthFields() { + jQuery('.wpcf-currentloan--block, .wpcf-cocurrentloan--block').each(function() { + const $block = jQuery(this); + const $loanTypeField = $block.find('select[name*="loantype"]'); + const $durationField = $block.find('input[name*="durationmonth"]'); + const $borrowedCapitalField = $block.find('input[name*="borrowedcapital"]'); + const $monthlyPaymentField = $block.find('input[name*="monthlypayment"]'); + + if ($loanTypeField.length > 0) { + const selectedValue = $loanTypeField.val(); + + // Gestion du champ durationmonth + if ($durationField.length > 0) { + if (selectedValue === '1') { + $durationField.prop('readonly', true); + $durationField.addClass('readonly-field'); + } else { + $durationField.prop('readonly', false); + $durationField.removeClass('readonly-field'); + } + } + + // Gestion des labels borrowedcapital + if ($borrowedCapitalField.length > 0) { + const $borrowedCapitalLabel = $borrowedCapitalField.closest('.form-group').find('label'); + if ($borrowedCapitalLabel.length > 0) { + if (selectedValue === '1') { + $borrowedCapitalLabel.text('Plafond de la carte'); + } else { + $borrowedCapitalLabel.text('Capital emprunté'); + } + } + } + + // Gestion des labels monthlypayment + if ($monthlyPaymentField.length > 0) { + const $monthlyPaymentLabel = $monthlyPaymentField.closest('.form-group').find('label'); + if ($monthlyPaymentLabel.length > 0) { + if (selectedValue === '1') { + $monthlyPaymentLabel.text('Remboursement mensuel'); + } else { + $monthlyPaymentLabel.text('Mensualité'); + } + } + } + } + }); + } + + // Initialiser au chargement de la page + initializeDurationMonthFields(); + + // Initialiser le système de sauvegarde après la définition des fonctions addCurrentLoan et addCoCurrentLoan + initFormStorage(); + + jQuery('body').on('click', 'button.wpcf-currentload--add, button.wpcf-cocurrentload--add', function(e) { + e.preventDefault() + jQuery(this).hasClass('wpcf-currentload--add') ? addCurrentLoan() : addCoCurrentLoan() + }) + + function addCurrentLoan() { + var newLoan = currentLoanProto.replaceAll('__number__', currentLoanCount) + jQuery(newLoan).insertBefore(jQuery('.wpcf-currentload--add')) + + currentLoanCount++ + + // Déclencher l'événement personnalisé pour la sauvegarde + $(document).trigger('currentLoanAdded'); + } + + function addCoCurrentLoan() { + var newLoan = coCurrentLoanProto.replaceAll('__number__', coCurrentLoanCount) + jQuery(newLoan).insertBefore(jQuery('.wpcf-cocurrentload--add')) + + coCurrentLoanCount++ + + // Déclencher l'événement personnalisé pour la sauvegarde + $(document).trigger('currentLoanAdded'); + } + + jQuery('body').on('click', '.wpcf-currentloan--block--remove, .wpcf-cocurrentloan--block--remove', function(e) { + e.preventDefault(); + jQuery(this).parent().remove(); + + // Déclencher l'événement personnalisé pour la sauvegarde + $(document).trigger('currentLoanRemoved'); + }); + + // Gestionnaire pour les champs de type de prêt des crédits en cours + jQuery('body').on('change', 'select[name*="loantype"]', function() { + const selectedValue = jQuery(this).val(); + const $currentBlock = jQuery(this).closest('.wpcf-currentloan--block, .wpcf-cocurrentloan--block'); + + console.log('Type de prêt sélectionné:', selectedValue, 'dans le bloc:', $currentBlock); + + // Gestion du champ durationmonth selon le type de prêt + const $durationField = $currentBlock.find('input[name*="durationmonth"]'); + if ($durationField.length > 0) { + if (selectedValue === '1') { + // Si le type de prêt vaut "1", rendre le champ durationmonth readonly + $durationField.prop('readonly', true); + $durationField.addClass('readonly-field'); + console.log('Champ durationmonth mis en readonly'); + } else { + // Sinon, rendre le champ éditable + $durationField.prop('readonly', false); + $durationField.removeClass('readonly-field'); + console.log('Champ durationmonth rendu éditable'); + } + } + + // Gestion des labels des champs borrowedcapital et monthlypayment + const $borrowedCapitalField = $currentBlock.find('input[name*="borrowedcapital"]'); + const $monthlyPaymentField = $currentBlock.find('input[name*="monthlypayment"]'); + + if ($borrowedCapitalField.length > 0) { + const $borrowedCapitalLabel = $borrowedCapitalField.closest('.form-group').find('label'); + if ($borrowedCapitalLabel.length > 0) { + if (selectedValue === '1') { + $borrowedCapitalLabel.text('Plafond de la carte'); + } else { + $borrowedCapitalLabel.text('Capital emprunté'); + } + } + } + + if ($monthlyPaymentField.length > 0) { + const $monthlyPaymentLabel = $monthlyPaymentField.closest('.form-group').find('label'); + if ($monthlyPaymentLabel.length > 0) { + if (selectedValue === '1') { + $monthlyPaymentLabel.text('Remboursement mensuel'); + } else { + $monthlyPaymentLabel.text('Mensualité'); + } + } + } + + // Ici vous pouvez ajouter la logique spécifique selon le type de prêt sélectionné + // Par exemple, afficher/masquer d'autres champs selon le type + + // Exemple de logique conditionnelle selon le type de prêt + switch(selectedValue) { + case '1': // Hypothèque + console.log('Prêt hypothécaire sélectionné'); + // Logique spécifique pour les prêts hypothécaires + break; + case '2': // Prêt personnel + console.log('Prêt personnel sélectionné'); + // Logique spécifique pour les prêts personnels + break; + case '3': // Crédit auto + console.log('Crédit auto sélectionné'); + // Logique spécifique pour les crédits auto + break; + default: + console.log('Autre type de prêt sélectionné:', selectedValue); + break; + } + + // Déclencher l'événement personnalisé pour la sauvegarde + $(document).trigger('currentLoanTypeChanged', { + value: selectedValue, + block: $currentBlock + }); + }); + + // Fonction pour afficher/cacher la zone isFichedDisplay + function displayIsFichedZone() { + var hasFiched = jQuery('input[name="isFiched"]:checked').length > 0 && + jQuery('input[name="isFiched"]:checked').val() == 1; + + jQuery('.isFichedDisplay').toggleClass('d-none', !hasFiched); + } + + // Vérifier l'état initial + var isFichedField = jQuery('input[name="isFiched"]:checked'); + if (isFichedField.length > 0) { + displayIsFichedZone(); + } + + // Ajouter l'écouteur d'événement pour le changement + jQuery('body').on('change', 'input[name="isFiched"]', displayIsFichedZone); + + // Fonction pour afficher/cacher la zone isIndependant + function displayIsIndependantZone() { + var isIndependant = jQuery('select[name="job"]').val() === '5'; + var zone = jQuery('.isIndependant'); + zone.toggleClass('d-none', !isIndependant); + + // Gérer l'attribut required/pattern en fonction de la visibilité + if (isIndependant) { + zone.find('input, select, textarea').each(function() { + var wasRequired = jQuery(this).attr('data-initial-required') === '1'; + if (wasRequired) { + jQuery(this).attr('required', true); + } else { + jQuery(this).removeAttr('required'); + } + }); + togglePatternForContainer(zone, true); + } else { + zone.find('input, select, textarea').removeAttr('required'); + togglePatternForContainer(zone, false); + } + + makeLabelRequired(); + } + + // Vérifier l'état initial + var jobSelect = jQuery('select[name="job"]'); + if (jobSelect.length > 0) { + displayIsIndependantZone(); + } + + // Ajouter l'écouteur d'événement pour le changement + jQuery('body').on('change', 'select[name="job"]', displayIsIndependantZone); + + // Fonction pour afficher/cacher la zone hasLoyer + function displayHasLoyerZone() { + var isLocataire = jQuery('select[name="habitation_type"]').val() === 'locataire'; + jQuery('.hasLoyer').toggleClass('d-none', !isLocataire); + } + + // Vérifier l'état initial + var situationSelect = jQuery('select[name="habitation_type"]'); + if (situationSelect.length > 0) { + displayHasLoyerZone(); + } + + // Ajouter l'écouteur d'événement pour le changement + jQuery('body').on('change', 'select[name="habitation_type"]', displayHasLoyerZone); + + // Affichage de la taille totale des fichiers sélectionnés pour le champ IDpaycheck + vérification taille max 2 Mo + jQuery('body').on('change', '#IDpaycheck, #IDcopaycheck', function(e) { + var files = e.target.files; + var totalSize = 0; + var maxSize = 2 * 1024 * 1024; // 2 Mo en octets + var errorFiles = []; + for (var i = 0; i < files.length; i++) { + totalSize += files[i].size; + if (files[i].size > maxSize) { + errorFiles.push(files[i].name); + } + } + // Conversion en Mo, arrondi à 2 décimales + var totalSizeMo = (totalSize / (1024 * 1024)).toFixed(2); + // Création ou sélection de l'élément d'affichage + var infoId = 'paycheck-size-info'; + var infoElem = jQuery('#' + infoId); + if (infoElem.length === 0) { + infoElem = jQuery('
    '); + jQuery(this).after(infoElem); + } + // Création ou sélection de l'élément d'erreur + var errorId = 'paycheck-size-error'; + var errorElem = jQuery('#' + errorId); + if (errorElem.length === 0) { + errorElem = jQuery('
    '); + infoElem.after(errorElem); + } + var submitBtn = jQuery('.form-submit button[type="submit"]'); + if (files.length > 0) { + infoElem.text('Taille totale des fichiers sélectionnés : ' + totalSizeMo + ' Mo'); + } else { + infoElem.text(''); + } + if (errorFiles.length > 0) { + errorElem.html('Fichier(s) trop volumineux (> 2 Mo) :
    ' + errorFiles.join(', ') + ''); + submitBtn.prop('disabled', true); + } else { + errorElem.text(''); + submitBtn.prop('disabled', false); + } + }); + + // Affichage conditionnel du champ "fonds propres" selon le choix Oui/Non avec effet slide + const yesRadio = document.getElementById('estateequity_yes'); + const noRadio = document.getElementById('estateequity_no'); + if (yesRadio && noRadio) { + $(yesRadio).on('change', function() { + if (yesRadio.checked) { + $('.fonds-propres').stop(true, true).slideDown(); + $('[name="estateequity"]').prop('required', true); + } + }); + $(noRadio).on('change', function() { + if (noRadio.checked) { + $('.fonds-propres').stop(true, true).slideUp(); + $('[name="estateequity"]').prop('required', false); + } + }); + // Initialisation à l'ouverture de la page + if (yesRadio.checked) { + $('.fonds-propres').show(); + } else { + $('.fonds-propres').hide(); + } + } + + // Variables pour le debouncing des inputs + let capitalTimeout; + let durationTimeout; + let isCreditCalculationEnabled = true; + + if(jQuery('#creditCalcManualSwitch').length > 0) + isCreditCalculationEnabled = true; + + // Liste des types de crédit qui utilisent des années + const LOAN_TYPES_IN_YEARS = ['am', 'amr', 'cied', 'ph']; + + // Fonction pour mettre à jour l'affichage des valeurs calculées + function updateCreditDisplay(result) { + console.log('updateCreditDisplay - result:', result); + + // Calcul du TAEG + const taeg = parseFloat(result.taux_nominal_annuel.replace('%', '')); + const taux_debiteur = (taeg * 0.11 + taeg).toFixed(2); + + // Mise à jour des champs cachés + jQuery('input[name="capital"]').val(result.capital); + jQuery('input[name="duree"]').val(result.duree); + jQuery('input[name="cout_total"]').val(result.cout_total); + jQuery('input[name="mensualite"]').val(result.mensualite); + jQuery('input[name="taux_nominal_annuel"]').val(result.taux_nominal_annuel); + + console.log('updateCreditDisplay - Champs cachés mis à jour:', { + capital: result.capital, + duree: result.duree, + cout_total: result.cout_total, + mensualite: result.mensualite, + taux: result.taux_nominal_annuel + }); + + // Mise à jour de l'affichage dans .credit-info + jQuery('.credit-info .credit-item').each(function() { + var $value = jQuery(this).find('.credit-value'); + var $label = jQuery(this).find('.credit-label'); + + if($label.text().includes('Montant:')) { + $value.text(result.capital + ' €'); + } + else if($label.text().includes('Durée:')) { + $value.text(result.duree + ($('input[name="type_credit"]').val() === 'am' ? ' ans' : ' mois')); + } + else if($label.text().includes('Mensualité:')) { + $value.text(result.mensualite + '€'); + } + else if($label.text().includes('Coût total:')) { + $value.text(result.cout_total + '€'); + } + else if($label.text().includes('TAEG:')) { + $value.text(taux_debiteur + '%'); + } + else if($label.text().includes('Taux débiteur:')) { + $value.text(result.taux_nominal_annuel); + } + }); + + // Mise à jour du récapitulatif dans .info-credits-step + jQuery('.info-credits-step .row > div').each(function() { + $(this).find('p').each(function() { + var $label = $(this); + var $value = $label.next('span'); + + if($label.text().includes('Montant emprunté :')) { + $value.text(result.capital + ' €'); + } + else if($label.text().includes('Durée :')) { + $value.text(result.duree + ($('input[name="type_credit"]').val() === 'am' ? ' ans' : ' mois')); + } + else if($label.text().includes('Mensualité :')) { + $value.text(result.mensualite + ' €'); + } + else if($label.text().includes('Coût Total :')) { + $value.text(result.cout_total + ' €'); + } + else if($label.text().includes('Taux débiteur :')) { + $value.text(result.taux_nominal_annuel); + } + else if($label.text().includes('Taeg :')) { + $value.text(taux_debiteur + '%'); + } + }); + }); + + console.log('updateCreditDisplay - Affichage mis à jour'); + } + + // Fonction pour mettre à jour les limites et valeurs des champs selon le type de crédit + function updateFieldLimits(selectedType) { + const creditType = map_values[selectedType]; + if (!creditType) { + console.warn('Type de crédit non reconnu:', selectedType); + return; + } + + const $capitalField = jQuery('#IDbatiment_emprunt'); + const $durationField = jQuery('#IDbatiment_duree'); + let currentCapital = parseFloat($capitalField.val()); + + // Récupérer les limites depuis form_sliders pour les durées + const sliderConfig = form_sliders[creditType]; + if (!sliderConfig) { + console.warn('Configuration slider non trouvée pour:', creditType); + return; + } + + // Récupérer les limites spécifiques du crédit depuis cd_js.groups + const creditConfig = cd_js.groups[selectedType]; + if (creditConfig && creditConfig.capital_max) { + // Ne modifier le montant que s'il dépasse la limite du crédit choisi + if (currentCapital > creditConfig.capital_max) { + currentCapital = creditConfig.capital_selected || creditConfig.capital_max; + $capitalField.val(currentCapital); + } + } + + // Mettre à jour les attributs min/max du champ capital + $capitalField.attr('min', sliderConfig.capital_min); + $capitalField.attr('max', sliderConfig.capital_max); + $capitalField.attr('step', sliderConfig.capital_step || 100); + + // Ajuster la valeur du capital si nécessaire selon les limites du slider + if (currentCapital > sliderConfig.capital_max) { + currentCapital = sliderConfig.capital_max; + $capitalField.val(currentCapital); + } else if (currentCapital < sliderConfig.capital_min) { + currentCapital = sliderConfig.capital_min; + $capitalField.val(currentCapital); + } + + // Déterminer la durée maximale disponible pour ce montant + const isYearlyDuration = LOAN_TYPES_IN_YEARS.includes(creditType); + let maxDurationForAmount = sliderConfig.durees[sliderConfig.durees.length - 1]; + + // Parcourir les durées disponibles dans l'ordre décroissant + for (let i = sliderConfig.durees.length - 1; i >= 0; i--) { + const duration = sliderConfig.durees[i]; + // Vérifier si cette durée est valide pour le montant actuel + if (currentCapital >= sliderConfig.capital_min && currentCapital <= sliderConfig.capital_max) { + maxDurationForAmount = duration; + break; + } + } + + // Convertir la durée maximale en années si nécessaire + const displayDuration = isYearlyDuration ? Math.floor(maxDurationForAmount / 12) : maxDurationForAmount; + const minDuration = isYearlyDuration ? Math.ceil(sliderConfig.duree_min / 12) : sliderConfig.duree_min; + const maxDuration = isYearlyDuration ? Math.floor(sliderConfig.duree_max / 12) : sliderConfig.duree_max; + + // Mettre à jour les attributs min/max du champ durée + $durationField.attr('min', minDuration); + $durationField.attr('max', maxDuration); + + // Définir la durée maximale disponible + $durationField.val(displayDuration); + + // Mettre à jour l'unité dans l'input-group-text + jQuery('.input-group-text').text(isYearlyDuration ? 'Ans' : 'Mois'); + + // Mettre à jour l'affichage + calculateCredit(); + + // Mettre à jour le champ caché type_credit + jQuery('input[name="type_credit"]').val(creditType); + } + + // Gestionnaire pour le changement de type de crédit + jQuery('#IDestateloantype').on('change', function() { + const creditType = jQuery(this).val(); + if (creditType) { + updateFieldLimits(creditType); + calculateCredit(); + } + }); + + // Fonction pour arrondir le capital à la valeur acceptable la plus proche + function snapCapitalValue(value, creditType) { + if (!creditType || !form_sliders[creditType]) { + return value; + } + + const sliderConfig = form_sliders[creditType]; + + // Utiliser le step défini dans form_sliders + const step = sliderConfig.capital_step || 100; + + // S'assurer que la valeur est dans les limites + value = Math.max(sliderConfig.capital_min, Math.min(value, sliderConfig.capital_max)); + + // Arrondir à la valeur la plus proche selon le step + return Math.round(value / step) * step; + } + + // Fonction pour arrondir la durée à la valeur acceptable la plus proche + function snapDurationValue(value, creditType) { + if (!creditType || !form_sliders[creditType]) { + return value; + } + + const sliderConfig = form_sliders[creditType]; + const isYearlyDuration = LOAN_TYPES_IN_YEARS.includes(creditType); + + console.log('snapDurationValue - value:', value); + console.log('snapDurationValue - creditType:', creditType); + console.log('snapDurationValue - isYearlyDuration:', isYearlyDuration); + + if (isYearlyDuration) { + // Pour les crédits en années, on vérifie juste les limites min/max + // Les limites sont déjà en années pour ces types de crédit + const minYears = sliderConfig.duree_min; + const maxYears = sliderConfig.duree_max; + + console.log('snapDurationValue - minYears:', minYears); + console.log('snapDurationValue - maxYears:', maxYears); + + if (value > maxYears) return maxYears; + if (value < minYears) return minYears; + return value; + } else { + // Pour les autres crédits, on cherche la durée disponible la plus proche + let closestDuration = sliderConfig.durees[0]; + let minDiff = Math.abs(value - sliderConfig.durees[0]); + + for (let i = 1; i < sliderConfig.durees.length; i++) { + const diff = Math.abs(value - sliderConfig.durees[i]); + if (diff < minDiff) { + minDiff = diff; + closestDuration = sliderConfig.durees[i]; + } + } + return closestDuration; + } + } + + // Fonction pour calculer la mensualité + function calc_mens(mnt, dur, taeg) { + const creditType = jQuery('input[name="type_credit"]').val(); + + // Pour le crédit pont, on ne calcule que les intérêts mensuels + if (creditType === 'cdp') { + const t100 = taeg / 100; + // Calcul des intérêts mensuels uniquement : (capital * taux_annuel) / 12 + const mens = (mnt * t100) / 12; + return Math.floor(mens * 100) / 100; + } + + // Pour les autres types de crédit, calcul normal + const t100 = taeg / 100; + const t101 = 1 + t100; + const d12 = 1 / 12; + const dur12 = dur / 12; + const buf1 = Math.pow(t101, d12); + const buf2 = Math.pow(1 / t101, dur12); + const mens = (mnt * (buf1 - 1)) / (1 - buf2); + + return Math.floor(mens * 100) / 100; + } + + // Notre propre fonction de calcul qui utilise les fonctions de base de cd_main.js + function calculateCredit() { + const capital = parseFloat(jQuery('#IDbatiment_emprunt').val()); + const duration = parseInt(jQuery('#IDbatiment_duree').val()); + const selectedType = jQuery('#IDestateloantype').val(); + const creditType = map_values[selectedType]; + + console.log('=== Début calcul crédit ==='); + console.log('Type sélectionné:', selectedType); + console.log('Type de crédit mappé:', creditType); + console.log('Capital:', capital); + console.log('Durée:', duration); + + if (isNaN(capital) || isNaN(duration) || !creditType) { + console.warn('Valeurs invalides pour le calcul:', { + capital: isNaN(capital) ? 'invalide' : capital, + duration: isNaN(duration) ? 'invalide' : duration, + selectedType, + creditType: !creditType ? 'non mappé' : creditType + }); + return; + } + + // Convertir la durée en mois si nécessaire pour les calculs + const isYearlyDuration = LOAN_TYPES_IN_YEARS.includes(creditType); + const durationForCalculation = isYearlyDuration ? duration * 12 : duration; + + console.log('Durée pour calcul:', durationForCalculation, isYearlyDuration ? '(en années)' : '(en mois)'); + + let results; + // Appeler la fonction de calcul appropriée + switch(creditType) { + case 'pat': + results = calculate_pat(capital, duration); + break; + case 'am': + results = calculate_am(capital, duration); + break; + case 'ph': + results = calculate_ph(capital, duration); + break; + case 'amr': + case 'cdp': + case 'cied': + results = calculate_mono_rate_bt_10_30(creditType, capital, duration); + break; + case 'fin_neuve': + results = calculate_fin_neuve(capital, duration); + break; + case 'fin_occ_m3a': + results = calculate_pao_m_3(capital, duration); + break; + case 'fin_occ_p3a': + results = calculate_pao_p_3(capital, duration); + break; + case 'mobil_carav': + results = calculate_mobilhome(capital, duration); + break; + case 'regroup_cred': + results = calculate_regroupement_de_credit(capital, duration); + break; + case 'frais_notaire': + results = calculate_frais_notaire(capital, duration); + break; + case 'but_immo': + results = calculate_but_immo(capital, duration); + break; + default: + console.warn('Type de crédit non reconnu:', creditType); + results = calculate_pat(capital, duration); + } + + if (!results) { + console.warn('Pas de résultats retournés par la fonction de calcul'); + return; + } + + console.log('Résultats bruts:', results); + + // Extraire les valeurs des résultats + const [min_duration, max_duration, selected_duration, duree_in_range, taux_nominal] = results; + + // Convertir le taux en nombre si c'est une chaîne + const taux = parseFloat(String(taux_nominal).replace('%', '')); + + if (isNaN(taux)) { + console.error('Taux nominal invalide après conversion:', { + original: taux_nominal, + converti: taux + }); + return; + } + + console.log('Taux nominal (débiteur):', taux + '%'); + console.log('Durée sélectionnée:', selected_duration, isYearlyDuration ? 'mois (convertie)' : 'mois'); + + // Pour les crédits en années, la durée retournée est déjà en mois + const durationInMonths = isYearlyDuration ? durationForCalculation : selected_duration; + + // Calculer la mensualité avec notre fonction locale + const mensualite = calc_mens(capital, durationInMonths, taux); + + if (isNaN(mensualite)) { + console.error('Erreur dans le calcul de la mensualité:', { + capital, + durationInMonths, + taux + }); + return; + } + + const cout_total = (mensualite * durationInMonths).toFixed(2); + + console.log('Mensualité calculée:', mensualite.toFixed(2) + '€'); + console.log('Coût total calculé:', cout_total + '€'); + + // Créer l'objet result pour updateCreditDisplay + const displayResult = { + capital: capital, + duree: duration, + mensualite: mensualite.toFixed(2), + cout_total: cout_total, + taux_nominal_annuel: taux.toFixed(2) + ' %', + taux_debiteur: taux.toFixed(2) + ' %' + }; + + console.log('Résultat final pour affichage:', displayResult); + console.log('--- Fin calcul crédit ---'); + + // Mettre à jour l'affichage + updateCreditDisplay(displayResult); + + // Mettre à jour le champ caché type_credit + jQuery('input[name="type_credit"]').val(creditType); + } + + if(isCreditCalculationEnabled) { + // Remplacer tous les appels à calculate_mensualite par calculateCredit + jQuery('#IDbatiment_emprunt') + .on('input', function() { + const $this = jQuery(this); + clearTimeout(capitalTimeout); + + if ($this.val() !== '') { + capitalTimeout = setTimeout(() => { + let capital = parseFloat($this.val()); + if (!isNaN(capital)) { + const creditType = jQuery('input[name="type_credit"]').val(); + const snappedValue = snapCapitalValue(capital, creditType); + if (snappedValue !== capital) { + $this.val(snappedValue); + } + calculateCredit(); + } + }, 500); // Délai un peu plus long pour laisser le temps de taper + } + }) + .on('change', function() { + // Validation finale quand on quitte le champ (onblur) + const $this = jQuery(this); + if ($this.val() !== '') { + let capital = parseFloat($this.val()); + if (!isNaN(capital)) { + const selectedType = jQuery('#IDestateloantype').val(); + const creditConfig = cd_js.groups[selectedType]; + + // Vérifier les limites du crédit + if (creditConfig && creditConfig.capital_max && capital > creditConfig.capital_max) { + capital = creditConfig.capital_selected || creditConfig.capital_max; + $this.val(capital); + } + + // Snap à la valeur la plus proche et recalcul + const creditType = jQuery('input[name="type_credit"]').val(); + const snappedValue = snapCapitalValue(capital, creditType); + if (snappedValue !== capital) { + $this.val(snappedValue); + } + calculateCredit(); + } + } + }); + + jQuery('#IDbatiment_duree') + .on('input', function() { + const $this = jQuery(this); + clearTimeout(durationTimeout); + durationTimeout = setTimeout(() => { + let duration = parseInt($this.val()); + if (!isNaN(duration)) { + const creditType = jQuery('input[name="type_credit"]').val(); + console.log('Input duration:', duration); + console.log('Credit type:', creditType); + console.log('Is yearly:', LOAN_TYPES_IN_YEARS.includes(creditType)); + + // Ne pas snapper pendant la saisie pour les crédits en années + if (LOAN_TYPES_IN_YEARS.includes(creditType)) { + calculateCredit(); + } else { + const snappedValue = snapDurationValue(duration, creditType); + if (snappedValue !== duration) { + $this.val(snappedValue); + } + calculateCredit(); + } + } + }, 300); + }) + .on('change', function() { + let duration = parseInt($(this).val()); + if (!isNaN(duration)) { + const creditType = jQuery('input[name="type_credit"]').val(); + console.log('onchange - creditType:', creditType); + console.log('onchange - LOAN_TYPES_IN_YEARS:', LOAN_TYPES_IN_YEARS); + console.log('onchange - includes?', LOAN_TYPES_IN_YEARS.includes(creditType)); + + if (LOAN_TYPES_IN_YEARS.includes(creditType)) { + console.log('change', duration); + const snappedValue = snapDurationValue(duration, creditType); + console.log('snappedValue', snappedValue); + if (snappedValue !== duration) { + $(this).val(snappedValue); + } + } else { + // Pour les autres crédits, comportement normal + const snappedValue = snapDurationValue(duration, creditType); + if (snappedValue !== duration) { + $(this).val(snappedValue); + } + } + calculateCredit(); + } + }); + + // Calcul initial au chargement + /* $(document).ready(function() { + const creditType = $('input[name="type_credit"]').val(); + if (creditType) { + updateFieldLimits(creditType); + calculateCredit(); + } + }); */ + + // Gestionnaire pour la soumission du formulaire - s'exécute AVANT la validation HTML5 + jQuery('.form-submit').on('submit', function(e) { + // Retirer l'attribut required de tous les champs dans les sections cachées + // AVANT la validation HTML5 pour éviter l'erreur "not focusable" + removeRequiredFromHiddenFields(); + // Recalculer une dernière fois avant l'envoi + calculateCredit(); + // Laisser le formulaire se soumettre normalement après avoir retiré les required des champs cachés + }); + } + + function findRate(type) { + console.log('findRate - Type recherché:', type); + let rate; + + switch(type) { + case 'amr': + rate = cd_js.groups.achat_maison_de_rapport.de_10_a_30_ans; + break; + case 'cdp': + rate = cd_js.groups.credit_pont.de_10_a_30_ans; + break; + case 'cied': + rate = cd_js.groups.independants_et_entreprises_en_difficultes.de_10_a_30_ans; + break; + default: + console.warn('Type de crédit non reconnu pour le taux mono:', type); + rate = null; + } + + console.log('findRate - Taux trouvé:', rate); + return rate; + } + + function calculate_mono_rate_bt_10_30(type, selected_capital, selected_duration) { + const annual_rate = findRate(type); + if (!annual_rate) { + console.error('Taux non trouvé pour le type:', type); + return null; + } + + const min_duration = 10; + const max_duration = 30; + let duree_in_range = true; + const add_message = ''; + + if (min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration) { + // La durée est dans la plage + } else { + duree_in_range = false; + selected_duration = max_duration; + } + + // Convertir la durée en mois pour le calcul + selected_duration = selected_duration * 12; + + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message]; + } + +}); + +// --- Changement dynamique du label Numéro de registre national selon la nationalité (emprunteur et co-emprunteur) --- +jQuery(function($) { + function setupNationalRegLabel(selectId, labelId) { + var defaultLabel = 'Numéro de registre national'; + var luxLabel = 'Numéro de sécurité sociale'; + var select = $('#' + selectId); + var labelSelector = 'label[for="' + labelId + '"]'; + function updateLabel() { + var val = select.val(); + if (val === 'LU') { + $(labelSelector).text(luxLabel); + } else { + $(labelSelector).text(defaultLabel); + } + } + select.on('change', updateLabel); + // Initialisation au chargement + updateLabel(); + } + setupNationalRegLabel('IDnationality', 'IDnationalregistrationnumber'); + setupNationalRegLabel('IDconationality', 'IDconationalregistrationnumber'); +}); + +// --- Initialisation des Inputmasks pour les champs de date --- +jQuery(function($) { + // Initialisation des champs de date avec inputmask + jQuery('input[data-inputmask]').inputmask(); + + // Configuration spécifique pour tous les champs de date + jQuery('.input-date').inputmask({ + mask: '99/99/9999', + placeholder: 'JJ/MM/AAAA', + clearMaskOnLostFocus: false, + showMaskOnHover: true, + showMaskOnFocus: true + }); +}); + +if(jQuery('.etat-civil-pat').length > 0) { + + // Variable pour tracker si le co-emprunteur a été forcé par l'état civil + let coBorrowerForcedByCivilStatus = false; + + jQuery('#IDcivilstatus').on('change', function() { + let etatCivil = jQuery('#IDcivilstatus').val(), + switchValue = 4, + hascoborrower_input = jQuery('[name="hascoborrower"]'), + parent = hascoborrower_input.parents('fieldset'), + info = cd_js.info_pat; + + if(etatCivil == switchValue) { + // État civil = 4 : forcer l'activation du co-emprunteur + hascoborrower_input[1].checked = true; + coBorrowerForcedByCivilStatus = true; + parent.append('
    ' + info + '
    '); + } else { + // État civil ≠ 4 : ne désactiver que si c'était précédemment forcé + if(coBorrowerForcedByCivilStatus) { + hascoborrower_input[0].checked = true; + coBorrowerForcedByCivilStatus = false; + parent.find('.alert').remove(); + } + // Si ce n'était pas forcé, on laisse le choix de l'utilisateur + } + + // Déclencher l'événement change sur le bouton radio pour activer displayCoBorrower + // Mais éviter les déclenchements multiples si cojob = 5 + var cojobValue = jQuery('select[name="cojob"]').val(); + if (cojobValue !== '5') { + jQuery('input[name="hascoborrower"]:checked').trigger('change'); + } else { + // Si cojob = 5, appeler directement sans trigger pour éviter la cascade + displayCoBorrower(); + } + }); + + // Réinitialiser le flag quand l'utilisateur change manuellement le co-emprunteur + jQuery('[name="hascoborrower"]').on('change', function() { + if(!jQuery('#IDcivilstatus').val() == 4) { + coBorrowerForcedByCivilStatus = false; + } + }); + +} \ No newline at end of file diff --git a/assets/js/form_main.old.js b/assets/js/form_main.old.js new file mode 100644 index 0000000..7ed57f4 --- /dev/null +++ b/assets/js/form_main.old.js @@ -0,0 +1,1438 @@ +jQuery(function($) { + jQuery('form.load_simulator').each(function() { + jQuery(this).attr('action', window.location.origin + '/credit-step1') + }) + + /** + * Système de sauvegarde localStorage + */ + const FORM_STORAGE_KEY = 'credit_direct_form_data'; + const FORM_STORAGE_TIMESTAMP = 'credit_direct_form_timestamp'; + const STORAGE_EXPIRY_HOURS = 24; // Les données expirent après 24h + + /** + * Affiche l'indicateur de sauvegarde + */ + function showSaveIndicator(message, type = 'success') { + let indicator = jQuery('.auto-save-indicator'); + + if (indicator.length === 0) { + indicator = jQuery('
    '); + jQuery('body').append(indicator); + } + + indicator.removeClass('show saving error').addClass('show ' + type); + indicator.text(message); + + // Masquer après 3 secondes + setTimeout(() => { + indicator.removeClass('show'); + }, 3000); + } + + /** + * Sauvegarde les données du formulaire dans localStorage + */ + function saveFormData() { + // Afficher l'indicateur de sauvegarde + showSaveIndicator('Sauvegarde en cours...', 'saving'); + + const formData = {}; + const currentStep = getCurrentStep(); + + // Récupérer tous les champs du formulaire + jQuery('form.form-submit').find('input, select, textarea').each(function() { + const $field = jQuery(this); + const name = $field.attr('name'); + const type = $field.attr('type'); + + if (!name) return; + + let value = ''; + + switch (type) { + case 'checkbox': + value = $field.is(':checked') ? $field.val() : ''; + break; + case 'radio': + if ($field.is(':checked')) { + value = $field.val(); + } + break; + case 'file': + // Ne pas sauvegarder les fichiers + return; + default: + value = $field.val() || ''; + break; + } + + // Ne sauvegarder que si la valeur n'est pas vide + if (value !== '') { + formData[name] = value; + } + }); + + // Sauvegarder avec l'étape actuelle et le timestamp + const dataToSave = { + step: currentStep, + data: formData, + timestamp: Date.now() + }; + + try { + localStorage.setItem(FORM_STORAGE_KEY, JSON.stringify(dataToSave)); + localStorage.setItem(FORM_STORAGE_TIMESTAMP, Date.now().toString()); + console.log('Données sauvegardées dans localStorage:', dataToSave); + + // Afficher le succès + setTimeout(() => { + showSaveIndicator('Données sauvegardées', 'success'); + }, 500); + + } catch (e) { + console.error('Erreur lors de la sauvegarde localStorage:', e); + showSaveIndicator('Erreur de sauvegarde', 'error'); + } + } + + /** + * Restaure les données du formulaire depuis localStorage + */ + function restoreFormData() { + try { + const savedData = localStorage.getItem(FORM_STORAGE_KEY); + if (!savedData) return false; + + const parsedData = JSON.parse(savedData); + const now = Date.now(); + const savedTime = parsedData.timestamp || 0; + + // Vérifier si les données ne sont pas expirées + if (now - savedTime > STORAGE_EXPIRY_HOURS * 60 * 60 * 1000) { + console.log('Données localStorage expirées, suppression...'); + clearFormData(); + return false; + } + + const formData = parsedData.data || {}; + let restoredCount = 0; + + // Restaurer les valeurs + Object.keys(formData).forEach(name => { + const $field = jQuery('form.form-submit').find(`[name="${name}"]`); + if ($field.length === 0) return; + + const value = formData[name]; + const type = $field.attr('type'); + + switch (type) { + case 'checkbox': + if (value) { + $field.prop('checked', true); + } + break; + case 'radio': + $field.filter(`[value="${value}"]`).prop('checked', true); + break; + default: + $field.val(value); + break; + } + + // Ajouter un effet visuel temporaire + $field.addClass('field-restored'); + setTimeout(() => { + $field.removeClass('field-restored'); + }, 2000); + + restoredCount++; + }); + + console.log(`${restoredCount} champs restaurés depuis localStorage`); + + if (restoredCount > 0) { + showSaveIndicator(`${restoredCount} champs restaurés`, 'success'); + } + + return restoredCount > 0; + + } catch (e) { + console.error('Erreur lors de la restauration localStorage:', e); + return false; + } + } + + /** + * Efface les données du formulaire du localStorage + */ + function clearFormData() { + try { + localStorage.removeItem(FORM_STORAGE_KEY); + localStorage.removeItem(FORM_STORAGE_TIMESTAMP); + console.log('Données localStorage effacées'); + + // Masquer le message d'information + jQuery('.localstorage-info').fadeOut(); + + // Afficher un message de confirmation + showSaveIndicator('Données effacées', 'success'); + + } catch (e) { + console.error('Erreur lors de l\'effacement localStorage:', e); + showSaveIndicator('Erreur lors de l\'effacement', 'error'); + } + } + + // Rendre la fonction accessible globalement + window.clearFormData = clearFormData; + + /** + * Détermine l'étape actuelle basée sur l'URL + */ + function getCurrentStep() { + const path = window.location.pathname; + if (path.includes('credit-step1')) return 'step1'; + if (path.includes('credit-step2')) return 'step2'; + if (path.includes('credit-step3')) return 'step3'; + if (path.includes('credit-step4')) return 'step4'; + if (path.includes('credit-step5')) return 'step5'; + return 'unknown'; + } + + /** + * Sauvegarde automatique lors de la modification des champs + */ + function setupAutoSave() { + // Sauvegarde sur clic du lien "previous-step" + jQuery('a.previous-step').on('click', function(e) { + /* e.preventDefault(); */ + saveFormData(); + }); + + // Sauvegarde sur changement de valeur (désactivé) + // jQuery('form.form-submit').on('change input', 'input, select, textarea', function() { + // // Debounce pour éviter trop de sauvegardes + // clearTimeout(window.autoSaveTimeout); + // window.autoSaveTimeout = setTimeout(saveFormData, 1000); + // }); + + // Sauvegarde sur clic des boutons radio/checkbox (désactivé) + // jQuery('form.form-submit').on('click', 'input[type="radio"], input[type="checkbox"]', function() { + // setTimeout(saveFormData, 100); + // }); + + // Sauvegarde avant soumission du formulaire (désactivé) + // jQuery('form.form-submit').on('submit', function() { + // saveFormData(); + // }); + + // Sauvegarde avant navigation (bouton étape précédente) (désactivé) + // jQuery('a[href*="credit-step"]').on('click', function() { + // saveFormData(); + // }); + + // Sauvegarde lors de l'ajout/suppression de crédits en cours (désactivé) + // $(document).on('currentLoanAdded currentLoanRemoved', function() { + // setTimeout(saveFormData, 500); + // }); + } + + /** + * Affiche le message d'information localStorage + */ + function showLocalStorageInfo() { + const savedData = localStorage.getItem(FORM_STORAGE_KEY); + if (!savedData) return; + + // Vérifier si le message existe déjà + if (jQuery('.localstorage-info').length > 0) return; + + const infoHtml = ` +
    + 💾 + Vos données sont sauvegardées automatiquement. + +
    + `; + + // Insérer au début du formulaire + jQuery('form.form-submit').prepend(infoHtml); + } + + /** + * Initialise le système de sauvegarde + */ + function initFormStorage() { + + if(hasCreditDirectToken()) + return; + + //check if localStorage is empty + if(localStorage.getItem(FORM_STORAGE_KEY) === null) + return; + + // Restaurer les données au chargement + const restored = restoreFormData(); + + // Configurer la sauvegarde automatique + setupAutoSave(); + + // Effacer les données après soumission réussie (optionnel) + jQuery(document).on('formSubmitted', function() { + clearFormData(); + }); + + // Si des données ont été restaurées, initialiser l'affichage des zones conditionnelles + if (restored) { + setTimeout(function() { + initializePreFilledValues(); + }, 200); + } + + // Afficher le message d'information + showLocalStorageInfo(); + + console.log('Système de sauvegarde localStorage initialisé'); + } + + function hasCreditDirectToken() { + return window.location.search.includes('credit-direct-token'); + } + + // Initialiser le système de sauvegarde UNIQUEMENT si le paramètre est présent dans l'URL + initFormStorage(); + if (hasCreditDirectToken()) { + } + + /** + * General + */ + function empty(value) { return value == undefined || value == null || value == [] || value == ''; } + + function makeLabelRequired(containerSelector = 'body') { + if (jQuery(containerSelector).length > 0) { + jQuery(containerSelector).find('input:required, select:required, textarea:required').each(function() { + var labelId = jQuery(this).attr('id'); + var label = jQuery('label[for="' + labelId + '"]') + + if (label.length > 0 && label.html().charAt(label.html().length - 1) !== '*') { + label.html(label.html() + '*') + } + }) + } + } + + if (jQuery('.wpcf-borrower').length > 0) { + makeLabelRequired('.wpcf-borrower') + } else { + makeLabelRequired('.form-submit') + } + + /** + * Step 2 + */ + function changeJobLabels(value, container) { + var jobLabels = { + independent: { + factory: 'de l\'entreprise', + salary: 'Revenu imposable annuel', + startDate: 'de début d\'activité' + }, + withoutEmployer: { + employer: 'de l\'employeur/organisme de paiement', + salary: 'Indemnités mensuelles', + startDate: 'd\'engagement' + }, + withEmployer: { + employer: 'de l\'employeur/organisme de paiement', + salary: 'Salaire net mensuel', + startDate: 'd\'engagement' + } + }, job = { + independent: 5, + withoutEmployer: ['1','6','9','12'] + }; + + console.log('job', value, job.independent); + + var prefix = container.find('#IDcofirstname').length > 0 ? 'co' : '' + var fields = ['emname', 'emaddress', 'emzip', 'emcity', 'emcountry', 'commitmentdate', 'salary'] + + fields.forEach(id => { + var labelText = null + + switch (id) { + case 'commitmentdate': + if(value === job.independent) { + labelText = jobLabels.independent.startDate + } else if(job.withoutEmployer.includes(value)) { + labelText = jobLabels.withoutEmployer.startDate + } else { + labelText = jobLabels.withEmployer.startDate + } + break; + + case 'salary': + + if(value === job.independent) { + labelText = jobLabels.independent.salary + } else if(job.withoutEmployer.includes(value)) { + labelText = jobLabels.withoutEmployer.salary + } else { + labelText = jobLabels.withEmployer.salary + } + break; + + default: + if(value === job.independent) { + labelText = jobLabels.independent.factory + } else if(job.withoutEmployer.includes(value)) { + labelText = jobLabels.withoutEmployer.employer + } else { + labelText = jobLabels.withEmployer.employer + } + break; + } + + container.find('label[for="ID' + prefix + id + '"] > span').text(labelText); + + console.log('labelText', labelText); + }); + + /* console.log('container', container); + console.log('prefix', container.find('.'+prefix+'independent_section')); */ + console.log('value', value); + + if(value == job.independent) { + container.find('.'+prefix+'independent_section').fadeIn().removeClass('hidden'); + //remove required attributes + container.find('.'+prefix+'employee_section').find('input, select').removeAttr('required'); + container.find('.'+prefix+'employee_section').fadeOut().addClass('hidden'); + container.find('.'+prefix+'independent_section').find('input, select').attr('required', true); + } else if(job.withoutEmployer.includes(value)) { + container.find('.withemployer_section').fadeOut().addClass('hidden'); + container.find('.withemployer_section').find('input, select').removeAttr('required'); + + console.log((jobLabels.withoutEmployer.salary)); + /* container.find('.'+prefix+'IDsalary').prev().text(jobLabels.withoutEmployer.salary); + + console.log(container.find('#'+prefix+'IDsalary').prev()); */ + } else { + container.find('.'+prefix+'independent_section').fadeOut().addClass('hidden'); + //not input field required + container.find('.'+prefix+'employee_section').find('input:not([type="file"]), select').attr('required', true); + container.find('.'+prefix+'employee_section').fadeIn().removeClass('hidden'); + + //except file inputs + container.find('.'+prefix+'independent_section').find('input:not([type="file"]), select').removeAttr('required'); + + if(jQuery('.withemployer_section').hasClass('hidden')) { + jQuery('.withemployer_section').fadeIn().removeClass('hidden'); + jQuery('.withemployer_section').find('input, select').attr('required', true); + } + } + + container + .find('#ID' + prefix + 'emnumber') + .attr('required', value === job.independent) + .parent() + .toggleClass('d-none', value !== job.independent) + + makeLabelRequired() + } + + function displayCoBorrower() { + var + excludedFieldsName = [ + 'cocontract_type', + 'coemname', + 'coemaddress', + 'coemzip', + 'coemcity', + 'coemcountry', + 'cocommitmentdate', + 'cooiamouthmealvoucher', + 'cooiamouthrentalincome', + 'cooiamouthunemployment', + 'cooiamouthother', + 'cooiothertext', + 'co_secteur_activite', + 'co_num_tva', + 'coMtn_loyer' + ], + hasCoBorrower = + jQuery('input[name="hascoborrower"]:checked').length > 0 && + jQuery('input[name="hascoborrower"]:checked').val() == 1, + key = '.wpcf-coborrower', + cols_key = '.credit-cols'; + + console.log('hasCoBorrower', hasCoBorrower); + + // Gestion de l'affichage/masquage + jQuery(key).toggleClass('d-none', !hasCoBorrower); + + // Gestion des colonnes + if (hasCoBorrower) { + // Mode deux colonnes + jQuery(cols_key).removeClass('col-md-12').addClass('col-md-6'); + + // Ajuster les colonnes internes + jQuery('.credit-cols [class*="col-md-"]').each(function() { + var classes = jQuery(this).attr('class').split(' '); + classes.forEach(function(className) { + if (className.startsWith('col-md-')) { + var currentSize = parseInt(className.replace('col-md-', '')); + console.log('currentSize', currentSize); + + // Sauvegarder la taille originale si ce n'est pas déjà fait + if (!jQuery(this).data('original-size')) { + jQuery(this).data('original-size', className); + } + + // Définir la nouvelle taille + jQuery(this).removeClass(className).addClass('col-md-12'); + } + }.bind(this)); + }); + } else { + // Mode une colonne + jQuery('.credit-cols .wpcf-borrower').removeClass('col-md-6'); + + if(!jQuery(cols_key).hasClass('col-md-12')) + jQuery(cols_key).addClass('col-md-12').removeClass('col-md-6'); + + // Restaurer les colonnes internes à leur taille d'origine + jQuery('.credit-cols [class*="col-md-"]').each(function() { + var originalSize = jQuery(this).data('original-size'); + + if (originalSize) { + // Supprimer toutes les classes col-md-* actuelles + var classes = jQuery(this).attr('class').split(' '); + classes.forEach(function(className) { + if (className.startsWith('col-md-')) { + jQuery(this).removeClass(className); + } + }.bind(this)); + + // Restaurer la taille originale + jQuery(this).addClass(originalSize); + } + }); + } + + // Gestion des champs requis + jQuery(key).find('input[type="text"], input[type="number"], input[type="date"], select, textarea').each(function() { + if (excludedFieldsName.indexOf(jQuery(this).attr('name')) < 0) { + jQuery(this).attr('required', hasCoBorrower) + } + }) + + if (!hasCoBorrower) { + jQuery(key).find('input[type="checkbox"]:checked, input[type="radio"][value="0"]').each(function() { + jQuery(this).prop('checked', jQuery(this).attr('type') === 'radio') + }) + + jQuery(key).find('input:not([type="checkbox"]):not([type="radio"]), select, textarea').each(function() { + jQuery(this).val('') + }) + } + + makeLabelRequired(key) + displayOtherIncome( + hasCoBorrower && jQuery('input[name="cohasotherincome"]:checked').length > 0 && jQuery('input[name="cohasotherincome"]:checked').val() == 1, + '.co' + ) + } + + function displayOtherIncome(show, key) { + var target = jQuery('.wpcf-otherincome' + key) + + if (target.length > 0) { + target.toggleClass('d-none', !show); + + if (!show) { + target.find('input[type="checkbox"]:checked, input[type="radio"][value="0"]').each(function() { + jQuery(this).prop('checked', jQuery(this).attr('type') === 'radio') + }) + } + + displayOtherIncomeSubFields(target.find('input[type="checkbox"], input[type="radio"]:checked')) + } + } + + function displayOtherIncomeSubFields(el) { + el.each(function() { + var subFields = jQuery(this).closest('.form-row').find('.form-group') + + if (subFields.length > 0) { + subFields.toggleClass('d-none', !jQuery(this).is(':checked')) + subFields.find('input').attr('required', jQuery(this).is(':checked')) + } + }) + } + + function initializePreFilledValues() { + // Gérer l'affichage des sections basé sur les valeurs pré-remplies + setTimeout(function() { + // Vérifier si hascoborrower est pré-rempli + var hasCoBorrowerChecked = jQuery('input[name="hascoborrower"]:checked'); + if (hasCoBorrowerChecked.length > 0) { + displayCoBorrower(); + } + + // Vérifier si hasotherincome est pré-rempli (emprunteur) + var hasOtherIncomeChecked = jQuery('input[name="hasotherincome"]:checked'); + if (hasOtherIncomeChecked.length > 0) { + displayOtherIncome(hasOtherIncomeChecked.val() == 1, '.em'); + } + + // Vérifier si cohasotherincome est pré-rempli (co-emprunteur) + var coHasOtherIncomeChecked = jQuery('input[name="cohasotherincome"]:checked'); + if (coHasOtherIncomeChecked.length > 0) { + displayOtherIncome(coHasOtherIncomeChecked.val() == 1, '.co'); + } + + // Vérifier si hascurrentloan est pré-rempli + var hasCurrentLoanChecked = jQuery('input[name="hascurrentloan"]:checked'); + if (hasCurrentLoanChecked.length > 0) { + var isChecked = hasCurrentLoanChecked.val() == '1'; + jQuery('.wpcf-currentloan').toggleClass('d-none', !isChecked); + } + + // Vérifier si cohascurrentloan est pré-rempli + var coHasCurrentLoanChecked = jQuery('input[name="cohascurrentloan"]:checked'); + if (coHasCurrentLoanChecked.length > 0) { + var isChecked = coHasCurrentLoanChecked.val() == '1'; + jQuery('.wpcf-cocurrentloan').toggleClass('d-none', !isChecked); + } + + // Gérer les champs autres revenus pré-remplis + jQuery('.wpcf-otherincome input[type="checkbox"]:checked').each(function() { + displayOtherIncomeSubFields(jQuery(this)); + }); + + // Gérer les champs indépendant pré-remplis + var jobSelect = jQuery('select[name="job"]'); + if (jobSelect.length > 0 && jobSelect.val()) { + changeJobLabels(jobSelect.val(), jobSelect.closest('fieldset')); + } + + var coJobSelect = jQuery('select[name="cojob"]'); + if (coJobSelect.length > 0 && coJobSelect.val()) { + changeJobLabels(coJobSelect.val(), coJobSelect.closest('fieldset')); + } + }, 100); // Petit délai pour s'assurer que le DOM est chargé + } + + var hasCoBorrowerField = jQuery('input[name="hascoborrower"]:checked') + + if (hasCoBorrowerField.length > 0) { + displayCoBorrower() + } + + if (jQuery('input[name="hasotherincome"]:checked').length > 0) { + displayOtherIncome(jQuery('input[name="hasotherincome"]:checked').val() == 1, '.em') + } + + // Initialisation pour les valeurs pré-remplies + initializePreFilledValues(); + + jQuery('body').on('change', 'input[name="hascoborrower"]', displayCoBorrower); + + jQuery('body').on('change', 'input[name="hasotherincome"]', function() { + displayOtherIncome(jQuery(this).val() == 1, '.em') + }); + + jQuery('body').on('change', 'input.wpcf-otherincome--oitype', function(e) { + displayOtherIncomeSubFields(jQuery(e.target)) + }); + + jQuery('body').on('change', 'input[name="cohasotherincome"]', function() { + displayOtherIncome(jQuery(this).val() == 1, '.co') + }); + + jQuery('body').on('change', 'select[name="job"], select[name="cojob"]', function() { + changeJobLabels(jQuery(this).val(), jQuery(this).closest('fieldset')) + }); + + /** + * Step 3 + */ + jQuery('body').on('change', 'select[name="hometype"], select[name="cohometype"]', function(e) { + var val = jQuery(this).val(), + c = 'd-none', + cname = 'wpcf-' + jQuery(this).attr('name') + '--complement-home' + val, + elements = jQuery('.wpcf-' + jQuery(this).attr('name') + '--complement .form-group'); + + elements.addClass(c); + + elements.each(function() { + if (jQuery(this).hasClass(cname)) { + jQuery('.' + cname).removeClass(c); + } + + jQuery(this).find('input, select').attr('required', !jQuery(this).hasClass(c)) + makeLabelRequired(jQuery(this).context) + }) + + }); + + var currentLoanProto = jQuery('.wpcf-currentloan--block').length > 0 ? jQuery('.wpcf-currentloan--block') : null; + var currentLoanCount = 0; + + if (currentLoanProto !== null) { + currentLoanProto.removeClass('wpcf-prototype'); + currentLoanProto = currentLoanProto[0].outerHTML + jQuery('.wpcf-currentloan--block').remove() + } + + var coCurrentLoanProto = jQuery('.wpcf-cocurrentloan--block').length > 0 ? jQuery('.wpcf-cocurrentloan--block') : null; + var coCurrentLoanCount = 0; + + if (coCurrentLoanProto !== null) { + coCurrentLoanProto.removeClass('wpcf-prototype'); + coCurrentLoanProto = coCurrentLoanProto[0].outerHTML + jQuery('.wpcf-cocurrentloan--block').remove() + } + + jQuery('body').on('change', 'input[name="hascurrentloan"], input[name="cohascurrentloan"]', function(e) { + var selector = jQuery(this).attr('name') === 'hascurrentloan' ? '.wpcf-currentloan' : '.wpcf-cocurrentloan'; + var elem = jQuery(selector), + c = 'd-none'; + // Pour les radio, on vérifie la value sélectionnée + var isChecked = jQuery('input[name="' + jQuery(this).attr('name') + '"]:checked').val() == '1'; + elem.toggleClass(c, !isChecked); + if (!isChecked) { + jQuery(this).attr('name') === 'hascurrentloan' ? jQuery('.wpcf-currentloan--block').remove() : jQuery('.wpcf-cocurrentloan--block').remove(); + } else if (elem.find(selector + '--block').length < 1) { + jQuery(this).attr('name') === 'hascurrentloan' ? addCurrentLoan() : addCoCurrentLoan(); + } + }); + + // Affichage initial au chargement de la page + function updateCurrentLoanVisibility() { + var isChecked = jQuery('input[name="hascurrentloan"]:checked').val() == '1'; + jQuery('.wpcf-currentloan').toggleClass('d-none', !isChecked); + if (!isChecked) { + jQuery('.wpcf-currentloan--block').remove(); + } else if (jQuery('.wpcf-currentloan--block').length < 1) { + addCurrentLoan(); + } + var isCoChecked = jQuery('input[name="cohascurrentloan"]:checked').val() == '1'; + jQuery('.wpcf-cocurrentloan').toggleClass('d-none', !isCoChecked); + if (!isCoChecked) { + jQuery('.wpcf-cocurrentloan--block').remove(); + } else if (jQuery('.wpcf-cocurrentloan--block').length < 1) { + addCoCurrentLoan(); + } + } + // Appel au chargement + updateCurrentLoanVisibility(); + + jQuery('body').on('click', 'button.wpcf-currentload--add, button.wpcf-cocurrentload--add', function(e) { + e.preventDefault() + jQuery(this).hasClass('wpcf-currentload--add') ? addCurrentLoan() : addCoCurrentLoan() + }) + + function addCurrentLoan() { + var newLoan = currentLoanProto.replaceAll('__number__', currentLoanCount) + jQuery(newLoan).insertBefore(jQuery('.wpcf-currentload--add')) + + currentLoanCount++ + + // Déclencher l'événement personnalisé pour la sauvegarde + $(document).trigger('currentLoanAdded'); + } + + function addCoCurrentLoan() { + var newLoan = coCurrentLoanProto.replaceAll('__number__', coCurrentLoanCount) + jQuery(newLoan).insertBefore(jQuery('.wpcf-cocurrentload--add')) + + coCurrentLoanCount++ + + // Déclencher l'événement personnalisé pour la sauvegarde + $(document).trigger('currentLoanAdded'); + } + + jQuery('body').on('click', '.wpcf-currentloan--block--remove, .wpcf-cocurrentloan--block--remove', function(e) { + e.preventDefault(); + jQuery(this).parent().remove(); + + // Déclencher l'événement personnalisé pour la sauvegarde + $(document).trigger('currentLoanRemoved'); + }); + + // Fonction pour afficher/cacher la zone isFichedDisplay + function displayIsFichedZone() { + var hasFiched = jQuery('input[name="isFiched"]:checked').length > 0 && + jQuery('input[name="isFiched"]:checked').val() == 1; + + jQuery('.isFichedDisplay').toggleClass('d-none', !hasFiched); + } + + // Vérifier l'état initial + var isFichedField = jQuery('input[name="isFiched"]:checked'); + if (isFichedField.length > 0) { + displayIsFichedZone(); + } + + // Ajouter l'écouteur d'événement pour le changement + jQuery('body').on('change', 'input[name="isFiched"]', displayIsFichedZone); + + // Fonction pour afficher/cacher la zone isIndependant + function displayIsIndependantZone() { + var isIndependant = jQuery('select[name="job"]').val() === '5'; + jQuery('.isIndependant').toggleClass('d-none', !isIndependant); + } + + // Vérifier l'état initial + var jobSelect = jQuery('select[name="job"]'); + if (jobSelect.length > 0) { + displayIsIndependantZone(); + } + + // Ajouter l'écouteur d'événement pour le changement + jQuery('body').on('change', 'select[name="job"]', displayIsIndependantZone); + + // Fonction pour afficher/cacher la zone hasLoyer + function displayHasLoyerZone() { + var isLocataire = jQuery('select[name="housing_status"]').val() === 'locataire'; + jQuery('.hasLoyer').toggleClass('d-none', !isLocataire); + } + + // Vérifier l'état initial + var situationSelect = jQuery('select[name="housing_status"]'); + if (situationSelect.length > 0) { + displayHasLoyerZone(); + } + + // Ajouter l'écouteur d'événement pour le changement + jQuery('body').on('change', 'select[name="housing_status"]', displayHasLoyerZone); + + // Affichage de la taille totale des fichiers sélectionnés pour le champ IDpaycheck + vérification taille max 2 Mo + jQuery('body').on('change', '#IDpaycheck, #IDcopaycheck', function(e) { + var files = e.target.files; + var totalSize = 0; + var maxSize = 2 * 1024 * 1024; // 2 Mo en octets + var errorFiles = []; + for (var i = 0; i < files.length; i++) { + totalSize += files[i].size; + if (files[i].size > maxSize) { + errorFiles.push(files[i].name); + } + } + // Conversion en Mo, arrondi à 2 décimales + var totalSizeMo = (totalSize / (1024 * 1024)).toFixed(2); + // Création ou sélection de l'élément d'affichage + var infoId = 'paycheck-size-info'; + var infoElem = jQuery('#' + infoId); + if (infoElem.length === 0) { + infoElem = jQuery('
    '); + jQuery(this).after(infoElem); + } + // Création ou sélection de l'élément d'erreur + var errorId = 'paycheck-size-error'; + var errorElem = jQuery('#' + errorId); + if (errorElem.length === 0) { + errorElem = jQuery('
    '); + infoElem.after(errorElem); + } + var submitBtn = jQuery('.form-submit button[type="submit"]'); + if (files.length > 0) { + infoElem.text('Taille totale des fichiers sélectionnés : ' + totalSizeMo + ' Mo'); + } else { + infoElem.text(''); + } + if (errorFiles.length > 0) { + errorElem.html('Fichier(s) trop volumineux (> 2 Mo) :
    ' + errorFiles.join(', ') + ''); + submitBtn.prop('disabled', true); + } else { + errorElem.text(''); + submitBtn.prop('disabled', false); + } + }); + + // Affichage conditionnel du champ "fonds propres" selon le choix Oui/Non avec effet slide + const yesRadio = document.getElementById('estateequity_yes'); + const noRadio = document.getElementById('estateequity_no'); + if (yesRadio && noRadio) { + $(yesRadio).on('change', function() { + if (yesRadio.checked) { + $('.fonds-propres').stop(true, true).slideDown(); + $('[name="estateequity"]').prop('required', true); + } + }); + $(noRadio).on('change', function() { + if (noRadio.checked) { + $('.fonds-propres').stop(true, true).slideUp(); + $('[name="estateequity"]').prop('required', false); + } + }); + // Initialisation à l'ouverture de la page + if (yesRadio.checked) { + $('.fonds-propres').show(); + } else { + $('.fonds-propres').hide(); + } + } + + // Variables pour le debouncing des inputs + let capitalTimeout; + let durationTimeout; + let isCreditCalculationEnabled = true; + + if(jQuery('#creditCalcManualSwitch').length > 0) + isCreditCalculationEnabled = true; + + // Liste des types de crédit qui utilisent des années + const LOAN_TYPES_IN_YEARS = ['am', 'amr', 'cied', 'ph']; + + // Fonction pour mettre à jour l'affichage des valeurs calculées + function updateCreditDisplay(result) { + console.log('updateCreditDisplay - result:', result); + + // Calcul du TAEG + const taeg = parseFloat(result.taux_nominal_annuel.replace('%', '')); + const taux_debiteur = (taeg * 0.11 + taeg).toFixed(2); + + // Mise à jour des champs cachés + jQuery('input[name="capital"]').val(result.capital); + jQuery('input[name="duree"]').val(result.duree); + jQuery('input[name="cout_total"]').val(result.cout_total); + jQuery('input[name="mensualite"]').val(result.mensualite); + jQuery('input[name="taux_nominal_annuel"]').val(result.taux_nominal_annuel); + + console.log('updateCreditDisplay - Champs cachés mis à jour:', { + capital: result.capital, + duree: result.duree, + cout_total: result.cout_total, + mensualite: result.mensualite, + taux: result.taux_nominal_annuel + }); + + // Mise à jour de l'affichage dans .credit-info + jQuery('.credit-info .credit-item').each(function() { + var $value = jQuery(this).find('.credit-value'); + var $label = jQuery(this).find('.credit-label'); + + if($label.text().includes('Montant:')) { + $value.text(result.capital + ' €'); + } + else if($label.text().includes('Durée:')) { + $value.text(result.duree + ($('input[name="type_credit"]').val() === 'am' ? ' ans' : ' mois')); + } + else if($label.text().includes('Mensualité:')) { + $value.text(result.mensualite + '€'); + } + else if($label.text().includes('Coût total:')) { + $value.text(result.cout_total + '€'); + } + else if($label.text().includes('TAEG:')) { + $value.text(taux_debiteur + '%'); + } + else if($label.text().includes('Taux débiteur:')) { + $value.text(result.taux_nominal_annuel); + } + }); + + // Mise à jour du récapitulatif dans .info-credits-step + jQuery('.info-credits-step .row > div').each(function() { + $(this).find('p').each(function() { + var $label = $(this); + var $value = $label.next('span'); + + if($label.text().includes('Montant emprunté :')) { + $value.text(result.capital + ' €'); + } + else if($label.text().includes('Durée :')) { + $value.text(result.duree + ($('input[name="type_credit"]').val() === 'am' ? ' ans' : ' mois')); + } + else if($label.text().includes('Mensualité :')) { + $value.text(result.mensualite + ' €'); + } + else if($label.text().includes('Coût Total :')) { + $value.text(result.cout_total + ' €'); + } + else if($label.text().includes('Taux débiteur :')) { + $value.text(result.taux_nominal_annuel); + } + else if($label.text().includes('Taeg :')) { + $value.text(taux_debiteur + '%'); + } + }); + }); + + console.log('updateCreditDisplay - Affichage mis à jour'); + } + + // Fonction pour mettre à jour les limites et valeurs des champs selon le type de crédit + function updateFieldLimits(selectedType) { + const creditType = map_values[selectedType]; + if (!creditType) { + console.warn('Type de crédit non reconnu:', selectedType); + return; + } + + const $capitalField = jQuery('#IDbatiment_emprunt'); + const $durationField = jQuery('#IDbatiment_duree'); + let currentCapital = parseFloat($capitalField.val()); + + // Récupérer les limites depuis form_sliders pour les durées + const sliderConfig = form_sliders[creditType]; + if (!sliderConfig) { + console.warn('Configuration slider non trouvée pour:', creditType); + return; + } + + // Récupérer les limites spécifiques du crédit depuis cd_js.groups + const creditConfig = cd_js.groups[selectedType]; + if (creditConfig && creditConfig.capital_max) { + // Ne modifier le montant que s'il dépasse la limite du crédit choisi + if (currentCapital > creditConfig.capital_max) { + currentCapital = creditConfig.capital_selected || creditConfig.capital_max; + $capitalField.val(currentCapital); + } + } + + // Mettre à jour les attributs min/max du champ capital + $capitalField.attr('min', sliderConfig.capital_min); + $capitalField.attr('max', sliderConfig.capital_max); + $capitalField.attr('step', sliderConfig.capital_step || 100); + + // Ajuster la valeur du capital si nécessaire selon les limites du slider + if (currentCapital > sliderConfig.capital_max) { + currentCapital = sliderConfig.capital_max; + $capitalField.val(currentCapital); + } else if (currentCapital < sliderConfig.capital_min) { + currentCapital = sliderConfig.capital_min; + $capitalField.val(currentCapital); + } + + // Déterminer la durée maximale disponible pour ce montant + const isYearlyDuration = LOAN_TYPES_IN_YEARS.includes(creditType); + let maxDurationForAmount = sliderConfig.durees[sliderConfig.durees.length - 1]; + + // Parcourir les durées disponibles dans l'ordre décroissant + for (let i = sliderConfig.durees.length - 1; i >= 0; i--) { + const duration = sliderConfig.durees[i]; + // Vérifier si cette durée est valide pour le montant actuel + if (currentCapital >= sliderConfig.capital_min && currentCapital <= sliderConfig.capital_max) { + maxDurationForAmount = duration; + break; + } + } + + // Convertir la durée maximale en années si nécessaire + const displayDuration = isYearlyDuration ? Math.floor(maxDurationForAmount / 12) : maxDurationForAmount; + const minDuration = isYearlyDuration ? Math.ceil(sliderConfig.duree_min / 12) : sliderConfig.duree_min; + const maxDuration = isYearlyDuration ? Math.floor(sliderConfig.duree_max / 12) : sliderConfig.duree_max; + + // Mettre à jour les attributs min/max du champ durée + $durationField.attr('min', minDuration); + $durationField.attr('max', maxDuration); + + // Définir la durée maximale disponible + $durationField.val(displayDuration); + + // Mettre à jour l'unité dans l'input-group-text + jQuery('.input-group-text').text(isYearlyDuration ? 'Ans' : 'Mois'); + + // Mettre à jour l'affichage + calculateCredit(); + + // Mettre à jour le champ caché type_credit + jQuery('input[name="type_credit"]').val(creditType); + } + + // Gestionnaire pour le changement de type de crédit + jQuery('#IDestateloantype').on('change', function() { + const creditType = jQuery(this).val(); + if (creditType) { + updateFieldLimits(creditType); + calculateCredit(); + } + }); + + // Fonction pour arrondir le capital à la valeur acceptable la plus proche + function snapCapitalValue(value, creditType) { + if (!creditType || !form_sliders[creditType]) { + return value; + } + + const sliderConfig = form_sliders[creditType]; + + // Utiliser le step défini dans form_sliders + const step = sliderConfig.capital_step || 100; + + // S'assurer que la valeur est dans les limites + value = Math.max(sliderConfig.capital_min, Math.min(value, sliderConfig.capital_max)); + + // Arrondir à la valeur la plus proche selon le step + return Math.round(value / step) * step; + } + + // Fonction pour arrondir la durée à la valeur acceptable la plus proche + function snapDurationValue(value, creditType) { + if (!creditType || !form_sliders[creditType]) { + return value; + } + + const sliderConfig = form_sliders[creditType]; + const isYearlyDuration = LOAN_TYPES_IN_YEARS.includes(creditType); + + console.log('snapDurationValue - value:', value); + console.log('snapDurationValue - creditType:', creditType); + console.log('snapDurationValue - isYearlyDuration:', isYearlyDuration); + + if (isYearlyDuration) { + // Pour les crédits en années, on vérifie juste les limites min/max + // Les limites sont déjà en années pour ces types de crédit + const minYears = sliderConfig.duree_min; + const maxYears = sliderConfig.duree_max; + + console.log('snapDurationValue - minYears:', minYears); + console.log('snapDurationValue - maxYears:', maxYears); + + if (value > maxYears) return maxYears; + if (value < minYears) return minYears; + return value; + } else { + // Pour les autres crédits, on cherche la durée disponible la plus proche + let closestDuration = sliderConfig.durees[0]; + let minDiff = Math.abs(value - sliderConfig.durees[0]); + + for (let i = 1; i < sliderConfig.durees.length; i++) { + const diff = Math.abs(value - sliderConfig.durees[i]); + if (diff < minDiff) { + minDiff = diff; + closestDuration = sliderConfig.durees[i]; + } + } + return closestDuration; + } + } + + // Fonction pour calculer la mensualité + function calc_mens(mnt, dur, taeg) { + const creditType = jQuery('input[name="type_credit"]').val(); + + // Pour le crédit pont, on ne calcule que les intérêts mensuels + if (creditType === 'cdp') { + const t100 = taeg / 100; + // Calcul des intérêts mensuels uniquement : (capital * taux_annuel) / 12 + const mens = (mnt * t100) / 12; + return Math.floor(mens * 100) / 100; + } + + // Pour les autres types de crédit, calcul normal + const t100 = taeg / 100; + const t101 = 1 + t100; + const d12 = 1 / 12; + const dur12 = dur / 12; + const buf1 = Math.pow(t101, d12); + const buf2 = Math.pow(1 / t101, dur12); + const mens = (mnt * (buf1 - 1)) / (1 - buf2); + + return Math.floor(mens * 100) / 100; + } + + // Notre propre fonction de calcul qui utilise les fonctions de base de cd_main.js + function calculateCredit() { + const capital = parseFloat(jQuery('#IDbatiment_emprunt').val()); + const duration = parseInt(jQuery('#IDbatiment_duree').val()); + const selectedType = jQuery('#IDestateloantype').val(); + const creditType = map_values[selectedType]; + + console.log('=== Début calcul crédit ==='); + console.log('Type sélectionné:', selectedType); + console.log('Type de crédit mappé:', creditType); + console.log('Capital:', capital); + console.log('Durée:', duration); + + if (isNaN(capital) || isNaN(duration) || !creditType) { + console.warn('Valeurs invalides pour le calcul:', { + capital: isNaN(capital) ? 'invalide' : capital, + duration: isNaN(duration) ? 'invalide' : duration, + selectedType, + creditType: !creditType ? 'non mappé' : creditType + }); + return; + } + + // Convertir la durée en mois si nécessaire pour les calculs + const isYearlyDuration = LOAN_TYPES_IN_YEARS.includes(creditType); + const durationForCalculation = isYearlyDuration ? duration * 12 : duration; + + console.log('Durée pour calcul:', durationForCalculation, isYearlyDuration ? '(en années)' : '(en mois)'); + + let results; + // Appeler la fonction de calcul appropriée + switch(creditType) { + case 'pat': + results = calculate_pat(capital, duration); + break; + case 'am': + results = calculate_am(capital, duration); + break; + case 'ph': + results = calculate_ph(capital, duration); + break; + case 'amr': + case 'cdp': + case 'cied': + results = calculate_mono_rate_bt_10_30(creditType, capital, duration); + break; + case 'fin_neuve': + results = calculate_fin_neuve(capital, duration); + break; + case 'fin_occ_m3a': + results = calculate_pao_m_3(capital, duration); + break; + case 'fin_occ_p3a': + results = calculate_pao_p_3(capital, duration); + break; + case 'mobil_carav': + results = calculate_mobilhome(capital, duration); + break; + case 'regroup_cred': + results = calculate_regroupement_de_credit(capital, duration); + break; + case 'frais_notaire': + results = calculate_frais_notaire(capital, duration); + break; + case 'but_immo': + results = calculate_but_immo(capital, duration); + break; + default: + console.warn('Type de crédit non reconnu:', creditType); + results = calculate_pat(capital, duration); + } + + if (!results) { + console.warn('Pas de résultats retournés par la fonction de calcul'); + return; + } + + console.log('Résultats bruts:', results); + + // Extraire les valeurs des résultats + const [min_duration, max_duration, selected_duration, duree_in_range, taux_nominal] = results; + + // Convertir le taux en nombre si c'est une chaîne + const taux = parseFloat(String(taux_nominal).replace('%', '')); + + if (isNaN(taux)) { + console.error('Taux nominal invalide après conversion:', { + original: taux_nominal, + converti: taux + }); + return; + } + + console.log('Taux nominal (débiteur):', taux + '%'); + console.log('Durée sélectionnée:', selected_duration, isYearlyDuration ? 'mois (convertie)' : 'mois'); + + // Pour les crédits en années, la durée retournée est déjà en mois + const durationInMonths = isYearlyDuration ? durationForCalculation : selected_duration; + + // Calculer la mensualité avec notre fonction locale + const mensualite = calc_mens(capital, durationInMonths, taux); + + if (isNaN(mensualite)) { + console.error('Erreur dans le calcul de la mensualité:', { + capital, + durationInMonths, + taux + }); + return; + } + + const cout_total = (mensualite * durationInMonths).toFixed(2); + + console.log('Mensualité calculée:', mensualite.toFixed(2) + '€'); + console.log('Coût total calculé:', cout_total + '€'); + + // Créer l'objet result pour updateCreditDisplay + const displayResult = { + capital: capital, + duree: duration, + mensualite: mensualite.toFixed(2), + cout_total: cout_total, + taux_nominal_annuel: taux.toFixed(2) + ' %', + taux_debiteur: taux.toFixed(2) + ' %' + }; + + console.log('Résultat final pour affichage:', displayResult); + console.log('--- Fin calcul crédit ---'); + + // Mettre à jour l'affichage + updateCreditDisplay(displayResult); + + // Mettre à jour le champ caché type_credit + jQuery('input[name="type_credit"]').val(creditType); + } + + if(isCreditCalculationEnabled) { + // Remplacer tous les appels à calculate_mensualite par calculateCredit + jQuery('#IDbatiment_emprunt') + .on('input', function() { + const $this = jQuery(this); + clearTimeout(capitalTimeout); + + if ($this.val() !== '') { + capitalTimeout = setTimeout(() => { + let capital = parseFloat($this.val()); + if (!isNaN(capital)) { + const creditType = jQuery('input[name="type_credit"]').val(); + const snappedValue = snapCapitalValue(capital, creditType); + if (snappedValue !== capital) { + $this.val(snappedValue); + } + calculateCredit(); + } + }, 500); // Délai un peu plus long pour laisser le temps de taper + } + }) + .on('change', function() { + // Validation finale quand on quitte le champ (onblur) + const $this = jQuery(this); + if ($this.val() !== '') { + let capital = parseFloat($this.val()); + if (!isNaN(capital)) { + const selectedType = jQuery('#IDestateloantype').val(); + const creditConfig = cd_js.groups[selectedType]; + + // Vérifier les limites du crédit + if (creditConfig && creditConfig.capital_max && capital > creditConfig.capital_max) { + capital = creditConfig.capital_selected || creditConfig.capital_max; + $this.val(capital); + } + + // Snap à la valeur la plus proche et recalcul + const creditType = jQuery('input[name="type_credit"]').val(); + const snappedValue = snapCapitalValue(capital, creditType); + if (snappedValue !== capital) { + $this.val(snappedValue); + } + calculateCredit(); + } + } + }); + + jQuery('#IDbatiment_duree') + .on('input', function() { + const $this = jQuery(this); + clearTimeout(durationTimeout); + durationTimeout = setTimeout(() => { + let duration = parseInt($this.val()); + if (!isNaN(duration)) { + const creditType = jQuery('input[name="type_credit"]').val(); + console.log('Input duration:', duration); + console.log('Credit type:', creditType); + console.log('Is yearly:', LOAN_TYPES_IN_YEARS.includes(creditType)); + + // Ne pas snapper pendant la saisie pour les crédits en années + if (LOAN_TYPES_IN_YEARS.includes(creditType)) { + calculateCredit(); + } else { + const snappedValue = snapDurationValue(duration, creditType); + if (snappedValue !== duration) { + $this.val(snappedValue); + } + calculateCredit(); + } + } + }, 300); + }) + .on('change', function() { + let duration = parseInt($(this).val()); + if (!isNaN(duration)) { + const creditType = jQuery('input[name="type_credit"]').val(); + console.log('onchange - creditType:', creditType); + console.log('onchange - LOAN_TYPES_IN_YEARS:', LOAN_TYPES_IN_YEARS); + console.log('onchange - includes?', LOAN_TYPES_IN_YEARS.includes(creditType)); + + if (LOAN_TYPES_IN_YEARS.includes(creditType)) { + console.log('change', duration); + const snappedValue = snapDurationValue(duration, creditType); + console.log('snappedValue', snappedValue); + if (snappedValue !== duration) { + $(this).val(snappedValue); + } + } else { + // Pour les autres crédits, comportement normal + const snappedValue = snapDurationValue(duration, creditType); + if (snappedValue !== duration) { + $(this).val(snappedValue); + } + } + calculateCredit(); + } + }); + + // Calcul initial au chargement + /* $(document).ready(function() { + const creditType = $('input[name="type_credit"]').val(); + if (creditType) { + updateFieldLimits(creditType); + calculateCredit(); + } + }); */ + + // Gestionnaire pour la soumission du formulaire + jQuery('.form-submit').on('submit', function() { + // Recalculer une dernière fois avant l'envoi + calculateCredit(); + }); + } + + function findRate(type) { + console.log('findRate - Type recherché:', type); + let rate; + + switch(type) { + case 'amr': + rate = cd_js.groups.achat_maison_de_rapport.de_10_a_30_ans; + break; + case 'cdp': + rate = cd_js.groups.credit_pont.de_10_a_30_ans; + break; + case 'cied': + rate = cd_js.groups.independants_et_entreprises_en_difficultes.de_10_a_30_ans; + break; + default: + console.warn('Type de crédit non reconnu pour le taux mono:', type); + rate = null; + } + + console.log('findRate - Taux trouvé:', rate); + return rate; + } + + function calculate_mono_rate_bt_10_30(type, selected_capital, selected_duration) { + const annual_rate = findRate(type); + if (!annual_rate) { + console.error('Taux non trouvé pour le type:', type); + return null; + } + + const min_duration = 10; + const max_duration = 30; + let duree_in_range = true; + const add_message = ''; + + if (min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration) { + // La durée est dans la plage + } else { + duree_in_range = false; + selected_duration = max_duration; + } + + // Convertir la durée en mois pour le calcul + selected_duration = selected_duration * 12; + + return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message]; + } + +}); \ No newline at end of file diff --git a/assets/js/libraries/additional-methods.min.js b/assets/js/libraries/additional-methods.min.js new file mode 100644 index 0000000..80f14b5 --- /dev/null +++ b/assets/js/libraries/additional-methods.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.5 - 7/1/2022 + * https://jqueryvalidation.org/ + * Copyright (c) 2022 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","./jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return function(){function b(a){return a.replace(/<.[^<>]*?>/g," ").replace(/ | /gi," ").replace(/[.(),;:!?%#$'\"_+=\/\-“”’]*/g,"")}a.validator.addMethod("maxWords",function(a,c,d){return this.optional(c)||b(a).match(/\b\w+\b/g).length<=d},a.validator.format("Please enter {0} words or less.")),a.validator.addMethod("minWords",function(a,c,d){return this.optional(c)||b(a).match(/\b\w+\b/g).length>=d},a.validator.format("Please enter at least {0} words.")),a.validator.addMethod("rangeWords",function(a,c,d){var e=b(a),f=/\b\w+\b/g;return this.optional(c)||e.match(f).length>=d[0]&&e.match(f).length<=d[1]},a.validator.format("Please enter between {0} and {1} words."))}(),a.validator.addMethod("abaRoutingNumber",function(a){var b=0,c=a.split(""),d=c.length;if(9!==d)return!1;for(var e=0;e9?"0":f,g="JABCDEFGHI".substr(f,1).toString(),i.match(/[ABEH]/)?k===f:i.match(/[KPQS]/)?k===g:k===f||k===g},"Please specify a valid CIF number."),a.validator.addMethod("cnhBR",function(a){if(a=a.replace(/([~!@#$%^&*()_+=`{}\[\]\-|\\:;'<>,.\/? ])+/g,""),11!==a.length)return!1;var b,c,d,e,f,g,h=0,i=0;if(b=a.charAt(0),new Array(12).join(b)===a)return!1;for(e=0,f=9,g=0;e<9;++e,--f)h+=+(a.charAt(e)*f);for(c=h%11,c>=10&&(c=0,i=2),h=0,e=0,f=1,g=0;e<9;++e,++f)h+=+(a.charAt(e)*f);return d=h%11,d>=10?d=0:d-=i,String(c).concat(d)===a.substr(-2)},"Please specify a valid CNH number."),a.validator.addMethod("cnpjBR",function(a,b){"use strict";if(this.optional(b))return!0;if(a=a.replace(/[^\d]+/g,""),14!==a.length)return!1;if("00000000000000"===a||"11111111111111"===a||"22222222222222"===a||"33333333333333"===a||"44444444444444"===a||"55555555555555"===a||"66666666666666"===a||"77777777777777"===a||"88888888888888"===a||"99999999999999"===a)return!1;for(var c=a.length-2,d=a.substring(0,c),e=a.substring(c),f=0,g=c-7,h=c;h>=1;h--)f+=d.charAt(c-h)*g--,g<2&&(g=9);var i=f%11<2?0:11-f%11;if(i!==parseInt(e.charAt(0),10))return!1;c+=1,d=a.substring(0,c),f=0,g=c-7;for(var j=c;j>=1;j--)f+=d.charAt(c-j)*g--,g<2&&(g=9);return i=f%11<2?0:11-f%11,i===parseInt(e.charAt(1),10)},"Please specify a CNPJ value number."),a.validator.addMethod("cpfBR",function(a,b){"use strict";if(this.optional(b))return!0;if(a=a.replace(/([~!@#$%^&*()_+=`{}\[\]\-|\\:;'<>,.\/? ])+/g,""),11!==a.length)return!1;var c,d,e,f,g=0;if(c=parseInt(a.substring(9,10),10),d=parseInt(a.substring(10,11),10),e=function(a,b){var c=10*a%11;return 10!==c&&11!==c||(c=0),c===b},""===a||"00000000000"===a||"11111111111"===a||"22222222222"===a||"33333333333"===a||"44444444444"===a||"55555555555"===a||"66666666666"===a||"77777777777"===a||"88888888888"===a||"99999999999"===a)return!1;for(f=1;f<=9;f++)g+=parseInt(a.substring(f-1,f),10)*(11-f);if(e(g,c)){for(g=0,f=1;f<=10;f++)g+=parseInt(a.substring(f-1,f),10)*(12-f);return e(g,d)}return!1},"Please specify a valid CPF number."),a.validator.addMethod("creditcard",function(a,b){if(this.optional(b))return"dependency-mismatch";if(/[^0-9 \-]+/.test(a))return!1;var c,d,e=0,f=0,g=!1;if(a=a.replace(/\D/g,""),a.length<13||a.length>19)return!1;for(c=a.length-1;c>=0;c--)d=a.charAt(c),f=parseInt(d,10),g&&(f*=2)>9&&(f-=9),e+=f,g=!g;return e%10===0},"Please enter a valid credit card number."),a.validator.addMethod("creditcardtypes",function(a,b,c){if(/[^0-9\-]+/.test(a))return!1;a=a.replace(/\D/g,"");var d=0;return c.mastercard&&(d|=1),c.visa&&(d|=2),c.amex&&(d|=4),c.dinersclub&&(d|=8),c.enroute&&(d|=16),c.discover&&(d|=32),c.jcb&&(d|=64),c.unknown&&(d|=128),c.all&&(d=255),1&d&&(/^(5[12345])/.test(a)||/^(2[234567])/.test(a))?16===a.length:2&d&&/^(4)/.test(a)?16===a.length:4&d&&/^(3[47])/.test(a)?15===a.length:8&d&&/^(3(0[012345]|[68]))/.test(a)?14===a.length:16&d&&/^(2(014|149))/.test(a)?15===a.length:32&d&&/^(6011)/.test(a)?16===a.length:64&d&&/^(3)/.test(a)?16===a.length:64&d&&/^(2131|1800)/.test(a)?15===a.length:!!(128&d)},"Please enter a valid credit card number."),a.validator.addMethod("currency",function(a,b,c){var d,e="string"==typeof c,f=e?c:c[0],g=!!e||c[1];return f=f.replace(/,/g,""),f=g?f+"]":f+"]?",d="^["+f+"([1-9]{1}[0-9]{0,2}(\\,[0-9]{3})*(\\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,}(\\.[0-9]{0,2})?|0(\\.[0-9]{0,2})?|(\\.[0-9]{1,2})?)$",d=new RegExp(d),this.optional(b)||d.test(a)},"Please specify a valid currency."),a.validator.addMethod("dateFA",function(a,b){return this.optional(b)||/^[1-4]\d{3}\/((0?[1-6]\/((3[0-1])|([1-2][0-9])|(0?[1-9])))|((1[0-2]|(0?[7-9]))\/(30|([1-2][0-9])|(0?[1-9]))))$/.test(a)},a.validator.messages.date),a.validator.addMethod("dateITA",function(a,b){var c,d,e,f,g,h=!1,i=/^\d{1,2}\/\d{1,2}\/\d{4}$/;return i.test(a)?(c=a.split("/"),d=parseInt(c[0],10),e=parseInt(c[1],10),f=parseInt(c[2],10),g=new Date(Date.UTC(f,e-1,d,12,0,0,0)),h=g.getUTCFullYear()===f&&g.getUTCMonth()===e-1&&g.getUTCDate()===d):h=!1,this.optional(b)||h},a.validator.messages.date),a.validator.addMethod("dateNL",function(a,b){return this.optional(b)||/^(0?[1-9]|[12]\d|3[01])[\.\/\-](0?[1-9]|1[012])[\.\/\-]([12]\d)?(\d\d)$/.test(a)},a.validator.messages.date),a.validator.addMethod("extension",function(a,b,c){return c="string"==typeof c?c.replace(/,/g,"|"):"png|jpe?g|gif",this.optional(b)||a.match(new RegExp("\\.("+c+")$","i"))},a.validator.format("Please enter a value with a valid extension.")),a.validator.addMethod("giroaccountNL",function(a,b){return this.optional(b)||/^[0-9]{1,7}$/.test(a)},"Please specify a valid giro account number."),a.validator.addMethod("greaterThan",function(b,c,d){var e=a(d);return this.settings.onfocusout&&e.not(".validate-greaterThan-blur").length&&e.addClass("validate-greaterThan-blur").on("blur.validate-greaterThan",function(){a(c).valid()}),b>e.val()},"Please enter a greater value."),a.validator.addMethod("greaterThanEqual",function(b,c,d){var e=a(d);return this.settings.onfocusout&&e.not(".validate-greaterThanEqual-blur").length&&e.addClass("validate-greaterThanEqual-blur").on("blur.validate-greaterThanEqual",function(){a(c).valid()}),b>=e.val()},"Please enter a greater value."),a.validator.addMethod("iban",function(a,b){if(this.optional(b))return!0;var c,d,e,f,g,h,i,j,k,l=a.replace(/ /g,"").toUpperCase(),m="",n=!0,o="",p="",q=5;if(l.lengthd)},a.validator.format("Please select no more than {0} files.")),a.validator.addMethod("maxsize",function(b,c,d){if(this.optional(c))return!0;if("file"===a(c).attr("type")&&c.files&&c.files.length)for(var e=0;ed)return!1;return!0},a.validator.format("File size must not exceed {0} bytes each.")),a.validator.addMethod("maxsizetotal",function(b,c,d){if(this.optional(c))return!0;if("file"===a(c).attr("type")&&c.files&&c.files.length)for(var e=0,f=0;fd)return!1;return!0},a.validator.format("Total size of all files must not exceed {0} bytes.")),a.validator.addMethod("mobileNL",function(a,b){return this.optional(b)||/^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)6((\s|\s?\-\s?)?[0-9]){8}$/.test(a)},"Please specify a valid mobile number."),a.validator.addMethod("mobileRU",function(a,b){var c=a.replace(/\(|\)|\s+|-/g,"");return this.optional(b)||c.length>9&&/^((\+7|7|8)+([0-9]){10})$/.test(c)},"Please specify a valid mobile number."),a.validator.addMethod("mobileUK",function(a,b){return a=a.replace(/\(|\)|\s+|-/g,""),this.optional(b)||a.length>9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?|0)7(?:[1345789]\d{2}|624)\s?\d{3}\s?\d{3})$/)},"Please specify a valid mobile number."),a.validator.addMethod("netmask",function(a,b){return this.optional(b)||/^(254|252|248|240|224|192|128)\.0\.0\.0|255\.(254|252|248|240|224|192|128|0)\.0\.0|255\.255\.(254|252|248|240|224|192|128|0)\.0|255\.255\.255\.(254|252|248|240|224|192|128|0)/i.test(a)},"Please enter a valid netmask."),a.validator.addMethod("nieES",function(a,b){"use strict";if(this.optional(b))return!0;var c,d=new RegExp(/^[MXYZ]{1}[0-9]{7,8}[TRWAGMYFPDXBNJZSQVHLCKET]{1}$/gi),e="TRWAGMYFPDXBNJZSQVHLCKET",f=a.substr(a.length-1).toUpperCase();return a=a.toString().toUpperCase(),!(a.length>10||a.length<9||!d.test(a))&&(a=a.replace(/^[X]/,"0").replace(/^[Y]/,"1").replace(/^[Z]/,"2"),c=9===a.length?a.substr(0,8):a.substr(0,9),e.charAt(parseInt(c,10)%23)===f)},"Please specify a valid NIE number."),a.validator.addMethod("nifES",function(a,b){"use strict";return!!this.optional(b)||(a=a.toUpperCase(),!!a.match("((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)")&&(/^[0-9]{8}[A-Z]{1}$/.test(a)?"TRWAGMYFPDXBNJZSQVHLCKE".charAt(a.substring(8,0)%23)===a.charAt(8):!!/^[KLM]{1}/.test(a)&&a[8]==="TRWAGMYFPDXBNJZSQVHLCKE".charAt(a.substring(8,1)%23)))},"Please specify a valid NIF number."),a.validator.addMethod("nipPL",function(a){"use strict";if(a=a.replace(/[^0-9]/g,""),10!==a.length)return!1;for(var b=[6,5,7,2,3,4,5,6,7],c=0,d=0;d<9;d++)c+=b[d]*a[d];var e=c%11,f=10===e?0:e;return f===parseInt(a[9],10)},"Please specify a valid NIP number."),a.validator.addMethod("nisBR",function(a){var b,c,d,e,f,g=0;if(a=a.replace(/([~!@#$%^&*()_+=`{}\[\]\-|\\:;'<>,.\/? ])+/g,""),11!==a.length)return!1;for(c=parseInt(a.substring(10,11),10),b=parseInt(a.substring(0,10),10),e=2;e<12;e++)f=e,10===e&&(f=2),11===e&&(f=3),g+=b%10*f,b=parseInt(b/10,10);return d=g%11,d=d>1?11-d:0,c===d},"Please specify a valid NIS/PIS number."),a.validator.addMethod("notEqualTo",function(b,c,d){return this.optional(c)||!a.validator.methods.equalTo.call(this,b,c,d)},"Please enter a different value, values must not be the same."),a.validator.addMethod("nowhitespace",function(a,b){return this.optional(b)||/^\S+$/i.test(a)},"No white space please."),a.validator.addMethod("pattern",function(a,b,c){return!!this.optional(b)||("string"==typeof c&&(c=new RegExp("^(?:"+c+")$")),c.test(a))},"Invalid format."),a.validator.addMethod("phoneNL",function(a,b){return this.optional(b)||/^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)[1-9]((\s|\s?\-\s?)?[0-9]){8}$/.test(a)},"Please specify a valid phone number."),a.validator.addMethod("phonePL",function(a,b){a=a.replace(/\s+/g,"");var c=/^(?:(?:(?:\+|00)?48)|(?:\(\+?48\)))?(?:1[2-8]|2[2-69]|3[2-49]|4[1-68]|5[0-9]|6[0-35-9]|[7-8][1-9]|9[145])\d{7}$/;return this.optional(b)||c.test(a)},"Please specify a valid phone number."),a.validator.addMethod("phonesUK",function(a,b){return a=a.replace(/\(|\)|\s+|-/g,""),this.optional(b)||a.length>9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?|0)(?:1\d{8,9}|[23]\d{9}|7(?:[1345789]\d{8}|624\d{6})))$/)},"Please specify a valid uk phone number."),a.validator.addMethod("phoneUK",function(a,b){return a=a.replace(/\(|\)|\s+|-/g,""),this.optional(b)||a.length>9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?)|(?:\(?0))(?:\d{2}\)?\s?\d{4}\s?\d{4}|\d{3}\)?\s?\d{3}\s?\d{3,4}|\d{4}\)?\s?(?:\d{5}|\d{3}\s?\d{3})|\d{5}\)?\s?\d{4,5})$/)},"Please specify a valid phone number."),a.validator.addMethod("phoneUS",function(a,b){return a=a.replace(/\s+/g,""),this.optional(b)||a.length>9&&a.match(/^(\+?1-?)?(\([2-9]([02-9]\d|1[02-9])\)|[2-9]([02-9]\d|1[02-9]))-?[2-9]\d{2}-?\d{4}$/)},"Please specify a valid phone number."),a.validator.addMethod("postalcodeBR",function(a,b){return this.optional(b)||/^\d{2}.\d{3}-\d{3}?$|^\d{5}-?\d{3}?$/.test(a)},"Informe um CEP válido."),a.validator.addMethod("postalCodeCA",function(a,b){return this.optional(b)||/^[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ] *\d[ABCEGHJKLMNPRSTVWXYZ]\d$/i.test(a)},"Please specify a valid postal code."),a.validator.addMethod("postalcodeIT",function(a,b){return this.optional(b)||/^\d{5}$/.test(a)},"Please specify a valid postal code."),a.validator.addMethod("postalcodeNL",function(a,b){return this.optional(b)||/^[1-9][0-9]{3}\s?[a-zA-Z]{2}$/.test(a)},"Please specify a valid postal code."),a.validator.addMethod("postcodeUK",function(a,b){return this.optional(b)||/^((([A-PR-UWYZ][0-9])|([A-PR-UWYZ][0-9][0-9])|([A-PR-UWYZ][A-HK-Y][0-9])|([A-PR-UWYZ][A-HK-Y][0-9][0-9])|([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRVWXY]))\s?([0-9][ABD-HJLNP-UW-Z]{2})|(GIR)\s?(0AA))$/i.test(a)},"Please specify a valid UK postcode."),a.validator.addMethod("require_from_group",function(b,c,d){var e=a(d[1],c.form),f=e.eq(0),g=f.data("valid_req_grp")?f.data("valid_req_grp"):a.extend({},this),h=e.filter(function(){return g.elementValue(this)}).length>=d[0];return f.data("valid_req_grp",g),a(c).data("being_validated")||(e.data("being_validated",!0),e.each(function(){g.element(this)}),e.data("being_validated",!1)),h},a.validator.format("Please fill at least {0} of these fields.")),a.validator.addMethod("skip_or_fill_minimum",function(b,c,d){var e=a(d[1],c.form),f=e.eq(0),g=f.data("valid_skip")?f.data("valid_skip"):a.extend({},this),h=e.filter(function(){return g.elementValue(this)}).length,i=0===h||h>=d[0];return f.data("valid_skip",g),a(c).data("being_validated")||(e.data("being_validated",!0),e.each(function(){g.element(this)}),e.data("being_validated",!1)),i},a.validator.format("Please either skip these fields or fill at least {0} of them.")),a.validator.addMethod("stateUS",function(a,b,c){var d,e="undefined"==typeof c,f=!e&&"undefined"!=typeof c.caseSensitive&&c.caseSensitive,g=!e&&"undefined"!=typeof c.includeTerritories&&c.includeTerritories,h=!e&&"undefined"!=typeof c.includeMilitary&&c.includeMilitary;return d=g||h?g&&h?"^(A[AEKLPRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$":g?"^(A[KLRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$":"^(A[AEKLPRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$":"^(A[KLRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$",d=f?new RegExp(d):new RegExp(d,"i"),this.optional(b)||d.test(a)},"Please specify a valid state."),a.validator.addMethod("strippedminlength",function(b,c,d){return a(b).text().length>=d},a.validator.format("Please enter at least {0} characters.")),a.validator.addMethod("time",function(a,b){return this.optional(b)||/^([01]\d|2[0-3]|[0-9])(:[0-5]\d){1,2}$/.test(a)},"Please enter a valid time, between 00:00 and 23:59."),a.validator.addMethod("time12h",function(a,b){return this.optional(b)||/^((0?[1-9]|1[012])(:[0-5]\d){1,2}(\ ?[AP]M))$/i.test(a)},"Please enter a valid time in 12-hour am/pm format."),a.validator.addMethod("url2",function(a,b){return this.optional(b)||/^(?:(?:(?:https?|ftp):)?\/\/)(?:(?:[^\]\[?\/<~#`!@$^&*()+=}|:";',>{ ]|%[0-9A-Fa-f]{2})+(?::(?:[^\]\[?\/<~#`!@$^&*()+=}|:";',>{ ]|%[0-9A-Fa-f]{2})*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z0-9\u00a1-\uffff][a-z0-9\u00a1-\uffff_-]{0,62})?[a-z0-9\u00a1-\uffff]\.)+(?:[a-z\u00a1-\uffff]{2,}\.?)|(?:(?:[a-z0-9\u00a1-\uffff][a-z0-9\u00a1-\uffff_-]{0,62})?[a-z0-9\u00a1-\uffff])|(?:(?:[a-z0-9\u00a1-\uffff][a-z0-9\u00a1-\uffff_-]{0,62}\.)))(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(a)},a.validator.messages.url),a.validator.addMethod("vinUS",function(a){if(17!==a.length)return!1;var b,c,d,e,f,g,h=["A","B","C","D","E","F","G","H","J","K","L","M","N","P","R","S","T","U","V","W","X","Y","Z"],i=[1,2,3,4,5,6,7,8,1,2,3,4,5,7,9,2,3,4,5,6,7,8,9],j=[8,7,6,5,4,3,2,10,0,9,8,7,6,5,4,3,2],k=0;for(b=0;b<17;b++){if(e=j[b],d=a.slice(b,b+1),8===b&&(g=d),isNaN(d)){for(c=0;c=4)throw new Error("Bootstrap's JavaScript requires at least jQuery v1.9.1 but less than v4.0.0")}};u.jQueryDetection(),i.default.fn.emulateTransitionEnd=function(t){var e=this,n=!1;return i.default(this).one(u.TRANSITION_END,(function(){n=!0})),setTimeout((function(){n||u.triggerTransitionEnd(e)}),t),this},i.default.event.special[u.TRANSITION_END]={bindType:l,delegateType:l,handle:function(t){if(i.default(t.target).is(this))return t.handleObj.handler.apply(this,arguments)}};var f="bs.alert",d=i.default.fn.alert,c=function(){function t(t){this._element=t}var e=t.prototype;return e.close=function(t){var e=this._element;t&&(e=this._getRootElement(t)),this._triggerCloseEvent(e).isDefaultPrevented()||this._removeElement(e)},e.dispose=function(){i.default.removeData(this._element,f),this._element=null},e._getRootElement=function(t){var e=u.getSelectorFromElement(t),n=!1;return e&&(n=document.querySelector(e)),n||(n=i.default(t).closest(".alert")[0]),n},e._triggerCloseEvent=function(t){var e=i.default.Event("close.bs.alert");return i.default(t).trigger(e),e},e._removeElement=function(t){var e=this;if(i.default(t).removeClass("show"),i.default(t).hasClass("fade")){var n=u.getTransitionDurationFromElement(t);i.default(t).one(u.TRANSITION_END,(function(n){return e._destroyElement(t,n)})).emulateTransitionEnd(n)}else this._destroyElement(t)},e._destroyElement=function(t){i.default(t).detach().trigger("closed.bs.alert").remove()},t._jQueryInterface=function(e){return this.each((function(){var n=i.default(this),o=n.data(f);o||(o=new t(this),n.data(f,o)),"close"===e&&o[e](this)}))},t._handleDismiss=function(t){return function(e){e&&e.preventDefault(),t.close(this)}},r(t,null,[{key:"VERSION",get:function(){return"4.6.2"}}]),t}();i.default(document).on("click.bs.alert.data-api",'[data-dismiss="alert"]',c._handleDismiss(new c)),i.default.fn.alert=c._jQueryInterface,i.default.fn.alert.Constructor=c,i.default.fn.alert.noConflict=function(){return i.default.fn.alert=d,c._jQueryInterface};var h="bs.button",p=i.default.fn.button,m="active",g='[data-toggle^="button"]',_='input:not([type="hidden"])',v=".btn",b=function(){function t(t){this._element=t,this.shouldAvoidTriggerChange=!1}var e=t.prototype;return e.toggle=function(){var t=!0,e=!0,n=i.default(this._element).closest('[data-toggle="buttons"]')[0];if(n){var o=this._element.querySelector(_);if(o){if("radio"===o.type)if(o.checked&&this._element.classList.contains(m))t=!1;else{var r=n.querySelector(".active");r&&i.default(r).removeClass(m)}t&&("checkbox"!==o.type&&"radio"!==o.type||(o.checked=!this._element.classList.contains(m)),this.shouldAvoidTriggerChange||i.default(o).trigger("change")),o.focus(),e=!1}}this._element.hasAttribute("disabled")||this._element.classList.contains("disabled")||(e&&this._element.setAttribute("aria-pressed",!this._element.classList.contains(m)),t&&i.default(this._element).toggleClass(m))},e.dispose=function(){i.default.removeData(this._element,h),this._element=null},t._jQueryInterface=function(e,n){return this.each((function(){var o=i.default(this),r=o.data(h);r||(r=new t(this),o.data(h,r)),r.shouldAvoidTriggerChange=n,"toggle"===e&&r[e]()}))},r(t,null,[{key:"VERSION",get:function(){return"4.6.2"}}]),t}();i.default(document).on("click.bs.button.data-api",g,(function(t){var e=t.target,n=e;if(i.default(e).hasClass("btn")||(e=i.default(e).closest(v)[0]),!e||e.hasAttribute("disabled")||e.classList.contains("disabled"))t.preventDefault();else{var o=e.querySelector(_);if(o&&(o.hasAttribute("disabled")||o.classList.contains("disabled")))return void t.preventDefault();"INPUT"!==n.tagName&&"LABEL"===e.tagName||b._jQueryInterface.call(i.default(e),"toggle","INPUT"===n.tagName)}})).on("focus.bs.button.data-api blur.bs.button.data-api",g,(function(t){var e=i.default(t.target).closest(v)[0];i.default(e).toggleClass("focus",/^focus(in)?$/.test(t.type))})),i.default(window).on("load.bs.button.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-toggle="buttons"] .btn')),e=0,n=t.length;e0,this._pointerEvent=Boolean(window.PointerEvent||window.MSPointerEvent),this._addEventListeners()}var e=t.prototype;return e.next=function(){this._isSliding||this._slide(C)},e.nextWhenVisible=function(){var t=i.default(this._element);!document.hidden&&t.is(":visible")&&"hidden"!==t.css("visibility")&&this.next()},e.prev=function(){this._isSliding||this._slide(S)},e.pause=function(t){t||(this._isPaused=!0),this._element.querySelector(".carousel-item-next, .carousel-item-prev")&&(u.triggerTransitionEnd(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null},e.cycle=function(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config.interval&&!this._isPaused&&(this._updateInterval(),this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))},e.to=function(t){var e=this;this._activeElement=this._element.querySelector(D);var n=this._getItemIndex(this._activeElement);if(!(t>this._items.length-1||t<0))if(this._isSliding)i.default(this._element).one(N,(function(){return e.to(t)}));else{if(n===t)return this.pause(),void this.cycle();var o=t>n?C:S;this._slide(o,this._items[t])}},e.dispose=function(){i.default(this._element).off(".bs.carousel"),i.default.removeData(this._element,E),this._items=null,this._config=null,this._element=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null},e._getConfig=function(t){return t=a({},A,t),u.typeCheckConfig(y,t,k),t},e._handleSwipe=function(){var t=Math.abs(this.touchDeltaX);if(!(t<=40)){var e=t/this.touchDeltaX;this.touchDeltaX=0,e>0&&this.prev(),e<0&&this.next()}},e._addEventListeners=function(){var t=this;this._config.keyboard&&i.default(this._element).on("keydown.bs.carousel",(function(e){return t._keydown(e)})),"hover"===this._config.pause&&i.default(this._element).on("mouseenter.bs.carousel",(function(e){return t.pause(e)})).on("mouseleave.bs.carousel",(function(e){return t.cycle(e)})),this._config.touch&&this._addTouchEventListeners()},e._addTouchEventListeners=function(){var t=this;if(this._touchSupported){var e=function(e){t._pointerEvent&&I[e.originalEvent.pointerType.toUpperCase()]?t.touchStartX=e.originalEvent.clientX:t._pointerEvent||(t.touchStartX=e.originalEvent.touches[0].clientX)},n=function(e){t._pointerEvent&&I[e.originalEvent.pointerType.toUpperCase()]&&(t.touchDeltaX=e.originalEvent.clientX-t.touchStartX),t._handleSwipe(),"hover"===t._config.pause&&(t.pause(),t.touchTimeout&&clearTimeout(t.touchTimeout),t.touchTimeout=setTimeout((function(e){return t.cycle(e)}),500+t._config.interval))};i.default(this._element.querySelectorAll(".carousel-item img")).on("dragstart.bs.carousel",(function(t){return t.preventDefault()})),this._pointerEvent?(i.default(this._element).on("pointerdown.bs.carousel",(function(t){return e(t)})),i.default(this._element).on("pointerup.bs.carousel",(function(t){return n(t)})),this._element.classList.add("pointer-event")):(i.default(this._element).on("touchstart.bs.carousel",(function(t){return e(t)})),i.default(this._element).on("touchmove.bs.carousel",(function(e){return function(e){t.touchDeltaX=e.originalEvent.touches&&e.originalEvent.touches.length>1?0:e.originalEvent.touches[0].clientX-t.touchStartX}(e)})),i.default(this._element).on("touchend.bs.carousel",(function(t){return n(t)})))}},e._keydown=function(t){if(!/input|textarea/i.test(t.target.tagName))switch(t.which){case 37:t.preventDefault(),this.prev();break;case 39:t.preventDefault(),this.next()}},e._getItemIndex=function(t){return this._items=t&&t.parentNode?[].slice.call(t.parentNode.querySelectorAll(".carousel-item")):[],this._items.indexOf(t)},e._getItemByDirection=function(t,e){var n=t===C,i=t===S,o=this._getItemIndex(e),r=this._items.length-1;if((i&&0===o||n&&o===r)&&!this._config.wrap)return e;var a=(o+(t===S?-1:1))%this._items.length;return-1===a?this._items[this._items.length-1]:this._items[a]},e._triggerSlideEvent=function(t,e){var n=this._getItemIndex(t),o=this._getItemIndex(this._element.querySelector(D)),r=i.default.Event("slide.bs.carousel",{relatedTarget:t,direction:e,from:o,to:n});return i.default(this._element).trigger(r),r},e._setActiveIndicatorElement=function(t){if(this._indicatorsElement){var e=[].slice.call(this._indicatorsElement.querySelectorAll(".active"));i.default(e).removeClass(T);var n=this._indicatorsElement.children[this._getItemIndex(t)];n&&i.default(n).addClass(T)}},e._updateInterval=function(){var t=this._activeElement||this._element.querySelector(D);if(t){var e=parseInt(t.getAttribute("data-interval"),10);e?(this._config.defaultInterval=this._config.defaultInterval||this._config.interval,this._config.interval=e):this._config.interval=this._config.defaultInterval||this._config.interval}},e._slide=function(t,e){var n,o,r,a=this,s=this._element.querySelector(D),l=this._getItemIndex(s),f=e||s&&this._getItemByDirection(t,s),d=this._getItemIndex(f),c=Boolean(this._interval);if(t===C?(n="carousel-item-left",o="carousel-item-next",r="left"):(n="carousel-item-right",o="carousel-item-prev",r="right"),f&&i.default(f).hasClass(T))this._isSliding=!1;else if(!this._triggerSlideEvent(f,r).isDefaultPrevented()&&s&&f){this._isSliding=!0,c&&this.pause(),this._setActiveIndicatorElement(f),this._activeElement=f;var h=i.default.Event(N,{relatedTarget:f,direction:r,from:l,to:d});if(i.default(this._element).hasClass("slide")){i.default(f).addClass(o),u.reflow(f),i.default(s).addClass(n),i.default(f).addClass(n);var p=u.getTransitionDurationFromElement(s);i.default(s).one(u.TRANSITION_END,(function(){i.default(f).removeClass(n+" "+o).addClass(T),i.default(s).removeClass("active "+o+" "+n),a._isSliding=!1,setTimeout((function(){return i.default(a._element).trigger(h)}),0)})).emulateTransitionEnd(p)}else i.default(s).removeClass(T),i.default(f).addClass(T),this._isSliding=!1,i.default(this._element).trigger(h);c&&this.cycle()}},t._jQueryInterface=function(e){return this.each((function(){var n=i.default(this).data(E),o=a({},A,i.default(this).data());"object"==typeof e&&(o=a({},o,e));var r="string"==typeof e?e:o.slide;if(n||(n=new t(this,o),i.default(this).data(E,n)),"number"==typeof e)n.to(e);else if("string"==typeof r){if("undefined"==typeof n[r])throw new TypeError('No method named "'+r+'"');n[r]()}else o.interval&&o.ride&&(n.pause(),n.cycle())}))},t._dataApiClickHandler=function(e){var n=u.getSelectorFromElement(this);if(n){var o=i.default(n)[0];if(o&&i.default(o).hasClass("carousel")){var r=a({},i.default(o).data(),i.default(this).data()),s=this.getAttribute("data-slide-to");s&&(r.interval=!1),t._jQueryInterface.call(i.default(o),r),s&&i.default(o).data(E).to(s),e.preventDefault()}}},r(t,null,[{key:"VERSION",get:function(){return"4.6.2"}},{key:"Default",get:function(){return A}}]),t}();i.default(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",O._dataApiClickHandler),i.default(window).on("load.bs.carousel.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-ride="carousel"]')),e=0,n=t.length;e0&&(this._selector=a,this._triggerArray.push(r))}this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle()}var e=t.prototype;return e.toggle=function(){i.default(this._element).hasClass(P)?this.hide():this.show()},e.show=function(){var e,n,o=this;if(!(this._isTransitioning||i.default(this._element).hasClass(P)||(this._parent&&0===(e=[].slice.call(this._parent.querySelectorAll(".show, .collapsing")).filter((function(t){return"string"==typeof o._config.parent?t.getAttribute("data-parent")===o._config.parent:t.classList.contains(F)}))).length&&(e=null),e&&(n=i.default(e).not(this._selector).data(j))&&n._isTransitioning))){var r=i.default.Event("show.bs.collapse");if(i.default(this._element).trigger(r),!r.isDefaultPrevented()){e&&(t._jQueryInterface.call(i.default(e).not(this._selector),"hide"),n||i.default(e).data(j,null));var a=this._getDimension();i.default(this._element).removeClass(F).addClass(R),this._element.style[a]=0,this._triggerArray.length&&i.default(this._triggerArray).removeClass(B).attr("aria-expanded",!0),this.setTransitioning(!0);var s="scroll"+(a[0].toUpperCase()+a.slice(1)),l=u.getTransitionDurationFromElement(this._element);i.default(this._element).one(u.TRANSITION_END,(function(){i.default(o._element).removeClass(R).addClass("collapse show"),o._element.style[a]="",o.setTransitioning(!1),i.default(o._element).trigger("shown.bs.collapse")})).emulateTransitionEnd(l),this._element.style[a]=this._element[s]+"px"}}},e.hide=function(){var t=this;if(!this._isTransitioning&&i.default(this._element).hasClass(P)){var e=i.default.Event("hide.bs.collapse");if(i.default(this._element).trigger(e),!e.isDefaultPrevented()){var n=this._getDimension();this._element.style[n]=this._element.getBoundingClientRect()[n]+"px",u.reflow(this._element),i.default(this._element).addClass(R).removeClass("collapse show");var o=this._triggerArray.length;if(o>0)for(var r=0;r=0)return 1;return 0}(),Y=U&&window.Promise?function(t){var e=!1;return function(){e||(e=!0,window.Promise.resolve().then((function(){e=!1,t()})))}}:function(t){var e=!1;return function(){e||(e=!0,setTimeout((function(){e=!1,t()}),V))}};function z(t){return t&&"[object Function]"==={}.toString.call(t)}function K(t,e){if(1!==t.nodeType)return[];var n=t.ownerDocument.defaultView.getComputedStyle(t,null);return e?n[e]:n}function X(t){return"HTML"===t.nodeName?t:t.parentNode||t.host}function G(t){if(!t)return document.body;switch(t.nodeName){case"HTML":case"BODY":return t.ownerDocument.body;case"#document":return t.body}var e=K(t),n=e.overflow,i=e.overflowX,o=e.overflowY;return/(auto|scroll|overlay)/.test(n+o+i)?t:G(X(t))}function $(t){return t&&t.referenceNode?t.referenceNode:t}var J=U&&!(!window.MSInputMethodContext||!document.documentMode),Z=U&&/MSIE 10/.test(navigator.userAgent);function tt(t){return 11===t?J:10===t?Z:J||Z}function et(t){if(!t)return document.documentElement;for(var e=tt(10)?document.body:null,n=t.offsetParent||null;n===e&&t.nextElementSibling;)n=(t=t.nextElementSibling).offsetParent;var i=n&&n.nodeName;return i&&"BODY"!==i&&"HTML"!==i?-1!==["TH","TD","TABLE"].indexOf(n.nodeName)&&"static"===K(n,"position")?et(n):n:t?t.ownerDocument.documentElement:document.documentElement}function nt(t){return null!==t.parentNode?nt(t.parentNode):t}function it(t,e){if(!(t&&t.nodeType&&e&&e.nodeType))return document.documentElement;var n=t.compareDocumentPosition(e)&Node.DOCUMENT_POSITION_FOLLOWING,i=n?t:e,o=n?e:t,r=document.createRange();r.setStart(i,0),r.setEnd(o,0);var a,s,l=r.commonAncestorContainer;if(t!==l&&e!==l||i.contains(o))return"BODY"===(s=(a=l).nodeName)||"HTML"!==s&&et(a.firstElementChild)!==a?et(l):l;var u=nt(t);return u.host?it(u.host,e):it(t,nt(e).host)}function ot(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"top",n="top"===e?"scrollTop":"scrollLeft",i=t.nodeName;if("BODY"===i||"HTML"===i){var o=t.ownerDocument.documentElement,r=t.ownerDocument.scrollingElement||o;return r[n]}return t[n]}function rt(t,e){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],i=ot(e,"top"),o=ot(e,"left"),r=n?-1:1;return t.top+=i*r,t.bottom+=i*r,t.left+=o*r,t.right+=o*r,t}function at(t,e){var n="x"===e?"Left":"Top",i="Left"===n?"Right":"Bottom";return parseFloat(t["border"+n+"Width"])+parseFloat(t["border"+i+"Width"])}function st(t,e,n,i){return Math.max(e["offset"+t],e["scroll"+t],n["client"+t],n["offset"+t],n["scroll"+t],tt(10)?parseInt(n["offset"+t])+parseInt(i["margin"+("Height"===t?"Top":"Left")])+parseInt(i["margin"+("Height"===t?"Bottom":"Right")]):0)}function lt(t){var e=t.body,n=t.documentElement,i=tt(10)&&getComputedStyle(n);return{height:st("Height",e,n,i),width:st("Width",e,n,i)}}var ut=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},ft=function(){function t(t,e){for(var n=0;n2&&void 0!==arguments[2]&&arguments[2],i=tt(10),o="HTML"===e.nodeName,r=pt(t),a=pt(e),s=G(t),l=K(e),u=parseFloat(l.borderTopWidth),f=parseFloat(l.borderLeftWidth);n&&o&&(a.top=Math.max(a.top,0),a.left=Math.max(a.left,0));var d=ht({top:r.top-a.top-u,left:r.left-a.left-f,width:r.width,height:r.height});if(d.marginTop=0,d.marginLeft=0,!i&&o){var c=parseFloat(l.marginTop),h=parseFloat(l.marginLeft);d.top-=u-c,d.bottom-=u-c,d.left-=f-h,d.right-=f-h,d.marginTop=c,d.marginLeft=h}return(i&&!n?e.contains(s):e===s&&"BODY"!==s.nodeName)&&(d=rt(d,e)),d}function gt(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=t.ownerDocument.documentElement,i=mt(t,n),o=Math.max(n.clientWidth,window.innerWidth||0),r=Math.max(n.clientHeight,window.innerHeight||0),a=e?0:ot(n),s=e?0:ot(n,"left"),l={top:a-i.top+i.marginTop,left:s-i.left+i.marginLeft,width:o,height:r};return ht(l)}function _t(t){var e=t.nodeName;if("BODY"===e||"HTML"===e)return!1;if("fixed"===K(t,"position"))return!0;var n=X(t);return!!n&&_t(n)}function vt(t){if(!t||!t.parentElement||tt())return document.documentElement;for(var e=t.parentElement;e&&"none"===K(e,"transform");)e=e.parentElement;return e||document.documentElement}function bt(t,e,n,i){var o=arguments.length>4&&void 0!==arguments[4]&&arguments[4],r={top:0,left:0},a=o?vt(t):it(t,$(e));if("viewport"===i)r=gt(a,o);else{var s=void 0;"scrollParent"===i?"BODY"===(s=G(X(e))).nodeName&&(s=t.ownerDocument.documentElement):s="window"===i?t.ownerDocument.documentElement:i;var l=mt(s,a,o);if("HTML"!==s.nodeName||_t(a))r=l;else{var u=lt(t.ownerDocument),f=u.height,d=u.width;r.top+=l.top-l.marginTop,r.bottom=f+l.top,r.left+=l.left-l.marginLeft,r.right=d+l.left}}var c="number"==typeof(n=n||0);return r.left+=c?n:n.left||0,r.top+=c?n:n.top||0,r.right-=c?n:n.right||0,r.bottom-=c?n:n.bottom||0,r}function yt(t){return t.width*t.height}function Et(t,e,n,i,o){var r=arguments.length>5&&void 0!==arguments[5]?arguments[5]:0;if(-1===t.indexOf("auto"))return t;var a=bt(n,i,r,o),s={top:{width:a.width,height:e.top-a.top},right:{width:a.right-e.right,height:a.height},bottom:{width:a.width,height:a.bottom-e.bottom},left:{width:e.left-a.left,height:a.height}},l=Object.keys(s).map((function(t){return ct({key:t},s[t],{area:yt(s[t])})})).sort((function(t,e){return e.area-t.area})),u=l.filter((function(t){var e=t.width,i=t.height;return e>=n.clientWidth&&i>=n.clientHeight})),f=u.length>0?u[0].key:l[0].key,d=t.split("-")[1];return f+(d?"-"+d:"")}function wt(t,e,n){var i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,o=i?vt(e):it(e,$(n));return mt(n,o,i)}function Tt(t){var e=t.ownerDocument.defaultView.getComputedStyle(t),n=parseFloat(e.marginTop||0)+parseFloat(e.marginBottom||0),i=parseFloat(e.marginLeft||0)+parseFloat(e.marginRight||0);return{width:t.offsetWidth+i,height:t.offsetHeight+n}}function Ct(t){var e={left:"right",right:"left",bottom:"top",top:"bottom"};return t.replace(/left|right|bottom|top/g,(function(t){return e[t]}))}function St(t,e,n){n=n.split("-")[0];var i=Tt(t),o={width:i.width,height:i.height},r=-1!==["right","left"].indexOf(n),a=r?"top":"left",s=r?"left":"top",l=r?"height":"width",u=r?"width":"height";return o[a]=e[a]+e[l]/2-i[l]/2,o[s]=n===s?e[s]-i[u]:e[Ct(s)],o}function Nt(t,e){return Array.prototype.find?t.find(e):t.filter(e)[0]}function Dt(t,e,n){return(void 0===n?t:t.slice(0,function(t,e,n){if(Array.prototype.findIndex)return t.findIndex((function(t){return t.name===n}));var i=Nt(t,(function(t){return t.name===n}));return t.indexOf(i)}(t,0,n))).forEach((function(t){t.function&&console.warn("`modifier.function` is deprecated, use `modifier.fn`!");var n=t.function||t.fn;t.enabled&&z(n)&&(e.offsets.popper=ht(e.offsets.popper),e.offsets.reference=ht(e.offsets.reference),e=n(e,t))})),e}function At(){if(!this.state.isDestroyed){var t={instance:this,styles:{},arrowStyles:{},attributes:{},flipped:!1,offsets:{}};t.offsets.reference=wt(this.state,this.popper,this.reference,this.options.positionFixed),t.placement=Et(this.options.placement,t.offsets.reference,this.popper,this.reference,this.options.modifiers.flip.boundariesElement,this.options.modifiers.flip.padding),t.originalPlacement=t.placement,t.positionFixed=this.options.positionFixed,t.offsets.popper=St(this.popper,t.offsets.reference,t.placement),t.offsets.popper.position=this.options.positionFixed?"fixed":"absolute",t=Dt(this.modifiers,t),this.state.isCreated?this.options.onUpdate(t):(this.state.isCreated=!0,this.options.onCreate(t))}}function kt(t,e){return t.some((function(t){var n=t.name;return t.enabled&&n===e}))}function It(t){for(var e=[!1,"ms","Webkit","Moz","O"],n=t.charAt(0).toUpperCase()+t.slice(1),i=0;i1&&void 0!==arguments[1]&&arguments[1],n=Qt.indexOf(t),i=Qt.slice(n+1).concat(Qt.slice(0,n));return e?i.reverse():i}var Ut={placement:"bottom",positionFixed:!1,eventsEnabled:!0,removeOnDestroy:!1,onCreate:function(){},onUpdate:function(){},modifiers:{shift:{order:100,enabled:!0,fn:function(t){var e=t.placement,n=e.split("-")[0],i=e.split("-")[1];if(i){var o=t.offsets,r=o.reference,a=o.popper,s=-1!==["bottom","top"].indexOf(n),l=s?"left":"top",u=s?"width":"height",f={start:dt({},l,r[l]),end:dt({},l,r[l]+r[u]-a[u])};t.offsets.popper=ct({},a,f[i])}return t}},offset:{order:200,enabled:!0,fn:function(t,e){var n,i=e.offset,o=t.placement,r=t.offsets,a=r.popper,s=r.reference,l=o.split("-")[0];return n=Rt(+i)?[+i,0]:function(t,e,n,i){var o=[0,0],r=-1!==["right","left"].indexOf(i),a=t.split(/(\+|\-)/).map((function(t){return t.trim()})),s=a.indexOf(Nt(a,(function(t){return-1!==t.search(/,|\s/)})));a[s]&&-1===a[s].indexOf(",")&&console.warn("Offsets separated by white space(s) are deprecated, use a comma (,) instead.");var l=/\s*,\s*|\s+/,u=-1!==s?[a.slice(0,s).concat([a[s].split(l)[0]]),[a[s].split(l)[1]].concat(a.slice(s+1))]:[a];return u=u.map((function(t,i){var o=(1===i?!r:r)?"height":"width",a=!1;return t.reduce((function(t,e){return""===t[t.length-1]&&-1!==["+","-"].indexOf(e)?(t[t.length-1]=e,a=!0,t):a?(t[t.length-1]+=e,a=!1,t):t.concat(e)}),[]).map((function(t){return function(t,e,n,i){var o=t.match(/((?:\-|\+)?\d*\.?\d*)(.*)/),r=+o[1],a=o[2];return r?0===a.indexOf("%")?ht("%p"===a?n:i)[e]/100*r:"vh"===a||"vw"===a?("vh"===a?Math.max(document.documentElement.clientHeight,window.innerHeight||0):Math.max(document.documentElement.clientWidth,window.innerWidth||0))/100*r:r:t}(t,o,e,n)}))})),u.forEach((function(t,e){t.forEach((function(n,i){Rt(n)&&(o[e]+=n*("-"===t[i-1]?-1:1))}))})),o}(i,a,s,l),"left"===l?(a.top+=n[0],a.left-=n[1]):"right"===l?(a.top+=n[0],a.left+=n[1]):"top"===l?(a.left+=n[0],a.top-=n[1]):"bottom"===l&&(a.left+=n[0],a.top+=n[1]),t.popper=a,t},offset:0},preventOverflow:{order:300,enabled:!0,fn:function(t,e){var n=e.boundariesElement||et(t.instance.popper);t.instance.reference===n&&(n=et(n));var i=It("transform"),o=t.instance.popper.style,r=o.top,a=o.left,s=o[i];o.top="",o.left="",o[i]="";var l=bt(t.instance.popper,t.instance.reference,e.padding,n,t.positionFixed);o.top=r,o.left=a,o[i]=s,e.boundaries=l;var u=e.priority,f=t.offsets.popper,d={primary:function(t){var n=f[t];return f[t]l[t]&&!e.escapeWithReference&&(i=Math.min(f[n],l[t]-("right"===t?f.width:f.height))),dt({},n,i)}};return u.forEach((function(t){var e=-1!==["left","top"].indexOf(t)?"primary":"secondary";f=ct({},f,d[e](t))})),t.offsets.popper=f,t},priority:["left","right","top","bottom"],padding:5,boundariesElement:"scrollParent"},keepTogether:{order:400,enabled:!0,fn:function(t){var e=t.offsets,n=e.popper,i=e.reference,o=t.placement.split("-")[0],r=Math.floor,a=-1!==["top","bottom"].indexOf(o),s=a?"right":"bottom",l=a?"left":"top",u=a?"width":"height";return n[s]r(i[s])&&(t.offsets.popper[l]=r(i[s])),t}},arrow:{order:500,enabled:!0,fn:function(t,e){var n;if(!Mt(t.instance.modifiers,"arrow","keepTogether"))return t;var i=e.element;if("string"==typeof i){if(!(i=t.instance.popper.querySelector(i)))return t}else if(!t.instance.popper.contains(i))return console.warn("WARNING: `arrow.element` must be child of its popper element!"),t;var o=t.placement.split("-")[0],r=t.offsets,a=r.popper,s=r.reference,l=-1!==["left","right"].indexOf(o),u=l?"height":"width",f=l?"Top":"Left",d=f.toLowerCase(),c=l?"left":"top",h=l?"bottom":"right",p=Tt(i)[u];s[h]-pa[h]&&(t.offsets.popper[d]+=s[d]+p-a[h]),t.offsets.popper=ht(t.offsets.popper);var m=s[d]+s[u]/2-p/2,g=K(t.instance.popper),_=parseFloat(g["margin"+f]),v=parseFloat(g["border"+f+"Width"]),b=m-t.offsets.popper[d]-_-v;return b=Math.max(Math.min(a[u]-p,b),0),t.arrowElement=i,t.offsets.arrow=(dt(n={},d,Math.round(b)),dt(n,c,""),n),t},element:"[x-arrow]"},flip:{order:600,enabled:!0,fn:function(t,e){if(kt(t.instance.modifiers,"inner"))return t;if(t.flipped&&t.placement===t.originalPlacement)return t;var n=bt(t.instance.popper,t.instance.reference,e.padding,e.boundariesElement,t.positionFixed),i=t.placement.split("-")[0],o=Ct(i),r=t.placement.split("-")[1]||"",a=[];switch(e.behavior){case"flip":a=[i,o];break;case"clockwise":a=Wt(i);break;case"counterclockwise":a=Wt(i,!0);break;default:a=e.behavior}return a.forEach((function(s,l){if(i!==s||a.length===l+1)return t;i=t.placement.split("-")[0],o=Ct(i);var u=t.offsets.popper,f=t.offsets.reference,d=Math.floor,c="left"===i&&d(u.right)>d(f.left)||"right"===i&&d(u.left)d(f.top)||"bottom"===i&&d(u.top)d(n.right),m=d(u.top)d(n.bottom),_="left"===i&&h||"right"===i&&p||"top"===i&&m||"bottom"===i&&g,v=-1!==["top","bottom"].indexOf(i),b=!!e.flipVariations&&(v&&"start"===r&&h||v&&"end"===r&&p||!v&&"start"===r&&m||!v&&"end"===r&&g),y=!!e.flipVariationsByContent&&(v&&"start"===r&&p||v&&"end"===r&&h||!v&&"start"===r&&g||!v&&"end"===r&&m),E=b||y;(c||_||E)&&(t.flipped=!0,(c||_)&&(i=a[l+1]),E&&(r=function(t){return"end"===t?"start":"start"===t?"end":t}(r)),t.placement=i+(r?"-"+r:""),t.offsets.popper=ct({},t.offsets.popper,St(t.instance.popper,t.offsets.reference,t.placement)),t=Dt(t.instance.modifiers,t,"flip"))})),t},behavior:"flip",padding:5,boundariesElement:"viewport",flipVariations:!1,flipVariationsByContent:!1},inner:{order:700,enabled:!1,fn:function(t){var e=t.placement,n=e.split("-")[0],i=t.offsets,o=i.popper,r=i.reference,a=-1!==["left","right"].indexOf(n),s=-1===["top","left"].indexOf(n);return o[a?"left":"top"]=r[n]-(s?o[a?"width":"height"]:0),t.placement=Ct(e),t.offsets.popper=ht(o),t}},hide:{order:800,enabled:!0,fn:function(t){if(!Mt(t.instance.modifiers,"hide","preventOverflow"))return t;var e=t.offsets.reference,n=Nt(t.instance.modifiers,(function(t){return"preventOverflow"===t.name})).boundaries;if(e.bottomn.right||e.top>n.bottom||e.right2&&void 0!==arguments[2]?arguments[2]:{};ut(this,t),this.scheduleUpdate=function(){return requestAnimationFrame(i.update)},this.update=Y(this.update.bind(this)),this.options=ct({},t.Defaults,o),this.state={isDestroyed:!1,isCreated:!1,scrollParents:[]},this.reference=e&&e.jquery?e[0]:e,this.popper=n&&n.jquery?n[0]:n,this.options.modifiers={},Object.keys(ct({},t.Defaults.modifiers,o.modifiers)).forEach((function(e){i.options.modifiers[e]=ct({},t.Defaults.modifiers[e]||{},o.modifiers?o.modifiers[e]:{})})),this.modifiers=Object.keys(this.options.modifiers).map((function(t){return ct({name:t},i.options.modifiers[t])})).sort((function(t,e){return t.order-e.order})),this.modifiers.forEach((function(t){t.enabled&&z(t.onLoad)&&t.onLoad(i.reference,i.popper,i.options,t,i.state)})),this.update();var r=this.options.eventsEnabled;r&&this.enableEventListeners(),this.state.eventsEnabled=r}return ft(t,[{key:"update",value:function(){return At.call(this)}},{key:"destroy",value:function(){return Ot.call(this)}},{key:"enableEventListeners",value:function(){return Pt.call(this)}},{key:"disableEventListeners",value:function(){return Ft.call(this)}}]),t}();Vt.Utils=("undefined"!=typeof window?window:global).PopperUtils,Vt.placements=qt,Vt.Defaults=Ut;var Yt=Vt,zt="dropdown",Kt="bs.dropdown",Xt=i.default.fn[zt],Gt=new RegExp("38|40|27"),$t="disabled",Jt="show",Zt="dropdown-menu-right",te="hide.bs.dropdown",ee="hidden.bs.dropdown",ne="click.bs.dropdown.data-api",ie="keydown.bs.dropdown.data-api",oe='[data-toggle="dropdown"]',re=".dropdown-menu",ae={offset:0,flip:!0,boundary:"scrollParent",reference:"toggle",display:"dynamic",popperConfig:null},se={offset:"(number|string|function)",flip:"boolean",boundary:"(string|element)",reference:"(string|element)",display:"string",popperConfig:"(null|object)"},le=function(){function t(t,e){this._element=t,this._popper=null,this._config=this._getConfig(e),this._menu=this._getMenuElement(),this._inNavbar=this._detectNavbar(),this._addEventListeners()}var e=t.prototype;return e.toggle=function(){if(!this._element.disabled&&!i.default(this._element).hasClass($t)){var e=i.default(this._menu).hasClass(Jt);t._clearMenus(),e||this.show(!0)}},e.show=function(e){if(void 0===e&&(e=!1),!(this._element.disabled||i.default(this._element).hasClass($t)||i.default(this._menu).hasClass(Jt))){var n={relatedTarget:this._element},o=i.default.Event("show.bs.dropdown",n),r=t._getParentFromElement(this._element);if(i.default(r).trigger(o),!o.isDefaultPrevented()){if(!this._inNavbar&&e){if("undefined"==typeof Yt)throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");var a=this._element;"parent"===this._config.reference?a=r:u.isElement(this._config.reference)&&(a=this._config.reference,"undefined"!=typeof this._config.reference.jquery&&(a=this._config.reference[0])),"scrollParent"!==this._config.boundary&&i.default(r).addClass("position-static"),this._popper=new Yt(a,this._menu,this._getPopperConfig())}"ontouchstart"in document.documentElement&&0===i.default(r).closest(".navbar-nav").length&&i.default(document.body).children().on("mouseover",null,i.default.noop),this._element.focus(),this._element.setAttribute("aria-expanded",!0),i.default(this._menu).toggleClass(Jt),i.default(r).toggleClass(Jt).trigger(i.default.Event("shown.bs.dropdown",n))}}},e.hide=function(){if(!this._element.disabled&&!i.default(this._element).hasClass($t)&&i.default(this._menu).hasClass(Jt)){var e={relatedTarget:this._element},n=i.default.Event(te,e),o=t._getParentFromElement(this._element);i.default(o).trigger(n),n.isDefaultPrevented()||(this._popper&&this._popper.destroy(),i.default(this._menu).toggleClass(Jt),i.default(o).toggleClass(Jt).trigger(i.default.Event(ee,e)))}},e.dispose=function(){i.default.removeData(this._element,Kt),i.default(this._element).off(".bs.dropdown"),this._element=null,this._menu=null,null!==this._popper&&(this._popper.destroy(),this._popper=null)},e.update=function(){this._inNavbar=this._detectNavbar(),null!==this._popper&&this._popper.scheduleUpdate()},e._addEventListeners=function(){var t=this;i.default(this._element).on("click.bs.dropdown",(function(e){e.preventDefault(),e.stopPropagation(),t.toggle()}))},e._getConfig=function(t){return t=a({},this.constructor.Default,i.default(this._element).data(),t),u.typeCheckConfig(zt,t,this.constructor.DefaultType),t},e._getMenuElement=function(){if(!this._menu){var e=t._getParentFromElement(this._element);e&&(this._menu=e.querySelector(re))}return this._menu},e._getPlacement=function(){var t=i.default(this._element.parentNode),e="bottom-start";return t.hasClass("dropup")?e=i.default(this._menu).hasClass(Zt)?"top-end":"top-start":t.hasClass("dropright")?e="right-start":t.hasClass("dropleft")?e="left-start":i.default(this._menu).hasClass(Zt)&&(e="bottom-end"),e},e._detectNavbar=function(){return i.default(this._element).closest(".navbar").length>0},e._getOffset=function(){var t=this,e={};return"function"==typeof this._config.offset?e.fn=function(e){return e.offsets=a({},e.offsets,t._config.offset(e.offsets,t._element)),e}:e.offset=this._config.offset,e},e._getPopperConfig=function(){var t={placement:this._getPlacement(),modifiers:{offset:this._getOffset(),flip:{enabled:this._config.flip},preventOverflow:{boundariesElement:this._config.boundary}}};return"static"===this._config.display&&(t.modifiers.applyStyle={enabled:!1}),a({},t,this._config.popperConfig)},t._jQueryInterface=function(e){return this.each((function(){var n=i.default(this).data(Kt);if(n||(n=new t(this,"object"==typeof e?e:null),i.default(this).data(Kt,n)),"string"==typeof e){if("undefined"==typeof n[e])throw new TypeError('No method named "'+e+'"');n[e]()}}))},t._clearMenus=function(e){if(!e||3!==e.which&&("keyup"!==e.type||9===e.which))for(var n=[].slice.call(document.querySelectorAll(oe)),o=0,r=n.length;o0&&a--,40===e.which&&adocument.documentElement.clientHeight;n||(this._element.style.overflowY="hidden"),this._element.classList.add(pe);var o=u.getTransitionDurationFromElement(this._dialog);i.default(this._element).off(u.TRANSITION_END),i.default(this._element).one(u.TRANSITION_END,(function(){t._element.classList.remove(pe),n||i.default(t._element).one(u.TRANSITION_END,(function(){t._element.style.overflowY=""})).emulateTransitionEnd(t._element,o)})).emulateTransitionEnd(o),this._element.focus()}},e._showElement=function(t){var e=this,n=i.default(this._element).hasClass(ce),o=this._dialog?this._dialog.querySelector(".modal-body"):null;this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.appendChild(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),i.default(this._dialog).hasClass("modal-dialog-scrollable")&&o?o.scrollTop=0:this._element.scrollTop=0,n&&u.reflow(this._element),i.default(this._element).addClass(he),this._config.focus&&this._enforceFocus();var r=i.default.Event("shown.bs.modal",{relatedTarget:t}),a=function(){e._config.focus&&e._element.focus(),e._isTransitioning=!1,i.default(e._element).trigger(r)};if(n){var s=u.getTransitionDurationFromElement(this._dialog);i.default(this._dialog).one(u.TRANSITION_END,a).emulateTransitionEnd(s)}else a()},e._enforceFocus=function(){var t=this;i.default(document).off(_e).on(_e,(function(e){document!==e.target&&t._element!==e.target&&0===i.default(t._element).has(e.target).length&&t._element.focus()}))},e._setEscapeEvent=function(){var t=this;this._isShown?i.default(this._element).on(ye,(function(e){t._config.keyboard&&27===e.which?(e.preventDefault(),t.hide()):t._config.keyboard||27!==e.which||t._triggerBackdropTransition()})):this._isShown||i.default(this._element).off(ye)},e._setResizeEvent=function(){var t=this;this._isShown?i.default(window).on(ve,(function(e){return t.handleUpdate(e)})):i.default(window).off(ve)},e._hideModal=function(){var t=this;this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._showBackdrop((function(){i.default(document.body).removeClass(de),t._resetAdjustments(),t._resetScrollbar(),i.default(t._element).trigger(me)}))},e._removeBackdrop=function(){this._backdrop&&(i.default(this._backdrop).remove(),this._backdrop=null)},e._showBackdrop=function(t){var e=this,n=i.default(this._element).hasClass(ce)?ce:"";if(this._isShown&&this._config.backdrop){if(this._backdrop=document.createElement("div"),this._backdrop.className="modal-backdrop",n&&this._backdrop.classList.add(n),i.default(this._backdrop).appendTo(document.body),i.default(this._element).on(be,(function(t){e._ignoreBackdropClick?e._ignoreBackdropClick=!1:t.target===t.currentTarget&&("static"===e._config.backdrop?e._triggerBackdropTransition():e.hide())})),n&&u.reflow(this._backdrop),i.default(this._backdrop).addClass(he),!t)return;if(!n)return void t();var o=u.getTransitionDurationFromElement(this._backdrop);i.default(this._backdrop).one(u.TRANSITION_END,t).emulateTransitionEnd(o)}else if(!this._isShown&&this._backdrop){i.default(this._backdrop).removeClass(he);var r=function(){e._removeBackdrop(),t&&t()};if(i.default(this._element).hasClass(ce)){var a=u.getTransitionDurationFromElement(this._backdrop);i.default(this._backdrop).one(u.TRANSITION_END,r).emulateTransitionEnd(a)}else r()}else t&&t()},e._adjustDialog=function(){var t=this._element.scrollHeight>document.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},e._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},e._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=Math.round(t.left+t.right)
    ',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",customClass:"",sanitize:!0,sanitizeFn:null,whiteList:{"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},popperConfig:null},We={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(number|string|function)",container:"(string|element|boolean)",fallbackPlacement:"(string|array)",boundary:"(string|element)",customClass:"(string|function)",sanitize:"boolean",sanitizeFn:"(null|function)",whiteList:"object",popperConfig:"(null|object)"},Ue={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"},Ve=function(){function t(t,e){if("undefined"==typeof Yt)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var e=t.prototype;return e.enable=function(){this._isEnabled=!0},e.disable=function(){this._isEnabled=!1},e.toggleEnabled=function(){this._isEnabled=!this._isEnabled},e.toggle=function(t){if(this._isEnabled)if(t){var e=this.constructor.DATA_KEY,n=i.default(t.currentTarget).data(e);n||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),i.default(t.currentTarget).data(e,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(i.default(this.getTipElement()).hasClass(Fe))return void this._leave(null,this);this._enter(null,this)}},e.dispose=function(){clearTimeout(this._timeout),i.default.removeData(this.element,this.constructor.DATA_KEY),i.default(this.element).off(this.constructor.EVENT_KEY),i.default(this.element).closest(".modal").off("hide.bs.modal",this._hideModalHandler),this.tip&&i.default(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},e.show=function(){var t=this;if("none"===i.default(this.element).css("display"))throw new Error("Please use show on visible elements");var e=i.default.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){i.default(this.element).trigger(e);var n=u.findShadowRoot(this.element),o=i.default.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(e.isDefaultPrevented()||!o)return;var r=this.getTipElement(),a=u.getUID(this.constructor.NAME);r.setAttribute("id",a),this.element.setAttribute("aria-describedby",a),this.setContent(),this.config.animation&&i.default(r).addClass(Pe);var s="function"==typeof this.config.placement?this.config.placement.call(this,r,this.element):this.config.placement,l=this._getAttachment(s);this.addAttachmentClass(l);var f=this._getContainer();i.default(r).data(this.constructor.DATA_KEY,this),i.default.contains(this.element.ownerDocument.documentElement,this.tip)||i.default(r).appendTo(f),i.default(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new Yt(this.element,r,this._getPopperConfig(l)),i.default(r).addClass(Fe),i.default(r).addClass(this.config.customClass),"ontouchstart"in document.documentElement&&i.default(document.body).children().on("mouseover",null,i.default.noop);var d=function(){t.config.animation&&t._fixTransition();var e=t._hoverState;t._hoverState=null,i.default(t.element).trigger(t.constructor.Event.SHOWN),e===Be&&t._leave(null,t)};if(i.default(this.tip).hasClass(Pe)){var c=u.getTransitionDurationFromElement(this.tip);i.default(this.tip).one(u.TRANSITION_END,d).emulateTransitionEnd(c)}else d()}},e.hide=function(t){var e=this,n=this.getTipElement(),o=i.default.Event(this.constructor.Event.HIDE),r=function(){e._hoverState!==Re&&n.parentNode&&n.parentNode.removeChild(n),e._cleanTipClass(),e.element.removeAttribute("aria-describedby"),i.default(e.element).trigger(e.constructor.Event.HIDDEN),null!==e._popper&&e._popper.destroy(),t&&t()};if(i.default(this.element).trigger(o),!o.isDefaultPrevented()){if(i.default(n).removeClass(Fe),"ontouchstart"in document.documentElement&&i.default(document.body).children().off("mouseover",null,i.default.noop),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,i.default(this.tip).hasClass(Pe)){var a=u.getTransitionDurationFromElement(n);i.default(n).one(u.TRANSITION_END,r).emulateTransitionEnd(a)}else r();this._hoverState=""}},e.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},e.isWithContent=function(){return Boolean(this.getTitle())},e.addAttachmentClass=function(t){i.default(this.getTipElement()).addClass("bs-tooltip-"+t)},e.getTipElement=function(){return this.tip=this.tip||i.default(this.config.template)[0],this.tip},e.setContent=function(){var t=this.getTipElement();this.setElementContent(i.default(t.querySelectorAll(".tooltip-inner")),this.getTitle()),i.default(t).removeClass("fade show")},e.setElementContent=function(t,e){"object"!=typeof e||!e.nodeType&&!e.jquery?this.config.html?(this.config.sanitize&&(e=ke(e,this.config.whiteList,this.config.sanitizeFn)),t.html(e)):t.text(e):this.config.html?i.default(e).parent().is(t)||t.empty().append(e):t.text(i.default(e).text())},e.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},e._getPopperConfig=function(t){var e=this;return a({},{placement:t,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:".arrow"},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){return e._handlePopperPlacementChange(t)}},this.config.popperConfig)},e._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=a({},e.offsets,t.config.offset(e.offsets,t.element)),e}:e.offset=this.config.offset,e},e._getContainer=function(){return!1===this.config.container?document.body:u.isElement(this.config.container)?i.default(this.config.container):i.default(document).find(this.config.container)},e._getAttachment=function(t){return qe[t.toUpperCase()]},e._setListeners=function(){var t=this;this.config.trigger.split(" ").forEach((function(e){if("click"===e)i.default(t.element).on(t.constructor.Event.CLICK,t.config.selector,(function(e){return t.toggle(e)}));else if("manual"!==e){var n=e===He?t.constructor.Event.MOUSEENTER:t.constructor.Event.FOCUSIN,o=e===He?t.constructor.Event.MOUSELEAVE:t.constructor.Event.FOCUSOUT;i.default(t.element).on(n,t.config.selector,(function(e){return t._enter(e)})).on(o,t.config.selector,(function(e){return t._leave(e)}))}})),this._hideModalHandler=function(){t.element&&t.hide()},i.default(this.element).closest(".modal").on("hide.bs.modal",this._hideModalHandler),this.config.selector?this.config=a({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},e._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},e._enter=function(t,e){var n=this.constructor.DATA_KEY;(e=e||i.default(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),i.default(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusin"===t.type?Me:He]=!0),i.default(e.getTipElement()).hasClass(Fe)||e._hoverState===Re?e._hoverState=Re:(clearTimeout(e._timeout),e._hoverState=Re,e.config.delay&&e.config.delay.show?e._timeout=setTimeout((function(){e._hoverState===Re&&e.show()}),e.config.delay.show):e.show())},e._leave=function(t,e){var n=this.constructor.DATA_KEY;(e=e||i.default(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),i.default(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusout"===t.type?Me:He]=!1),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState=Be,e.config.delay&&e.config.delay.hide?e._timeout=setTimeout((function(){e._hoverState===Be&&e.hide()}),e.config.delay.hide):e.hide())},e._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},e._getConfig=function(t){var e=i.default(this.element).data();return Object.keys(e).forEach((function(t){-1!==Le.indexOf(t)&&delete e[t]})),"number"==typeof(t=a({},this.constructor.Default,e,"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),u.typeCheckConfig(Ie,t,this.constructor.DefaultType),t.sanitize&&(t.template=ke(t.template,t.whiteList,t.sanitizeFn)),t},e._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},e._cleanTipClass=function(){var t=i.default(this.getTipElement()),e=t.attr("class").match(je);null!==e&&e.length&&t.removeClass(e.join(""))},e._handlePopperPlacementChange=function(t){this.tip=t.instance.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(t.placement))},e._fixTransition=function(){var t=this.getTipElement(),e=this.config.animation;null===t.getAttribute("x-placement")&&(i.default(t).removeClass(Pe),this.config.animation=!1,this.hide(),this.show(),this.config.animation=e)},t._jQueryInterface=function(e){return this.each((function(){var n=i.default(this),o=n.data(Oe),r="object"==typeof e&&e;if((o||!/dispose|hide/.test(e))&&(o||(o=new t(this,r),n.data(Oe,o)),"string"==typeof e)){if("undefined"==typeof o[e])throw new TypeError('No method named "'+e+'"');o[e]()}}))},r(t,null,[{key:"VERSION",get:function(){return"4.6.2"}},{key:"Default",get:function(){return Qe}},{key:"NAME",get:function(){return Ie}},{key:"DATA_KEY",get:function(){return Oe}},{key:"Event",get:function(){return Ue}},{key:"EVENT_KEY",get:function(){return".bs.tooltip"}},{key:"DefaultType",get:function(){return We}}]),t}();i.default.fn.tooltip=Ve._jQueryInterface,i.default.fn.tooltip.Constructor=Ve,i.default.fn.tooltip.noConflict=function(){return i.default.fn.tooltip=xe,Ve._jQueryInterface};var Ye="bs.popover",ze=i.default.fn.popover,Ke=new RegExp("(^|\\s)bs-popover\\S+","g"),Xe=a({},Ve.Default,{placement:"right",trigger:"click",content:"",template:''}),Ge=a({},Ve.DefaultType,{content:"(string|element|function)"}),$e={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"},Je=function(t){var e,n;function o(){return t.apply(this,arguments)||this}n=t,(e=o).prototype=Object.create(n.prototype),e.prototype.constructor=e,s(e,n);var a=o.prototype;return a.isWithContent=function(){return this.getTitle()||this._getContent()},a.addAttachmentClass=function(t){i.default(this.getTipElement()).addClass("bs-popover-"+t)},a.getTipElement=function(){return this.tip=this.tip||i.default(this.config.template)[0],this.tip},a.setContent=function(){var t=i.default(this.getTipElement());this.setElementContent(t.find(".popover-header"),this.getTitle());var e=this._getContent();"function"==typeof e&&(e=e.call(this.element)),this.setElementContent(t.find(".popover-body"),e),t.removeClass("fade show")},a._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},a._cleanTipClass=function(){var t=i.default(this.getTipElement()),e=t.attr("class").match(Ke);null!==e&&e.length>0&&t.removeClass(e.join(""))},o._jQueryInterface=function(t){return this.each((function(){var e=i.default(this).data(Ye),n="object"==typeof t?t:null;if((e||!/dispose|hide/.test(t))&&(e||(e=new o(this,n),i.default(this).data(Ye,e)),"string"==typeof t)){if("undefined"==typeof e[t])throw new TypeError('No method named "'+t+'"');e[t]()}}))},r(o,null,[{key:"VERSION",get:function(){return"4.6.2"}},{key:"Default",get:function(){return Xe}},{key:"NAME",get:function(){return"popover"}},{key:"DATA_KEY",get:function(){return Ye}},{key:"Event",get:function(){return $e}},{key:"EVENT_KEY",get:function(){return".bs.popover"}},{key:"DefaultType",get:function(){return Ge}}]),o}(Ve);i.default.fn.popover=Je._jQueryInterface,i.default.fn.popover.Constructor=Je,i.default.fn.popover.noConflict=function(){return i.default.fn.popover=ze,Je._jQueryInterface};var Ze="scrollspy",tn="bs.scrollspy",en=i.default.fn[Ze],nn="active",on="position",rn=".nav, .list-group",an={offset:10,method:"auto",target:""},sn={offset:"number",method:"string",target:"(string|element)"},ln=function(){function t(t,e){var n=this;this._element=t,this._scrollElement="BODY"===t.tagName?window:t,this._config=this._getConfig(e),this._selector=this._config.target+" .nav-link,"+this._config.target+" .list-group-item,"+this._config.target+" .dropdown-item",this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,i.default(this._scrollElement).on("scroll.bs.scrollspy",(function(t){return n._process(t)})),this.refresh(),this._process()}var e=t.prototype;return e.refresh=function(){var t=this,e=this._scrollElement===this._scrollElement.window?"offset":on,n="auto"===this._config.method?e:this._config.method,o=n===on?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),[].slice.call(document.querySelectorAll(this._selector)).map((function(t){var e,r=u.getSelectorFromElement(t);if(r&&(e=document.querySelector(r)),e){var a=e.getBoundingClientRect();if(a.width||a.height)return[i.default(e)[n]().top+o,r]}return null})).filter(Boolean).sort((function(t,e){return t[0]-e[0]})).forEach((function(e){t._offsets.push(e[0]),t._targets.push(e[1])}))},e.dispose=function(){i.default.removeData(this._element,tn),i.default(this._scrollElement).off(".bs.scrollspy"),this._element=null,this._scrollElement=null,this._config=null,this._selector=null,this._offsets=null,this._targets=null,this._activeTarget=null,this._scrollHeight=null},e._getConfig=function(t){if("string"!=typeof(t=a({},an,"object"==typeof t&&t?t:{})).target&&u.isElement(t.target)){var e=i.default(t.target).attr("id");e||(e=u.getUID(Ze),i.default(t.target).attr("id",e)),t.target="#"+e}return u.typeCheckConfig(Ze,t,sn),t},e._getScrollTop=function(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop},e._getScrollHeight=function(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)},e._getOffsetHeight=function(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height},e._process=function(){var t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),n=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=n){var i=this._targets[this._targets.length-1];this._activeTarget!==i&&this._activate(i)}else{if(this._activeTarget&&t0)return this._activeTarget=null,void this._clear();for(var o=this._offsets.length;o--;)this._activeTarget!==this._targets[o]&&t>=this._offsets[o]&&("undefined"==typeof this._offsets[o+1]||t li > .active",gn=function(){function t(t){this._element=t}var e=t.prototype;return e.show=function(){var t=this;if(!(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&i.default(this._element).hasClass(dn)||i.default(this._element).hasClass("disabled")||this._element.hasAttribute("disabled"))){var e,n,o=i.default(this._element).closest(".nav, .list-group")[0],r=u.getSelectorFromElement(this._element);if(o){var a="UL"===o.nodeName||"OL"===o.nodeName?mn:pn;n=(n=i.default.makeArray(i.default(o).find(a)))[n.length-1]}var s=i.default.Event("hide.bs.tab",{relatedTarget:this._element}),l=i.default.Event("show.bs.tab",{relatedTarget:n});if(n&&i.default(n).trigger(s),i.default(this._element).trigger(l),!l.isDefaultPrevented()&&!s.isDefaultPrevented()){r&&(e=document.querySelector(r)),this._activate(this._element,o);var f=function(){var e=i.default.Event("hidden.bs.tab",{relatedTarget:t._element}),o=i.default.Event("shown.bs.tab",{relatedTarget:n});i.default(n).trigger(e),i.default(t._element).trigger(o)};e?this._activate(e,e.parentNode,f):f()}}},e.dispose=function(){i.default.removeData(this._element,un),this._element=null},e._activate=function(t,e,n){var o=this,r=(!e||"UL"!==e.nodeName&&"OL"!==e.nodeName?i.default(e).children(pn):i.default(e).find(mn))[0],a=n&&r&&i.default(r).hasClass(cn),s=function(){return o._transitionComplete(t,r,n)};if(r&&a){var l=u.getTransitionDurationFromElement(r);i.default(r).removeClass(hn).one(u.TRANSITION_END,s).emulateTransitionEnd(l)}else s()},e._transitionComplete=function(t,e,n){if(e){i.default(e).removeClass(dn);var o=i.default(e.parentNode).find("> .dropdown-menu .active")[0];o&&i.default(o).removeClass(dn),"tab"===e.getAttribute("role")&&e.setAttribute("aria-selected",!1)}i.default(t).addClass(dn),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),u.reflow(t),t.classList.contains(cn)&&t.classList.add(hn);var r=t.parentNode;if(r&&"LI"===r.nodeName&&(r=r.parentNode),r&&i.default(r).hasClass("dropdown-menu")){var a=i.default(t).closest(".dropdown")[0];if(a){var s=[].slice.call(a.querySelectorAll(".dropdown-toggle"));i.default(s).addClass(dn)}t.setAttribute("aria-expanded",!0)}n&&n()},t._jQueryInterface=function(e){return this.each((function(){var n=i.default(this),o=n.data(un);if(o||(o=new t(this),n.data(un,o)),"string"==typeof e){if("undefined"==typeof o[e])throw new TypeError('No method named "'+e+'"');o[e]()}}))},r(t,null,[{key:"VERSION",get:function(){return"4.6.2"}}]),t}();i.default(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',(function(t){t.preventDefault(),gn._jQueryInterface.call(i.default(this),"show")})),i.default.fn.tab=gn._jQueryInterface,i.default.fn.tab.Constructor=gn,i.default.fn.tab.noConflict=function(){return i.default.fn.tab=fn,gn._jQueryInterface};var _n="bs.toast",vn=i.default.fn.toast,bn="hide",yn="show",En="showing",wn="click.dismiss.bs.toast",Tn={animation:!0,autohide:!0,delay:500},Cn={animation:"boolean",autohide:"boolean",delay:"number"},Sn=function(){function t(t,e){this._element=t,this._config=this._getConfig(e),this._timeout=null,this._setListeners()}var e=t.prototype;return e.show=function(){var t=this,e=i.default.Event("show.bs.toast");if(i.default(this._element).trigger(e),!e.isDefaultPrevented()){this._clearTimeout(),this._config.animation&&this._element.classList.add("fade");var n=function(){t._element.classList.remove(En),t._element.classList.add(yn),i.default(t._element).trigger("shown.bs.toast"),t._config.autohide&&(t._timeout=setTimeout((function(){t.hide()}),t._config.delay))};if(this._element.classList.remove(bn),u.reflow(this._element),this._element.classList.add(En),this._config.animation){var o=u.getTransitionDurationFromElement(this._element);i.default(this._element).one(u.TRANSITION_END,n).emulateTransitionEnd(o)}else n()}},e.hide=function(){if(this._element.classList.contains(yn)){var t=i.default.Event("hide.bs.toast");i.default(this._element).trigger(t),t.isDefaultPrevented()||this._close()}},e.dispose=function(){this._clearTimeout(),this._element.classList.contains(yn)&&this._element.classList.remove(yn),i.default(this._element).off(wn),i.default.removeData(this._element,_n),this._element=null,this._config=null},e._getConfig=function(t){return t=a({},Tn,i.default(this._element).data(),"object"==typeof t&&t?t:{}),u.typeCheckConfig("toast",t,this.constructor.DefaultType),t},e._setListeners=function(){var t=this;i.default(this._element).on(wn,'[data-dismiss="toast"]',(function(){return t.hide()}))},e._close=function(){var t=this,e=function(){t._element.classList.add(bn),i.default(t._element).trigger("hidden.bs.toast")};if(this._element.classList.remove(yn),this._config.animation){var n=u.getTransitionDurationFromElement(this._element);i.default(this._element).one(u.TRANSITION_END,e).emulateTransitionEnd(n)}else e()},e._clearTimeout=function(){clearTimeout(this._timeout),this._timeout=null},t._jQueryInterface=function(e){return this.each((function(){var n=i.default(this),o=n.data(_n);if(o||(o=new t(this,"object"==typeof e&&e),n.data(_n,o)),"string"==typeof e){if("undefined"==typeof o[e])throw new TypeError('No method named "'+e+'"');o[e](this)}}))},r(t,null,[{key:"VERSION",get:function(){return"4.6.2"}},{key:"DefaultType",get:function(){return Cn}},{key:"Default",get:function(){return Tn}}]),t}();i.default.fn.toast=Sn._jQueryInterface,i.default.fn.toast.Constructor=Sn,i.default.fn.toast.noConflict=function(){return i.default.fn.toast=vn,Sn._jQueryInterface},t.Alert=c,t.Button=b,t.Carousel=O,t.Collapse=W,t.Dropdown=le,t.Modal=Se,t.Popover=Je,t.Scrollspy=ln,t.Tab=gn,t.Toast=Sn,t.Tooltip=Ve,t.Util=u,Object.defineProperty(t,"__esModule",{value:!0})})); +//# sourceMappingURL=bootstrap.bundle.min.js.map \ No newline at end of file diff --git a/assets/js/libraries/bootstrap.min.js b/assets/js/libraries/bootstrap.min.js new file mode 100644 index 0000000..97206dc --- /dev/null +++ b/assets/js/libraries/bootstrap.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v4.6.2 (https://getbootstrap.com/) + * Copyright 2011-2022 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("jquery"),require("popper.js")):"function"==typeof define&&define.amd?define(["exports","jquery","popper.js"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap={},t.jQuery,t.Popper)}(this,(function(t,e,n){"use strict";function i(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var o=i(e),a=i(n);function s(t,e){for(var n=0;n=4)throw new Error("Bootstrap's JavaScript requires at least jQuery v1.9.1 but less than v4.0.0")}};d.jQueryDetection(),o.default.fn.emulateTransitionEnd=function(t){var e=this,n=!1;return o.default(this).one(d.TRANSITION_END,(function(){n=!0})),setTimeout((function(){n||d.triggerTransitionEnd(e)}),t),this},o.default.event.special[d.TRANSITION_END]={bindType:f,delegateType:f,handle:function(t){if(o.default(t.target).is(this))return t.handleObj.handler.apply(this,arguments)}};var c="bs.alert",h=o.default.fn.alert,g=function(){function t(t){this._element=t}var e=t.prototype;return e.close=function(t){var e=this._element;t&&(e=this._getRootElement(t)),this._triggerCloseEvent(e).isDefaultPrevented()||this._removeElement(e)},e.dispose=function(){o.default.removeData(this._element,c),this._element=null},e._getRootElement=function(t){var e=d.getSelectorFromElement(t),n=!1;return e&&(n=document.querySelector(e)),n||(n=o.default(t).closest(".alert")[0]),n},e._triggerCloseEvent=function(t){var e=o.default.Event("close.bs.alert");return o.default(t).trigger(e),e},e._removeElement=function(t){var e=this;if(o.default(t).removeClass("show"),o.default(t).hasClass("fade")){var n=d.getTransitionDurationFromElement(t);o.default(t).one(d.TRANSITION_END,(function(n){return e._destroyElement(t,n)})).emulateTransitionEnd(n)}else this._destroyElement(t)},e._destroyElement=function(t){o.default(t).detach().trigger("closed.bs.alert").remove()},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this),i=n.data(c);i||(i=new t(this),n.data(c,i)),"close"===e&&i[e](this)}))},t._handleDismiss=function(t){return function(e){e&&e.preventDefault(),t.close(this)}},l(t,null,[{key:"VERSION",get:function(){return"4.6.2"}}]),t}();o.default(document).on("click.bs.alert.data-api",'[data-dismiss="alert"]',g._handleDismiss(new g)),o.default.fn.alert=g._jQueryInterface,o.default.fn.alert.Constructor=g,o.default.fn.alert.noConflict=function(){return o.default.fn.alert=h,g._jQueryInterface};var m="bs.button",p=o.default.fn.button,_="active",v='[data-toggle^="button"]',y='input:not([type="hidden"])',b=".btn",E=function(){function t(t){this._element=t,this.shouldAvoidTriggerChange=!1}var e=t.prototype;return e.toggle=function(){var t=!0,e=!0,n=o.default(this._element).closest('[data-toggle="buttons"]')[0];if(n){var i=this._element.querySelector(y);if(i){if("radio"===i.type)if(i.checked&&this._element.classList.contains(_))t=!1;else{var a=n.querySelector(".active");a&&o.default(a).removeClass(_)}t&&("checkbox"!==i.type&&"radio"!==i.type||(i.checked=!this._element.classList.contains(_)),this.shouldAvoidTriggerChange||o.default(i).trigger("change")),i.focus(),e=!1}}this._element.hasAttribute("disabled")||this._element.classList.contains("disabled")||(e&&this._element.setAttribute("aria-pressed",!this._element.classList.contains(_)),t&&o.default(this._element).toggleClass(_))},e.dispose=function(){o.default.removeData(this._element,m),this._element=null},t._jQueryInterface=function(e,n){return this.each((function(){var i=o.default(this),a=i.data(m);a||(a=new t(this),i.data(m,a)),a.shouldAvoidTriggerChange=n,"toggle"===e&&a[e]()}))},l(t,null,[{key:"VERSION",get:function(){return"4.6.2"}}]),t}();o.default(document).on("click.bs.button.data-api",v,(function(t){var e=t.target,n=e;if(o.default(e).hasClass("btn")||(e=o.default(e).closest(b)[0]),!e||e.hasAttribute("disabled")||e.classList.contains("disabled"))t.preventDefault();else{var i=e.querySelector(y);if(i&&(i.hasAttribute("disabled")||i.classList.contains("disabled")))return void t.preventDefault();"INPUT"!==n.tagName&&"LABEL"===e.tagName||E._jQueryInterface.call(o.default(e),"toggle","INPUT"===n.tagName)}})).on("focus.bs.button.data-api blur.bs.button.data-api",v,(function(t){var e=o.default(t.target).closest(b)[0];o.default(e).toggleClass("focus",/^focus(in)?$/.test(t.type))})),o.default(window).on("load.bs.button.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-toggle="buttons"] .btn')),e=0,n=t.length;e0,this._pointerEvent=Boolean(window.PointerEvent||window.MSPointerEvent),this._addEventListeners()}var e=t.prototype;return e.next=function(){this._isSliding||this._slide(N)},e.nextWhenVisible=function(){var t=o.default(this._element);!document.hidden&&t.is(":visible")&&"hidden"!==t.css("visibility")&&this.next()},e.prev=function(){this._isSliding||this._slide(D)},e.pause=function(t){t||(this._isPaused=!0),this._element.querySelector(".carousel-item-next, .carousel-item-prev")&&(d.triggerTransitionEnd(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null},e.cycle=function(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config.interval&&!this._isPaused&&(this._updateInterval(),this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))},e.to=function(t){var e=this;this._activeElement=this._element.querySelector(I);var n=this._getItemIndex(this._activeElement);if(!(t>this._items.length-1||t<0))if(this._isSliding)o.default(this._element).one(A,(function(){return e.to(t)}));else{if(n===t)return this.pause(),void this.cycle();var i=t>n?N:D;this._slide(i,this._items[t])}},e.dispose=function(){o.default(this._element).off(".bs.carousel"),o.default.removeData(this._element,w),this._items=null,this._config=null,this._element=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null},e._getConfig=function(t){return t=r({},k,t),d.typeCheckConfig(T,t,O),t},e._handleSwipe=function(){var t=Math.abs(this.touchDeltaX);if(!(t<=40)){var e=t/this.touchDeltaX;this.touchDeltaX=0,e>0&&this.prev(),e<0&&this.next()}},e._addEventListeners=function(){var t=this;this._config.keyboard&&o.default(this._element).on("keydown.bs.carousel",(function(e){return t._keydown(e)})),"hover"===this._config.pause&&o.default(this._element).on("mouseenter.bs.carousel",(function(e){return t.pause(e)})).on("mouseleave.bs.carousel",(function(e){return t.cycle(e)})),this._config.touch&&this._addTouchEventListeners()},e._addTouchEventListeners=function(){var t=this;if(this._touchSupported){var e=function(e){t._pointerEvent&&j[e.originalEvent.pointerType.toUpperCase()]?t.touchStartX=e.originalEvent.clientX:t._pointerEvent||(t.touchStartX=e.originalEvent.touches[0].clientX)},n=function(e){t._pointerEvent&&j[e.originalEvent.pointerType.toUpperCase()]&&(t.touchDeltaX=e.originalEvent.clientX-t.touchStartX),t._handleSwipe(),"hover"===t._config.pause&&(t.pause(),t.touchTimeout&&clearTimeout(t.touchTimeout),t.touchTimeout=setTimeout((function(e){return t.cycle(e)}),500+t._config.interval))};o.default(this._element.querySelectorAll(".carousel-item img")).on("dragstart.bs.carousel",(function(t){return t.preventDefault()})),this._pointerEvent?(o.default(this._element).on("pointerdown.bs.carousel",(function(t){return e(t)})),o.default(this._element).on("pointerup.bs.carousel",(function(t){return n(t)})),this._element.classList.add("pointer-event")):(o.default(this._element).on("touchstart.bs.carousel",(function(t){return e(t)})),o.default(this._element).on("touchmove.bs.carousel",(function(e){return function(e){t.touchDeltaX=e.originalEvent.touches&&e.originalEvent.touches.length>1?0:e.originalEvent.touches[0].clientX-t.touchStartX}(e)})),o.default(this._element).on("touchend.bs.carousel",(function(t){return n(t)})))}},e._keydown=function(t){if(!/input|textarea/i.test(t.target.tagName))switch(t.which){case 37:t.preventDefault(),this.prev();break;case 39:t.preventDefault(),this.next()}},e._getItemIndex=function(t){return this._items=t&&t.parentNode?[].slice.call(t.parentNode.querySelectorAll(".carousel-item")):[],this._items.indexOf(t)},e._getItemByDirection=function(t,e){var n=t===N,i=t===D,o=this._getItemIndex(e),a=this._items.length-1;if((i&&0===o||n&&o===a)&&!this._config.wrap)return e;var s=(o+(t===D?-1:1))%this._items.length;return-1===s?this._items[this._items.length-1]:this._items[s]},e._triggerSlideEvent=function(t,e){var n=this._getItemIndex(t),i=this._getItemIndex(this._element.querySelector(I)),a=o.default.Event("slide.bs.carousel",{relatedTarget:t,direction:e,from:i,to:n});return o.default(this._element).trigger(a),a},e._setActiveIndicatorElement=function(t){if(this._indicatorsElement){var e=[].slice.call(this._indicatorsElement.querySelectorAll(".active"));o.default(e).removeClass(S);var n=this._indicatorsElement.children[this._getItemIndex(t)];n&&o.default(n).addClass(S)}},e._updateInterval=function(){var t=this._activeElement||this._element.querySelector(I);if(t){var e=parseInt(t.getAttribute("data-interval"),10);e?(this._config.defaultInterval=this._config.defaultInterval||this._config.interval,this._config.interval=e):this._config.interval=this._config.defaultInterval||this._config.interval}},e._slide=function(t,e){var n,i,a,s=this,l=this._element.querySelector(I),r=this._getItemIndex(l),u=e||l&&this._getItemByDirection(t,l),f=this._getItemIndex(u),c=Boolean(this._interval);if(t===N?(n="carousel-item-left",i="carousel-item-next",a="left"):(n="carousel-item-right",i="carousel-item-prev",a="right"),u&&o.default(u).hasClass(S))this._isSliding=!1;else if(!this._triggerSlideEvent(u,a).isDefaultPrevented()&&l&&u){this._isSliding=!0,c&&this.pause(),this._setActiveIndicatorElement(u),this._activeElement=u;var h=o.default.Event(A,{relatedTarget:u,direction:a,from:r,to:f});if(o.default(this._element).hasClass("slide")){o.default(u).addClass(i),d.reflow(u),o.default(l).addClass(n),o.default(u).addClass(n);var g=d.getTransitionDurationFromElement(l);o.default(l).one(d.TRANSITION_END,(function(){o.default(u).removeClass(n+" "+i).addClass(S),o.default(l).removeClass("active "+i+" "+n),s._isSliding=!1,setTimeout((function(){return o.default(s._element).trigger(h)}),0)})).emulateTransitionEnd(g)}else o.default(l).removeClass(S),o.default(u).addClass(S),this._isSliding=!1,o.default(this._element).trigger(h);c&&this.cycle()}},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this).data(w),i=r({},k,o.default(this).data());"object"==typeof e&&(i=r({},i,e));var a="string"==typeof e?e:i.slide;if(n||(n=new t(this,i),o.default(this).data(w,n)),"number"==typeof e)n.to(e);else if("string"==typeof a){if("undefined"==typeof n[a])throw new TypeError('No method named "'+a+'"');n[a]()}else i.interval&&i.ride&&(n.pause(),n.cycle())}))},t._dataApiClickHandler=function(e){var n=d.getSelectorFromElement(this);if(n){var i=o.default(n)[0];if(i&&o.default(i).hasClass("carousel")){var a=r({},o.default(i).data(),o.default(this).data()),s=this.getAttribute("data-slide-to");s&&(a.interval=!1),t._jQueryInterface.call(o.default(i),a),s&&o.default(i).data(w).to(s),e.preventDefault()}}},l(t,null,[{key:"VERSION",get:function(){return"4.6.2"}},{key:"Default",get:function(){return k}}]),t}();o.default(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",P._dataApiClickHandler),o.default(window).on("load.bs.carousel.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-ride="carousel"]')),e=0,n=t.length;e0&&(this._selector=s,this._triggerArray.push(a))}this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle()}var e=t.prototype;return e.toggle=function(){o.default(this._element).hasClass(q)?this.hide():this.show()},e.show=function(){var e,n,i=this;if(!(this._isTransitioning||o.default(this._element).hasClass(q)||(this._parent&&0===(e=[].slice.call(this._parent.querySelectorAll(".show, .collapsing")).filter((function(t){return"string"==typeof i._config.parent?t.getAttribute("data-parent")===i._config.parent:t.classList.contains(F)}))).length&&(e=null),e&&(n=o.default(e).not(this._selector).data(R))&&n._isTransitioning))){var a=o.default.Event("show.bs.collapse");if(o.default(this._element).trigger(a),!a.isDefaultPrevented()){e&&(t._jQueryInterface.call(o.default(e).not(this._selector),"hide"),n||o.default(e).data(R,null));var s=this._getDimension();o.default(this._element).removeClass(F).addClass(Q),this._element.style[s]=0,this._triggerArray.length&&o.default(this._triggerArray).removeClass(B).attr("aria-expanded",!0),this.setTransitioning(!0);var l="scroll"+(s[0].toUpperCase()+s.slice(1)),r=d.getTransitionDurationFromElement(this._element);o.default(this._element).one(d.TRANSITION_END,(function(){o.default(i._element).removeClass(Q).addClass("collapse show"),i._element.style[s]="",i.setTransitioning(!1),o.default(i._element).trigger("shown.bs.collapse")})).emulateTransitionEnd(r),this._element.style[s]=this._element[l]+"px"}}},e.hide=function(){var t=this;if(!this._isTransitioning&&o.default(this._element).hasClass(q)){var e=o.default.Event("hide.bs.collapse");if(o.default(this._element).trigger(e),!e.isDefaultPrevented()){var n=this._getDimension();this._element.style[n]=this._element.getBoundingClientRect()[n]+"px",d.reflow(this._element),o.default(this._element).addClass(Q).removeClass("collapse show");var i=this._triggerArray.length;if(i>0)for(var a=0;a0},e._getOffset=function(){var t=this,e={};return"function"==typeof this._config.offset?e.fn=function(e){return e.offsets=r({},e.offsets,t._config.offset(e.offsets,t._element)),e}:e.offset=this._config.offset,e},e._getPopperConfig=function(){var t={placement:this._getPlacement(),modifiers:{offset:this._getOffset(),flip:{enabled:this._config.flip},preventOverflow:{boundariesElement:this._config.boundary}}};return"static"===this._config.display&&(t.modifiers.applyStyle={enabled:!1}),r({},t,this._config.popperConfig)},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this).data(K);if(n||(n=new t(this,"object"==typeof e?e:null),o.default(this).data(K,n)),"string"==typeof e){if("undefined"==typeof n[e])throw new TypeError('No method named "'+e+'"');n[e]()}}))},t._clearMenus=function(e){if(!e||3!==e.which&&("keyup"!==e.type||9===e.which))for(var n=[].slice.call(document.querySelectorAll(it)),i=0,a=n.length;i0&&s--,40===e.which&&sdocument.documentElement.clientHeight;n||(this._element.style.overflowY="hidden"),this._element.classList.add(ht);var i=d.getTransitionDurationFromElement(this._dialog);o.default(this._element).off(d.TRANSITION_END),o.default(this._element).one(d.TRANSITION_END,(function(){t._element.classList.remove(ht),n||o.default(t._element).one(d.TRANSITION_END,(function(){t._element.style.overflowY=""})).emulateTransitionEnd(t._element,i)})).emulateTransitionEnd(i),this._element.focus()}},e._showElement=function(t){var e=this,n=o.default(this._element).hasClass(dt),i=this._dialog?this._dialog.querySelector(".modal-body"):null;this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.appendChild(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),o.default(this._dialog).hasClass("modal-dialog-scrollable")&&i?i.scrollTop=0:this._element.scrollTop=0,n&&d.reflow(this._element),o.default(this._element).addClass(ct),this._config.focus&&this._enforceFocus();var a=o.default.Event("shown.bs.modal",{relatedTarget:t}),s=function(){e._config.focus&&e._element.focus(),e._isTransitioning=!1,o.default(e._element).trigger(a)};if(n){var l=d.getTransitionDurationFromElement(this._dialog);o.default(this._dialog).one(d.TRANSITION_END,s).emulateTransitionEnd(l)}else s()},e._enforceFocus=function(){var t=this;o.default(document).off(pt).on(pt,(function(e){document!==e.target&&t._element!==e.target&&0===o.default(t._element).has(e.target).length&&t._element.focus()}))},e._setEscapeEvent=function(){var t=this;this._isShown?o.default(this._element).on(yt,(function(e){t._config.keyboard&&27===e.which?(e.preventDefault(),t.hide()):t._config.keyboard||27!==e.which||t._triggerBackdropTransition()})):this._isShown||o.default(this._element).off(yt)},e._setResizeEvent=function(){var t=this;this._isShown?o.default(window).on(_t,(function(e){return t.handleUpdate(e)})):o.default(window).off(_t)},e._hideModal=function(){var t=this;this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._showBackdrop((function(){o.default(document.body).removeClass(ft),t._resetAdjustments(),t._resetScrollbar(),o.default(t._element).trigger(gt)}))},e._removeBackdrop=function(){this._backdrop&&(o.default(this._backdrop).remove(),this._backdrop=null)},e._showBackdrop=function(t){var e=this,n=o.default(this._element).hasClass(dt)?dt:"";if(this._isShown&&this._config.backdrop){if(this._backdrop=document.createElement("div"),this._backdrop.className="modal-backdrop",n&&this._backdrop.classList.add(n),o.default(this._backdrop).appendTo(document.body),o.default(this._element).on(vt,(function(t){e._ignoreBackdropClick?e._ignoreBackdropClick=!1:t.target===t.currentTarget&&("static"===e._config.backdrop?e._triggerBackdropTransition():e.hide())})),n&&d.reflow(this._backdrop),o.default(this._backdrop).addClass(ct),!t)return;if(!n)return void t();var i=d.getTransitionDurationFromElement(this._backdrop);o.default(this._backdrop).one(d.TRANSITION_END,t).emulateTransitionEnd(i)}else if(!this._isShown&&this._backdrop){o.default(this._backdrop).removeClass(ct);var a=function(){e._removeBackdrop(),t&&t()};if(o.default(this._element).hasClass(dt)){var s=d.getTransitionDurationFromElement(this._backdrop);o.default(this._backdrop).one(d.TRANSITION_END,a).emulateTransitionEnd(s)}else a()}else t&&t()},e._adjustDialog=function(){var t=this._element.scrollHeight>document.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},e._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},e._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=Math.round(t.left+t.right)
    ',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",customClass:"",sanitize:!0,sanitizeFn:null,whiteList:{"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},popperConfig:null},Ut={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(number|string|function)",container:"(string|element|boolean)",fallbackPlacement:"(string|array)",boundary:"(string|element)",customClass:"(string|function)",sanitize:"boolean",sanitizeFn:"(null|function)",whiteList:"object",popperConfig:"(null|object)"},Mt={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"},Wt=function(){function t(t,e){if("undefined"==typeof a.default)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var e=t.prototype;return e.enable=function(){this._isEnabled=!0},e.disable=function(){this._isEnabled=!1},e.toggleEnabled=function(){this._isEnabled=!this._isEnabled},e.toggle=function(t){if(this._isEnabled)if(t){var e=this.constructor.DATA_KEY,n=o.default(t.currentTarget).data(e);n||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),o.default(t.currentTarget).data(e,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(o.default(this.getTipElement()).hasClass(Rt))return void this._leave(null,this);this._enter(null,this)}},e.dispose=function(){clearTimeout(this._timeout),o.default.removeData(this.element,this.constructor.DATA_KEY),o.default(this.element).off(this.constructor.EVENT_KEY),o.default(this.element).closest(".modal").off("hide.bs.modal",this._hideModalHandler),this.tip&&o.default(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},e.show=function(){var t=this;if("none"===o.default(this.element).css("display"))throw new Error("Please use show on visible elements");var e=o.default.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){o.default(this.element).trigger(e);var n=d.findShadowRoot(this.element),i=o.default.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(e.isDefaultPrevented()||!i)return;var s=this.getTipElement(),l=d.getUID(this.constructor.NAME);s.setAttribute("id",l),this.element.setAttribute("aria-describedby",l),this.setContent(),this.config.animation&&o.default(s).addClass(Lt);var r="function"==typeof this.config.placement?this.config.placement.call(this,s,this.element):this.config.placement,u=this._getAttachment(r);this.addAttachmentClass(u);var f=this._getContainer();o.default(s).data(this.constructor.DATA_KEY,this),o.default.contains(this.element.ownerDocument.documentElement,this.tip)||o.default(s).appendTo(f),o.default(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new a.default(this.element,s,this._getPopperConfig(u)),o.default(s).addClass(Rt),o.default(s).addClass(this.config.customClass),"ontouchstart"in document.documentElement&&o.default(document.body).children().on("mouseover",null,o.default.noop);var c=function(){t.config.animation&&t._fixTransition();var e=t._hoverState;t._hoverState=null,o.default(t.element).trigger(t.constructor.Event.SHOWN),e===qt&&t._leave(null,t)};if(o.default(this.tip).hasClass(Lt)){var h=d.getTransitionDurationFromElement(this.tip);o.default(this.tip).one(d.TRANSITION_END,c).emulateTransitionEnd(h)}else c()}},e.hide=function(t){var e=this,n=this.getTipElement(),i=o.default.Event(this.constructor.Event.HIDE),a=function(){e._hoverState!==xt&&n.parentNode&&n.parentNode.removeChild(n),e._cleanTipClass(),e.element.removeAttribute("aria-describedby"),o.default(e.element).trigger(e.constructor.Event.HIDDEN),null!==e._popper&&e._popper.destroy(),t&&t()};if(o.default(this.element).trigger(i),!i.isDefaultPrevented()){if(o.default(n).removeClass(Rt),"ontouchstart"in document.documentElement&&o.default(document.body).children().off("mouseover",null,o.default.noop),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,o.default(this.tip).hasClass(Lt)){var s=d.getTransitionDurationFromElement(n);o.default(n).one(d.TRANSITION_END,a).emulateTransitionEnd(s)}else a();this._hoverState=""}},e.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},e.isWithContent=function(){return Boolean(this.getTitle())},e.addAttachmentClass=function(t){o.default(this.getTipElement()).addClass("bs-tooltip-"+t)},e.getTipElement=function(){return this.tip=this.tip||o.default(this.config.template)[0],this.tip},e.setContent=function(){var t=this.getTipElement();this.setElementContent(o.default(t.querySelectorAll(".tooltip-inner")),this.getTitle()),o.default(t).removeClass("fade show")},e.setElementContent=function(t,e){"object"!=typeof e||!e.nodeType&&!e.jquery?this.config.html?(this.config.sanitize&&(e=At(e,this.config.whiteList,this.config.sanitizeFn)),t.html(e)):t.text(e):this.config.html?o.default(e).parent().is(t)||t.empty().append(e):t.text(o.default(e).text())},e.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},e._getPopperConfig=function(t){var e=this;return r({},{placement:t,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:".arrow"},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){return e._handlePopperPlacementChange(t)}},this.config.popperConfig)},e._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=r({},e.offsets,t.config.offset(e.offsets,t.element)),e}:e.offset=this.config.offset,e},e._getContainer=function(){return!1===this.config.container?document.body:d.isElement(this.config.container)?o.default(this.config.container):o.default(document).find(this.config.container)},e._getAttachment=function(t){return Bt[t.toUpperCase()]},e._setListeners=function(){var t=this;this.config.trigger.split(" ").forEach((function(e){if("click"===e)o.default(t.element).on(t.constructor.Event.CLICK,t.config.selector,(function(e){return t.toggle(e)}));else if("manual"!==e){var n=e===Ft?t.constructor.Event.MOUSEENTER:t.constructor.Event.FOCUSIN,i=e===Ft?t.constructor.Event.MOUSELEAVE:t.constructor.Event.FOCUSOUT;o.default(t.element).on(n,t.config.selector,(function(e){return t._enter(e)})).on(i,t.config.selector,(function(e){return t._leave(e)}))}})),this._hideModalHandler=function(){t.element&&t.hide()},o.default(this.element).closest(".modal").on("hide.bs.modal",this._hideModalHandler),this.config.selector?this.config=r({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},e._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},e._enter=function(t,e){var n=this.constructor.DATA_KEY;(e=e||o.default(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),o.default(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusin"===t.type?Qt:Ft]=!0),o.default(e.getTipElement()).hasClass(Rt)||e._hoverState===xt?e._hoverState=xt:(clearTimeout(e._timeout),e._hoverState=xt,e.config.delay&&e.config.delay.show?e._timeout=setTimeout((function(){e._hoverState===xt&&e.show()}),e.config.delay.show):e.show())},e._leave=function(t,e){var n=this.constructor.DATA_KEY;(e=e||o.default(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),o.default(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusout"===t.type?Qt:Ft]=!1),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState=qt,e.config.delay&&e.config.delay.hide?e._timeout=setTimeout((function(){e._hoverState===qt&&e.hide()}),e.config.delay.hide):e.hide())},e._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},e._getConfig=function(t){var e=o.default(this.element).data();return Object.keys(e).forEach((function(t){-1!==Pt.indexOf(t)&&delete e[t]})),"number"==typeof(t=r({},this.constructor.Default,e,"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),d.typeCheckConfig(It,t,this.constructor.DefaultType),t.sanitize&&(t.template=At(t.template,t.whiteList,t.sanitizeFn)),t},e._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},e._cleanTipClass=function(){var t=o.default(this.getTipElement()),e=t.attr("class").match(jt);null!==e&&e.length&&t.removeClass(e.join(""))},e._handlePopperPlacementChange=function(t){this.tip=t.instance.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(t.placement))},e._fixTransition=function(){var t=this.getTipElement(),e=this.config.animation;null===t.getAttribute("x-placement")&&(o.default(t).removeClass(Lt),this.config.animation=!1,this.hide(),this.show(),this.config.animation=e)},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this),i=n.data(kt),a="object"==typeof e&&e;if((i||!/dispose|hide/.test(e))&&(i||(i=new t(this,a),n.data(kt,i)),"string"==typeof e)){if("undefined"==typeof i[e])throw new TypeError('No method named "'+e+'"');i[e]()}}))},l(t,null,[{key:"VERSION",get:function(){return"4.6.2"}},{key:"Default",get:function(){return Ht}},{key:"NAME",get:function(){return It}},{key:"DATA_KEY",get:function(){return kt}},{key:"Event",get:function(){return Mt}},{key:"EVENT_KEY",get:function(){return".bs.tooltip"}},{key:"DefaultType",get:function(){return Ut}}]),t}();o.default.fn.tooltip=Wt._jQueryInterface,o.default.fn.tooltip.Constructor=Wt,o.default.fn.tooltip.noConflict=function(){return o.default.fn.tooltip=Ot,Wt._jQueryInterface};var Vt="bs.popover",zt=o.default.fn.popover,Kt=new RegExp("(^|\\s)bs-popover\\S+","g"),Xt=r({},Wt.Default,{placement:"right",trigger:"click",content:"",template:''}),Yt=r({},Wt.DefaultType,{content:"(string|element|function)"}),$t={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"},Jt=function(t){var e,n;function i(){return t.apply(this,arguments)||this}n=t,(e=i).prototype=Object.create(n.prototype),e.prototype.constructor=e,u(e,n);var a=i.prototype;return a.isWithContent=function(){return this.getTitle()||this._getContent()},a.addAttachmentClass=function(t){o.default(this.getTipElement()).addClass("bs-popover-"+t)},a.getTipElement=function(){return this.tip=this.tip||o.default(this.config.template)[0],this.tip},a.setContent=function(){var t=o.default(this.getTipElement());this.setElementContent(t.find(".popover-header"),this.getTitle());var e=this._getContent();"function"==typeof e&&(e=e.call(this.element)),this.setElementContent(t.find(".popover-body"),e),t.removeClass("fade show")},a._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},a._cleanTipClass=function(){var t=o.default(this.getTipElement()),e=t.attr("class").match(Kt);null!==e&&e.length>0&&t.removeClass(e.join(""))},i._jQueryInterface=function(t){return this.each((function(){var e=o.default(this).data(Vt),n="object"==typeof t?t:null;if((e||!/dispose|hide/.test(t))&&(e||(e=new i(this,n),o.default(this).data(Vt,e)),"string"==typeof t)){if("undefined"==typeof e[t])throw new TypeError('No method named "'+t+'"');e[t]()}}))},l(i,null,[{key:"VERSION",get:function(){return"4.6.2"}},{key:"Default",get:function(){return Xt}},{key:"NAME",get:function(){return"popover"}},{key:"DATA_KEY",get:function(){return Vt}},{key:"Event",get:function(){return $t}},{key:"EVENT_KEY",get:function(){return".bs.popover"}},{key:"DefaultType",get:function(){return Yt}}]),i}(Wt);o.default.fn.popover=Jt._jQueryInterface,o.default.fn.popover.Constructor=Jt,o.default.fn.popover.noConflict=function(){return o.default.fn.popover=zt,Jt._jQueryInterface};var Gt="scrollspy",Zt="bs.scrollspy",te=o.default.fn[Gt],ee="active",ne="position",ie=".nav, .list-group",oe={offset:10,method:"auto",target:""},ae={offset:"number",method:"string",target:"(string|element)"},se=function(){function t(t,e){var n=this;this._element=t,this._scrollElement="BODY"===t.tagName?window:t,this._config=this._getConfig(e),this._selector=this._config.target+" .nav-link,"+this._config.target+" .list-group-item,"+this._config.target+" .dropdown-item",this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,o.default(this._scrollElement).on("scroll.bs.scrollspy",(function(t){return n._process(t)})),this.refresh(),this._process()}var e=t.prototype;return e.refresh=function(){var t=this,e=this._scrollElement===this._scrollElement.window?"offset":ne,n="auto"===this._config.method?e:this._config.method,i=n===ne?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),[].slice.call(document.querySelectorAll(this._selector)).map((function(t){var e,a=d.getSelectorFromElement(t);if(a&&(e=document.querySelector(a)),e){var s=e.getBoundingClientRect();if(s.width||s.height)return[o.default(e)[n]().top+i,a]}return null})).filter(Boolean).sort((function(t,e){return t[0]-e[0]})).forEach((function(e){t._offsets.push(e[0]),t._targets.push(e[1])}))},e.dispose=function(){o.default.removeData(this._element,Zt),o.default(this._scrollElement).off(".bs.scrollspy"),this._element=null,this._scrollElement=null,this._config=null,this._selector=null,this._offsets=null,this._targets=null,this._activeTarget=null,this._scrollHeight=null},e._getConfig=function(t){if("string"!=typeof(t=r({},oe,"object"==typeof t&&t?t:{})).target&&d.isElement(t.target)){var e=o.default(t.target).attr("id");e||(e=d.getUID(Gt),o.default(t.target).attr("id",e)),t.target="#"+e}return d.typeCheckConfig(Gt,t,ae),t},e._getScrollTop=function(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop},e._getScrollHeight=function(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)},e._getOffsetHeight=function(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height},e._process=function(){var t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),n=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=n){var i=this._targets[this._targets.length-1];this._activeTarget!==i&&this._activate(i)}else{if(this._activeTarget&&t0)return this._activeTarget=null,void this._clear();for(var o=this._offsets.length;o--;)this._activeTarget!==this._targets[o]&&t>=this._offsets[o]&&("undefined"==typeof this._offsets[o+1]||t li > .active",ge=function(){function t(t){this._element=t}var e=t.prototype;return e.show=function(){var t=this;if(!(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&o.default(this._element).hasClass(ue)||o.default(this._element).hasClass("disabled")||this._element.hasAttribute("disabled"))){var e,n,i=o.default(this._element).closest(".nav, .list-group")[0],a=d.getSelectorFromElement(this._element);if(i){var s="UL"===i.nodeName||"OL"===i.nodeName?he:ce;n=(n=o.default.makeArray(o.default(i).find(s)))[n.length-1]}var l=o.default.Event("hide.bs.tab",{relatedTarget:this._element}),r=o.default.Event("show.bs.tab",{relatedTarget:n});if(n&&o.default(n).trigger(l),o.default(this._element).trigger(r),!r.isDefaultPrevented()&&!l.isDefaultPrevented()){a&&(e=document.querySelector(a)),this._activate(this._element,i);var u=function(){var e=o.default.Event("hidden.bs.tab",{relatedTarget:t._element}),i=o.default.Event("shown.bs.tab",{relatedTarget:n});o.default(n).trigger(e),o.default(t._element).trigger(i)};e?this._activate(e,e.parentNode,u):u()}}},e.dispose=function(){o.default.removeData(this._element,le),this._element=null},e._activate=function(t,e,n){var i=this,a=(!e||"UL"!==e.nodeName&&"OL"!==e.nodeName?o.default(e).children(ce):o.default(e).find(he))[0],s=n&&a&&o.default(a).hasClass(fe),l=function(){return i._transitionComplete(t,a,n)};if(a&&s){var r=d.getTransitionDurationFromElement(a);o.default(a).removeClass(de).one(d.TRANSITION_END,l).emulateTransitionEnd(r)}else l()},e._transitionComplete=function(t,e,n){if(e){o.default(e).removeClass(ue);var i=o.default(e.parentNode).find("> .dropdown-menu .active")[0];i&&o.default(i).removeClass(ue),"tab"===e.getAttribute("role")&&e.setAttribute("aria-selected",!1)}o.default(t).addClass(ue),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),d.reflow(t),t.classList.contains(fe)&&t.classList.add(de);var a=t.parentNode;if(a&&"LI"===a.nodeName&&(a=a.parentNode),a&&o.default(a).hasClass("dropdown-menu")){var s=o.default(t).closest(".dropdown")[0];if(s){var l=[].slice.call(s.querySelectorAll(".dropdown-toggle"));o.default(l).addClass(ue)}t.setAttribute("aria-expanded",!0)}n&&n()},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this),i=n.data(le);if(i||(i=new t(this),n.data(le,i)),"string"==typeof e){if("undefined"==typeof i[e])throw new TypeError('No method named "'+e+'"');i[e]()}}))},l(t,null,[{key:"VERSION",get:function(){return"4.6.2"}}]),t}();o.default(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',(function(t){t.preventDefault(),ge._jQueryInterface.call(o.default(this),"show")})),o.default.fn.tab=ge._jQueryInterface,o.default.fn.tab.Constructor=ge,o.default.fn.tab.noConflict=function(){return o.default.fn.tab=re,ge._jQueryInterface};var me="bs.toast",pe=o.default.fn.toast,_e="hide",ve="show",ye="showing",be="click.dismiss.bs.toast",Ee={animation:!0,autohide:!0,delay:500},Te={animation:"boolean",autohide:"boolean",delay:"number"},we=function(){function t(t,e){this._element=t,this._config=this._getConfig(e),this._timeout=null,this._setListeners()}var e=t.prototype;return e.show=function(){var t=this,e=o.default.Event("show.bs.toast");if(o.default(this._element).trigger(e),!e.isDefaultPrevented()){this._clearTimeout(),this._config.animation&&this._element.classList.add("fade");var n=function(){t._element.classList.remove(ye),t._element.classList.add(ve),o.default(t._element).trigger("shown.bs.toast"),t._config.autohide&&(t._timeout=setTimeout((function(){t.hide()}),t._config.delay))};if(this._element.classList.remove(_e),d.reflow(this._element),this._element.classList.add(ye),this._config.animation){var i=d.getTransitionDurationFromElement(this._element);o.default(this._element).one(d.TRANSITION_END,n).emulateTransitionEnd(i)}else n()}},e.hide=function(){if(this._element.classList.contains(ve)){var t=o.default.Event("hide.bs.toast");o.default(this._element).trigger(t),t.isDefaultPrevented()||this._close()}},e.dispose=function(){this._clearTimeout(),this._element.classList.contains(ve)&&this._element.classList.remove(ve),o.default(this._element).off(be),o.default.removeData(this._element,me),this._element=null,this._config=null},e._getConfig=function(t){return t=r({},Ee,o.default(this._element).data(),"object"==typeof t&&t?t:{}),d.typeCheckConfig("toast",t,this.constructor.DefaultType),t},e._setListeners=function(){var t=this;o.default(this._element).on(be,'[data-dismiss="toast"]',(function(){return t.hide()}))},e._close=function(){var t=this,e=function(){t._element.classList.add(_e),o.default(t._element).trigger("hidden.bs.toast")};if(this._element.classList.remove(ve),this._config.animation){var n=d.getTransitionDurationFromElement(this._element);o.default(this._element).one(d.TRANSITION_END,e).emulateTransitionEnd(n)}else e()},e._clearTimeout=function(){clearTimeout(this._timeout),this._timeout=null},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this),i=n.data(me);if(i||(i=new t(this,"object"==typeof e&&e),n.data(me,i)),"string"==typeof e){if("undefined"==typeof i[e])throw new TypeError('No method named "'+e+'"');i[e](this)}}))},l(t,null,[{key:"VERSION",get:function(){return"4.6.2"}},{key:"DefaultType",get:function(){return Te}},{key:"Default",get:function(){return Ee}}]),t}();o.default.fn.toast=we._jQueryInterface,o.default.fn.toast.Constructor=we,o.default.fn.toast.noConflict=function(){return o.default.fn.toast=pe,we._jQueryInterface},t.Alert=g,t.Button=E,t.Carousel=P,t.Collapse=V,t.Dropdown=lt,t.Modal=Ct,t.Popover=Jt,t.Scrollspy=se,t.Tab=ge,t.Toast=we,t.Tooltip=Wt,t.Util=d,Object.defineProperty(t,"__esModule",{value:!0})})); +//# sourceMappingURL=bootstrap.min.js.map \ No newline at end of file diff --git a/assets/js/libraries/iziModal.min.js b/assets/js/libraries/iziModal.min.js new file mode 100644 index 0000000..be57b02 --- /dev/null +++ b/assets/js/libraries/iziModal.min.js @@ -0,0 +1,6 @@ +/* +* iziModal | v1.6.1 +* https://izimodal.marcelodolza.com +* by Marcelo Dolza. +*/ +!function(i){"function"==typeof define&&define.amd?define(["jquery"],i):"object"==typeof module&&module.exports?module.exports=function(t,e){return void 0===e&&(e="undefined"!=typeof window?require("jquery"):require("jquery")(t)),i(e),e}:i(jQuery)}(function(d){var h=d(window),l=d(document),c="iziModal",o="closing",u="closed",p="opening",m="opened",e="destroyed";function f(t){if(9===t)return-1!==navigator.appVersion.indexOf("MSIE 9.");t=navigator.userAgent;return-1"+t+"",null,!1));return t.find("*").each(function(){var i;i=this,d.each(i.attributes,function(){var t=this.name,e=this.value;0!=t.indexOf("on")&&0!=e.indexOf("javascript:")||d(i).removeAttr(t)})}),t.html()}var v=function(){var t,e=document.createElement("fakeelement"),i={animation:"animationend",OAnimation:"oAnimationEnd",MozAnimation:"animationend",WebkitAnimation:"webkitAnimationEnd"};for(t in i)if(void 0!==e.style[t])return i[t]}(),$=!!/Mobi/.test(navigator.userAgent);window.$iziModal={},window.$iziModal.autoOpen=0,window.$iziModal.history=!1;function b(t,e){this.init(t,e)}return b.prototype={constructor:b,init:function(t,n){var o=this;this.$element=d(t),void 0!==this.$element[0].id&&""!==this.$element[0].id?this.id=this.$element[0].id:(this.id=c+Math.floor(1e7*Math.random()+1),this.$element.attr("id",this.id)),this.classes=void 0!==this.$element.attr("class")?this.$element.attr("class"):"",this.content=this.$element.html(),this.state=u,this.options=n,this.width=0,this.timer=null,this.timerTimeout=null,this.progressBar=null,this.isPaused=!1,this.isFullscreen=!1,this.headerHeight=0,this.modalHeight=0,this.$overlay=d('
    ').css("background-color",n.overlayColor),this.$navigate=d('
    Use
    '),this.group={name:this.$element.attr("data-"+c+"-group"),index:null,ids:[]},this.$element.attr("aria-hidden","true"),this.$element.attr("aria-labelledby",this.id),this.$element.attr("role","dialog"),this.$element.hasClass("iziModal")||this.$element.addClass("iziModal"),void 0===this.group.name&&""!==n.group&&(this.group.name=n.group,this.$element.attr("data-"+c+"-group",n.group)),!0===this.options.loop&&this.$element.attr("data-"+c+"-loop",!0),d.each(this.options,function(t,e){var i=o.$element.attr("data-"+c+"-"+t);try{void 0!==i&&(n[t]=""===i||"true"==i||"false"!=i&&("function"==typeof e?new Function(i):i))}catch(t){}}),!1!==n.appendTo&&this.$element.appendTo(n.appendTo),!0===n.iframe?(this.$element.html('
    '+this.content+"
    "),null!==n.iframeHeight&&this.$element.find("."+c+"-iframe").css("height",n.iframeHeight)):this.$element.html('
    '+this.content+"
    "),null!==this.options.background&&this.$element.css("background",this.options.background),this.$wrap=this.$element.find("."+c+"-wrap"),null===n.zindex||isNaN(parseInt(n.zindex))||(this.$element.css("z-index",n.zindex),this.$navigate.css("z-index",n.zindex-1),this.$overlay.css("z-index",n.zindex-2)),""!==n.radius&&this.$element.css("border-radius",n.radius),""!==n.padding&&this.$element.find("."+c+"-content").css("padding",n.padding),""!==n.theme&&("light"===n.theme?this.$element.addClass(c+"-light"):this.$element.addClass(n.theme)),!0===n.rtl&&this.$element.addClass(c+"-rtl"),!0===n.openFullscreen&&(this.isFullscreen=!0,this.$element.addClass("isFullscreen")),this.createHeader(),this.recalcWidth(),this.recalcVerticalPos(),!o.options.afterRender||"function"!=typeof o.options.afterRender&&"object"!=typeof o.options.afterRender||o.options.afterRender(o)},createHeader:function(){this.$header=d('

    '),!0===this.options.closeButton&&this.$header.find("."+c+"-header-buttons").append('"),!0===this.options.fullscreen&&this.$header.find("."+c+"-header-buttons").append('"),!0===this.options.timeoutProgressbar&&this.$header.prepend(d('
    ').append(d("
    ").css("background-color",this.options.timeoutProgressbarColor))),""===this.options.subtitle?this.$header.addClass(c+"-noSubtitle"):this.$header.find("."+c+"-header-subtitle").html(i(this.options.subtitle)),""!==this.options.title&&(this.$header.find("."+c+"-header-title").html(i(this.options.title)),null!==this.options.headerColor&&(!0===this.options.borderBottom&&this.$element.css("border-bottom","3px solid "+this.options.headerColor),this.$header.css("background",this.options.headerColor)),null===this.options.icon&&null===this.options.iconText||(this.$header.prepend(''),null!==this.options.icon&&this.$header.find("."+c+"-header-icon").addClass(this.options.icon).css("color",this.options.iconColor),null!==this.options.iconText&&this.$header.find("."+c+"-header-icon").html(i(this.options.iconText))),this.$element.css("overflow","hidden").prepend(this.$header))},setGroup:function(t){var i,n=this,e=this.group.name||t;this.group.ids=[],void 0!==t&&t!==this.group.name&&(e=t,this.group.name=e,this.$element.attr("data-"+c+"-group",e)),void 0!==e&&""!==e&&(i=0,d.each(d("."+c+"[data-"+c+"-group="+e+"]"),function(t,e){n.group.ids.push(d(this)[0].id),n.id==d(this)[0].id&&(n.group.index=i),i++}))},toggle:function(){this.state==m&&this.close(),this.state==u&&this.open()},startProgress:function(t){var e=this;this.isPaused=!1,clearTimeout(this.timerTimeout),!0===this.options.timeoutProgressbar?(this.progressBar={hideEta:null,maxHideTime:null,currentTime:(new Date).getTime(),el:this.$element.find("."+c+"-progressbar > div"),updateProgress:function(){var t;e.isPaused||(e.progressBar.currentTime=e.progressBar.currentTime+10,t=(e.progressBar.hideEta-e.progressBar.currentTime)/e.progressBar.maxHideTime*100,e.progressBar.el.width(t+"%"),t<0&&e.close())}},0 div").width("100%")},open:function(i){var t,e,n,o,s=this;try{void 0!==i&&!1===i.preventClose&&d.each(d("."+c),function(t,e){var i;void 0!==d(e).data().iziModal&&("opened"!=(i=d(e).iziModal("getState"))&&"opening"!=i||d(e).iziModal("close"))})}catch(t){}function a(){s.state=m,s.$element.trigger(m),!s.options.onOpened||"function"!=typeof s.options.onOpened&&"object"!=typeof s.options.onOpened||s.options.onOpened(s)}if(s.options.history?(t=document.title,document.title=t+" - "+s.options.title,e="#"+s.id,n=e.replace(/^.*#/,""),(o=d(e)).attr("id",n+"-tmp"),window.location.hash=e,o.attr("id",n),document.title=t,window.$iziModal.history=!0):window.$iziModal.history=!1,this.state==u){if(s.$element.off("click","[data-"+c+"-close]").on("click","[data-"+c+"-close]",function(t){t.preventDefault();t=d(t.currentTarget).attr("data-"+c+"-transitionOut");void 0!==t?s.close({transition:t}):s.close()}),s.$element.off("click","[data-"+c+"-fullscreen]").on("click","[data-"+c+"-fullscreen]",function(t){t.preventDefault(),!0===s.isFullscreen?(s.isFullscreen=!1,s.$element.removeClass("isFullscreen")):(s.isFullscreen=!0,s.$element.addClass("isFullscreen")),s.options.onFullscreen&&"function"==typeof s.options.onFullscreen&&s.options.onFullscreen(s),s.$element.trigger("fullscreen",s)}),s.$navigate.off("click","."+c+"-navigate-next").on("click","."+c+"-navigate-next",function(t){s.next(t)}),s.$element.off("click","[data-"+c+"-next]").on("click","[data-"+c+"-next]",function(t){s.next(t)}),s.$navigate.off("click","."+c+"-navigate-prev").on("click","."+c+"-navigate-prev",function(t){s.prev(t)}),s.$element.off("click","[data-"+c+"-prev]").on("click","[data-"+c+"-prev]",function(t){s.prev(t)}),this.setGroup(),this.state=p,this.$element.trigger(p),this.$element.attr("aria-hidden","false"),!0===this.options.timeoutProgressbar&&this.$element.find("."+c+"-progressbar > div").width("100%"),!0===this.options.iframe){this.$element.find("."+c+"-content").addClass(c+"-content-loader"),this.$element.find("."+c+"-iframe").on("load",function(){d(this).parent().removeClass(c+"-content-loader")});var r=null;try{r=""!==d(i.currentTarget).attr("href")?d(i.currentTarget).attr("href"):null}catch(t){}if(null!==this.options.iframeURL&&null==r&&(r=this.options.iframeURL),null==r)throw new Error("Failed to find iframe URL");this.$element.find("."+c+"-iframe").attr("src",r)}(this.options.bodyOverflow||$)&&(d("html").addClass(c+"-isOverflow"),$&&d("body").css("overflow","hidden")),this.options.onOpening&&"function"==typeof this.options.onOpening&&this.options.onOpening(this),function(){var t;1'),this.$header.find("."+c+"-header-title").html(i(t))},setSubtitle:function(t){""===t?(this.$header.find("."+c+"-header-subtitle").remove(),this.$header.addClass(c+"-noSubtitle")):(0===this.$header.find("."+c+"-header-subtitle").length&&this.$header.append('

    '),this.$header.removeClass(c+"-noSubtitle")),this.$header.find("."+c+"-header-subtitle").html(i(t)),this.options.subtitle=t},setIcon:function(t){0===this.$header.find("."+c+"-header-icon").length&&this.$header.prepend(''),this.$header.find("."+c+"-header-icon").attr("class",c+"-header-icon "+t),this.options.icon=t},setIconText:function(t){this.$header.find("."+c+"-header-icon").html(i(t)),this.options.iconText=t},setHeaderColor:function(t){!0===this.options.borderBottom&&this.$element.css("border-bottom","3px solid "+t),this.$header.css("background",t),this.options.headerColor=t},setBackground:function(t){!1===t?(this.options.background=null,this.$element.css("background","")):(this.$element.css("background",t),this.options.background=t)},setZindex:function(t){isNaN(parseInt(this.options.zindex))||(this.options.zindex=t,this.$element.css("z-index",t),this.$navigate.css("z-index",t-1),this.$overlay.css("z-index",t-2))},setFullscreen:function(t){t?(this.isFullscreen=!0,this.$element.addClass("isFullscreen")):(this.isFullscreen=!1,this.$element.removeClass("isFullscreen"))},setContent:function(t){"object"==typeof t&&(!0===(t.default||!1)&&(this.content=t.content),t=t.content),!1===this.options.iframe&&this.$element.find("."+c+"-content").html(i(t))},setTransitionIn:function(t){this.options.transitionIn=t},setTransitionOut:function(t){this.options.transitionOut=t},setTimeout:function(t){this.options.timeout=t},resetContent:function(){this.$element.find("."+c+"-content").html(this.content)},startLoading:function(){this.$element.find("."+c+"-loader").length||this.$element.append('
    '),this.$element.find("."+c+"-loader").css({top:this.headerHeight,borderRadius:this.options.radius})},stopLoading:function(){var t=this.$element.find("."+c+"-loader");t.length||(this.$element.prepend('
    '),t=this.$element.find("."+c+"-loader").css("border-radius",this.options.radius)),t.removeClass("fadeIn").addClass("fadeOut"),setTimeout(function(){t.remove()},600)},recalcWidth:function(){var t;this.$element.css("max-width",this.options.width),f()&&(1<(t=this.options.width).toString().split("%").length&&(t=this.$element.outerWidth()),this.$element.css({left:"50%",marginLeft:-t/2}))},recalcVerticalPos:function(t){null!==this.options.top&&!1!==this.options.top?(this.$element.css("margin-top",this.options.top),0===this.options.top&&this.$element.css({borderTopRightRadius:0,borderTopLeftRadius:0})):!1===t&&this.$element.css({marginTop:"",borderRadius:this.options.radius}),null!==this.options.bottom&&!1!==this.options.bottom?(this.$element.css("margin-bottom",this.options.bottom),0===this.options.bottom&&this.$element.css({borderBottomRightRadius:0,borderBottomLeftRadius:0})):!1===t&&this.$element.css({marginBottom:"",borderRadius:this.options.radius})},recalcLayout:function(){var t=this,e=h.height(),i=this.$element.outerHeight(),n=this.$element.outerWidth(),o=this.$element.find("."+c+"-content")[0].scrollHeight,s=o+this.headerHeight,a=this.$element.innerHeight()-this.headerHeight,r=(parseInt(-(this.$element.innerHeight()+1)/2),this.$wrap.scrollTop()),l=0;f()&&(n>=h.width()||!0===this.isFullscreen?this.$element.css({left:"0",marginLeft:""}):this.$element.css({left:"50%",marginLeft:-n/2})),!0===this.options.borderBottom&&""!==this.options.title&&(l=3),this.$element.find("."+c+"-header").length&&this.$element.find("."+c+"-header").is(":visible")?(this.headerHeight=parseInt(this.$element.find("."+c+"-header").innerHeight()),this.$element.css("overflow","hidden")):(this.headerHeight=0,this.$element.css("overflow","")),this.$element.find("."+c+"-loader").length&&this.$element.find("."+c+"-loader").css("top",this.headerHeight),i!==this.modalHeight&&(this.modalHeight=i,this.options.onResize&&"function"==typeof this.options.onResize&&this.options.onResize(this)),this.state!=m&&this.state!=p||(!0===this.options.iframe&&(e=h.width()?this.$element.find("."+c+"-button-fullscreen").hide():this.$element.find("."+c+"-button-fullscreen").show(),this.recalcButtons(),!1===this.isFullscreen&&(e=e-(g(this.options.top)||0)-(g(this.options.bottom)||0)),e=a.currentIndex());c(b.nextSelector,d).toggleClass("disabled",a.currentIndex()>=a.navigationLength());c(b.nextSelector,d).toggleClass("hidden", +a.currentIndex()>=a.navigationLength()&&0=a.navigationLength()&&0=a.navigationLength()&&0a.navigationLength()||(h.push(g),e.find('li:has([data-toggle="tab"])'+ +(b.withVisible?":visible":"")+":eq("+c+") a").tab("show"))};this.previous=function(g){if(d.hasClass("first")||b.onPrevious&&"function"===typeof b.onPrevious&&!1===b.onPrevious(f,e,a.previousIndex()))return!1;g=a.currentIndex();var c=a.previousIndex();0>c||(h.push(g),e.find('li:has([data-toggle="tab"])'+(b.withVisible?":visible":"")+":eq("+c+") a").tab("show"))};this.first=function(g){if(b.onFirst&&"function"===typeof b.onFirst&&!1===b.onFirst(f,e,a.firstIndex())||d.hasClass("disabled"))return!1;h.push(a.currentIndex()); +e.find('li:has([data-toggle="tab"]):eq(0) a').tab("show")};this.last=function(g){if(b.onLast&&"function"===typeof b.onLast&&!1===b.onLast(f,e,a.lastIndex())||d.hasClass("disabled"))return!1;h.push(a.currentIndex());e.find('li:has([data-toggle="tab"]):eq('+a.navigationLength()+") a").tab("show")};this.finish=function(g){if(b.onFinish&&"function"===typeof b.onFinish)b.onFinish(f,e,a.lastIndex())};this.back=function(){if(0==h.length)return null;var a=h.pop();if(b.onBack&&"function"===typeof b.onBack&& +!1===b.onBack(f,e,a))return h.push(a),!1;d.find('li:has([data-toggle="tab"]):eq('+a+") a").tab("show")};this.currentIndex=function(){return e.find('li:has([data-toggle="tab"])'+(b.withVisible?":visible":"")).index(f)};this.firstIndex=function(){return 0};this.lastIndex=function(){return a.navigationLength()};this.getIndex=function(a){return e.find('li:has([data-toggle="tab"])'+(b.withVisible?":visible":"")).index(a)};this.nextIndex=function(){var a=this.currentIndex(),c;do a++,c=e.find('li:has([data-toggle="tab"])'+ +(b.withVisible?":visible":"")+":eq("+a+")");while(c&&c.hasClass("disabled"));return a};this.previousIndex=function(){var a=this.currentIndex(),c;do a--,c=e.find('li:has([data-toggle="tab"])'+(b.withVisible?":visible":"")+":eq("+a+")");while(c&&c.hasClass("disabled"));return a};this.navigationLength=function(){return e.find('li:has([data-toggle="tab"])'+(b.withVisible?":visible":"")).length-1};this.activeTab=function(){return f};this.nextTab=function(){return e.find('li:has([data-toggle="tab"]):eq('+ +(a.currentIndex()+1)+")").length?e.find('li:has([data-toggle="tab"]):eq('+(a.currentIndex()+1)+")"):null};this.previousTab=function(){return 0>=a.currentIndex()?null:e.find('li:has([data-toggle="tab"]):eq('+parseInt(a.currentIndex()-1)+")")};this.show=function(b){b=isNaN(b)?d.find('li:has([data-toggle="tab"]) a[href="#'+b+'"]'):d.find('li:has([data-toggle="tab"]):eq('+b+") a");0this.length)&&-1!==this.indexOf(e,t)})},546:function(e,t,n){var i,r=n(340),a=(i=n(3978))&&i.__esModule?i:{default:i},o=n(6032),s=n(7539);var l=a.default.dependencyLib;function c(e,t){for(var n="",i=0;i0&&t>0&&(!n.digitsOptional||i)){var r=e.indexOf(n.radixPoint),a=!1;n.negationSymbol.back===e[e.length-1]&&(a=!0,e.length--),-1===r&&(e.push(n.radixPoint),r=e.length-1);for(var o=1;o<=t;o++)isFinite(e[r+o])||(e[r+o]="0")}return a&&e.push(n.negationSymbol.back),e}function f(e,t){var n=0;for(var i in"+"===e&&(n=s.seekNext.call(this,t.validPositions.length-1)),t.tests)if((i=parseInt(i))>=n)for(var r=0,a=t.tests[i].length;r1&&(e.placeholder=e.placeholder.charAt(0)),"radixFocus"===e.positionCaretOnClick&&""===e.placeholder&&(e.positionCaretOnClick="lvp");var t="0",n=e.radixPoint;!0===e.numericInput&&void 0===e.__financeInput?(t="1",e.positionCaretOnClick="radixFocus"===e.positionCaretOnClick?"lvp":e.positionCaretOnClick,e.digitsOptional=!1,isNaN(e.digits)&&(e.digits=-1!==e.digits.indexOf(",")?e.digits.split(",")[0]:2),e._radixDance=!1,n=","===e.radixPoint?"?":"!",""!==e.radixPoint&&void 0===e.definitions[n]&&(e.definitions[n]={},e.definitions[n].validator="["+e.radixPoint+"]",e.definitions[n].placeholder=e.radixPoint,e.definitions[n].static=!0,e.definitions[n].generated=!0)):(e.__financeInput=!1,e.numericInput=!0);var i,a="[+]";if(a+=c(e.prefix,e),""!==e.groupSeparator?(void 0===e.definitions[e.groupSeparator]&&(e.definitions[e.groupSeparator]={},e.definitions[e.groupSeparator].validator="["+e.groupSeparator+"]",e.definitions[e.groupSeparator].placeholder=e.groupSeparator,e.definitions[e.groupSeparator].static=!0,e.definitions[e.groupSeparator].generated=!0),a+=e._mask(e)):a+="9{+}",void 0!==e.digits&&0!==e.digits){var o=e.digits.toString().split(",");isFinite(o[0])&&o[1]&&isFinite(o[1])?a+=n+t+"{"+e.digits+"}":(isNaN(e.digits)||parseInt(e.digits)>0)&&(e.digitsOptional||e.jitMasking?(i=a+n+t+"{0,"+e.digits+"}",e.keepStatic=!0):a+=n+t+"{"+e.digits+"}")}else e.inputmode="numeric";return a+=c(e.suffix,e),a+="[-]",i&&(a=[i+c(e.suffix,e)+"[-]",a]),e.greedy=!1,function(e){void 0===e.parseMinMaxOptions&&(null!==e.min&&(e.min=e.min.toString().replace(new RegExp((0,r.escapeRegex)(e.groupSeparator),"g"),""),","===e.radixPoint&&(e.min=e.min.replace(e.radixPoint,".")),e.min=isFinite(e.min)?parseFloat(e.min):NaN,isNaN(e.min)&&(e.min=Number.MIN_VALUE)),null!==e.max&&(e.max=e.max.toString().replace(new RegExp((0,r.escapeRegex)(e.groupSeparator),"g"),""),","===e.radixPoint&&(e.max=e.max.replace(e.radixPoint,".")),e.max=isFinite(e.max)?parseFloat(e.max):NaN,isNaN(e.max)&&(e.max=Number.MAX_VALUE)),e.parseMinMaxOptions="done")}(e),""!==e.radixPoint&&e.substituteRadixPoint&&(e.substitutes["."==e.radixPoint?",":"."]=e.radixPoint),a},_mask:function(e){return"("+e.groupSeparator+"999){+|1}"},digits:"*",digitsOptional:!0,enforceDigitsOnBlur:!1,radixPoint:".",positionCaretOnClick:"radixFocus",_radixDance:!0,groupSeparator:"",allowMinus:!0,negationSymbol:{front:"-",back:""},prefix:"",suffix:"",min:null,max:null,SetMaxOnOverflow:!1,step:1,inputType:"text",unmaskAsNumber:!1,roundingFN:Math.round,inputmode:"decimal",shortcuts:{k:"1000",m:"1000000"},placeholder:"0",greedy:!1,rightAlign:!0,insertMode:!0,autoUnmask:!1,skipOptionalPartCharacter:"",usePrototypeDefinitions:!1,stripLeadingZeroes:!0,substituteRadixPoint:!0,definitions:{0:{validator:d},1:{validator:d,definitionSymbol:"9"},9:{validator:"[0-9\uff10-\uff19\u0660-\u0669\u06f0-\u06f9]",definitionSymbol:"*"},"+":{validator:function(e,t,n,i,r){return r.allowMinus&&("-"===e||e===r.negationSymbol.front)}},"-":{validator:function(e,t,n,i,r){return r.allowMinus&&e===r.negationSymbol.back}}},preValidation:function(e,t,n,i,r,a,o,s){var l=this;if(!1!==r.__financeInput&&n===r.radixPoint)return!1;var c=e.indexOf(r.radixPoint),u=t;if(t=function(e,t,n,i,r){return r._radixDance&&r.numericInput&&t!==r.negationSymbol.back&&e<=n&&(n>0||t==r.radixPoint)&&(void 0===i.validPositions[e-1]||i.validPositions[e-1].input!==r.negationSymbol.back)&&(e-=1),e}(t,n,c,a,r),"-"===n||n===r.negationSymbol.front){if(!0!==r.allowMinus)return!1;var d=!1,h=p("+",a),m=p("-",a);return-1!==h&&(d=[h],-1!==m&&d.push(m)),!1!==d?{remove:d,caret:u-r.negationSymbol.back.length}:{insert:[{pos:f.call(l,"+",a),c:r.negationSymbol.front,fromIsValid:!0},{pos:f.call(l,"-",a),c:r.negationSymbol.back,fromIsValid:void 0}],caret:u+r.negationSymbol.back.length}}if(n===r.groupSeparator)return{caret:u};if(s)return!0;if(-1!==c&&!0===r._radixDance&&!1===i&&n===r.radixPoint&&void 0!==r.digits&&(isNaN(r.digits)||parseInt(r.digits)>0)&&c!==t){var v=f.call(l,r.radixPoint,a);return a.validPositions[v]&&(a.validPositions[v].generatedInput=a.validPositions[v].generated||!1),{caret:r._radixDance&&t===c-1?c+1:c}}if(!1===r.__financeInput)if(i){if(r.digitsOptional)return{rewritePosition:o.end};if(!r.digitsOptional){if(o.begin>c&&o.end<=c)return n===r.radixPoint?{insert:{pos:c+1,c:"0",fromIsValid:!0},rewritePosition:c}:{rewritePosition:c+1};if(o.begin0&&""===this.__valueGet.call(this.el))return{rewritePosition:c};return{rewritePosition:t}},postValidation:function(e,t,n,i,r,a,o,s,c){if(!1===i)return i;if(o)return!0;if(null!==r.min||null!==r.max){var f=r.onUnMask(e.slice().reverse().join(""),void 0,l.extend({},r,{unmaskAsNumber:!0}));if(null!==r.min&&fr.min.toString().length||e[0]===r.radixPoint||f<0))return!1;if(null!==r.max&&r.max>=0&&f>r.max)return!!r.SetMaxOnOverflow&&{refreshFromBuffer:!0,buffer:u(r.max.toString().replace(".",r.radixPoint).split(""),r.digits,r).reverse()}}return i},onUnMask:function(e,t,n){if(""===t&&!0===n.nullable)return t;var i=e.replace(n.prefix,"");return i=(i=i.replace(n.suffix,"")).replace(new RegExp((0,r.escapeRegex)(n.groupSeparator),"g"),""),""!==n.placeholder.charAt(0)&&(i=i.replace(new RegExp(n.placeholder.charAt(0),"g"),"0")),n.unmaskAsNumber?(""!==n.radixPoint&&-1!==i.indexOf(n.radixPoint)&&(i=i.replace(r.escapeRegex.call(this,n.radixPoint),".")),i=(i=i.replace(new RegExp("^"+(0,r.escapeRegex)(n.negationSymbol.front)),"-")).replace(new RegExp((0,r.escapeRegex)(n.negationSymbol.back)+"$"),""),Number(i)):i},isComplete:function(e,t){var n=(t.numericInput?e.slice().reverse():e).join("");return n=(n=(n=(n=(n=n.replace(new RegExp("^"+(0,r.escapeRegex)(t.negationSymbol.front)),"-")).replace(new RegExp((0,r.escapeRegex)(t.negationSymbol.back)+"$"),"")).replace(t.prefix,"")).replace(t.suffix,"")).replace(new RegExp((0,r.escapeRegex)(t.groupSeparator)+"([0-9]{3})","g"),"$1"),","===t.radixPoint&&(n=n.replace((0,r.escapeRegex)(t.radixPoint),".")),isFinite(n)},onBeforeMask:function(e,t){e=null!=e?e:"";var n=t.radixPoint||",";isFinite(t.digits)&&(t.digits=parseInt(t.digits)),"number"!=typeof e&&"number"!==t.inputType||""===n||(e=e.toString().replace(".",n));var i="-"===e.charAt(0)||e.charAt(0)===t.negationSymbol.front,a=e.split(n),o=a[0].replace(/[^\-0-9]/g,""),s=a.length>1?a[1].replace(/[^0-9]/g,""):"",l=a.length>1;e=o+(""!==s?n+s:s);var c=0;if(""!==n&&(c=t.digitsOptional?t.digitst.max&&(e=t.max.toString().replace(".",n))}return i&&"-"!==e.charAt(0)&&(e="-"+e),u(e.toString().split(""),c,t,l).join("")},onBeforeWrite:function(e,t,n,i){function a(e,t){if(!1!==i.__financeInput||t){var n=e.indexOf(i.radixPoint);-1!==n&&e.splice(n,1)}if(""!==i.groupSeparator)for(;-1!==(n=e.indexOf(i.groupSeparator));)e.splice(n,1);return e}var o,s;if(i.stripLeadingZeroes&&(s=function(e,t){var n=new RegExp("(^"+(""!==t.negationSymbol.front?(0,r.escapeRegex)(t.negationSymbol.front)+"?":"")+(0,r.escapeRegex)(t.prefix)+")(.*)("+(0,r.escapeRegex)(t.suffix)+(""!=t.negationSymbol.back?(0,r.escapeRegex)(t.negationSymbol.back)+"?":"")+"$)").exec(e.slice().reverse().join("")),i=n?n[2]:"",a=!1;return i&&(i=i.split(t.radixPoint.charAt(0))[0],a=new RegExp("^[0"+t.groupSeparator+"]*").exec(i)),!(!a||!(a[0].length>1||a[0].length>0&&a[0].length0;p--)this.maskset.validPositions.splice(c+p,1),delete t[c+p];if(e)switch(e.type){case"blur":case"checkval":if(null!==i.min||null!==i.max){var d=i.onUnMask(t.slice().reverse().join(""),void 0,l.extend({},i,{unmaskAsNumber:!0}));if(null!==i.min&&di.max)return{refreshFromBuffer:!0,buffer:u(i.max.toString().replace(".",i.radixPoint).split(""),i.digits,i).reverse()}}if(t[t.length-1]===i.negationSymbol.front){var h=new RegExp("(^"+(""!=i.negationSymbol.front?(0,r.escapeRegex)(i.negationSymbol.front)+"?":"")+(0,r.escapeRegex)(i.prefix)+")(.*)("+(0,r.escapeRegex)(i.suffix)+(""!=i.negationSymbol.back?(0,r.escapeRegex)(i.negationSymbol.back)+"?":"")+"$)").exec(a(t.slice(),!0).reverse().join(""));0==(h?h[2]:"")&&(o={refreshFromBuffer:!0,buffer:[0]})}else if(""!==i.radixPoint){t.indexOf(i.radixPoint)===i.suffix.length&&(o&&o.buffer?o.buffer.splice(0,1+i.suffix.length):(t.splice(0,1+i.suffix.length),o={refreshFromBuffer:!0,buffer:a(t)}))}if(i.enforceDigitsOnBlur){var m=((o=o||{})&&o.buffer||t).slice().reverse();o.refreshFromBuffer=!0,o.buffer=u(m,i.digits,i,!0).reverse()}}return o},onKeyDown:function(e,t,n,i){var r,a=l(this);if(3!=e.location){var s,c=e.key;if((s=i.shortcuts&&i.shortcuts[c])&&s.length>1)return this.inputmask.__valueSet.call(this,parseFloat(this.inputmask.unmaskedvalue())*parseInt(s)),a.trigger("setvalue"),!1}if(e.ctrlKey)switch(e.key){case o.keys.ArrowUp:return this.inputmask.__valueSet.call(this,parseFloat(this.inputmask.unmaskedvalue())+parseInt(i.step)),a.trigger("setvalue"),!1;case o.keys.ArrowDown:return this.inputmask.__valueSet.call(this,parseFloat(this.inputmask.unmaskedvalue())-parseInt(i.step)),a.trigger("setvalue"),!1}if(!e.shiftKey&&(e.key===o.keys.Delete||e.key===o.keys.Backspace||e.key===o.keys.BACKSPACE_SAFARI)&&n.begin!==t.length){if(t[e.key===o.keys.Delete?n.begin-1:n.end]===i.negationSymbol.front)return r=t.slice().reverse(),""!==i.negationSymbol.front&&r.shift(),""!==i.negationSymbol.back&&r.pop(),a.trigger("setvalue",[r.join(""),n.begin]),!1;if(!0===i._radixDance){var f,p=t.indexOf(i.radixPoint);if(i.digitsOptional){if(0===p)return(r=t.slice().reverse()).pop(),a.trigger("setvalue",[r.join(""),n.begin>=r.length?r.length:n.begin]),!1}else if(-1!==p&&(n.begin=r.length?p+1:n.begin]),!1}}}},currency:{prefix:"",groupSeparator:",",alias:"numeric",digits:2,digitsOptional:!1},decimal:{alias:"numeric"},integer:{alias:"numeric",inputmode:"numeric",digits:0},percentage:{alias:"numeric",min:0,max:100,suffix:" %",digits:0,allowMinus:!1},indianns:{alias:"numeric",_mask:function(e){return"("+e.groupSeparator+"99){*|1}("+e.groupSeparator+"999){1|1}"},groupSeparator:",",radixPoint:".",placeholder:"0",digits:2,digitsOptional:!1}})},1507:function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.HandleNativePlaceholder=function(e,t){var n=e?e.inputmask:this;if(r.ie){if(e.inputmask._valueGet()!==t&&(e.placeholder!==t||""===e.placeholder)){var i=l.getBuffer.call(n).slice(),a=e.inputmask._valueGet();if(a!==t){var o=l.getLastValidPosition.call(n);-1===o&&a===l.getBufferTemplate.call(n).join("")?i=[]:-1!==o&&v.call(n,i),y(e,i)}}}else e.placeholder!==t&&(e.placeholder=t,""===e.placeholder&&e.removeAttribute("placeholder"))},t.applyInputValue=m,t.checkVal=g,t.clearOptionalTail=v,t.unmaskedvalue=function(e){var t=e?e.inputmask:this,n=t.opts,i=t.maskset;if(e){if(void 0===e.inputmask)return e.value;e.inputmask&&e.inputmask.refreshValue&&m(e,e.inputmask._valueGet(!0))}for(var r=[],a=i.validPositions,s=0,c=a.length;s0)return o.default.format(u,d(d({},n),{},{mask:n.outputMask,alias:null}));return u},t.writeBuffer=y;var i,r=n(4351),a=n(6047),o=(i=n(3978))&&i.__esModule?i:{default:i},s=n(6032),l=n(7539),c=n(7687),u=n(5895);function f(e){return f="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},f(e)}function p(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function d(e){for(var t=1;t0&&" "===n[i-1];)i--;var r=0===i&&!l.isMask.call(s,e)&&(u.getTest.call(s,e).match.nativeDef===t.charAt(0)||!0===u.getTest.call(s,e).match.static&&u.getTest.call(s,e).match.nativeDef==="'"+t.charAt(0)||" "===u.getTest.call(s,e).match.nativeDef&&(u.getTest.call(s,e+1).match.nativeDef===t.charAt(0)||!0===u.getTest.call(s,e+1).match.static&&u.getTest.call(s,e+1).match.nativeDef==="'"+t.charAt(0)));if(!r&&i>0&&!l.isMask.call(s,e,!1,!0)){var a=l.seekNext.call(s,e);s.caretPos.begin0){var x,P,S=l.seekNext.call(s,-1,void 0,!1);if(!c.isComplete.call(s,l.getBuffer.call(s))&&k.length<=S||c.isComplete.call(s,l.getBuffer.call(s))&&k.length>0&&k.length!==S&&0===k[0]){for(var w=S;void 0!==(x=k.shift());)if(x>>0;if(0===i)return!1;for(var r=0|t,a=Math.max(r>=0?r:i-Math.abs(r),0);ae.length)&&(t=e.length);for(var n=0,i=Array(t);n=r){var a=/\d+$/.exec(i[0]),o=a?i[0][0]+"x":i[0],s=void 0;if(void 0!==e){if(a){var c=M(t).lastIndex,u=D.call(n,i.index,t,n&&n.maskset);M(t).lastIndex=c,s=e.slice(0,e.indexOf(u.nextMatch[0]))}else{for(var f=i[0][0],p=i.index;n&&(t.placeholder["".concat(i.index,"'").concat(l.getTest.call(n,p).match.placeholder)]||l.getTest.call(n,p).match.placeholder)===f;)p++;r=p;var d=p-i.index;s=e.slice(0,d||O(o)&&O(o)[4]||o.length)}e=e.slice(s.length)}Object.prototype.hasOwnProperty.call(b,o)&&this.setValue(this,s,o,O(o)[2],O(o)[1])}}},{key:"setValue",value:function(e,t,n,i,r){if(void 0!==t)switch(i){case"ampm":e[i]=t,e["raw"+i]=t.replace(/\s/g,"_");break;case"month":if("MMM"===n||"MMMM"===n){e[i]=E("MMM"===n?k.monthNames.slice(0,12).findIndex((function(e){return t.toLowerCase()===e.toLowerCase()}))+1:k.monthNames.slice(12,24).findIndex((function(e){return t.toLowerCase()===e.toLowerCase()}))+1,2),e[i]="00"===e[i]?"":e[i].toString(),e["raw"+i]=e[i];break}default:e[i]=t.replace(/[^0-9]/g,"0"),e["raw"+i]=t.replace(/\s/g,"_")}if(void 0!==r){var a=e[i];("day"===i&&29===parseInt(a)||"month"===i&&2===parseInt(a))&&(29!==parseInt(e.day)||2!==parseInt(e.month)||""!==e.year&&void 0!==e.year||e._date.setFullYear(2012,1,29)),"day"===i&&(g=!0,0===parseInt(a)&&(a=1)),"month"===i&&(g=!0),"year"===i&&(g=!0,a.length0&&t--,Date.prototype.setMonth.call(this,t)},"month",function(){return Date.prototype.getMonth.call(this)+1}],MM:["0[1-9]|1[012]",function(e){var t=e?parseInt(e):0;return t>0&&t--,Date.prototype.setMonth.call(this,t)},"month",function(){return E(Date.prototype.getMonth.call(this)+1,2)}],MMM:[k.monthNames.slice(0,12).join("|"),function(e){var t=k.monthNames.slice(0,12).findIndex((function(t){return e.toLowerCase()===t.toLowerCase()}));return-1!==t&&Date.prototype.setMonth.call(this,t)},"month",function(){return k.monthNames.slice(0,12)[Date.prototype.getMonth.call(this)]}],MMMM:[k.monthNames.slice(12,24).join("|"),function(e){var t=k.monthNames.slice(12,24).findIndex((function(t){return e.toLowerCase()===t.toLowerCase()}));return-1!==t&&Date.prototype.setMonth.call(this,t)},"month",function(){return k.monthNames.slice(12,24)[Date.prototype.getMonth.call(this)]}],yy:["[0-9]{2}",function(e){var t=(new Date).getFullYear().toString().slice(0,2);Date.prototype.setFullYear.call(this,"".concat(t).concat(e))},"year",function(){return E(Date.prototype.getFullYear.call(this),2)},2],yyyy:["[0-9]{4}",Date.prototype.setFullYear,"year",function(){return E(Date.prototype.getFullYear.call(this),4)},4],h:["[1-9]|1[0-2]",Date.prototype.setHours,"hours",Date.prototype.getHours],hh:["0[1-9]|1[0-2]",Date.prototype.setHours,"hours",function(){return E(Date.prototype.getHours.call(this),2)}],hx:[function(e){return"[0-9]{".concat(e,"}")},Date.prototype.setHours,"hours",function(e){return Date.prototype.getHours}],H:["1?[0-9]|2[0-3]",Date.prototype.setHours,"hours",Date.prototype.getHours],HH:["0[0-9]|1[0-9]|2[0-3]",Date.prototype.setHours,"hours",function(){return E(Date.prototype.getHours.call(this),2)}],Hx:[function(e){return"[0-9]{".concat(e,"}")},Date.prototype.setHours,"hours",function(e){return function(){return E(Date.prototype.getHours.call(this),e)}}],m:["[1-5]?[0-9]",Date.prototype.setMinutes,"minutes",Date.prototype.getMinutes],mm:["0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]",Date.prototype.setMinutes,"minutes",function(){return E(Date.prototype.getMinutes.call(this),2)}],s:["[1-5]?[0-9]",Date.prototype.setSeconds,"seconds",Date.prototype.getSeconds],ss:["0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]",Date.prototype.setSeconds,"seconds",function(){return E(Date.prototype.getSeconds.call(this),2)}],l:["[0-9]{3}",Date.prototype.setMilliseconds,"milliseconds",function(){return E(Date.prototype.getMilliseconds.call(this),3)},3],L:["[0-9]{2}",Date.prototype.setMilliseconds,"milliseconds",function(){return E(Date.prototype.getMilliseconds.call(this),2)},2],t:["[ap]",S,"ampm",w,1],tt:["[ap]m",S,"ampm",w,2],T:["[AP]",S,"ampm",w,1],TT:["[AP]M",S,"ampm",w,2],Z:[".*",void 0,"Z",function(){var e=this.toString().match(/\((.+)\)/)[1];e.includes(" ")&&(e=(e=e.replace("-"," ").toUpperCase()).split(" ").map((function(e){return c(e,1)[0]})).join(""));return e}],o:[""],S:[""]},x={D:"d",DD:"dd",DDD:"ddd",DDDD:"dddd",YY:"yy",YYYY:"yyyy",sss:"L"},P={isoDate:"yyyy-MM-dd",isoTime:"HH:mm:ss",isoDateTime:"yyyy-MM-dd\\THH:mm:ss",isoUtcDateTime:"UTC:yyyy-MM-dd\\THH:mm:ss\\Z"};function S(e){var t=this.getHours();e.toLowerCase().includes("p")?this.setHours(t+12):e.toLowerCase().includes("a")&&t>=12&&this.setHours(t-12)}function w(){var e=this.getHours();return(e=e||12)>=12?"PM":"AM"}function O(e){var t=x[e]||e,n=/\d+$/.exec(t);if(n&&void 0!==n[0]){var i=b[t[0]+"x"].slice("");return i[0]=i[0](n[0]),i[3]=i[3](n[0]),i}if(b[t])return b[t]}function M(e){if(!e.tokenizer){var t,n=[],i=[],r=function(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!n){if(Array.isArray(e)||(n=u(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var i=0,r=function(){};return{s:r,n:function(){return i>=e.length?{done:!0}:{done:!1,value:e[i++]}},e:function(e){throw e},f:r}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,o=!0,s=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return o=e.done,e},e:function(e){s=!0,a=e},f:function(){try{o||null==n.return||n.return()}finally{if(s)throw a}}}}(Object.keys(b).concat(Object.keys(x)));try{for(r.s();!(t=r.n()).done;){var a=t.value;if(/\.*x$/.test(a)){var o=a[0]+"\\d+";-1===i.indexOf(o)&&i.push(o)}else-1===n.indexOf(a[0])&&n.push(a[0])}}catch(e){r.e(e)}finally{r.f()}e.tokenizer="("+(i.length>0?i.join("|")+"|":"")+n.join("+|")+"+)+?|.",e.tokenizer=new RegExp(e.tokenizer,"g")}return e.tokenizer}function _(e,t,n){if(!g)return!0;if(void 0===e.rawday||!isFinite(e.rawday)&&new Date(e.date.getFullYear(),isFinite(e.rawmonth)?e.month:e.date.getMonth()+1,0).getDate()>=e.day||"29"==e.day&&(!isFinite(e.rawyear)||void 0===e.rawyear||""===e.rawyear)||new Date(e.date.getFullYear(),isFinite(e.rawmonth)?e.month:e.date.getMonth()+1,0).getDate()>=e.day)return t;if("29"==e.day){var i=D.call(this,t.pos,n,this.maskset);if(i.targetMatch&&["yyyy","YYYY"].includes(i.targetMatch[0])&&t.pos-i.targetMatchIndex==2)return t.remove=t.pos+1,t}else if(2==e.date.getMonth()&&"30"==e.day&&void 0!==t.c)return e.day="03",e.date.setDate(3),e.date.setMonth(1),t.insert=[{pos:t.pos,c:"0"},{pos:t.pos+1,c:t.c}],t.caret=s.seekNext.call(this,t.pos+1),t;return!1}function j(e,t,n){var i,a,o="",s=0,l=!1,c={};for(M(n).lastIndex=0;i=M(n).exec(e);)if(i[0]===n.escapeChar)l=!0;else{if(void 0===t)if(!l&&(a=O(i[0])))o+="("+a[0]+")",n.placeholder&&""!==n.placeholder?(c[s]=n.placeholder[i.index%n.placeholder.length],c["".concat(i.index,"'").concat(n.placeholder[i.index%n.placeholder.length])]=i[0].charAt(0)):c[s]=i[0].charAt(0);else switch(i[0]){case"[":o+="(";break;case"]":o+=")?";break;default:o+=(0,r.escapeRegex)(i[0]),c[s]=i[0].charAt(0)}else if(!l&&(a=O(i[0])))if(a[3])o+=a[3].call(t.date);else a[2]&&void 0!==t["raw"+a[2]]?o+=t["raw"+a[2]]:o+=i[0];else o+=i[0];s++,l=!1}return void 0===t&&(n.placeholder=c),o}function E(e,t,n){for(e=String(e),t=t||2;e.length=e+1){var p="";if(n&&n.tests[e]){var d=Object.keys(t.placeholder).filter((function(t){for(var i=r.index-1;i0?t.placeholder[d[0]]:n.tests[e][0].match.placeholder}if(-1!==r[0].indexOf(p)){i=r,r=M(t).exec(t.inputFormat);break}}}return{targetMatchIndex:o-s,nextMatch:r,targetMatch:i}}a.default.extendAliases({datetime:{mask:function(e){if(e.numericInput=!1,b.S=k.ordinalSuffix.join("|"),e.inputFormat=P[e.inputFormat]||e.inputFormat,e.repeat&&(e.repeat=parseInt(e.repeat.toString()),e.repeat>0)){for(var t="",n=0;n1){var c=O(l.targetMatch[0])[0];if(new RegExp(c).test("0"+e[t-1]))return e[t]=e[t-1],e[t-1]="0",{fuzzy:!0,buffer:e,refreshFromBuffer:{start:t-1,end:t+1},pos:t+1}}}return!0},postValidation:function(e,t,n,i,r,a,o,s){var c,u,f=this;if(o)return!0;if(!1===i&&((c=D.call(f,t+1,r,a)).targetMatch&&c.targetMatchIndex===t&&c.targetMatch[0].length>1&&void 0!==O(c.targetMatch[0])?u=O(c.targetMatch[0])[0]:(c=D.call(f,t+2,r,a)).targetMatch&&c.targetMatchIndex===t+1&&c.targetMatch[0].length>1&&void 0!==O(c.targetMatch[0])&&(u=O(c.targetMatch[0])),void 0!==u&&(t=c.targetMatchIndex,void 0!==a.validPositions[t+1]&&new RegExp(u).test(n+"0")?(e[t]=n,e[t+1]="0",i={pos:t+2,caret:t+1}):new RegExp(u).test("0"+n)&&(e[t]="0",e[t+1]=n,i={pos:t+2})),!1===i))return i;if(i.fuzzy&&(e=i.buffer,t=i.pos),(c=D.call(f,t,r,a)).targetMatch&&c.targetMatch[0]&&void 0!==O(c.targetMatch[0])){var p=O(c.targetMatch[0]);u=p[0];var d=e.slice(c.targetMatchIndex,c.targetMatchIndex+c.targetMatch[0].length);if(!1===new RegExp(u).test(d.join(""))&&2===c.targetMatch[0].length&&a.validPositions[c.targetMatchIndex]&&a.validPositions[c.targetMatchIndex+1]&&(a.validPositions[c.targetMatchIndex+1].input="0"),"year"==p[2])for(var h=l.getMaskTemplate.call(f,!1,1,void 0,!0),m=t+1;m=s.getTime())&&(e.date.setFullYear(y),e.year=i,t.insert=[{pos:t.pos+1,c:o[0]},{pos:t.pos+2,c:o[1]}])}}return t}(g,v,r)),v=function(e,t,n,i){if(!t)return t;if(t&&n.min&&!isNaN(n.min.date.getTime())){var r;for(e.reset(),M(n).lastIndex=0;r=M(n).exec(n.inputFormat);){var a;if((a=O(r[0]))&&a[3]){for(var o=a[1],s=e[a[2]],l=n.min[a[2]],c=n.max?n.max[a[2]]:l+1,u=[],f=!1,p=0;pl[p]):(p+r.index==0&&s[p]e.date.getTime()&&(u[p]=c[p]));o.call(e._date,u.join(""))}}t=n.min.date.getTime()<=e.date.getTime(),e.reInit()}return t&&n.max&&(isNaN(n.max.date.getTime())||(t=n.max.date.getTime()>=e.date.getTime())),t}(g,v=_.call(f,g,v,r),r,a)),void 0!==t&&v&&i.pos!==t?{buffer:j(r.inputFormat,g,r).split(""),refreshFromBuffer:{start:t,end:i.pos},pos:void 0!==i.caret?i.caret:i.pos}:v},onKeyDown:function(e,t,n,i){e.ctrlKey&&e.key===o.keys.ArrowRight&&(this.inputmask._valueSet(A(new Date,i)),m(this).trigger("setvalue"))},onUnMask:function(e,t,n){return t?j(n.outputFormat,T.call(this,e,n.inputFormat,n),n):t},casing:function(e,t,n,i){if(0==t.nativeDef.indexOf("[ap]"))return e.toLowerCase();if(0==t.nativeDef.indexOf("[AP]"))return e.toUpperCase();var r=l.getTest.call(this,[n-1]);return 0==r.match.def.indexOf("[AP]")||0===n||r&&r.input===String.fromCharCode(o.keyCode.Space)||r&&r.match.def===String.fromCharCode(o.keyCode.Space)||t.static&&t.def===t.def.toUpperCase()?e.toUpperCase():e.toLowerCase()},onBeforeMask:function(e,t){return"[object Date]"===Object.prototype.toString.call(e)&&(e=A(e,t)),e},insertMode:!1,insertModeVisual:!1,shiftPositions:!1,keepStatic:!1,inputmode:"numeric",prefillYear:!0}})},4240:function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.mask=function(){var e=this,t=this.opts,n=this.el,c=this.dependencyLib;a.EventRuler.off(n);var u=function(t,n){var i=t.getAttribute("type"),r="input"===t.tagName.toLowerCase()&&n.supportsInputType.includes(i)||t.isContentEditable||"textarea"===t.tagName.toLowerCase();if(!r)if("input"===t.tagName.toLowerCase()){var l=document.createElement("input");l.setAttribute("type",i),r="text"===l.type,l=null}else r="partial";return!1!==r?function(t){var i,r;function l(){return this.inputmask?this.inputmask.opts.autoUnmask?this.inputmask.unmaskedvalue():-1!==s.getLastValidPosition.call(e)||!0!==n.nullable?this.getRootNode().activeElement===this&&n.clearMaskOnLostFocus?(e.isRTL?o.clearOptionalTail.call(e,s.getBuffer.call(e).slice()).reverse():o.clearOptionalTail.call(e,s.getBuffer.call(e).slice())).join(""):i.call(this):"":i.call(this)}function u(e){r.call(this,e),this.inputmask&&(0,o.applyInputValue)(this,e)}if(!t.inputmask.__valueGet){if(!0!==n.noValuePatching){if(Object.getOwnPropertyDescriptor){var f=Object.getPrototypeOf?Object.getOwnPropertyDescriptor(Object.getPrototypeOf(t),"value"):void 0;f&&f.get&&f.set?(i=f.get,r=f.set,Object.defineProperty(t,"value",{get:l,set:u,configurable:!0})):"input"!==t.tagName.toLowerCase()&&(i=function(){return this.textContent},r=function(e){this.textContent=e},Object.defineProperty(t,"value",{get:l,set:u,configurable:!0}))}else document.__lookupGetter__&&t.__lookupGetter__("value")&&(i=t.__lookupGetter__("value"),r=t.__lookupSetter__("value"),t.__defineGetter__("value",l),t.__defineSetter__("value",u));t.inputmask.__valueGet=i,t.inputmask.__valueSet=r}t.inputmask._valueGet=function(t){return e.isRTL&&!0!==t?i.call(this.el).split("").reverse().join(""):i.call(this.el)},t.inputmask._valueSet=function(t,n){r.call(this.el,null==t?"":!0!==n&&e.isRTL?t.split("").reverse().join(""):t)},void 0===i&&(i=function(){return this.value},r=function(e){this.value=e},function(t){if(c.valHooks&&(void 0===c.valHooks[t]||!0!==c.valHooks[t].inputmaskpatch)){var i=c.valHooks[t]&&c.valHooks[t].get?c.valHooks[t].get:function(e){return e.value},r=c.valHooks[t]&&c.valHooks[t].set?c.valHooks[t].set:function(e,t){return e.value=t,e};c.valHooks[t]={get:function(t){if(t.inputmask){if(t.inputmask.opts.autoUnmask)return t.inputmask.unmaskedvalue();var r=i(t);return-1!==s.getLastValidPosition.call(e,void 0,void 0,t.inputmask.maskset.validPositions)||!0!==n.nullable?r:""}return i(t)},set:function(e,t){var n=r(e,t);return e.inputmask&&(0,o.applyInputValue)(e,t),n},inputmaskpatch:!0}}}(t.type),function(e){a.EventRuler.on(e,"mouseenter",(function(){var e=this,t=e.inputmask._valueGet(!0);t!=(e.inputmask.isRTL?s.getBuffer.call(e.inputmask).slice().reverse():s.getBuffer.call(e.inputmask)).join("")&&(0,o.applyInputValue)(e,t)}))}(t))}}(t):t.inputmask=void 0,r}(n,t);if(!1!==u){e.originalPlaceholder=n.placeholder,e.maxLength=void 0!==n?n.maxLength:void 0,-1===e.maxLength&&(e.maxLength=void 0),"inputMode"in n&&null===n.getAttribute("inputmode")&&(n.inputMode=t.inputmode,n.setAttribute("inputmode",t.inputmode)),!0===u&&(t.showMaskOnFocus=t.showMaskOnFocus&&-1===["cc-number","cc-exp"].indexOf(n.autocomplete),i.iphone&&(t.insertModeVisual=!1,n.setAttribute("autocorrect","off")),a.EventRuler.on(n,"submit",r.EventHandlers.submitEvent),a.EventRuler.on(n,"reset",r.EventHandlers.resetEvent),a.EventRuler.on(n,"blur",r.EventHandlers.blurEvent),a.EventRuler.on(n,"focus",r.EventHandlers.focusEvent),a.EventRuler.on(n,"invalid",r.EventHandlers.invalidEvent),a.EventRuler.on(n,"click",r.EventHandlers.clickEvent),a.EventRuler.on(n,"mouseleave",r.EventHandlers.mouseleaveEvent),a.EventRuler.on(n,"mouseenter",r.EventHandlers.mouseenterEvent),a.EventRuler.on(n,"paste",r.EventHandlers.pasteEvent),a.EventRuler.on(n,"cut",r.EventHandlers.cutEvent),a.EventRuler.on(n,"complete",t.oncomplete),a.EventRuler.on(n,"incomplete",t.onincomplete),a.EventRuler.on(n,"cleared",t.oncleared),!0!==t.inputEventOnly&&a.EventRuler.on(n,"keydown",r.EventHandlers.keyEvent),(i.mobile||t.inputEventOnly)&&n.removeAttribute("maxLength"),a.EventRuler.on(n,"input",r.EventHandlers.inputFallBackEvent)),a.EventRuler.on(n,"setvalue",r.EventHandlers.setValueEvent),void 0===e.applyMaskHook||e.applyMaskHook(),s.getBufferTemplate.call(e).join(""),e.undoValue=e._valueGet(!0);var f=n.getRootNode().activeElement;if(""!==n.inputmask._valueGet(!0)||!1===t.clearMaskOnLostFocus||f===n){(0,o.applyInputValue)(n,n.inputmask._valueGet(!0));var p=s.getBuffer.call(e).slice();!1===l.isComplete.call(e,p)&&t.clearIncomplete&&s.resetMaskSet.call(e,!1),t.clearMaskOnLostFocus&&f!==n&&(-1===s.getLastValidPosition.call(e)?p=[]:o.clearOptionalTail.call(e,p)),(!1===t.clearMaskOnLostFocus||t.showMaskOnFocus&&f===n||""!==n.inputmask._valueGet(!0))&&(0,o.writeBuffer)(n,p),f===n?s.caret.call(e,n,s.seekNext.call(e,s.getLastValidPosition.call(e))):s.caret.call(e,n,0)}}};var i=n(4351),r=n(6047),a=n(4136),o=n(1507),s=n(7539),l=n(7687)},4351:function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.mobile=t.iphone=t.ie=void 0;var i,r=(i=n(6266))&&i.__esModule?i:{default:i};var a=r.default.navigator&&r.default.navigator.userAgent||"";t.ie=a.indexOf("MSIE ")>0||a.indexOf("Trident/")>0,t.mobile=r.default.navigator&&r.default.navigator.userAgentData&&r.default.navigator.userAgentData.mobile||r.default.navigator&&r.default.navigator.maxTouchPoints||"ontouchstart"in r.default,t.iphone=/iphone/i.test(a)},4424:function(t){t.exports=e},4507:function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.analyseMask=function(e,t,n){var i,r,l,c,u,f,p=/(?:[?*+]|\{[0-9+*]+(?:,[0-9+*]*)?(?:\|[0-9+*]*)?\})|[^.?*+^${[]()|\\]+|./g,d=/\[\^?]?(?:[^\\\]]+|\\[\S\s]?)*]?|\\(?:0(?:[0-3][0-7]{0,2}|[4-7][0-7]?)?|[1-9][0-9]*|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}|c[A-Za-z]|[\S\s]?)|\((?:\?[:=!]?)?|(?:[?*+]|\{[0-9]+(?:,[0-9]*)?\})\??|[^.?*+^${[()|\\]+|./g,h=new o.default,m=[],v=[],g=!1,y=!1;function k(e,i,r){r=void 0!==r?r:e.matches.length;var o=e.matches[r-1],l=n.casing?"i":"";if(t)0===i.indexOf("[")||g&&/\\d|\\s|\\w|\\p/i.test(i)||"."===i?(/\\p\{.*}/i.test(i)&&(l+="u"),e.matches.splice(r++,0,{fn:new RegExp(i,l),static:!1,optionality:!1,newBlockMarker:void 0===o?"master":o.def!==i,casing:null,def:i,placeholder:"object"===s(n.placeholder)?n.placeholder[h.matches.length]:void 0,nativeDef:i})):(g&&(i=i[i.length-1]),i.split("").forEach((function(t,i){o=e.matches[r-1],e.matches.splice(r++,0,{fn:/[a-z]/i.test(n.staticDefinitionSymbol||t)?new RegExp("["+(n.staticDefinitionSymbol||t)+"]",l):null,static:!0,optionality:!1,newBlockMarker:void 0===o?"master":o.def!==t&&!0!==o.static,casing:null,def:n.staticDefinitionSymbol||t,placeholder:void 0!==n.staticDefinitionSymbol?t:"object"===s(n.placeholder)?n.placeholder[h.matches.length]:void 0,nativeDef:(g?"'":"")+t})}))),g=!1;else{var c=n.definitions&&n.definitions[i]||n.usePrototypeDefinitions&&a.default.prototype.definitions[i];c&&!g?("string"==typeof c.validator&&/\\p\{.*}/i.test(c.validator)&&(l+="u"),e.matches.splice(r++,0,{fn:c.validator?"string"==typeof c.validator?new RegExp(c.validator,l):new function(){this.test=c.validator}:/./,static:c.static||!1,optionality:c.optional||!1,defOptionality:c.optional||!1,newBlockMarker:void 0===o||c.optional?"master":o.def!==(c.definitionSymbol||i),casing:c.casing,def:c.definitionSymbol||i,placeholder:c.placeholder,nativeDef:i,generated:c.generated})):(e.matches.splice(r++,0,{fn:/[a-z]/i.test(n.staticDefinitionSymbol||i)?new RegExp("["+(n.staticDefinitionSymbol||i)+"]",l):null,static:!0,optionality:!1,newBlockMarker:void 0===o?"master":o.def!==i&&!0!==o.static,casing:null,def:n.staticDefinitionSymbol||i,placeholder:void 0!==n.staticDefinitionSymbol?i:void 0,nativeDef:(g?"'":"")+i}),g=!1)}}function b(){if(m.length>0){if(k(c=m[m.length-1],r),c.isAlternator){u=m.pop();for(var e=0;e0?(c=m[m.length-1]).matches.push(u):h.matches.push(u)}}else k(h,r)}function x(e){var t=new o.default(!0);return t.openGroup=!1,t.matches=e,t}function P(){if((l=m.pop()).openGroup=!1,void 0!==l)if(m.length>0){if((c=m[m.length-1]).matches.push(l),c.isAlternator){u=m.pop();for(var e=0;e0?(c=m[m.length-1]).matches.push(u):h.matches.push(u)}}else h.matches.push(l);else b()}function S(e){var t=e.pop();return t.isQuantifier&&(t=x([e.pop(),t])),t}t&&(n.optionalmarker[0]=void 0,n.optionalmarker[1]=void 0);for(;i=t?d.exec(e):p.exec(e);){if(r=i[0],t){switch(r.charAt(0)){case"?":r="{0,1}";break;case"+":case"*":r="{"+r+"}";break;case"|":if(0===m.length){var w=x(h.matches);w.openGroup=!0,m.push(w),h.matches=[],y=!0}}switch(r){case"\\d":r="[0-9]";break;case"\\p":r+=d.exec(e)[0],r+=d.exec(e)[0]}}if(g)b();else switch(r.charAt(0)){case"$":case"^":t||b();break;case n.escapeChar:g=!0,t&&b();break;case n.optionalmarker[1]:case n.groupmarker[1]:P();break;case n.optionalmarker[0]:m.push(new o.default(!1,!0));break;case n.groupmarker[0]:m.push(new o.default(!0));break;case n.quantifiermarker[0]:var O=new o.default(!1,!1,!0),M=(r=r.replace(/[{}?]/g,"")).split("|"),_=M[0].split(","),j=isNaN(_[0])?_[0]:parseInt(_[0]),E=1===_.length?j:isNaN(_[1])?_[1]:parseInt(_[1]),T=isNaN(M[1])?M[1]:parseInt(M[1]);"*"!==j&&"+"!==j||(j="*"===E?0:1),O.quantifier={min:j,max:E,jit:T};var A=m.length>0?m[m.length-1].matches:h.matches;(i=A.pop()).isGroup||(i=x([i])),A.push(i),A.push(O);break;case n.alternatormarker:if(m.length>0){var D=(c=m[m.length-1]).matches[c.matches.length-1];f=c.openGroup&&(void 0===D.matches||!1===D.isGroup&&!1===D.isAlternator)?m.pop():S(c.matches)}else f=S(h.matches);if(f.isAlternator)m.push(f);else if(f.alternatorGroup?(u=m.pop(),f.alternatorGroup=!1):u=new o.default(!1,!1,!1,!0),u.matches.push(f),m.push(u),f.openGroup){f.openGroup=!1;var C=new o.default(!0);C.alternatorGroup=!0,m.push(C)}break;default:b()}}y&&P();for(;m.length>0;)l=m.pop(),h.matches.push(l);h.matches.length>0&&(!function e(i){i&&i.matches&&i.matches.forEach((function(r,a){var o=i.matches[a+1];(void 0===o||void 0===o.matches||!1===o.isQuantifier)&&r&&r.isGroup&&(r.isGroup=!1,t||(k(r,n.groupmarker[0],0),!0!==r.openGroup&&k(r,n.groupmarker[1]))),e(r)}))}(h),v.push(h));(n.numericInput||n.isRTL)&&function e(t){for(var i in t.matches=t.matches.reverse(),t.matches)if(Object.prototype.hasOwnProperty.call(t.matches,i)){var r=parseInt(i);if(t.matches[i].isQuantifier&&t.matches[r+1]&&t.matches[r+1].isGroup){var a=t.matches[i];t.matches.splice(i,1),t.matches.splice(r+1,0,a)}void 0!==t.matches[i].matches?t.matches[i]=e(t.matches[i]):t.matches[i]=((o=t.matches[i])===n.optionalmarker[0]?o=n.optionalmarker[1]:o===n.optionalmarker[1]?o=n.optionalmarker[0]:o===n.groupmarker[0]?o=n.groupmarker[1]:o===n.groupmarker[1]&&(o=n.groupmarker[0]),o)}var o;return t}(v[0]);return v},t.generateMaskSet=function(e,t){var n;function o(e,t){var n=t.repeat,i=t.groupmarker,a=t.quantifiermarker,o=t.keepStatic;if(n>0||"*"===n||"+"===n){var s="*"===n?0:"+"===n?1:n;if(s!==n)e=i[0]+e+i[1]+a[0]+s+","+n+a[1];else for(var c=e,u=1;u1){null===e.keepStatic&&(e.keepStatic=!0);var u=e.groupmarker[0];return(e.isRTL?e.mask.reverse():e.mask).forEach((function(t){u.length>1&&(u+=e.alternatormarker),void 0!==t.mask&&"function"!=typeof t.mask?u+=t.mask:u+=t})),c(u+=e.groupmarker[1],e.mask,e)}e.mask=e.mask.pop()}n=e.mask&&void 0!==e.mask.mask&&"function"!=typeof e.mask.mask?c(e.mask.mask,e.mask,e):c(e.mask,e.mask,e);null===e.keepStatic&&(e.keepStatic=!1);return n};var i=c(n(8826)),r=n(340),a=c(n(3978)),o=c(n(9439));function s(e){return s="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},s(e)}function l(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,i=Array(t);ne.length)&&(t=e.length);for(var n=0,i=Array(t);n-1&&"."!==t.buffer[n-1]?(e=t.buffer[n-1]+e,e=n-2>-1&&"."!==t.buffer[n-2]?t.buffer[n-2]+e:"0"+e):e="00"+e,r.greedy&&parseInt(e)>255&&c.test("00"+e.charAt(2))){var a=[].concat(s(t.buffer.slice(0,n)),[".",e.charAt(2)]);if(a.join("").match(/\./g).length<4)return{refreshFromBuffer:!0,buffer:a,caret:n+2}}return c.test(e)}r.default.extendAliases({cssunit:{regex:"[+-]?[0-9]+\\.?([0-9]+)?(px|em|rem|ex|%|in|cm|mm|pt|pc)"},url:{regex:"(https?|ftp)://.*",autoUnmask:!1,keepStatic:!1,tabThrough:!0},ip:{mask:"i{1,3}.j{1,3}.k{1,3}.l{1,3}",definitions:{i:{validator:u},j:{validator:u},k:{validator:u},l:{validator:u}},onUnMask:function(e,t,n){return e},inputmode:"decimal",substitutes:{",":"."}},email:{mask:function(e){var t=e.separator,n=e.quantifier,i="*{1,64}[.*{1,64}][.*{1,64}][.*{1,63}]@-{1,63}.-{1,63}[.-{1,63}][.-{1,63}]",r=i;if(t)for(var a=0;a0)?d.call(a,y,v.call(a,y,c,y-1)):s.validPositions[y]).match,c=h.locator.slice(),g.push(!0===n?h.input:!1===n?u.nativeDef:f.call(a,y,u));else{u=(h=p.call(a,y,c,y-1)).match,c=h.locator.slice();var k=!0!==i&&(!1!==o.jitMasking?o.jitMasking:u.jit);(m=(m||s.validPositions[y-1])&&u.static&&u.def!==o.groupSeparator&&null===u.fn)||!1===k||void 0===k||"number"==typeof k&&isFinite(k)&&k>y?g.push(!1===n?u.nativeDef:f.call(a,g.length,u)):m=!1}y++}while(!0!==u.static||""!==u.def||t>y);""===g[g.length-1]&&g.pop();!1===n&&void 0!==s.maskLength||(s.maskLength=y-1);return o.greedy=l,g},t.getPlaceholder=f,t.getTest=h,t.getTestTemplate=p,t.getTests=v,t.isSubsetOf=m;var i,r=(i=n(3978))&&i.__esModule?i:{default:i},a=n(7539);function o(e){return function(e){if(Array.isArray(e))return s(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(e){if("string"==typeof e)return s(e,t);var n={}.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?s(e,t):void 0}}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function s(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,i=Array(t);n0&&(t=t.split(",").sort((function(e,t){return e-t}))[0]),void 0!==t?t.toString():""}function f(e,t,n){var i=this,r=this.opts,o=this.maskset;if(void 0!==(t=t||h.call(i,e).match).placeholder||!0===n){if(""!==t.placeholder&&!0===t.static&&!0!==t.generated){var s=a.getLastValidPosition.call(i,e),c=a.seekNext.call(i,s);return(n?e<=c:e-1&&void 0===o.validPositions[e]){var u,f=v.call(i,e),p=[];if("string"==typeof r.placeholder&&f.length>1+(""===f[f.length-1].match.def?1:0))for(var d=0;d1&&/[0-9a-bA-Z]/.test(p[0].match.def)))return r.placeholder.charAt(e%r.placeholder.length)}return t.def}return"object"===l(r.placeholder)?t.def:r.placeholder.charAt(e%r.placeholder.length)}function p(e,t,n){return this.maskset.validPositions[e]||d.call(this,e,v.call(this,e,t?t.slice():t,n))}function d(e,t){var n=this.opts,i=function(e,t){var n=0,i=!1;t.forEach((function(e){e.match.optionality&&(0!==n&&n!==e.match.optionality&&(i=!0),(0===n||n>e.match.optionality)&&(n=e.match.optionality))})),n&&(0==e||1==t.length?n=0:i||(n=0));return n}(e,t);e=e>0?e-1:0;var r,a,s,l=Math.max.apply(Math,o(t.map((function(e){return void 0===e.locator?0:e.locator.length})))),u=c(h.call(this,e),l),f=0;n.greedy&&t.length>1&&""===t[t.length-1].match.def&&(f=1);for(var p=0;p0&&"master"===s.match.newBlockMarker&&(!d.match.optionality||d.match.optionality-i<1||!d.match.newBlockMarker)||s&&!n.greedy&&s.match.optionalQuantifier&&!d.match.optionalQuantifier)&&(a=m,s=d)}return s}function h(e,t){var n=this.maskset;return n.validPositions[e]?n.validPositions[e]:(t||v.call(this,e))[0]}function m(e,t,n){function i(e){for(var t,n=[],i=-1,r=0,a=e.length;rt.alternation)for(var r=0;rn&&(e.alternation=n),!0}return e.alternation=void 0,!1}(n)}if(p>e+c._maxTestPos)throw new Error("Inputmask: There is probably an error in your mask definition or in the code. Create an issue on github with an example of the mask you are using. ".concat(l.mask));if(p===e&&void 0===a.matches){if(v.push({match:a,locator:s.reverse(),cd:y,mloc:{}}),!a.optionality||void 0!==d||!(c.definitions&&c.definitions[a.nativeDef]&&c.definitions[a.nativeDef].optional||r.default.prototype.definitions[a.nativeDef]&&r.default.prototype.definitions[a.nativeDef].optional))return!0;g=!0,p=e}else if(void 0!==a.matches){if(a.isGroup&&d!==a)return function(){if(a=f(t.matches[t.matches.indexOf(a)+1],s,d))return!0}();if(a.isOptional)return function(){var t=a,r=v.length;if(a=b(a,n,s,d),v.length>0){if(v.forEach((function(e,t){t>=r&&(e.match.optionality=e.match.optionality?e.match.optionality+1:1)})),i=v[v.length-1].match,void 0!==d||!h(i,t))return a;g=!0,p=e}}();if(a.isAlternator)return function(){function i(e){for(var t=0,n=0;n0?n.shift():-1;if(-1===M||"string"==typeof M){var _,j=p,E=n.slice(),T=[];if("string"==typeof M)T=M.split(",");else for(_=0;_=c.keepStatic)&&(T=T.slice(0,1));for(var R=0;Ry.matches[0].matches.length)break;h=v.slice(),p=j,v=[];for(var L=0;L0&&k,a=b.length>0&&!k,k&&g&&!a&&v.forEach((function(e,t){e.unMatchedAlternationStopped=!0})),n=E.slice()}else a=f(y.matches[M]||t.matches[M],[M].concat(s),d);if(a)return!0}();if(a.isQuantifier&&d!==t.matches[t.matches.indexOf(a)-1])return function(){for(var r,o=a,u=!1,d=function(n){var r=t.matches[t.matches.indexOf(o)-1];if(a=f(r,[n].concat(s),r))return v.forEach((function(t,s){(i=x(r,t.match)?t.match:v[v.length-1].match).optionalQuantifier=n>=o.quantifier.min,i.jit=(n+1)*(r.matches.indexOf(i)+1)>o.quantifier.jit,i.optionalQuantifier&&h(i,r)&&(g=!0,p=e,c.greedy&&null==l.validPositions[e-1]&&n>o.quantifier.min&&-1!=["*","+"].indexOf(o.quantifier.max)&&(v.pop(),y=void 0),u=!0,a=!1),!u&&i.jit&&(l.jitOffset[e]=r.matches.length-r.matches.indexOf(i))})),u?0:{v:!0}},m=n.length>0?n.shift():0;m<(isNaN(o.quantifier.max)?m+1:o.quantifier.max)&&p<=e&&0!==(r=d(m));m++)if(r)return r.v}();if(a=b(a,n,s,d))return!0}else p++}for(var d=n.length>0?n.shift():0;de)break}}function x(e,t){var n=-1!=e.matches.indexOf(t);return n||e.matches.forEach((function(e,i){void 0===e.matches||n||(n=x(e,t))})),n}function P(e,t){var n=[];return Array.isArray(t)||(t=[t]),t.length>0&&(void 0===t[0].alternation||!0===c.keepStatic||isFinite(parseInt(c.keepStatic))&&e>=c.keepStatic?0===(n=d.call(o,e,t.slice()).locator.slice()).length&&(n=t[0].locator.slice()):t.forEach((function(e){Object.values(e.mloc).forEach((function(e){e.forEach((function(e,t){var i=n[t];e.toString().includes(":")||i&&i.toString().includes(":")||(void 0===i?n[t]=e:i.toString().includes(e)||(n[t]=n[t]+","+e))}))}))}))),n}if(e>-1){if(void 0===t){for(var S,w=e-1;void 0===(S=l.validPositions[w]||l.tests[w])&&w>-1;)w--;void 0!==S&&w>-1&&(h=P(w,S),y=h.join(""),p=w)}if(l.tests[e]&&l.tests[e][0].cd===y)return l.tests[e];for(var O=h.shift();Oe)break}}return(0===v.length||g)&&v.push({match:{fn:null,static:!0,optionality:!1,casing:null,def:"",placeholder:""},locator:k&&0===v.filter((function(e){return!0!==e.unMatchedAlternationStopped})).length?[0]:[],mloc:{},cd:y}),void 0!==t&&l.tests[e]?a=s.extend(!0,[],v):(l.tests[e]=s.extend(!0,[],v),a=l.tests[e]),v.forEach((function(e){e.match.optionality=e.match.defOptionality||!1})),a}},6032:function(e,t){function n(e){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},n(e)}function i(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var i,r,a,o,s=[],l=!0,c=!1;try{if(a=(n=n.call(e)).next,0===t){if(Object(n)!==n)return;l=!1}else for(;!(l=(i=a.call(n)).done)&&(s.push(i.value),s.length!==t);l=!0);}catch(e){c=!0,r=e}finally{try{if(!l&&null!=n.return&&(o=n.return(),Object(o)!==o))return}finally{if(c)throw r}}return s}}(e,t)||function(e,t){if(e){if("string"==typeof e)return r(e,t);var n={}.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?r(e,t):void 0}}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function r(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,i=Array(t);n=0;--r){var a=this.tryEntries[r],o=a[4],s=this.prev,l=a[1],c=a[2];if(-1===a[0])return i("end"),!1;if(!l&&!c)throw Error("try statement without catch or finally");if(null!=a[0]&&a[0]<=s){if(s=0;--n){var i=this.tryEntries[n];if(i[0]>-1&&i[0]<=this.prev&&this.prev=0;--t){var n=this.tryEntries[t];if(n[2]===e)return this.complete(n[4],n[3]),O(n),d}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var n=this.tryEntries[t];if(n[0]===e){var i=n[4];if("throw"===i.type){var r=i.arg;O(n)}return r}}throw Error("illegal catch attempt")},delegateYield:function(t,n,i){return this.delegate={i:_(t),r:n,n:i},"next"===this.method&&(this.arg=e),d}},t}function d(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!n){if(Array.isArray(e)||(n=function(e,t){if(e){if("string"==typeof e)return h(e,t);var n={}.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?h(e,t):void 0}}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var i=0,r=function(){};return{s:r,n:function(){return i>=e.length?{done:!0}:{done:!1,value:e[i++]}},e:function(e){throw e},f:r}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,o=!0,s=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return o=e.done,e},e:function(e){s=!0,a=e},f:function(){try{o||null==n.return||n.return()}finally{if(s)throw a}}}}function h(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,i=Array(t);n=0&&k.end>0&&(e.preventDefault(),l.caret.call(f,m,k.begin,k.end))):(k.begin=l.seekNext.call(f,k.begin,!0),k.end=l.seekNext.call(f,k.begin,!0),k.end1,y.keypressEvent.call(this,e,t,n,i,a)},keypressEvent:function(e,t,n,i,r){var a=this.inputmask||this,u=a.opts,f=a.dependencyLib,p=a.maskset,d=a.el,h=f(d),m=e.key;if(!0===t||e.ctrlKey&&e.altKey&&!a.ignorable||!(e.ctrlKey||e.metaKey||a.ignorable)){if(m){var v,g=t?{begin:r,end:r}:l.caret.call(a,d);t||(m=u.substitutes[m]||m),p.writeOutBuffer=!0;var y=c.isValid.call(a,g,m,i,void 0,void 0,void 0,t);if(!1!==y&&(l.resetMaskSet.call(a,!0),v=void 0!==y.caret?y.caret:l.seekNext.call(a,y.pos.begin?y.pos.begin:y.pos),p.p=v),v=u.numericInput&&void 0===y.caret?l.seekPrevious.call(a,v):v,!1!==n&&(setTimeout((function(){u.onKeyValidation.call(d,m,y)}),0),p.writeOutBuffer&&!1!==y)){var k=l.getBuffer.call(a);(0,o.writeBuffer)(d,k,v,e,!0!==t)}if(e.preventDefault(),t)return!1!==y&&(y.forwardPosition=v),y}}else m===s.keys.Enter&&a.undoValue!==a._valueGet(!0)&&(a.undoValue=a._valueGet(!0),setTimeout((function(){h.trigger("change")}),0))},pasteEvent:(v=p().mark((function e(t){var n,i,r,s,c,u;return p().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:n=function(e,n,i,r,a){var c=l.caret.call(e,n,void 0,void 0,!0),u=i.substr(0,c.begin),f=i.substr(c.end,i.length);if(u==(e.isRTL?l.getBufferTemplate.call(e).slice().reverse():l.getBufferTemplate.call(e)).slice(0,c.begin).join("")&&(u=""),f==(e.isRTL?l.getBufferTemplate.call(e).slice().reverse():l.getBufferTemplate.call(e)).slice(c.end).join("")&&(f=""),r=u+r+f,e.isRTL&&!0!==s.numericInput){r=r.split("");var p,h=d(l.getBufferTemplate.call(e));try{for(h.s();!(p=h.n()).done;){var m=p.value;r[0]===m&&r.shift()}}catch(e){h.e(e)}finally{h.f()}r=r.reverse().join("")}var v=r;if("function"==typeof a){if(!1===(v=a.call(e,v,s)))return!1;v||(v=i)}(0,o.checkVal)(n,!0,!1,v.toString().split(""),t)},i=this,r=this.inputmask,s=r.opts,c=r._valueGet(!0),r.skipInputEvent=!0,t.clipboardData&&t.clipboardData.getData?u=t.clipboardData.getData("text/plain"):a.default.clipboardData&&a.default.clipboardData.getData&&(u=a.default.clipboardData.getData("Text")),n(r,i,c,u,s.onBeforePaste),t.preventDefault();case 7:case"end":return e.stop()}}),e,this)})),g=function(){var e=this,t=arguments;return new Promise((function(n,i){var r=v.apply(e,t);function a(e){m(r,n,i,a,o,"next",e)}function o(e){m(r,n,i,a,o,"throw",e)}a(void 0)}))},function(e){return g.apply(this,arguments)}),inputFallBackEvent:function(e){var t=this.inputmask,n=t.opts,i=t.dependencyLib;var a,c=this,f=c.inputmask._valueGet(!0),p=(t.isRTL?l.getBuffer.call(t).slice().reverse():l.getBuffer.call(t)).join(""),d=l.caret.call(t,c,void 0,void 0,!0);if(p!==f){if(a=function(e,i,r){for(var a,o,s,c=e.substr(0,r.begin).split(""),f=e.substr(r.begin).split(""),p=i.substr(0,r.begin).split(""),d=i.substr(r.begin).split(""),h=c.length>=p.length?c.length:p.length,m=f.length>=d.length?f.length:d.length,v="",g=[],y="~";c.length0)&&(t.undoValue=s,r.trigger("change"))}}},mouseenterEvent:function(){var e=this.inputmask,t=e.opts.showMaskOnHover,n=this;if(e.mouseEnter=!0,n.getRootNode().activeElement!==n){var i=(e.isRTL?l.getBufferTemplate.call(e).slice().reverse():l.getBufferTemplate.call(e)).join("");t&&(0,o.HandleNativePlaceholder)(n,i)}},submitEvent:function(){var e=this.inputmask,t=e.opts;e.undoValue!==e._valueGet(!0)&&e.$el.trigger("change"),-1===l.getLastValidPosition.call(e)&&e._valueGet&&e._valueGet()===l.getBufferTemplate.call(e).join("")&&e._valueSet(""),t.clearIncomplete&&!1===c.isComplete.call(e,l.getBuffer.call(e))&&e._valueSet(""),t.removeMaskOnSubmit&&(e._valueSet(e.unmaskedvalue(),!0),setTimeout((function(){(0,o.writeBuffer)(e.el,l.getBuffer.call(e))}),0))},resetEvent:function(){var e=this.inputmask;e.refreshValue=!0,setTimeout((function(){(0,o.applyInputValue)(e.el,e._valueGet(!0))}),0)}}},6266:function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n=!("undefined"==typeof window||!window.document||!window.document.createElement);t.default=n?window:{}},6664:function(e,t,n){var i=o(n(4424)),r=o(n(3978));function a(e){return a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},a(e)}function o(e){return e&&e.__esModule?e:{default:e}}void 0===i.default.fn.inputmask&&(i.default.fn.inputmask=function(e,t){var n,o=this[0];if(void 0===t&&(t={}),"string"==typeof e)switch(e){case"unmaskedvalue":return o&&o.inputmask?o.inputmask.unmaskedvalue():(0,i.default)(o).val();case"remove":return this.each((function(){this.inputmask&&this.inputmask.remove()}));case"getemptymask":return o&&o.inputmask?o.inputmask.getemptymask():"";case"hasMaskedValue":return!(!o||!o.inputmask)&&o.inputmask.hasMaskedValue();case"isComplete":return!o||!o.inputmask||o.inputmask.isComplete();case"getmetadata":return o&&o.inputmask?o.inputmask.getmetadata():void 0;case"setvalue":r.default.setValue(o,t);break;case"option":if("string"!=typeof t)return this.each((function(){if(void 0!==this.inputmask)return this.inputmask.option(t)}));if(o&&void 0!==o.inputmask)return o.inputmask.option(t);break;default:return t.alias=e,n=new r.default(t),this.each((function(){n.mask(this)}))}else{if(Array.isArray(e))return t.alias=e,n=new r.default(t),this.each((function(){n.mask(this)}));if("object"===a(e))return n=new r.default(e),void 0===e.mask&&void 0===e.alias?this.each((function(){if(void 0!==this.inputmask)return this.inputmask.option(e);n.mask(this)})):this.each((function(){n.mask(this)}));if(void 0===e)return this.each((function(){(n=new r.default(t)).mask(this)}))}})},7042:function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;t.default={_maxTestPos:500,placeholder:"_",optionalmarker:["[","]"],quantifiermarker:["{","}"],groupmarker:["(",")"],alternatormarker:"|",escapeChar:"\\",mask:null,regex:null,oncomplete:function(){},onincomplete:function(){},oncleared:function(){},repeat:0,greedy:!1,autoUnmask:!1,removeMaskOnSubmit:!1,clearMaskOnLostFocus:!0,insertMode:!0,insertModeVisual:!0,clearIncomplete:!1,alias:null,onKeyDown:function(){},onBeforeMask:null,onBeforePaste:function(e,t){return"function"==typeof t.onBeforeMask?t.onBeforeMask.call(this,e,t):e},onBeforeWrite:null,onUnMask:null,outputMask:null,showMaskOnFocus:!0,showMaskOnHover:!0,onKeyValidation:function(){},skipOptionalPartCharacter:" ",numericInput:!1,rightAlign:!1,undoOnEscape:!0,radixPoint:"",_radixDance:!1,groupSeparator:"",keepStatic:null,positionCaretOnTab:!0,tabThrough:!1,supportsInputType:["text","tel","url","password","search"],isComplete:null,preValidation:null,postValidation:null,staticDefinitionSymbol:void 0,jitMasking:!1,nullable:!0,inputEventOnly:!1,noValuePatching:!1,positionCaretOnClick:"lvp",casing:null,inputmode:"text",importDataAttributes:!0,shiftPositions:!0,usePrototypeDefinitions:!0,validationEventTimeOut:3e3,substitutes:{}}},7153:function(e,t,n){var i,r=(i=n(3978))&&i.__esModule?i:{default:i};r.default.dependencyLib.extend(!0,r.default.prototype.i18n,{dayNames:["Mon","Tue","Wed","Thu","Fri","Sat","Sun","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],monthNames:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec","January","February","March","April","May","June","July","August","September","October","November","December"],ordinalSuffix:["st","nd","rd","th"]})},7539:function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.caret=function(e,t,n,i,a){var o,s=this,l=this.opts;if(void 0===t)return"selectionStart"in e&&"selectionEnd"in e?(t=e.selectionStart,n=e.selectionEnd):r.default.getSelection?(o=r.default.getSelection().getRangeAt(0)).commonAncestorContainer.parentNode!==e&&o.commonAncestorContainer!==e||(t=o.startOffset,n=o.endOffset):document.selection&&document.selection.createRange&&(n=(t=0-(o=document.selection.createRange()).duplicate().moveStart("character",-e.inputmask._valueGet().length))+o.text.length),{begin:i?t:f.call(s,t),end:i?n:f.call(s,n)};if(Array.isArray(t)&&(n=s.isRTL?t[0]:t[1],t=s.isRTL?t[1]:t[0]),void 0!==t.begin&&(n=s.isRTL?t.begin:t.end,t=s.isRTL?t.end:t.begin),"number"==typeof t){t=i?t:f.call(s,t),n="number"==typeof(n=i?n:f.call(s,n))?n:t;var c=parseInt(((e.ownerDocument.defaultView||r.default).getComputedStyle?(e.ownerDocument.defaultView||r.default).getComputedStyle(e,null):e.currentStyle).fontSize)*n;if(e.scrollLeft=c>e.scrollWidth?c:0,e.inputmask.caretPos={begin:t,end:n},l.insertModeVisual&&!1===l.insertMode&&t===n&&(a||n++),e===e.getRootNode().activeElement){if("setSelectionRange"in e)e.setSelectionRange(t,n);else if(r.default.getSelection){if(o=document.createRange(),void 0===e.firstChild||null===e.firstChild){var u=document.createTextNode("");e.appendChild(u)}o.setStart(e.firstChild,tc&&(((n=u[t]).match.optionality||n.match.optionalQuantifier&&n.match.newBlockMarker||m&&(m!==u[t].locator[f.alternation]&&!0!==n.match.static||!0===n.match.static&&n.locator[f.alternation]&&a.checkAlternationMatch.call(i,n.locator[f.alternation].toString().split(","),m.toString().split(","))&&""!==o.getTests.call(i,t)[0].def))&&p[t]===o.getPlaceholder.call(i,t,n.match));t--)if(d--,n.match.optionality){for(var v=t;v>0;){var g=o.getTest.call(i,v);if("master"===g.match.newBlockMarker||!0===g.match.newBlockMarker)break;v--}if(void 0!==r.validPositions[v])break}t===c&&(d=t);return e?{l:d,def:u[d]?u[d].match:void 0}:d},t.determineNewCaretPosition=function(e,t,n){var i,r,a,f=this,p=f.maskset,d=f.opts;t&&(f.isRTL?e.end=e.begin:e.begin=e.end);if(e.begin===e.end){switch(n=n||d.positionCaretOnClick){case"none":break;case"select":e={begin:0,end:s.call(f).length};break;case"ignore":e.end=e.begin=u.call(f,l.call(f));break;case"radixFocus":if(f.clicked>1&&0===p.validPositions.length)break;if(function(e){if(""!==d.radixPoint&&0!==d.digits){var t=p.validPositions;if(void 0===t[e]||void 0===t[e].input){if(e=y||i===a)&&(a=y)}e.end=e.begin=a}}return e}},t.getBuffer=s,t.getBufferTemplate=function(){var e=this.maskset;void 0===e._buffer&&(e._buffer=o.getMaskTemplate.call(this,!1,1),void 0===e.buffer&&(e.buffer=e._buffer.slice()));return e._buffer},t.getLastValidPosition=l,t.isMask=c,t.resetMaskSet=function(e){var t=this.maskset;t.buffer=void 0,!0!==e&&(t.validPositions=[],t.p=0);!1===e&&(t.tests={},t.jitOffset={})},t.seekNext=u,t.seekPrevious=function(e,t){var n=this,i=e-1;if(e<=0)return 0;for(;i>0&&(!0===t&&(!0!==o.getTest.call(n,i).match.newBlockMarker||!c.call(n,i,void 0,!0))||!0!==t&&!c.call(n,i,void 0,!0));)i--;return i},t.translatePosition=f;var i,r=(i=n(6266))&&i.__esModule?i:{default:i},a=n(7687),o=n(5895);function s(e){var t=this,n=t.maskset;return void 0!==n.buffer&&!0!==e||(n.buffer=o.getMaskTemplate.call(t,!0,l.call(t),!0),void 0===n._buffer&&(n._buffer=n.buffer.slice())),n.buffer}function l(e,t,n){var i=this.maskset,r=-1,a=-1,o=n||i.validPositions;void 0===e&&(e=-1);for(var s=0,l=o.length;s=e&&(a=s));return-1===r||r===e?a:-1===a||e-r-1){if(n){var s=o.getTests.call(i,e);return s.length>1+(""===s[s.length-1].match.def?1:0)}var l=o.determineTestTemplate.call(i,e,o.getTests.call(i,e)),c=o.getPlaceholder.call(i,e,l.match);return l.match.def!==c}return!1}function u(e,t,n){var i=this;void 0===n&&(n=!0);for(var r=e+1;""!==o.getTest.call(i,r).match.def&&(!0===t&&(!0!==o.getTest.call(i,r).match.newBlockMarker||!c.call(i,r,void 0,!0))||!0!==t&&!c.call(i,r,void 0,n));)r++;return r}function f(e){var t=this.opts,n=this.el;return!this.isRTL||"number"!=typeof e||t.greedy&&""===t.placeholder||!n||(e=this._valueGet().length-e)<0&&(e=0),e}},7687:function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.alternate=s,t.checkAlternationMatch=function(e,t,n){for(var i,r=this.opts.greedy?t:t.slice(0,1),a=!1,o=void 0!==n?n.split(","):[],s=0;s=a.getBuffer.call(c).length&&h>=n.end&&(n.end=h+1);t===r.keys.Backspace?n.end-n.begin<1&&(n.begin=a.seekPrevious.call(c,n.begin)):t===r.keys.Delete&&n.begin===n.end&&(n.end=a.isMask.call(c,n.end,!0,!0)?n.end+1:a.seekNext.call(c,n.end)+1);!1!==(d=m.call(c,n))&&((!0!==i&&!1!==f.keepStatic||null!==f.regex&&-1!==o.getTest.call(c,n.begin).match.def.indexOf("|"))&&s.call(c,!0),!0!==i&&(u.p=t===r.keys.Delete?n.begin+d:n.begin,u.p=a.determineNewCaretPosition.call(c,{begin:u.p,end:u.p},!1,!1===f.insertMode&&t===r.keys.Backspace?"none":void 0).begin))},t.isComplete=c,t.isSelection=u,t.isValid=f,t.refreshFromBuffer=d,t.revalidateMask=m;var i=n(6047),r=n(6032),a=n(7539),o=n(5895);function s(e,t,n,i,r,l){var c=this,u=this.dependencyLib,p=this.opts,d=c.maskset;if(!c.hasAlternator)return!1;var h,m,v,g,y,k,b,x,P,S,w,O=u.extend(!0,[],d.validPositions),M=u.extend(!0,{},d.tests),_=!1,j=!1,E=void 0!==r?r:a.getLastValidPosition.call(c);if(l&&(S=l.begin,w=l.end,l.begin>l.end&&(S=l.end,w=l.begin)),-1===E&&void 0===r)h=0,m=(g=o.getTest.call(c,h)).alternation;else for(;E>=0;E--)if((v=0===E?o.getTest.call(c,0):d.validPositions[E])&&void 0!==v.alternation){if(E<=(e||0)&&g&&g.locator[v.alternation]!==v.locator[v.alternation])break;h=E,m=v.alternation,g=v}if(void 0!==m){b=parseInt(h),d.excludes[b]=d.excludes[b]||[],!0!==e&&d.excludes[b].push((0,o.getDecisionTaker)(g)+":"+g.alternation);var T=[],A=-1;for(y=b;b=w)&&T.push(k.input),d.validPositions.splice(b,1);for(-1===A&&void 0!==t&&(T.push(t),A=T.length-1);void 0!==d.excludes[b]&&d.excludes[b].length<10;){for(d.tests={},a.resetMaskSet.call(c,!0),_=!0,y=0;yt:e.end-e.begin>t}function f(e,t,n,i,r,p,v){var g=this,y=this.dependencyLib,k=this.opts,b=g.maskset;n=!0===n;var x=e;function P(e){if(void 0!==e){if(void 0!==e.remove&&(Array.isArray(e.remove)||(e.remove=[e.remove]),e.remove.sort((function(e,t){return g.isRTL?e.pos-t.pos:t.pos-e.pos})).forEach((function(e){m.call(g,{begin:e,end:e+1})})),e.remove=void 0),void 0!==e.insert&&(Array.isArray(e.insert)||(e.insert=[e.insert]),e.insert.sort((function(e,t){return g.isRTL?t.pos-e.pos:e.pos-t.pos})).forEach((function(e){""!==e.c&&f.call(g,e.pos,e.c,void 0===e.strict||e.strict,void 0!==e.fromIsValid?e.fromIsValid:i)})),e.insert=void 0),e.refreshFromBuffer&&e.buffer){var t=e.refreshFromBuffer;d.call(g,!0===t?t:t.start,t.end,e.buffer),e.refreshFromBuffer=void 0}void 0!==e.rewritePosition&&(x=e.rewritePosition,e=!0)}return e}function S(t,n,r){var s=!1;return o.getTests.call(g,t).every((function(c,f){var p=c.match;if(a.getBuffer.call(g,!0),!1!==(s=(!p.jit||void 0!==b.validPositions[a.seekPrevious.call(g,t)])&&(null!=p.fn?p.fn.test(n,b,t,r,k,u.call(g,e)):(n===p.def||n===k.skipOptionalPartCharacter)&&""!==p.def&&{c:o.getPlaceholder.call(g,t,p,!0)||p.def,pos:t}))){var d=void 0!==s.c?s.c:n,h=t;return d=d===k.skipOptionalPartCharacter&&!0===p.static?o.getPlaceholder.call(g,t,p,!0)||p.def:d,!0!==(s=P(s))&&void 0!==s.pos&&s.pos!==t&&(h=s.pos),!0!==s&&void 0===s.pos&&void 0===s.c?!1:(!1===m.call(g,e,y.extend({},c,{input:l.call(g,d,p,h)}),i,h)&&(s=!1),!1)}return!0})),s}void 0!==e.begin&&(x=g.isRTL?e.end:e.begin);var w=!0,O=y.extend(!0,[],b.validPositions);if(!1===k.keepStatic&&void 0!==b.excludes[x]&&!0!==r&&!0!==i)for(var M=x;M<(g.isRTL?e.begin:e.end);M++)void 0!==b.excludes[M]&&(b.excludes[M]=void 0,delete b.tests[M]);if("function"==typeof k.preValidation&&!0!==i&&!0!==p&&(w=P(w=k.preValidation.call(g,a.getBuffer.call(g),x,t,u.call(g,e),k,b,e,n||r))),!0===w){if(w=S(x,t,n),(!n||!0===i)&&!1===w&&!0!==p){var _=b.validPositions[x];if(!_||!0!==_.match.static||_.match.def!==t&&t!==k.skipOptionalPartCharacter){if(k.insertMode||void 0===b.validPositions[a.seekNext.call(g,x)]||e.end>x){var j=!1;if(b.jitOffset[x]&&void 0===b.validPositions[a.seekNext.call(g,x)]&&!1!==(w=f.call(g,x+b.jitOffset[x],t,!0,!0))&&(!0!==r&&(w.caret=x),j=!0),e.end>x&&(b.validPositions[x]=void 0),!j&&!a.isMask.call(g,x,k.keepStatic&&0===x))for(var E=x+1,T=a.seekNext.call(g,x,!1,0!==x);E<=T;E++)if(!1!==(w=S(E,t,n))){w=h.call(g,x,void 0!==w.pos?w.pos:E)||w,x=E;break}}}else w={caret:a.seekNext.call(g,x)}}if(g.hasAlternator&&!0!==r&&!n&&(r=!0,!1===w&&k.keepStatic&&(c.call(g,a.getBuffer.call(g))||0===x)?w=s.call(g,x,t,n,i,void 0,e):(u.call(g,e)&&b.tests[x]&&b.tests[x].length>1&&k.keepStatic||!0===w&&!0!==k.numericInput&&b.tests[x]&&b.tests[x].length>1&&a.getLastValidPosition.call(g,void 0,!0)>x)&&(w=s.call(g,!0)||w)),!0===w&&(w={pos:x}),"function"==typeof k.postValidation&&!0!==i&&!0!==p){var A=k.postValidation.call(g,a.getBuffer.call(g,!0),void 0!==e.begin?g.isRTL?e.end:e.begin:e,t,w,k,b,n,v,r);void 0!==A&&(w=!0===A?w:A)}}w&&void 0===w.pos&&(w.pos=x),!1===w||!0===p?(a.resetMaskSet.call(g,!0),b.validPositions=y.extend(!0,[],O)):h.call(g,void 0,x,!0);var D=P(w);void 0!==g.maxLength&&(a.getBuffer.call(g).length>g.maxLength&&!i&&(a.resetMaskSet.call(g,!0),b.validPositions=y.extend(!0,[],O),D=!1));return D}function p(e,t,n){for(var i=this.maskset,r=!1,a=o.getTests.call(this,e),s=0;s0&&!r.validPositions[e];e--);for(var l=e;le+1?t[e+1]&&!0===t[e+1].match.static&&t[e+1]:t[e+1];return r&&a}return!1}var h=0,m=void 0!==e.begin?e.begin:e,v=void 0!==e.end?e.end:e,g=!0;if(e.begin>e.end&&(m=e.end,v=e.begin),i=void 0!==i?i:m,void 0===n&&(m!==v||l.insertMode&&void 0!==s.validPositions[i]||void 0===t||t.match.optionalQuantifier||t.match.optionality)){var y,k=c.extend(!0,[],s.validPositions),b=a.getLastValidPosition.call(r,void 0,!0);s.p=m;var x=u.call(r,e)?m:i;for(y=b;y>=x;y--)s.validPositions.splice(y,1),void 0===t&&delete s.tests[y+1];var P,S,w=i,O=w;for(t&&(s.validPositions[i]=c.extend(!0,{},t),O++,w++),null==k[v]&&s.jitOffset[v]&&(v+=s.jitOffset[v]+1),y=t?v:v-1;y<=b;y++){if(void 0!==(P=k[y])&&!0!==P.generatedInput&&(y>=v||y>=m&&d(y,k,{begin:m,end:v}))){for(;""!==o.getTest.call(r,O).match.def;){if(!1!==(S=p.call(r,O,P,l))||"+"===P.match.def){"+"===P.match.def&&a.getBuffer.call(r,!0);var M=f.call(r,O,P.input,"+"!==P.match.def,!0);if(g=!1!==M,w=(M.pos||O)+1,!g&&S)break}else g=!1;if(g){void 0===t&&P.match.static&&y===e.begin&&h++;break}if(!g&&a.getBuffer.call(r),O>s.maskLength)break;O++}""==o.getTest.call(r,O).match.def&&(g=!1),O=w}if(!g)break}if(!g)return s.validPositions=c.extend(!0,[],k),a.resetMaskSet.call(r,!0),!1}else t&&o.getTest.call(r,i).match.cd===t.match.cd&&(s.validPositions[i]=c.extend(!0,{},t));return a.resetMaskSet.call(r,!0),h}},7960:function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0,n(8145),n(1669),n(1960),n(493),n(472),n(4829),n(4203),n(546),n(2952);var i,r=(i=n(3978))&&i.__esModule?i:{default:i};t.default=r.default},8145:function(){function e(t){return e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},e(t)}"function"!=typeof Object.getPrototypeOf&&(Object.getPrototypeOf="object"===e("test".__proto__)?function(e){return e.__proto__}:function(e){return e.constructor.prototype})},8826:function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var i,r=(i=n(4424))&&i.__esModule?i:{default:i};if(void 0===r.default)throw new Error("jQuery not loaded!");t.default=r.default},9439:function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t,n,i){this.matches=[],this.openGroup=e||!1,this.alternatorGroup=!1,this.isGroup=e||!1,this.isOptional=t||!1,this.isQuantifier=n||!1,this.isAlternator=i||!1,this.quantifier={min:1,max:1}}},9472:function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;t.default={9:{validator:"\\p{N}",definitionSymbol:"*"},a:{validator:"\\p{L}",definitionSymbol:"*"},"*":{validator:"[\\p{L}\\p{N}]"}}}},n={};function i(e){var r=n[e];if(void 0!==r)return r.exports;var a=n[e]={exports:{}};return t[e](a,a.exports,i),a.exports}var r={};return function(){var e=r;Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;var t,n=(t=i(7960))&&t.__esModule?t:{default:t};i(6664);e.default=n.default}(),r}()})); \ No newline at end of file diff --git a/assets/js/libraries/jquery.repeater.min.js b/assets/js/libraries/jquery.repeater.min.js new file mode 100644 index 0000000..4f27b58 --- /dev/null +++ b/assets/js/libraries/jquery.repeater.min.js @@ -0,0 +1,6 @@ +// jquery.repeater version 1.2.2 +// https://github.com/DubFriend/jquery.repeater +// (MIT) 15-04-2022 +// Brian Detering (http://www.briandetering.net/) + +!function(a){"use strict";var b=function(a){return a},c=function(b){return a.isArray(b)},d=function(a){return!c(a)&&a instanceof Object},e=function(b,c){return a.inArray(c,b)},f=function(a,b){return-1!==e(a,b)},g=function(a,b){for(var c in a)a.hasOwnProperty(c)&&b(a[c],c,a)},h=function(a){return a[a.length-1]},i=function(a){return Array.prototype.slice.call(a)},j=function(){var a={};return g(i(arguments),function(b){g(b,function(b,c){a[c]=b})}),a},k=function(a,b){var c=[];return g(a,function(a,d,e){c.push(b(a,d,e))}),c},l=function(a,b,c){var d={};return g(a,function(a,e,f){e=c?c(e,a):e,d[e]=b(a,e,f)}),d},m=function(a,b,d){return c(a)?k(a,b):l(a,b,d)},n=function(a,b){return m(a,function(a){return a[b]})},o=function(a,b){var d;return c(a)?(d=[],g(a,function(a,c,e){b(a,c,e)&&d.push(a)})):(d={},g(a,function(a,c,e){b(a,c,e)&&(d[c]=a)})),d},p=function(a,b,c){return m(a,function(a,d){return a[b].apply(a,c||[])})},q=function(a){a=a||{};var b={};return a.publish=function(a,c){g(b[a],function(a){a(c)})},a.subscribe=function(a,c){b[a]=b[a]||[],b[a].push(c)},a.unsubscribe=function(a){g(b,function(b){var c=e(b,a);-1!==c&&b.splice(c,1)})},a};!function(a){var b=function(a,b){var c=q(),d=a.$;return c.getType=function(){throw'implement me (return type. "text", "radio", etc.)'},c.$=function(a){return a?d.find(a):d},c.disable=function(){c.$().prop("disabled",!0),c.publish("isEnabled",!1)},c.enable=function(){c.$().prop("disabled",!1),c.publish("isEnabled",!0)},b.equalTo=function(a,b){return a===b},b.publishChange=function(){var a;return function(d,e){var f=c.get();b.equalTo(f,a)||c.publish("change",{e:d,domElement:e}),a=f}}(),c},i=function(a,c){var d=b(a,c);return d.get=function(){return d.$().val()},d.set=function(a){d.$().val(a)},d.clear=function(){d.set("")},c.buildSetter=function(a){return function(b){a.call(d,b)}},d},j=function(a){var b={},c=i(a,b);return c.getType=function(){return"text"},c.$().on("change keyup keydown",function(a){b.publishChange(a,this)}),c},k=function(a,b){a=c(a)?a:[a],b=c(b)?b:[b];var d=!0;return a.length!==b.length?d=!1:g(a,function(a){f(b,a)||(d=!1)}),d},l=function(a){var b={},c=i(a,b);return c.getType=function(){return"button"},c.$().on("change",function(a){b.publishChange(a,this)}),c},m=function(b){var d={},e=i(b,d);return e.getType=function(){return"checkbox"},e.get=function(){var b=[];return e.$().filter(":checked").each(function(){b.push(a(this).val())}),b},e.set=function(b){b=c(b)?b:[b],e.$().each(function(){a(this).prop("checked",!1)}),g(b,function(a){e.$().filter('[value="'+a+'"]').prop("checked",!0)})},d.equalTo=k,e.$().change(function(a){d.publishChange(a,this)}),e},n=function(a){var b=j(a);return b.getType=function(){return"email"},b},o=function(c){var d={},e=b(c,d);return e.getType=function(){return"file"},e.get=function(){return h(e.$().val().split("\\"))},e.clear=function(){this.$().each(function(){a(this).wrap("
    ").closest("form").get(0).reset(),a(this).unwrap()})},e.$().change(function(a){d.publishChange(a,this)}),e},r=function(a){var b={},c=i(a,b);return c.getType=function(){return"hidden"},c.$().change(function(a){b.publishChange(a,this)}),c},s=function(c){var d={},e=b(c,d);return e.getType=function(){return"file[multiple]"},e.get=function(){var a,b=e.$().get(0).files||[],c=[];for(a=0;a<(b.length||0);a+=1)c.push(b[a].name);return c},e.clear=function(){this.$().each(function(){a(this).wrap("").closest("form").get(0).reset(),a(this).unwrap()})},e.$().change(function(a){d.publishChange(a,this)}),e},t=function(a){var b={},d=i(a,b);return d.getType=function(){return"select[multiple]"},d.get=function(){return d.$().val()||[]},d.set=function(a){d.$().val(""===a?[]:c(a)?a:[a])},b.equalTo=k,d.$().change(function(a){b.publishChange(a,this)}),d},u=function(a){var b=j(a);return b.getType=function(){return"password"},b},v=function(b){var c={},d=i(b,c);return d.getType=function(){return"radio"},d.get=function(){return d.$().filter(":checked").val()||null},d.set=function(b){b?d.$().filter('[value="'+b+'"]').prop("checked",!0):d.$().each(function(){a(this).prop("checked",!1)})},d.$().change(function(a){c.publishChange(a,this)}),d},w=function(a){var b={},c=i(a,b);return c.getType=function(){return"range"},c.$().change(function(a){b.publishChange(a,this)}),c},x=function(a){var b={},c=i(a,b);return c.getType=function(){return"select"},c.$().change(function(a){b.publishChange(a,this)}),c},y=function(a){var b={},c=i(a,b);return c.getType=function(){return"textarea"},c.$().on("change keyup keydown",function(a){b.publishChange(a,this)}),c},z=function(a){var b=j(a);return b.getType=function(){return"url"},b},A=function(a){var b=j(a);return b.getType=function(){return"color"},b},B=function(a){var b=j(a);return b.getType=function(){return"date"},b},C=function(a){var b=j(a);return b.getType=function(){return"datetime-local"},b},D=function(a){var b=j(a);return b.getType=function(){return"month"},b},E=function(a){var b=j(a);return b.getType=function(){return"number"},b},F=function(a){var b=j(a);return b.getType=function(){return"search"},b},G=function(a){var b=j(a);return b.getType=function(){return"tel"},b},H=function(a){var b=j(a);return b.getType=function(){return"time"},b},I=function(a){var b=j(a);return b.getType=function(){return"week"},b},J=function(b){var c={},f=b.$,h=b.constructorOverride||{color:A,date:B,datetimeLocal:C,month:D,number:E,search:F,tel:G,time:H,week:I,button:l,text:j,url:z,email:n,password:u,range:w,textarea:y,select:x,"select[multiple]":t,radio:v,checkbox:m,file:o,"file[multiple]":s,hidden:r},i=function(b,e){(d(e)?e:f.find(e)).each(function(){var d=a(this).attr("name");c[d]=h[b]({$:a(this)})})},k=function(b,i){var j=[],k=d(i)?i:f.find(i);d(i)?c[k.attr("name")]=h[b]({$:k}):(k.each(function(){-1===e(j,a(this).attr("name"))&&j.push(a(this).attr("name"))}),g(j,function(a){c[a]=h[b]({$:f.find('input[name="'+a+'"]')})}))};return f.is("input, select, textarea")?f.is('input[type="button"], button, input[type="submit"]')?i("button",f):f.is("textarea")?i("textarea",f):f.is('input[type="text"]')||f.is("input")&&!f.attr("type")?i("text",f):f.is('input[type="password"]')?i("password",f):f.is('input[type="email"]')?i("email",f):f.is('input[type="url"]')?i("url",f):f.is('input[type="color"]')?i("color",f):f.is('input[type="date"]')?i("date",f):f.is('input[type="datetime-local"]')?i("datetimeLocal",f):f.is('input[type="month"]')?i("month",f):f.is('input[type="number"]')?i("number",f):f.is('input[type="search"]')?i("search",f):f.is('input[type="tel"]')?i("tel",f):f.is('input[type="time"]')?i("time",f):f.is('input[type="week"]')?i("week",f):f.is('input[type="range"]')?i("range",f):f.is("select")?f.is("[multiple]")?i("select[multiple]",f):i("select",f):f.is('input[type="file"]')?f.is("[multiple]")?i("file[multiple]",f):i("file",f):f.is('input[type="hidden"]')?i("hidden",f):f.is('input[type="radio"]')?k("radio",f):f.is('input[type="checkbox"]')?k("checkbox",f):i("text",f):(i("button",'input[type="button"], button, input[type="submit"]'),i("text",'input[type="text"]'),i("color",'input[type="color"]'),i("date",'input[type="date"]'),i("datetimeLocal",'input[type="datetime-local"]'),i("month",'input[type="month"]'),i("number",'input[type="number"]'),i("search",'input[type="search"]'),i("tel",'input[type="tel"]'),i("time",'input[type="time"]'),i("week",'input[type="week"]'),i("password",'input[type="password"]'),i("email",'input[type="email"]'),i("url",'input[type="url"]'),i("range",'input[type="range"]'),i("textarea","textarea"),i("select","select:not([multiple])"),i("select[multiple]","select[multiple]"),i("file",'input[type="file"]:not([multiple])'),i("file[multiple]",'input[type="file"][multiple]'),i("hidden",'input[type="hidden"]'),k("radio",'input[type="radio"]'),k("checkbox",'input[type="checkbox"]')),c};a.fn.inputVal=function(b){var c=a(this),d=J({$:c});return c.is("input, textarea, select")?void 0===b?d[c.attr("name")].get():(d[c.attr("name")].set(b),c):void 0===b?p(d,"get"):(g(b,function(a,b){d[b].set(a)}),c)},a.fn.inputOnChange=function(b){var c=a(this),d=J({$:c});return g(d,function(a){a.subscribe("change",function(a){b.call(a.domElement,a.e)})}),c},a.fn.inputDisable=function(){var b=a(this);return p(J({$:b}),"disable"),b},a.fn.inputEnable=function(){var b=a(this);return p(J({$:b}),"enable"),b},a.fn.inputClear=function(){var b=a(this);return p(J({$:b}),"clear"),b}}(jQuery),a.fn.repeaterVal=function(){var b=function(a){if(1===a.length&&(0===a[0].key.length||1===a[0].key.length&&!a[0].key[0]))return a[0].val;g(a,function(a){a.head=a.key.shift()});var c,d=function(){var b={};return g(a,function(a){b[a.head]||(b[a.head]=[]),b[a.head].push(a)}),b}();return/^[0-9]+$/.test(a[0].head)?(c=[],g(d,function(a){c.push(b(a))})):(c={},g(d,function(a,d){c[d]=b(a)})),c};return b(function(a){var b=[];return g(a,function(a,c){var d=[];"undefined"!==c&&(d.push(c.match(/^[^\[]*/)[0]),d=d.concat(m(c.match(/\[[^\]]*\]/g),function(a){return a.replace(/[\[\]]/g,"")})),b.push({val:a,key:d}))}),b}(a(this).inputVal()))},a.fn.repeater=function(c){c=c||{};var d;return a(this).each(function(){var e=a(this),f=c.show||function(){a(this).show()},i=c.hide||function(a){a()},k=e.find("[data-repeater-list]").first(),l=function(b,c){return b.filter(function(){return!c||0===a(this).closest(n(c,"selector").join(",")).length})},p=function(){return l(k.find("[data-repeater-item]"),c.repeaters)},q=k.find("[data-repeater-item]").first().clone().hide(),r=l(l(a(this).find("[data-repeater-item]"),c.repeaters).first().find("[data-repeater-delete]"),c.repeaters);c.isFirstItemUndeletable&&r&&r.remove();var s=function(){var a=k.data("repeater-list");return c.$parent?c.$parent.data("item-name")+"["+a+"]":a},t=function(b){c.repeaters&&b.each(function(){var b=a(this);g(c.repeaters,function(a){b.find(a.selector).repeater(j(a,{$parent:b}))})})},u=function(a,b,c){a&&g(a,function(a){c.call(b.find(a.selector)[0],a)})},v=function(b,c,d){b.each(function(b){var e=a(this);e.data("item-name",c+"["+b+"]"),l(e.find("[name]"),d).each(function(){var f=a(this),g=f.attr("name").match(/\[[^\]]+\]/g),i=g?h(g).replace(/\[|\]/g,""):f.attr("name"),j=c+"["+b+"]["+i+"]"+(f.is(":checkbox")||f.attr("multiple")?"[]":"");f.attr("name",j),u(d,e,function(d){var e=a(this);v(l(e.find("[data-repeater-item]"),d.repeaters||[]),c+"["+b+"]["+e.find("[data-repeater-list]").first().data("repeater-list")+"]",d.repeaters)})})}),k.find("input[name][checked]").removeAttr("checked").prop("checked",!0)};v(p(),s(),c.repeaters),t(p()),c.initEmpty&&p().remove(),c.ready&&c.ready(function(){v(p(),s(),c.repeaters)});var w=function(){var d=function(e,f,h){if(f||c.defaultValues){var i={};l(e.find("[name]"),h).each(function(){var b=a(this).attr("name").match(/\[([^\]]*)(\]|\]\[\])$/)[1];i[b]=a(this).attr("name")}),e.inputVal(m(o(f||c.defaultValues,function(a,b){return i[b]}),b,function(a){return i[a]}))}u(h,e,function(b){var c=a(this);l(c.find("[data-repeater-item]"),b.repeaters).each(function(){var e=c.find("[data-repeater-list]").data("repeater-list");if(f&&f[e]){var h=a(this).clone();c.find("[data-repeater-item]").remove(),g(f[e],function(a){var e=h.clone();d(e,a,b.repeaters||[]),c.find("[data-repeater-list]").append(e)})}else d(a(this),b.defaultValues,b.repeaters||[])})})};return function(b,e){k.append(b),v(p(),s(),c.repeaters),b.find("[name]").each(function(){a(this).inputClear()}),d(b,e||c.defaultValues,c.repeaters)}}(),x=function(a){var b=q.clone();w(b,a),c.repeaters&&t(b),f.call(b.get(0))};d=function(a){p().remove(),g(a,x)},l(e.find("[data-repeater-create]"),c.repeaters).click(function(){x()}),k.on("click","[data-repeater-delete]",function(){var b=a(this).closest("[data-repeater-item]").get(0);i.call(b,function(){a(b).remove(),v(p(),s(),c.repeaters)})})}),this.setList=d,this}}(jQuery); \ No newline at end of file diff --git a/assets/js/libraries/jquery.validate.min.js b/assets/js/libraries/jquery.validate.min.js new file mode 100644 index 0000000..442a413 --- /dev/null +++ b/assets/js/libraries/jquery.validate.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.5 - 7/1/2022 + * https://jqueryvalidation.org/ + * Copyright (c) 2022 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){a.extend(a.fn,{validate:function(b){if(!this.length)return void(b&&b.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing."));var c=a.data(this[0],"validator");return c?c:(this.attr("novalidate","novalidate"),c=new a.validator(b,this[0]),a.data(this[0],"validator",c),c.settings.onsubmit&&(this.on("click.validate",":submit",function(b){c.submitButton=b.currentTarget,a(this).hasClass("cancel")&&(c.cancelSubmit=!0),void 0!==a(this).attr("formnovalidate")&&(c.cancelSubmit=!0)}),this.on("submit.validate",function(b){function d(){var d,e;return c.submitButton&&(c.settings.submitHandler||c.formSubmitted)&&(d=a("").attr("name",c.submitButton.name).val(a(c.submitButton).val()).appendTo(c.currentForm)),!(c.settings.submitHandler&&!c.settings.debug)||(e=c.settings.submitHandler.call(c,c.currentForm,b),d&&d.remove(),void 0!==e&&e)}return c.settings.debug&&b.preventDefault(),c.cancelSubmit?(c.cancelSubmit=!1,d()):c.form()?c.pendingRequest?(c.formSubmitted=!0,!1):d():(c.focusInvalid(),!1)})),c)},valid:function(){var b,c,d;return a(this[0]).is("form")?b=this.validate().form():(d=[],b=!0,c=a(this[0].form).validate(),this.each(function(){b=c.element(this)&&b,b||(d=d.concat(c.errorList))}),c.errorList=d),b},rules:function(b,c){var d,e,f,g,h,i,j=this[0],k="undefined"!=typeof this.attr("contenteditable")&&"false"!==this.attr("contenteditable");if(null!=j&&(!j.form&&k&&(j.form=this.closest("form")[0],j.name=this.attr("name")),null!=j.form)){if(b)switch(d=a.data(j.form,"validator").settings,e=d.rules,f=a.validator.staticRules(j),b){case"add":a.extend(f,a.validator.normalizeRule(c)),delete f.messages,e[j.name]=f,c.messages&&(d.messages[j.name]=a.extend(d.messages[j.name],c.messages));break;case"remove":return c?(i={},a.each(c.split(/\s/),function(a,b){i[b]=f[b],delete f[b]}),i):(delete e[j.name],f)}return g=a.validator.normalizeRules(a.extend({},a.validator.classRules(j),a.validator.attributeRules(j),a.validator.dataRules(j),a.validator.staticRules(j)),j),g.required&&(h=g.required,delete g.required,g=a.extend({required:h},g)),g.remote&&(h=g.remote,delete g.remote,g=a.extend(g,{remote:h})),g}}});var b=function(a){return a.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")};a.extend(a.expr.pseudos||a.expr[":"],{blank:function(c){return!b(""+a(c).val())},filled:function(c){var d=a(c).val();return null!==d&&!!b(""+d)},unchecked:function(b){return!a(b).prop("checked")}}),a.validator=function(b,c){this.settings=a.extend(!0,{},a.validator.defaults,b),this.currentForm=c,this.init()},a.validator.format=function(b,c){return 1===arguments.length?function(){var c=a.makeArray(arguments);return c.unshift(b),a.validator.format.apply(this,c)}:void 0===c?b:(arguments.length>2&&c.constructor!==Array&&(c=a.makeArray(arguments).slice(1)),c.constructor!==Array&&(c=[c]),a.each(c,function(a,c){b=b.replace(new RegExp("\\{"+a+"\\}","g"),function(){return c})}),b)},a.extend(a.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",pendingClass:"pending",validClass:"valid",errorElement:"label",focusCleanup:!1,focusInvalid:!0,errorContainer:a([]),errorLabelContainer:a([]),onsubmit:!0,ignore:":hidden",ignoreTitle:!1,onfocusin:function(a){this.lastActive=a,this.settings.focusCleanup&&(this.settings.unhighlight&&this.settings.unhighlight.call(this,a,this.settings.errorClass,this.settings.validClass),this.hideThese(this.errorsFor(a)))},onfocusout:function(a){this.checkable(a)||!(a.name in this.submitted)&&this.optional(a)||this.element(a)},onkeyup:function(b,c){var d=[16,17,18,20,35,36,37,38,39,40,45,144,225];9===c.which&&""===this.elementValue(b)||a.inArray(c.keyCode,d)!==-1||(b.name in this.submitted||b.name in this.invalid)&&this.element(b)},onclick:function(a){a.name in this.submitted?this.element(a):a.parentNode.name in this.submitted&&this.element(a.parentNode)},highlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).addClass(c).removeClass(d):a(b).addClass(c).removeClass(d)},unhighlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).removeClass(c).addClass(d):a(b).removeClass(c).addClass(d)}},setDefaults:function(b){a.extend(a.validator.defaults,b)},messages:{required:"This field is required.",remote:"Please fix this field.",email:"Please enter a valid email address.",url:"Please enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please enter a valid date (ISO).",number:"Please enter a valid number.",digits:"Please enter only digits.",equalTo:"Please enter the same value again.",maxlength:a.validator.format("Please enter no more than {0} characters."),minlength:a.validator.format("Please enter at least {0} characters."),rangelength:a.validator.format("Please enter a value between {0} and {1} characters long."),range:a.validator.format("Please enter a value between {0} and {1}."),max:a.validator.format("Please enter a value less than or equal to {0}."),min:a.validator.format("Please enter a value greater than or equal to {0}."),step:a.validator.format("Please enter a multiple of {0}.")},autoCreateRanges:!1,prototype:{init:function(){function b(b){var c="undefined"!=typeof a(this).attr("contenteditable")&&"false"!==a(this).attr("contenteditable");if(!this.form&&c&&(this.form=a(this).closest("form")[0],this.name=a(this).attr("name")),d===this.form){var e=a.data(this.form,"validator"),f="on"+b.type.replace(/^validate/,""),g=e.settings;g[f]&&!a(this).is(g.ignore)&&g[f].call(e,this,b)}}this.labelContainer=a(this.settings.errorLabelContainer),this.errorContext=this.labelContainer.length&&this.labelContainer||a(this.currentForm),this.containers=a(this.settings.errorContainer).add(this.settings.errorLabelContainer),this.submitted={},this.valueCache={},this.pendingRequest=0,this.pending={},this.invalid={},this.reset();var c,d=this.currentForm,e=this.groups={};a.each(this.settings.groups,function(b,c){"string"==typeof c&&(c=c.split(/\s/)),a.each(c,function(a,c){e[c]=b})}),c=this.settings.rules,a.each(c,function(b,d){c[b]=a.validator.normalizeRule(d)}),a(this.currentForm).on("focusin.validate focusout.validate keyup.validate",":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], [type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], [type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], [type='radio'], [type='checkbox'], [contenteditable], [type='button']",b).on("click.validate","select, option, [type='radio'], [type='checkbox']",b),this.settings.invalidHandler&&a(this.currentForm).on("invalid-form.validate",this.settings.invalidHandler)},form:function(){return this.checkForm(),a.extend(this.submitted,this.errorMap),this.invalid=a.extend({},this.errorMap),this.valid()||a(this.currentForm).triggerHandler("invalid-form",[this]),this.showErrors(),this.valid()},checkForm:function(){this.prepareForm();for(var a=0,b=this.currentElements=this.elements();b[a];a++)this.check(b[a]);return this.valid()},element:function(b){var c,d,e=this.clean(b),f=this.validationTargetFor(e),g=this,h=!0;return void 0===f?delete this.invalid[e.name]:(this.prepareElement(f),this.currentElements=a(f),d=this.groups[f.name],d&&a.each(this.groups,function(a,b){b===d&&a!==f.name&&(e=g.validationTargetFor(g.clean(g.findByName(a))),e&&e.name in g.invalid&&(g.currentElements.push(e),h=g.check(e)&&h))}),c=this.check(f)!==!1,h=h&&c,c?this.invalid[f.name]=!1:this.invalid[f.name]=!0,this.numberOfInvalids()||(this.toHide=this.toHide.add(this.containers)),this.showErrors(),a(b).attr("aria-invalid",!c)),h},showErrors:function(b){if(b){var c=this;a.extend(this.errorMap,b),this.errorList=a.map(this.errorMap,function(a,b){return{message:a,element:c.findByName(b)[0]}}),this.successList=a.grep(this.successList,function(a){return!(a.name in b)})}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:function(){a.fn.resetForm&&a(this.currentForm).resetForm(),this.invalid={},this.submitted={},this.prepareForm(),this.hideErrors();var b=this.elements().removeData("previousValue").removeAttr("aria-invalid");this.resetElements(b)},resetElements:function(a){var b;if(this.settings.unhighlight)for(b=0;a[b];b++)this.settings.unhighlight.call(this,a[b],this.settings.errorClass,""),this.findByName(a[b].name).removeClass(this.settings.validClass);else a.removeClass(this.settings.errorClass).removeClass(this.settings.validClass)},numberOfInvalids:function(){return this.objectLength(this.invalid)},objectLength:function(a){var b,c=0;for(b in a)void 0!==a[b]&&null!==a[b]&&a[b]!==!1&&c++;return c},hideErrors:function(){this.hideThese(this.toHide)},hideThese:function(a){a.not(this.containers).text(""),this.addWrapper(a).hide()},valid:function(){return 0===this.size()},size:function(){return this.errorList.length},focusInvalid:function(){if(this.settings.focusInvalid)try{a(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").trigger("focus").trigger("focusin")}catch(b){}},findLastActive:function(){var b=this.lastActive;return b&&1===a.grep(this.errorList,function(a){return a.element.name===b.name}).length&&b},elements:function(){var b=this,c={};return a(this.currentForm).find("input, select, textarea, [contenteditable]").not(":submit, :reset, :image, :disabled").not(this.settings.ignore).filter(function(){var d=this.name||a(this).attr("name"),e="undefined"!=typeof a(this).attr("contenteditable")&&"false"!==a(this).attr("contenteditable");return!d&&b.settings.debug&&window.console&&console.error("%o has no name assigned",this),e&&(this.form=a(this).closest("form")[0],this.name=d),this.form===b.currentForm&&(!(d in c||!b.objectLength(a(this).rules()))&&(c[d]=!0,!0))})},clean:function(b){return a(b)[0]},errors:function(){var b=this.settings.errorClass.split(" ").join(".");return a(this.settings.errorElement+"."+b,this.errorContext)},resetInternals:function(){this.successList=[],this.errorList=[],this.errorMap={},this.toShow=a([]),this.toHide=a([])},reset:function(){this.resetInternals(),this.currentElements=a([])},prepareForm:function(){this.reset(),this.toHide=this.errors().add(this.containers)},prepareElement:function(a){this.reset(),this.toHide=this.errorsFor(a)},elementValue:function(b){var c,d,e=a(b),f=b.type,g="undefined"!=typeof e.attr("contenteditable")&&"false"!==e.attr("contenteditable");return"radio"===f||"checkbox"===f?this.findByName(b.name).filter(":checked").val():"number"===f&&"undefined"!=typeof b.validity?b.validity.badInput?"NaN":e.val():(c=g?e.text():e.val(),"file"===f?"C:\\fakepath\\"===c.substr(0,12)?c.substr(12):(d=c.lastIndexOf("/"),d>=0?c.substr(d+1):(d=c.lastIndexOf("\\"),d>=0?c.substr(d+1):c)):"string"==typeof c?c.replace(/\r/g,""):c)},check:function(b){b=this.validationTargetFor(this.clean(b));var c,d,e,f,g=a(b).rules(),h=a.map(g,function(a,b){return b}).length,i=!1,j=this.elementValue(b);"function"==typeof g.normalizer?f=g.normalizer:"function"==typeof this.settings.normalizer&&(f=this.settings.normalizer),f&&(j=f.call(b,j),delete g.normalizer);for(d in g){e={method:d,parameters:g[d]};try{if(c=a.validator.methods[d].call(this,j,b,e.parameters),"dependency-mismatch"===c&&1===h){i=!0;continue}if(i=!1,"pending"===c)return void(this.toHide=this.toHide.not(this.errorsFor(b)));if(!c)return this.formatAndAdd(b,e),!1}catch(k){throw this.settings.debug&&window.console&&console.log("Exception occurred when checking element "+b.id+", check the '"+e.method+"' method.",k),k instanceof TypeError&&(k.message+=". Exception occurred when checking element "+b.id+", check the '"+e.method+"' method."),k}}if(!i)return this.objectLength(g)&&this.successList.push(b),!0},customDataMessage:function(b,c){return a(b).data("msg"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase())||a(b).data("msg")},customMessage:function(a,b){var c=this.settings.messages[a];return c&&(c.constructor===String?c:c[b])},findDefined:function(){for(var a=0;aWarning: No message defined for "+b.name+""),e=/\$?\{(\d+)\}/g;return"function"==typeof d?d=d.call(this,c.parameters,b):e.test(d)&&(d=a.validator.format(d.replace(e,"{$1}"),c.parameters)),d},formatAndAdd:function(a,b){var c=this.defaultMessage(a,b);this.errorList.push({message:c,element:a,method:b.method}),this.errorMap[a.name]=c,this.submitted[a.name]=c},addWrapper:function(a){return this.settings.wrapper&&(a=a.add(a.parent(this.settings.wrapper))),a},defaultShowErrors:function(){var a,b,c;for(a=0;this.errorList[a];a++)c=this.errorList[a],this.settings.highlight&&this.settings.highlight.call(this,c.element,this.settings.errorClass,this.settings.validClass),this.showLabel(c.element,c.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(a=0;this.successList[a];a++)this.showLabel(this.successList[a]);if(this.settings.unhighlight)for(a=0,b=this.validElements();b[a];a++)this.settings.unhighlight.call(this,b[a],this.settings.errorClass,this.settings.validClass);this.toHide=this.toHide.not(this.toShow),this.hideErrors(),this.addWrapper(this.toShow).show()},validElements:function(){return this.currentElements.not(this.invalidElements())},invalidElements:function(){return a(this.errorList).map(function(){return this.element})},showLabel:function(b,c){var d,e,f,g,h=this.errorsFor(b),i=this.idOrName(b),j=a(b).attr("aria-describedby");h.length?(h.removeClass(this.settings.validClass).addClass(this.settings.errorClass),h.html(c)):(h=a("<"+this.settings.errorElement+">").attr("id",i+"-error").addClass(this.settings.errorClass).html(c||""),d=h,this.settings.wrapper&&(d=h.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(d):this.settings.errorPlacement?this.settings.errorPlacement.call(this,d,a(b)):d.insertAfter(b),h.is("label")?h.attr("for",i):0===h.parents("label[for='"+this.escapeCssMeta(i)+"']").length&&(f=h.attr("id"),j?j.match(new RegExp("\\b"+this.escapeCssMeta(f)+"\\b"))||(j+=" "+f):j=f,a(b).attr("aria-describedby",j),e=this.groups[b.name],e&&(g=this,a.each(g.groups,function(b,c){c===e&&a("[name='"+g.escapeCssMeta(b)+"']",g.currentForm).attr("aria-describedby",h.attr("id"))})))),!c&&this.settings.success&&(h.text(""),"string"==typeof this.settings.success?h.addClass(this.settings.success):this.settings.success(h,b)),this.toShow=this.toShow.add(h)},errorsFor:function(b){var c=this.escapeCssMeta(this.idOrName(b)),d=a(b).attr("aria-describedby"),e="label[for='"+c+"'], label[for='"+c+"'] *";return d&&(e=e+", #"+this.escapeCssMeta(d).replace(/\s+/g,", #")),this.errors().filter(e)},escapeCssMeta:function(a){return void 0===a?"":a.replace(/([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g,"\\$1")},idOrName:function(a){return this.groups[a.name]||(this.checkable(a)?a.name:a.id||a.name)},validationTargetFor:function(b){return this.checkable(b)&&(b=this.findByName(b.name)),a(b).not(this.settings.ignore)[0]},checkable:function(a){return/radio|checkbox/i.test(a.type)},findByName:function(b){return a(this.currentForm).find("[name='"+this.escapeCssMeta(b)+"']")},getLength:function(b,c){switch(c.nodeName.toLowerCase()){case"select":return a("option:selected",c).length;case"input":if(this.checkable(c))return this.findByName(c.name).filter(":checked").length}return b.length},depend:function(a,b){return!this.dependTypes[typeof a]||this.dependTypes[typeof a](a,b)},dependTypes:{"boolean":function(a){return a},string:function(b,c){return!!a(b,c.form).length},"function":function(a,b){return a(b)}},optional:function(b){var c=this.elementValue(b);return!a.validator.methods.required.call(this,c,b)&&"dependency-mismatch"},startRequest:function(b){this.pending[b.name]||(this.pendingRequest++,a(b).addClass(this.settings.pendingClass),this.pending[b.name]=!0)},stopRequest:function(b,c){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[b.name],a(b).removeClass(this.settings.pendingClass),c&&0===this.pendingRequest&&this.formSubmitted&&this.form()&&0===this.pendingRequest?(a(this.currentForm).trigger("submit"),this.submitButton&&a("input:hidden[name='"+this.submitButton.name+"']",this.currentForm).remove(),this.formSubmitted=!1):!c&&0===this.pendingRequest&&this.formSubmitted&&(a(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(b,c){return c="string"==typeof c&&c||"remote",a.data(b,"previousValue")||a.data(b,"previousValue",{old:null,valid:!0,message:this.defaultMessage(b,{method:c})})},destroy:function(){this.resetForm(),a(this.currentForm).off(".validate").removeData("validator").find(".validate-equalTo-blur").off(".validate-equalTo").removeClass("validate-equalTo-blur").find(".validate-lessThan-blur").off(".validate-lessThan").removeClass("validate-lessThan-blur").find(".validate-lessThanEqual-blur").off(".validate-lessThanEqual").removeClass("validate-lessThanEqual-blur").find(".validate-greaterThanEqual-blur").off(".validate-greaterThanEqual").removeClass("validate-greaterThanEqual-blur").find(".validate-greaterThan-blur").off(".validate-greaterThan").removeClass("validate-greaterThan-blur")}},classRuleSettings:{required:{required:!0},email:{email:!0},url:{url:!0},date:{date:!0},dateISO:{dateISO:!0},number:{number:!0},digits:{digits:!0},creditcard:{creditcard:!0}},addClassRules:function(b,c){b.constructor===String?this.classRuleSettings[b]=c:a.extend(this.classRuleSettings,b)},classRules:function(b){var c={},d=a(b).attr("class");return d&&a.each(d.split(" "),function(){this in a.validator.classRuleSettings&&a.extend(c,a.validator.classRuleSettings[this])}),c},normalizeAttributeRule:function(a,b,c,d){/min|max|step/.test(c)&&(null===b||/number|range|text/.test(b))&&(d=Number(d),isNaN(d)&&(d=void 0)),d||0===d?a[c]=d:b===c&&"range"!==b&&(a["date"===b?"dateISO":c]=!0)},attributeRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)"required"===c?(d=b.getAttribute(c),""===d&&(d=!0),d=!!d):d=f.attr(c),this.normalizeAttributeRule(e,g,c,d);return e.maxlength&&/-1|2147483647|524288/.test(e.maxlength)&&delete e.maxlength,e},dataRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)d=f.data("rule"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase()),""===d&&(d=!0),this.normalizeAttributeRule(e,g,c,d);return e},staticRules:function(b){var c={},d=a.data(b.form,"validator");return d.settings.rules&&(c=a.validator.normalizeRule(d.settings.rules[b.name])||{}),c},normalizeRules:function(b,c){return a.each(b,function(d,e){if(e===!1)return void delete b[d];if(e.param||e.depends){var f=!0;switch(typeof e.depends){case"string":f=!!a(e.depends,c.form).length;break;case"function":f=e.depends.call(c,c)}f?b[d]=void 0===e.param||e.param:(a.data(c.form,"validator").resetElements(a(c)),delete b[d])}}),a.each(b,function(a,d){b[a]="function"==typeof d&&"normalizer"!==a?d(c):d}),a.each(["minlength","maxlength"],function(){b[this]&&(b[this]=Number(b[this]))}),a.each(["rangelength","range"],function(){var a;b[this]&&(Array.isArray(b[this])?b[this]=[Number(b[this][0]),Number(b[this][1])]:"string"==typeof b[this]&&(a=b[this].replace(/[\[\]]/g,"").split(/[\s,]+/),b[this]=[Number(a[0]),Number(a[1])]))}),a.validator.autoCreateRanges&&(null!=b.min&&null!=b.max&&(b.range=[b.min,b.max],delete b.min,delete b.max),null!=b.minlength&&null!=b.maxlength&&(b.rangelength=[b.minlength,b.maxlength],delete b.minlength,delete b.maxlength)),b},normalizeRule:function(b){if("string"==typeof b){var c={};a.each(b.split(/\s/),function(){c[this]=!0}),b=c}return b},addMethod:function(b,c,d){a.validator.methods[b]=c,a.validator.messages[b]=void 0!==d?d:a.validator.messages[b],c.length<3&&a.validator.addClassRules(b,a.validator.normalizeRule(b))},methods:{required:function(b,c,d){if(!this.depend(d,c))return"dependency-mismatch";if("select"===c.nodeName.toLowerCase()){var e=a(c).val();return e&&e.length>0}return this.checkable(c)?this.getLength(b,c)>0:void 0!==b&&null!==b&&b.length>0},email:function(a,b){return this.optional(b)||/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(a)},url:function(a,b){return this.optional(b)||/^(?:(?:(?:https?|ftp):)?\/\/)(?:(?:[^\]\[?\/<~#`!@$^&*()+=}|:";',>{ ]|%[0-9A-Fa-f]{2})+(?::(?:[^\]\[?\/<~#`!@$^&*()+=}|:";',>{ ]|%[0-9A-Fa-f]{2})*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z0-9\u00a1-\uffff][a-z0-9\u00a1-\uffff_-]{0,62})?[a-z0-9\u00a1-\uffff]\.)+(?:[a-z\u00a1-\uffff]{2,}\.?))(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(a)},date:function(){var a=!1;return function(b,c){return a||(a=!0,this.settings.debug&&window.console&&console.warn("The `date` method is deprecated and will be removed in version '2.0.0'.\nPlease don't use it, since it relies on the Date constructor, which\nbehaves very differently across browsers and locales. Use `dateISO`\ninstead or one of the locale specific methods in `localizations/`\nand `additional-methods.js`.")),this.optional(c)||!/Invalid|NaN/.test(new Date(b).toString())}}(),dateISO:function(a,b){return this.optional(b)||/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(a)},number:function(a,b){return this.optional(b)||/^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(a)},digits:function(a,b){return this.optional(b)||/^\d+$/.test(a)},minlength:function(a,b,c){var d=Array.isArray(a)?a.length:this.getLength(a,b);return this.optional(b)||d>=c},maxlength:function(a,b,c){var d=Array.isArray(a)?a.length:this.getLength(a,b);return this.optional(b)||d<=c},rangelength:function(a,b,c){var d=Array.isArray(a)?a.length:this.getLength(a,b);return this.optional(b)||d>=c[0]&&d<=c[1]},min:function(a,b,c){return this.optional(b)||a>=c},max:function(a,b,c){return this.optional(b)||a<=c},range:function(a,b,c){return this.optional(b)||a>=c[0]&&a<=c[1]},step:function(b,c,d){var e,f=a(c).attr("type"),g="Step attribute on input type "+f+" is not supported.",h=["text","number","range"],i=new RegExp("\\b"+f+"\\b"),j=f&&!i.test(h.join()),k=function(a){var b=(""+a).match(/(?:\.(\d+))?$/);return b&&b[1]?b[1].length:0},l=function(a){return Math.round(a*Math.pow(10,e))},m=!0;if(j)throw new Error(g);return e=k(d),(k(b)>e||l(b)%l(d)!==0)&&(m=!1),this.optional(c)||m},equalTo:function(b,c,d){var e=a(d);return this.settings.onfocusout&&e.not(".validate-equalTo-blur").length&&e.addClass("validate-equalTo-blur").on("blur.validate-equalTo",function(){a(c).valid()}),b===e.val()},remote:function(b,c,d,e){if(this.optional(c))return"dependency-mismatch";e="string"==typeof e&&e||"remote";var f,g,h,i=this.previousValue(c,e);return this.settings.messages[c.name]||(this.settings.messages[c.name]={}),i.originalMessage=i.originalMessage||this.settings.messages[c.name][e],this.settings.messages[c.name][e]=i.message,d="string"==typeof d&&{url:d}||d,h=a.param(a.extend({data:b},d.data)),i.old===h?i.valid:(i.old=h,f=this,this.startRequest(c),g={},g[c.name]=b,a.ajax(a.extend(!0,{mode:"abort",port:"validate"+c.name,dataType:"json",data:g,context:f.currentForm,success:function(a){var d,g,h,j=a===!0||"true"===a;f.settings.messages[c.name][e]=i.originalMessage,j?(h=f.formSubmitted,f.resetInternals(),f.toHide=f.errorsFor(c),f.formSubmitted=h,f.successList.push(c),f.invalid[c.name]=!1,f.showErrors()):(d={},g=a||f.defaultMessage(c,{method:e,parameters:b}),d[c.name]=i.message=g,f.invalid[c.name]=!0,f.showErrors(d)),i.valid=j,f.stopRequest(c,j)}},d)),"pending")}}});var c,d={};return a.ajaxPrefilter?a.ajaxPrefilter(function(a,b,c){var e=a.port;"abort"===a.mode&&(d[e]&&d[e].abort(),d[e]=c)}):(c=a.ajax,a.ajax=function(b){var e=("mode"in b?b:a.ajaxSettings).mode,f=("port"in b?b:a.ajaxSettings).port;return"abort"===e?(d[f]&&d[f].abort(),d[f]=c.apply(this,arguments),d[f]):c.apply(this,arguments)}),a}); \ No newline at end of file diff --git a/assets/js/societes-credit-manager.js b/assets/js/societes-credit-manager.js new file mode 100644 index 0000000..ce372f9 --- /dev/null +++ b/assets/js/societes-credit-manager.js @@ -0,0 +1,276 @@ +jQuery(document).ready(function($) { + 'use strict'; + + let currentSocieteId = null; + let societesTable = null; + + // Initialiser Select2 sur les éléments appropriés + function initSelect2() { + if (typeof $.fn.select2 === 'function') { + // Select2 est disponible mais nous ne l'utilisons pas pour societe-type-credit + // Le select reste un select HTML standard + } else { + // Si Select2 n'est pas encore disponible, réessayer dans 100ms + setTimeout(initSelect2, 100); + } + } + + // Initialiser Select2 au chargement du document + $(document).ready(function() { + /* initSelect2(); */ + }); + + // Initialiser DataTables + if ($('#societes-table').length) { + societesTable = $('#societes-table').DataTable({ + ajax: { + url: societesCreditAjax.ajaxurl, + type: 'POST', + data: function(d) { + return { + action: 'societes_credit_list', + nonce: societesCreditAjax.nonce + }; + }, + dataSrc: function(json) { + if (json.success) { + return json.data.societes; + } + return []; + } + }, + columns: [ + { data: 'id' }, + { data: 'nom' }, + { + data: 'status', + render: function(data, type, row) { + if (data == 1) { + return 'Active'; + } else { + return 'Inactive'; + } + } + }, + { + data: null, + orderable: false, + render: function(data, type, row) { + return ` + + + `; + } + } + ], + language: { + url: '//cdn.datatables.net/plug-ins/1.13.4/i18n/fr-FR.json' + }, + order: [[1, 'asc']], + pageLength: 25, + responsive: true, + dom: '<"top"f>rt<"bottom"lip><"clear">' + }); + } + + // Afficher un message + function showMessage(message, type) { + // Supprimer les anciens messages + $('.societe-message').remove(); + + let noticeClass = 'notice-' + type; + if (type === 'info') { + noticeClass = 'notice-info'; + } + + const messageDiv = $('

    ' + message + '

    '); + $('.wrap h1').after(messageDiv); + + // Auto-suppression après 5 secondes (sauf pour les erreurs) + if (type !== 'error') { + setTimeout(function() { + messageDiv.fadeOut(function() { + messageDiv.remove(); + }); + }, 5000); + } + } + + // Ouvrir le modal + window.openSocieteModal = function(societeId = null) { + currentSocieteId = societeId; + + if (societeId) { + loadSocieteData(societeId); + } else { + $('#societe-form')[0].reset(); + $('#societe-status').prop('checked', true); + $('.credit-modal-header h2').text('Nouvelle société'); + // Réinitialiser le select multiple + $('#societe-type-credit').val([]); + } + + $('.societe-modal').addClass('show').show(); + // Pas de Select2 à réinitialiser pour ce select + // Le select reste un select HTML standard + }; + + // Fermer le modal + window.closeSocieteModal = function() { + $('.societe-modal').addClass('closing'); + + setTimeout(function() { + $('.societe-modal').removeClass('show closing').hide(); + currentSocieteId = null; + }, 300); + }; + + // Charger les données d'une société + function loadSocieteData(societeId) { + $.ajax({ + url: societesCreditAjax.ajaxurl, + type: 'POST', + data: { + action: 'societes_credit_get', + nonce: societesCreditAjax.nonce, + societe_id: societeId + }, + success: function(response) { + if (response.success) { + const societe = response.data.societe; + $('.credit-modal-header h2').text('Modifier la société'); + + // Remplir le formulaire + $('#societe-nom').val(societe.nom || ''); + $('#societe-status').prop('checked', societe.status == 1); + + // Remplir le select multiple des types de crédit + if (societe.type_credit) { + const typeCreditArray = typeof societe.type_credit === 'string' + ? societe.type_credit.split(',') + : societe.type_credit; + $('#societe-type-credit').val(typeCreditArray); + } else { + $('#societe-type-credit').val([]); + } + } else { + showMessage('Erreur: ' + response.data, 'error'); + } + }, + error: function() { + showMessage('Erreur de communication avec le serveur', 'error'); + } + }); + } + + // Sauvegarder la société + window.saveSociete = function() { + const typeCreditVal = $('#societe-type-credit').val() || []; + console.log('Type credit values:', typeCreditVal); + + // Créer FormData pour gérer correctement les arrays + const formData = new FormData(); + formData.append('action', currentSocieteId ? 'societes_credit_update' : 'societes_credit_create'); + formData.append('nonce', societesCreditAjax.nonce); + formData.append('nom', $('#societe-nom').val()); + formData.append('status', $('#societe-status').is(':checked') ? 'true' : 'false'); + + // Ajouter chaque valeur de type_credit individuellement + if (typeCreditVal && typeCreditVal.length > 0) { + typeCreditVal.forEach(function(value) { + formData.append('type_credit[]', value); + }); + } else { + formData.append('type_credit[]', ''); + } + + // Validation côté client + const nomValue = $('#societe-nom').val(); + if (!nomValue) { + showMessage('Le nom est obligatoire', 'error'); + return; + } + + // Ajouter l'ID si on modifie + if (currentSocieteId) { + formData.append('societe_id', currentSocieteId); + } + + // Envoyer la requête AJAX + $.ajax({ + url: societesCreditAjax.ajaxurl, + type: 'POST', + data: formData, + processData: false, + contentType: false, + success: function(response) { + if (response.success) { + showMessage(response.data.message, 'success'); + closeSocieteModal(); + + // Recharger la table + if (societesTable) { + societesTable.ajax.reload(null, false); + } + } else { + showMessage('Erreur: ' + response.data, 'error'); + } + }, + error: function() { + showMessage('Erreur de communication avec le serveur', 'error'); + } + }); + }; + + // Supprimer une société + window.deleteSociete = function(societeId) { + if (!confirm('Êtes-vous sûr de vouloir supprimer cette société de crédit ?')) { + return; + } + + $.ajax({ + url: societesCreditAjax.ajaxurl, + type: 'POST', + data: { + action: 'societes_credit_delete', + nonce: societesCreditAjax.nonce, + societe_id: societeId + }, + success: function(response) { + if (response.success) { + showMessage(response.data.message, 'success'); + + // Recharger la table + if (societesTable) { + societesTable.ajax.reload(null, false); + } + } else { + showMessage('Erreur: ' + response.data, 'error'); + } + }, + error: function() { + showMessage('Erreur de communication avec le serveur', 'error'); + } + }); + }; + + // Fermer le modal avec Escape + $(document).on('keydown', function(e) { + if (e.key === 'Escape' && $('.societe-modal').hasClass('show')) { + closeSocieteModal(); + } + }); + + // Soumettre le formulaire avec Enter + $('#societe-form').on('keypress', function(e) { + if (e.key === 'Enter' && e.target.tagName !== 'TEXTAREA') { + e.preventDefault(); + saveSociete(); + } + }); +}); + diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..5343925 --- /dev/null +++ b/composer.json @@ -0,0 +1,17 @@ +{ + "name": "esi/credit-direct", + "description": "Plugin WordPress pour la gestion des crédits", + "type": "wordpress-plugin", + "require": { + "php": ">=7.4", + "nesbot/carbon": "^2.0", + "symfony/translation": "^5.0|^6.0", + "mailchimp/marketing": "^3.0" + }, + "autoload": { + "psr-4": { + "ESI\\CreditDirect\\": "app/" + } + } +} + diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..ae023eb --- /dev/null +++ b/composer.lock @@ -0,0 +1,1242 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "1954df3fa5be7622dc0be452fb6577d6", + "packages": [ + { + "name": "carbonphp/carbon-doctrine-types", + "version": "3.2.0", + "source": { + "type": "git", + "url": "https://github.com/CarbonPHP/carbon-doctrine-types.git", + "reference": "18ba5ddfec8976260ead6e866180bd5d2f71aa1d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/CarbonPHP/carbon-doctrine-types/zipball/18ba5ddfec8976260ead6e866180bd5d2f71aa1d", + "reference": "18ba5ddfec8976260ead6e866180bd5d2f71aa1d", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "conflict": { + "doctrine/dbal": "<4.0.0 || >=5.0.0" + }, + "require-dev": { + "doctrine/dbal": "^4.0.0", + "nesbot/carbon": "^2.71.0 || ^3.0.0", + "phpunit/phpunit": "^10.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Carbon\\Doctrine\\": "src/Carbon/Doctrine/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "KyleKatarn", + "email": "kylekatarnls@gmail.com" + } + ], + "description": "Types to use Carbon in Doctrine", + "keywords": [ + "carbon", + "date", + "datetime", + "doctrine", + "time" + ], + "support": { + "issues": "https://github.com/CarbonPHP/carbon-doctrine-types/issues", + "source": "https://github.com/CarbonPHP/carbon-doctrine-types/tree/3.2.0" + }, + "funding": [ + { + "url": "https://github.com/kylekatarnls", + "type": "github" + }, + { + "url": "https://opencollective.com/Carbon", + "type": "open_collective" + }, + { + "url": "https://tidelift.com/funding/github/packagist/nesbot/carbon", + "type": "tidelift" + } + ], + "time": "2024-02-09T16:56:22+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "7.10.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "b51ac707cfa420b7bfd4e4d5e510ba8008e822b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b51ac707cfa420b7bfd4e4d5e510ba8008e822b4", + "reference": "b51ac707cfa420b7bfd4e4d5e510ba8008e822b4", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^2.3", + "guzzlehttp/psr7": "^2.8", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "provide": { + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "ext-curl": "*", + "guzzle/client-integration-tests": "3.0.2", + "php-http/message-factory": "^1.1", + "phpunit/phpunit": "^8.5.39 || ^9.6.20", + "psr/log": "^1.1 || ^2.0 || ^3.0" + }, + "suggest": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "psr-18", + "psr-7", + "rest", + "web service" + ], + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/7.10.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", + "type": "tidelift" + } + ], + "time": "2025-08-23T22:36:01+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "481557b130ef3790cf82b713667b43030dc9c957" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/481557b130ef3790cf82b713667b43030dc9c957", + "reference": "481557b130ef3790cf82b713667b43030dc9c957", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.44 || ^9.6.25" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/2.3.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2025-08-22T14:34:08+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "2.8.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "21dc724a0583619cd1652f673303492272778051" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/21dc724a0583619cd1652f673303492272778051", + "reference": "21dc724a0583619cd1652f673303492272778051", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0", + "ralouphie/getallheaders": "^3.0" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "http-interop/http-factory-tests": "0.9.0", + "phpunit/phpunit": "^8.5.44 || ^9.6.25" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/2.8.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", + "type": "tidelift" + } + ], + "time": "2025-08-23T21:21:41+00:00" + }, + { + "name": "mailchimp/marketing", + "version": "3.0.80", + "source": { + "type": "git", + "url": "https://github.com/mailchimp/mailchimp-marketing-php.git", + "reference": "c1a38f7248d8de7de412418fed8dae759b9e4b97" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mailchimp/mailchimp-marketing-php/zipball/c1a38f7248d8de7de412418fed8dae759b9e4b97", + "reference": "c1a38f7248d8de7de412418fed8dae759b9e4b97", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "ext-mbstring": "*", + "guzzlehttp/guzzle": "^6.4 || ^7.2", + "guzzlehttp/psr7": "^1.7 || ^2.0", + "php": ">=7.2" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "~2.12", + "phpunit/phpunit": "^7", + "squizlabs/php_codesniffer": "~2.6" + }, + "type": "library", + "autoload": { + "psr-4": { + "MailchimpMarketing\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "proprietary" + ], + "authors": [ + { + "name": "Mailchimp", + "homepage": "https://github.com/mailchimp/mailchimp-marketing-php" + } + ], + "homepage": "http://swagger.io", + "keywords": [ + "api", + "php", + "sdk", + "swagger" + ], + "support": { + "source": "https://github.com/mailchimp/mailchimp-marketing-php/tree/v3.0.80" + }, + "time": "2022-11-02T19:19:48+00:00" + }, + { + "name": "nesbot/carbon", + "version": "2.73.0", + "source": { + "type": "git", + "url": "https://github.com/CarbonPHP/carbon.git", + "reference": "9228ce90e1035ff2f0db84b40ec2e023ed802075" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/9228ce90e1035ff2f0db84b40ec2e023ed802075", + "reference": "9228ce90e1035ff2f0db84b40ec2e023ed802075", + "shasum": "" + }, + "require": { + "carbonphp/carbon-doctrine-types": "*", + "ext-json": "*", + "php": "^7.1.8 || ^8.0", + "psr/clock": "^1.0", + "symfony/polyfill-mbstring": "^1.0", + "symfony/polyfill-php80": "^1.16", + "symfony/translation": "^3.4 || ^4.0 || ^5.0 || ^6.0" + }, + "provide": { + "psr/clock-implementation": "1.0" + }, + "require-dev": { + "doctrine/dbal": "^2.0 || ^3.1.4 || ^4.0", + "doctrine/orm": "^2.7 || ^3.0", + "friendsofphp/php-cs-fixer": "^3.0", + "kylekatarnls/multi-tester": "^2.0", + "ondrejmirtes/better-reflection": "<6", + "phpmd/phpmd": "^2.9", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^0.12.99 || ^1.7.14", + "phpunit/php-file-iterator": "^2.0.5 || ^3.0.6", + "phpunit/phpunit": "^7.5.20 || ^8.5.26 || ^9.5.20", + "squizlabs/php_codesniffer": "^3.4" + }, + "bin": [ + "bin/carbon" + ], + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Carbon\\Laravel\\ServiceProvider" + ] + }, + "phpstan": { + "includes": [ + "extension.neon" + ] + }, + "branch-alias": { + "dev-2.x": "2.x-dev", + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Carbon\\": "src/Carbon/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Brian Nesbitt", + "email": "brian@nesbot.com", + "homepage": "https://markido.com" + }, + { + "name": "kylekatarnls", + "homepage": "https://github.com/kylekatarnls" + } + ], + "description": "An API extension for DateTime that supports 281 different languages.", + "homepage": "https://carbon.nesbot.com", + "keywords": [ + "date", + "datetime", + "time" + ], + "support": { + "docs": "https://carbon.nesbot.com/docs", + "issues": "https://github.com/briannesbitt/Carbon/issues", + "source": "https://github.com/briannesbitt/Carbon" + }, + "funding": [ + { + "url": "https://github.com/sponsors/kylekatarnls", + "type": "github" + }, + { + "url": "https://opencollective.com/Carbon#sponsor", + "type": "opencollective" + }, + { + "url": "https://tidelift.com/subscription/pkg/packagist-nesbot-carbon?utm_source=packagist-nesbot-carbon&utm_medium=referral&utm_campaign=readme", + "type": "tidelift" + } + ], + "time": "2025-01-08T20:10:23+00:00" + }, + { + "name": "psr/clock", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/clock.git", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Psr\\Clock\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for reading the clock.", + "homepage": "https://github.com/php-fig/clock", + "keywords": [ + "clock", + "now", + "psr", + "psr-20", + "time" + ], + "support": { + "issues": "https://github.com/php-fig/clock/issues", + "source": "https://github.com/php-fig/clock/tree/1.0.0" + }, + "time": "2022-11-25T14:36:26+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client" + }, + "time": "2023-09-23T14:17:50+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory" + }, + "time": "2024-04-15T12:06:14+00:00" + }, + { + "name": "psr/http-message", + "version": "2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/2.0" + }, + "time": "2023-04-04T09:54:51+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:21:43+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "php": ">=7.2" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-23T08:48:59+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608", + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-01-02T08:10:11+00:00" + }, + { + "name": "symfony/translation", + "version": "v6.4.26", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", + "reference": "c8559fe25c7ee7aa9d28f228903a46db008156a4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation/zipball/c8559fe25c7ee7aa9d28f228903a46db008156a4", + "reference": "c8559fe25c7ee7aa9d28f228903a46db008156a4", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/translation-contracts": "^2.5|^3.0" + }, + "conflict": { + "symfony/config": "<5.4", + "symfony/console": "<5.4", + "symfony/dependency-injection": "<5.4", + "symfony/http-client-contracts": "<2.5", + "symfony/http-kernel": "<5.4", + "symfony/service-contracts": "<2.5", + "symfony/twig-bundle": "<5.4", + "symfony/yaml": "<5.4" + }, + "provide": { + "symfony/translation-implementation": "2.3|3.0" + }, + "require-dev": { + "nikic/php-parser": "^4.18|^5.0", + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/http-client-contracts": "^2.5|^3.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/intl": "^5.4|^6.0|^7.0", + "symfony/polyfill-intl-icu": "^1.21", + "symfony/routing": "^5.4|^6.0|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/yaml": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\Translation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools to internationalize your application", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/translation/tree/v6.4.26" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-09-05T18:17:25+00:00" + }, + { + "name": "symfony/translation-contracts", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation-contracts.git", + "reference": "df210c7a2573f1913b2d17cc95f90f53a73d8f7d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/df210c7a2573f1913b2d17cc95f90f53a73d8f7d", + "reference": "df210c7a2573f1913b2d17cc95f90f53a73d8f7d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Translation\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to translation", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/translation-contracts/tree/v3.6.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-27T08:32:26+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=7.4" + }, + "platform-dev": [], + "plugin-api-version": "2.6.0" +} diff --git a/cred_init.php b/cred_init.php new file mode 100644 index 0000000..1ed5612 --- /dev/null +++ b/cred_init.php @@ -0,0 +1,122 @@ +load_actions(); + $factory->load_filters(); + + // Charger le système de rappel de crédit + self::import('app.models.credit'); + /* self::import('app.libraries.credit-reminder'); */ + + // Charger les shortcodes + self::import('app.controllers.shortcodes'); + + // Charger le gestionnaire de crédits + self::import('app.controllers.credit_manager'); + } +} \ No newline at end of file diff --git a/crons/crons_autoloader.php b/crons/crons_autoloader.php new file mode 100644 index 0000000..752a0b3 --- /dev/null +++ b/crons/crons_autoloader.php @@ -0,0 +1,12 @@ +init(); + + diff --git a/crons/crons_reminder.php b/crons/crons_reminder.php new file mode 100644 index 0000000..f47c079 --- /dev/null +++ b/crons/crons_reminder.php @@ -0,0 +1,11 @@ +send_reminder_email(); + +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..ac04d6d --- /dev/null +++ b/package-lock.json @@ -0,0 +1,37 @@ +{ + "name": "ESI_creditDirect", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "datatables.net-dt": "^2.3.4" + } + }, + "node_modules/datatables.net": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/datatables.net/-/datatables.net-2.3.4.tgz", + "integrity": "sha512-fKuRlrBIdpAl2uIFgl9enKecHB41QmFd/2nN9LBbOvItV/JalAxLcyqdZXex7wX4ZXjnJQEnv6xeS9veOpKzSw==", + "license": "MIT", + "dependencies": { + "jquery": ">=1.7" + } + }, + "node_modules/datatables.net-dt": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/datatables.net-dt/-/datatables.net-dt-2.3.4.tgz", + "integrity": "sha512-qOCnnUuFTiju4AOMM4xy4Lx87UfyHdIHIMYdbBXD4pAtvoWTH9wMzVTN/2gFNT4GlbrLkmGf5ZkU6uLRTTymMA==", + "license": "MIT", + "dependencies": { + "datatables.net": "2.3.4", + "jquery": ">=1.7" + } + }, + "node_modules/jquery": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", + "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==", + "license": "MIT" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..5dc8c9e --- /dev/null +++ b/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "datatables.net-dt": "^2.3.4" + } +} diff --git a/templates/admin/credit_import.php b/templates/admin/credit_import.php new file mode 100644 index 0000000..d2807bc --- /dev/null +++ b/templates/admin/credit_import.php @@ -0,0 +1,70 @@ + + +
    +

    Import de crédits

    + +

    Importez un fichier CSV conforme au modèle modèle mailing.csv. Séparateur attendu: point-virgule (;).

    + + +
    +

    Erreurs d'import:

    +
      + +
    • + +
    +
    + + + +
    +

    Import terminé.

    +

    Enregistrements insérés: | Ignorés/Erreurs:

    +
    + + + + + + + + + + + + + + + + + + + + + + +

    + + Retour à la liste +

    + +
    + + + diff --git a/templates/admin/credit_manager_table.php b/templates/admin/credit_manager_table.php new file mode 100644 index 0000000..66b4368 --- /dev/null +++ b/templates/admin/credit_manager_table.php @@ -0,0 +1,355 @@ + + +
    +

    Gestion des crédits

    + + +
    + +
    + + +
    +

    + Filtres + +

    + +
    + + +
    +

    Filtres rapides par statut

    +
    + + + + + + + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    IDTypeNomPrénomAdresseLocalitéEmailTéléphone/GSMSociété de créditMontantDateSignatureN° de dossierCodeStatutActions
    + + + +
    + + + + + \ No newline at end of file diff --git a/templates/admin/mailchimp_settings.php b/templates/admin/mailchimp_settings.php new file mode 100644 index 0000000..9024685 --- /dev/null +++ b/templates/admin/mailchimp_settings.php @@ -0,0 +1,46 @@ + +
    +

    + +
    + +
    + +
    + +

    +

    + +

    +
    composer require mailchimp/marketing
    +

    + mailchimp/mailchimp-marketing-php', 'esi-creditdirect'), + esc_url('https://github.com/mailchimp/mailchimp-marketing-php') + )); ?> +

    + +
    + +

    +

    + + +
    + + + + diff --git a/templates/admin/sendy_settings.php b/templates/admin/sendy_settings.php new file mode 100644 index 0000000..b8364da --- /dev/null +++ b/templates/admin/sendy_settings.php @@ -0,0 +1,48 @@ + +
    +

    + +
    + +
    + +
    + +

    +

    + +

    +
      +
    • +
    • API', 'esi-creditdirect'); ?>
    • +
    • +
    +

    + sendy.co', 'esi-creditdirect'), + esc_url('https://sendy.co') + )); ?> +

    + +
    + +

    +

    + + +
    + + diff --git a/templates/admin/societes_credit_table.php b/templates/admin/societes_credit_table.php new file mode 100644 index 0000000..412f14e --- /dev/null +++ b/templates/admin/societes_credit_table.php @@ -0,0 +1,161 @@ + + +
    +

    Gestion des Sociétés de Crédit

    + + +
    + +
    + + + + + + + + + + + + + + +
    IDNom de la sociétéStatusActions
    + + + +
    + + + + + diff --git a/templates/credit-step3.php b/templates/credit-step3.php new file mode 100644 index 0000000..54ddc9d --- /dev/null +++ b/templates/credit-step3.php @@ -0,0 +1,224 @@ + + +
    +
    +
    +

    Introduction de votre demande de crédit

    +
    +
    +
    + + + +
    +
    +
    +
    + +
    +
    + 1 + Contact +
    +
    + 2 + Revenus & charges +
    +
    + 3 + Informations personnelles +
    +
    + 4 + Coordonnées +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    + Emprunteur + Données personnelles +
    + + +
    +
    + + +
    +
    + + 'Belgique', + 'LU' => 'Luxembourg', + 'FR' => 'France', + 'DE' => 'Allemagne', + 'NL' => 'Pays-Bas', + ]; + // Liste de traduction FR pour les autres pays (extrait, à compléter si besoin) + $country_fr = [ + 'AD' => 'Andorre', 'AL' => 'Albanie', 'AT' => 'Autriche', 'BA' => 'Bosnie-Herzégovine', 'BG' => 'Bulgarie', 'BY' => 'Biélorussie', 'CH' => 'Suisse', 'CZ' => 'Tchéquie', 'DK' => 'Danemark', 'EE' => 'Estonie', 'ES' => 'Espagne', 'FI' => 'Finlande', 'GB' => 'Royaume-Uni', 'GR' => 'Grèce', 'HR' => 'Croatie', 'HU' => 'Hongrie', 'IE' => 'Irlande', 'IS' => 'Islande', 'IT' => 'Italie', 'LT' => 'Lituanie', 'LV' => 'Lettonie', 'MC' => 'Monaco', 'MD' => 'Moldavie', 'ME' => 'Monténégro', 'MK' => 'Macédoine du Nord', 'MT' => 'Malte', 'NO' => 'Norvège', 'PL' => 'Pologne', 'PT' => 'Portugal', 'RO' => 'Roumanie', 'RS' => 'Serbie', 'RU' => 'Russie', 'SE' => 'Suède', 'SI' => 'Slovénie', 'SK' => 'Slovaquie', 'SM' => 'Saint-Marin', 'UA' => 'Ukraine', 'VA' => 'Vatican', + // ... compléter si besoin ... + ]; + // Liste CSV (code => nom anglais) + $csv_countries = [ + 'AD' => 'Andorra', 'AE' => 'United Arab Emirates', 'AF' => 'Afghanistan', 'AG' => 'Antigua and Barbuda', 'AI' => 'Anguilla', 'AL' => 'Albania', 'AM' => 'Armenia', 'AN' => 'Netherlands Antilles', 'AO' => 'Angola', 'AQ' => 'Antarctica', 'AR' => 'Argentina', 'AS' => 'American Samoa', 'AT' => 'Austria', 'AU' => 'Australia', 'AW' => 'Aruba', 'AZ' => 'Azerbaijan', 'BA' => 'Bosnia and Herzegovina', 'BB' => 'Barbados', 'BD' => 'Bangladesh', 'BE' => 'Belgium', 'BF' => 'Burkina Faso', 'BG' => 'Bulgaria', 'BH' => 'Bahrain', 'BI' => 'Burundi', 'BJ' => 'Benin', 'BM' => 'Bermuda', 'BN' => 'Brunei', 'BO' => 'Bolivia', 'BR' => 'Brazil', 'BS' => 'Bahamas', 'BT' => 'Bhutan', 'BV' => 'Bouvet Island', 'BW' => 'Botswana', 'BY' => 'Belarus', 'BZ' => 'Belize', 'CA' => 'Canada', 'CC' => 'Cocos [Keeling] Islands', 'CD' => 'Congo [DRC]', 'CF' => 'Central African Republic', 'CG' => 'Congo [Republic]', 'CH' => 'Switzerland', 'CI' => +"Côte d'Ivoire", 'CK' => 'Cook Islands', 'CL' => 'Chile', 'CM' => 'Cameroon', 'CN' => 'China', 'CO' => 'Colombia', 'CR' => 'Costa Rica', 'CU' => 'Cuba', 'CV' => 'Cape Verde', 'CX' => 'Christmas Island', 'CY' => 'Cyprus', 'CZ' => 'Czech Republic', 'DE' => 'Germany', 'DJ' => 'Djibouti', 'DK' => 'Denmark', 'DM' => 'Dominica', 'DO' => 'Dominican Republic', 'DZ' => 'Algeria', 'EC' => 'Ecuador', 'EE' => 'Estonia', 'EG' => 'Egypt', 'EH' => 'Western Sahara', 'ER' => 'Eritrea', 'ES' => 'Spain', 'ET' => 'Ethiopia', 'FI' => 'Finland', 'FJ' => 'Fiji', 'FK' => 'Falkland Islands [Islas Malvinas]', 'FM' => 'Micronesia', 'FO' => 'Faroe Islands', 'FR' => 'France', 'GA' => 'Gabon', 'GB' => 'United Kingdom', 'GD' => 'Grenada', 'GE' => 'Georgia', 'GF' => 'French Guiana', 'GG' => 'Guernsey', 'GH' => 'Ghana', 'GI' => 'Gibraltar', 'GL' => 'Greenland', 'GM' => 'Gambia', 'GN' => 'Guinea', 'GP' => 'Guadeloupe', 'GQ' => 'Equatorial Guinea', 'GR' => 'Greece', 'GS' => 'South Georgia and the South Sandwich Islands', 'GT' => 'Guatemala', 'GU' => 'Guam', 'GW' => 'Guinea-Bissau', 'GY' => 'Guyana', 'GZ' => 'Gaza Strip', 'HK' => 'Hong Kong', 'HM' => 'Heard Island and McDonald Islands', 'HN' => 'Honduras', 'HR' => 'Croatia', 'HT' => 'Haiti', 'HU' => 'Hungary', 'ID' => 'Indonesia', 'IE' => 'Ireland', 'IL' => 'Israel', 'IM' => 'Isle of Man', 'IN' => 'India', 'IO' => 'British Indian Ocean Territory', 'IQ' => 'Iraq', 'IR' => 'Iran', 'IS' => 'Iceland', 'IT' => 'Italy', 'JE' => 'Jersey', 'JM' => 'Jamaica', 'JO' => 'Jordan', 'JP' => 'Japan', 'KE' => 'Kenya', 'KG' => 'Kyrgyzstan', 'KH' => 'Cambodia', 'KI' => 'Kiribati', 'KM' => 'Comoros', 'KN' => 'Saint Kitts and Nevis', 'KP' => 'North Korea', 'KR' => 'South Korea', 'KW' => 'Kuwait', 'KY' => 'Cayman Islands', 'KZ' => 'Kazakhstan', 'LA' => 'Laos', 'LB' => 'Lebanon', 'LC' => 'Saint Lucia', 'LI' => 'Liechtenstein', 'LK' => 'Sri Lanka', 'LR' => 'Liberia', 'LS' => 'Lesotho', 'LT' => 'Lithuania', 'LU' => 'Luxembourg', 'LV' => 'Latvia', 'LY' => 'Libya', 'MA' => 'Morocco', 'MC' => 'Monaco', 'MD' => 'Moldova', 'ME' => 'Montenegro', 'MG' => 'Madagascar', 'MH' => 'Marshall Islands', 'MK' => 'Macedonia [FYROM]', 'ML' => 'Mali', 'MM' => 'Myanmar [Burma]', 'MN' => 'Mongolia', 'MO' => 'Macau', 'MP' => 'Northern Mariana Islands', 'MQ' => 'Martinique', 'MR' => 'Mauritania', 'MS' => 'Montserrat', 'MT' => 'Malta', 'MU' => 'Mauritius', 'MV' => 'Maldives', 'MW' => 'Malawi', 'MX' => 'Mexico', 'MY' => 'Malaysia', 'MZ' => 'Mozambique', 'NA' => 'Namibia', 'NC' => 'New Caledonia', 'NE' => 'Niger', 'NF' => 'Norfolk Island', 'NG' => 'Nigeria', 'NI' => 'Nicaragua', 'NL' => 'Netherlands', 'NO' => 'Norway', 'NP' => 'Nepal', 'NR' => 'Nauru', 'NU' => 'Niue', 'NZ' => 'New Zealand', 'OM' => 'Oman', 'PA' => 'Panama', 'PE' => 'Peru', 'PF' => 'French Polynesia', 'PG' => 'Papua New Guinea', 'PH' => 'Philippines', 'PK' => 'Pakistan', 'PL' => 'Poland', 'PM' => 'Saint Pierre and Miquelon', 'PN' => 'Pitcairn Islands', 'PR' => 'Puerto Rico', 'PS' => 'Palestinian Territories', 'PT' => 'Portugal', 'PW' => 'Palau', 'PY' => 'Paraguay', 'QA' => 'Qatar', 'RE' => 'Réunion', 'RO' => 'Romania', 'RS' => 'Serbia', 'RU' => 'Russia', 'RW' => 'Rwanda', 'SA' => 'Saudi Arabia', 'SB' => 'Solomon Islands', 'SC' => 'Seychelles', 'SD' => 'Sudan', 'SE' => 'Sweden', 'SG' => 'Singapore', 'SH' => 'Saint Helena', 'SI' => 'Slovenia', 'SJ' => 'Svalbard and Jan Mayen', 'SK' => 'Slovakia', 'SL' => 'Sierra Leone', 'SM' => 'San Marino', 'SN' => 'Senegal', 'SO' => 'Somalia', 'SR' => 'Suriname', 'ST' => 'São Tomé and Príncipe', 'SV' => 'El Salvador', 'SY' => 'Syria', 'SZ' => 'Swaziland', 'TC' => 'Turks and Caicos Islands', 'TD' => 'Chad', 'TF' => 'French Southern Territories', 'TG' => 'Togo', 'TH' => 'Thailand', 'TJ' => 'Tajikistan', 'TK' => 'Tokelau', 'TL' => 'Timor-Leste', 'TM' => 'Turkmenistan', 'TN' => 'Tunisia', 'TO' => 'Tonga', 'TR' => 'Turkey', 'TT' => 'Trinidad and Tobago', 'TV' => 'Tuvalu', 'TW' => 'Taiwan', 'TZ' => 'Tanzania', 'UA' => 'Ukraine', 'UG' => 'Uganda', 'UM' => 'U.S. Minor Outlying Islands', 'US' => 'United States', 'UY' => 'Uruguay', 'UZ' => 'Uzbekistan', 'VA' => 'Vatican City', 'VC' => 'Saint Vincent and the Grenadines', 'VE' => 'Venezuela', 'VG' => 'British Virgin Islands', 'VI' => 'U.S. Virgin Islands', 'VN' => 'Vietnam', 'VU' => 'Vanuatu', 'WF' => 'Wallis and Futuna', 'WS' => 'Samoa', 'XK' => 'Kosovo', 'YE' => 'Yemen', 'YT' => 'Mayotte', 'ZA' => 'South Africa', 'ZM' => 'Zambia', 'ZW' => 'Zimbabwe', + ]; + // Construction du tableau final pour le 2e groupe + $other_countries = []; + foreach ($csv_countries as $code => $en_name) { + if (!isset($main_countries[$code])) { + $label = isset($country_fr[$code]) ? $country_fr[$code] : $en_name; + $other_countries[$code] = $label; + } + } + asort($other_countries, SORT_LOCALE_STRING); + // Persistance de la sélection + $selected = $model->getFieldValue('nationalite', $borrower); + ?> + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    + + +
    +
    + Co-Emprunteur + Données personnelles-- +
    + + +
    +
    + + +
    +
    + + 'Belgique', + 'LU' => 'Luxembourg', + 'FR' => 'France', + 'DE' => 'Allemagne', + 'NL' => 'Pays-Bas', + ]; + // Liste de traduction FR pour les autres pays (extrait, à compléter si besoin) + $country_fr = [ + 'AD' => 'Andorre', 'AL' => 'Albanie', 'AT' => 'Autriche', 'BA' => 'Bosnie-Herzégovine', 'BG' => 'Bulgarie', 'BY' => 'Biélorussie', 'CH' => 'Suisse', 'CZ' => 'Tchéquie', 'DK' => 'Danemark', 'EE' => 'Estonie', 'ES' => 'Espagne', 'FI' => 'Finlande', 'GB' => 'Royaume-Uni', 'GR' => 'Grèce', 'HR' => 'Croatie', 'HU' => 'Hongrie', 'IE' => 'Irlande', 'IS' => 'Islande', 'IT' => 'Italie', 'LT' => 'Lituanie', 'LV' => 'Lettonie', 'MC' => 'Monaco', 'MD' => 'Moldavie', 'ME' => 'Monténégro', 'MK' => 'Macédoine du Nord', 'MT' => 'Malte', 'NO' => 'Norvège', 'PL' => 'Pologne', 'PT' => 'Portugal', 'RO' => 'Roumanie', 'RS' => 'Serbie', 'RU' => 'Russie', 'SE' => 'Suède', 'SI' => 'Slovénie', 'SK' => 'Slovaquie', 'SM' => 'Saint-Marin', 'UA' => 'Ukraine', 'VA' => 'Vatican', + // ... compléter si besoin ... + ]; + // Liste CSV (code => nom anglais) + $csv_countries = [ + 'AD' => 'Andorra', 'AE' => 'United Arab Emirates', 'AF' => 'Afghanistan', 'AG' => 'Antigua and Barbuda', 'AI' => 'Anguilla', 'AL' => 'Albania', 'AM' => 'Armenia', 'AN' => 'Netherlands Antilles', 'AO' => 'Angola', 'AQ' => 'Antarctica', 'AR' => 'Argentina', 'AS' => 'American Samoa', 'AT' => 'Austria', 'AU' => 'Australia', 'AW' => 'Aruba', 'AZ' => 'Azerbaijan', 'BA' => 'Bosnia and Herzegovina', 'BB' => 'Barbados', 'BD' => 'Bangladesh', 'BE' => 'Belgium', 'BF' => 'Burkina Faso', 'BG' => 'Bulgaria', 'BH' => 'Bahrain', 'BI' => 'Burundi', 'BJ' => 'Benin', 'BM' => 'Bermuda', 'BN' => 'Brunei', 'BO' => 'Bolivia', 'BR' => 'Brazil', 'BS' => 'Bahamas', 'BT' => 'Bhutan', 'BV' => 'Bouvet Island', 'BW' => 'Botswana', 'BY' => 'Belarus', 'BZ' => 'Belize', 'CA' => 'Canada', 'CC' => 'Cocos [Keeling] Islands', 'CD' => 'Congo [DRC]', 'CF' => 'Central African Republic', 'CG' => 'Congo [Republic]', 'CH' => 'Switzerland', 'CI' => +"Côte d'Ivoire", 'CK' => 'Cook Islands', 'CL' => 'Chile', 'CM' => 'Cameroon', 'CN' => 'China', 'CO' => 'Colombia', 'CR' => 'Costa Rica', 'CU' => 'Cuba', 'CV' => 'Cape Verde', 'CX' => 'Christmas Island', 'CY' => 'Cyprus', 'CZ' => 'Czech Republic', 'DE' => 'Germany', 'DJ' => 'Djibouti', 'DK' => 'Denmark', 'DM' => 'Dominica', 'DO' => 'Dominican Republic', 'DZ' => 'Algeria', 'EC' => 'Ecuador', 'EE' => 'Estonia', 'EG' => 'Egypt', 'EH' => 'Western Sahara', 'ER' => 'Eritrea', 'ES' => 'Spain', 'ET' => 'Ethiopia', 'FI' => 'Finland', 'FJ' => 'Fiji', 'FK' => 'Falkland Islands [Islas Malvinas]', 'FM' => 'Micronesia', 'FO' => 'Faroe Islands', 'FR' => 'France', 'GA' => 'Gabon', 'GB' => 'United Kingdom', 'GD' => 'Grenada', 'GE' => 'Georgia', 'GF' => 'French Guiana', 'GG' => 'Guernsey', 'GH' => 'Ghana', 'GI' => 'Gibraltar', 'GL' => 'Greenland', 'GM' => 'Gambia', 'GN' => 'Guinea', 'GP' => 'Guadeloupe', 'GQ' => 'Equatorial Guinea', 'GR' => 'Greece', 'GS' => 'South Georgia and the South Sandwich Islands', 'GT' => 'Guatemala', 'GU' => 'Guam', 'GW' => 'Guinea-Bissau', 'GY' => 'Guyana', 'GZ' => 'Gaza Strip', 'HK' => 'Hong Kong', 'HM' => 'Heard Island and McDonald Islands', 'HN' => 'Honduras', 'HR' => 'Croatia', 'HT' => 'Haiti', 'HU' => 'Hungary', 'ID' => 'Indonesia', 'IE' => 'Ireland', 'IL' => 'Israel', 'IM' => 'Isle of Man', 'IN' => 'India', 'IO' => 'British Indian Ocean Territory', 'IQ' => 'Iraq', 'IR' => 'Iran', 'IS' => 'Iceland', 'IT' => 'Italy', 'JE' => 'Jersey', 'JM' => 'Jamaica', 'JO' => 'Jordan', 'JP' => 'Japan', 'KE' => 'Kenya', 'KG' => 'Kyrgyzstan', 'KH' => 'Cambodia', 'KI' => 'Kiribati', 'KM' => 'Comoros', 'KN' => 'Saint Kitts and Nevis', 'KP' => 'North Korea', 'KR' => 'South Korea', 'KW' => 'Kuwait', 'KY' => 'Cayman Islands', 'KZ' => 'Kazakhstan', 'LA' => 'Laos', 'LB' => 'Lebanon', 'LC' => 'Saint Lucia', 'LI' => 'Liechtenstein', 'LK' => 'Sri Lanka', 'LR' => 'Liberia', 'LS' => 'Lesotho', 'LT' => 'Lithuania', 'LU' => 'Luxembourg', 'LV' => 'Latvia', 'LY' => 'Libya', 'MA' => 'Morocco', 'MC' => 'Monaco', 'MD' => 'Moldova', 'ME' => 'Montenegro', 'MG' => 'Madagascar', 'MH' => 'Marshall Islands', 'MK' => 'Macedonia [FYROM]', 'ML' => 'Mali', 'MM' => 'Myanmar [Burma]', 'MN' => 'Mongolia', 'MO' => 'Macau', 'MP' => 'Northern Mariana Islands', 'MQ' => 'Martinique', 'MR' => 'Mauritania', 'MS' => 'Montserrat', 'MT' => 'Malta', 'MU' => 'Mauritius', 'MV' => 'Maldives', 'MW' => 'Malawi', 'MX' => 'Mexico', 'MY' => 'Malaysia', 'MZ' => 'Mozambique', 'NA' => 'Namibia', 'NC' => 'New Caledonia', 'NE' => 'Niger', 'NF' => 'Norfolk Island', 'NG' => 'Nigeria', 'NI' => 'Nicaragua', 'NL' => 'Netherlands', 'NO' => 'Norway', 'NP' => 'Nepal', 'NR' => 'Nauru', 'NU' => 'Niue', 'NZ' => 'New Zealand', 'OM' => 'Oman', 'PA' => 'Panama', 'PE' => 'Peru', 'PF' => 'French Polynesia', 'PG' => 'Papua New Guinea', 'PH' => 'Philippines', 'PK' => 'Pakistan', 'PL' => 'Poland', 'PM' => 'Saint Pierre and Miquelon', 'PN' => 'Pitcairn Islands', 'PR' => 'Puerto Rico', 'PS' => 'Palestinian Territories', 'PT' => 'Portugal', 'PW' => 'Palau', 'PY' => 'Paraguay', 'QA' => 'Qatar', 'RE' => 'Réunion', 'RO' => 'Romania', 'RS' => 'Serbia', 'RU' => 'Russia', 'RW' => 'Rwanda', 'SA' => 'Saudi Arabia', 'SB' => 'Solomon Islands', 'SC' => 'Seychelles', 'SD' => 'Sudan', 'SE' => 'Sweden', 'SG' => 'Singapore', 'SH' => 'Saint Helena', 'SI' => 'Slovenia', 'SJ' => 'Svalbard and Jan Mayen', 'SK' => 'Slovakia', 'SL' => 'Sierra Leone', 'SM' => 'San Marino', 'SN' => 'Senegal', 'SO' => 'Somalia', 'SR' => 'Suriname', 'ST' => 'São Tomé and Príncipe', 'SV' => 'El Salvador', 'SY' => 'Syria', 'SZ' => 'Swaziland', 'TC' => 'Turks and Caicos Islands', 'TD' => 'Chad', 'TF' => 'French Southern Territories', 'TG' => 'Togo', 'TH' => 'Thailand', 'TJ' => 'Tajikistan', 'TK' => 'Tokelau', 'TL' => 'Timor-Leste', 'TM' => 'Turkmenistan', 'TN' => 'Tunisia', 'TO' => 'Tonga', 'TR' => 'Turkey', 'TT' => 'Trinidad and Tobago', 'TV' => 'Tuvalu', 'TW' => 'Taiwan', 'TZ' => 'Tanzania', 'UA' => 'Ukraine', 'UG' => 'Uganda', 'UM' => 'U.S. Minor Outlying Islands', 'US' => 'United States', 'UY' => 'Uruguay', 'UZ' => 'Uzbekistan', 'VA' => 'Vatican City', 'VC' => 'Saint Vincent and the Grenadines', 'VE' => 'Venezuela', 'VG' => 'British Virgin Islands', 'VI' => 'U.S. Virgin Islands', 'VN' => 'Vietnam', 'VU' => 'Vanuatu', 'WF' => 'Wallis and Futuna', 'WS' => 'Samoa', 'XK' => 'Kosovo', 'YE' => 'Yemen', 'YT' => 'Mayotte', 'ZA' => 'South Africa', 'ZM' => 'Zambia', 'ZW' => 'Zimbabwe', + ]; + // Construction du tableau final pour le 2e groupe + $other_countries = []; + foreach ($csv_countries as $code => $en_name) { + if (!isset($main_countries[$code])) { + $label = isset($country_fr[$code]) ? $country_fr[$code] : $en_name; + $other_countries[$code] = $label; + } + } + asort($other_countries, SORT_LOCALE_STRING); + // Persistance de la sélection + $selected = isset($_POST['conationality']) ? $_POST['conationality'] : ''; + ?> + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    + +
    +
    +
    + Étape précédente + +
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/templates/email/clients_emails/_credit-step4-mail_client.php b/templates/email/clients_emails/_credit-step4-mail_client.php new file mode 100644 index 0000000..5ced479 --- /dev/null +++ b/templates/email/clients_emails/_credit-step4-mail_client.php @@ -0,0 +1,340 @@ + + + + + Demande de crédit + + + + + + + + + +
    + + + + + + + + +
    + + \ No newline at end of file diff --git a/templates/email/clients_emails/credit-one-step-mail-client.php b/templates/email/clients_emails/credit-one-step-mail-client.php new file mode 100644 index 0000000..3d7a1b6 --- /dev/null +++ b/templates/email/clients_emails/credit-one-step-mail-client.php @@ -0,0 +1,487 @@ + + + + + Demande de crédit + + + + + + + + + +
    + + + + + + + + + + + + + + +
    + + \ No newline at end of file diff --git a/templates/email/clients_emails/credit-step2-mail-client.php b/templates/email/clients_emails/credit-step2-mail-client.php new file mode 100644 index 0000000..93b05a1 --- /dev/null +++ b/templates/email/clients_emails/credit-step2-mail-client.php @@ -0,0 +1,330 @@ + + + + + Demande de crédit + + + + + + + + + +
    + + + + + + + + + + + + + + +
    + + diff --git a/templates/email/clients_emails/credit-step4-mail-client.php b/templates/email/clients_emails/credit-step4-mail-client.php new file mode 100644 index 0000000..cb07d7c --- /dev/null +++ b/templates/email/clients_emails/credit-step4-mail-client.php @@ -0,0 +1,522 @@ + + + + + Demande de crédit + + + + + + + + + +
    + + + + + + + + + + + +
    + + \ No newline at end of file diff --git a/templates/email/credit-one-step-mail-inter.php b/templates/email/credit-one-step-mail-inter.php new file mode 100644 index 0000000..867d259 --- /dev/null +++ b/templates/email/credit-one-step-mail-inter.php @@ -0,0 +1,113 @@ + $borrower, +]; + +if (is_object($coBorrower)) { + $people['coemprunteur'] = $coBorrower; +} +?> + $person) : ?> + + + +

    + + + + + + + Nom: + nom ?> + + + + Prenom: + prenom ?> + + + + + Telephone: + telephone ?> + + + + Email: + email ?> + + + + Agence: + FK_agence, $agencies) ? $agencies[$person->FK_agence]->Nom_agence : 'Agence inconnue' ?> + + + + + Etat civil: + FK_etat_civil, $civilStatus) ? $civilStatus[$person->FK_etat_civil]->nom_etat_civil : 'etat civil inconnu' ?> + + + + Date de naissance: + date_naissance ?> + + + + Nationalite: + nationalité ?> + + + + Adresse: + adresse ?> + + + + Code Postal: + code_postal ?> + + + + Localite - Pays: + localite ?> - pays ?> + + + +

    Revenus et charges

    + + + FK_profession, $works) ? $works[$person->FK_profession]->nom_profession : 'Profession inconnue' ?> + + Profession: + + + + + Type de contrat: + + contract_type) || $person->contract_type === ''): ?> + Non specifie + contract_type, $contractTypes)): ?> + contract_type] ?> + + Type de contrat de travail inconnu + + + + + + + : + salaire ?> € + + + + + Avec un co-emprunteur: + + + + + \ No newline at end of file diff --git a/templates/email/credit-one-step-mail.php b/templates/email/credit-one-step-mail.php new file mode 100644 index 0000000..44562a2 --- /dev/null +++ b/templates/email/credit-one-step-mail.php @@ -0,0 +1,487 @@ + + + + + Demande de crédit + + + + + + + + + +
    + + + + + + + + + + + +
    + + \ No newline at end of file diff --git a/templates/email/credit-one-step-mail_client.php b/templates/email/credit-one-step-mail_client.php new file mode 100644 index 0000000..b7ed5f3 --- /dev/null +++ b/templates/email/credit-one-step-mail_client.php @@ -0,0 +1,229 @@ + + + + + Demande de crédit + + +
    +
    + Crédit Direct +
    +
    + 'Locataire', + 'owner' => 'Proprietaire', + 'withoutrentalcharge' => 'Sans charge locative' +]; + +$map_credit_hypothecaire_en_cours = [ + 'withmortgageloan' => 'Avec credit hypothecaire', + 'mortgagechargeiber' => 'Libre de charge hypothecaire' +]; + +$map_sans_charge_locative = [ + 'other' => 'Autre', + 'withparents' => 'Chez les parents', + 'cohabitant' => 'Cohabitant', + 'family' => 'Famille' +]; + +$map_emprunt_personnes = [ + 'Seul','Avec un co-emprunteur' +]; + +$show_all_mail = false; + +$people = [ + 'emprunteur' => $borrower, +]; + +if (is_object($coBorrower)) { + $people['coemprunteur'] = $coBorrower; +} + +$taeg = str_replace('%', '', $currentCredit->taux_nominal_annuel); +$taux_debiteur = number_format(($taeg * 0.11) + $taeg, 2); + +if($currentCredit->type_credit == 'pat') + $show_all_mail = true; + +?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $person) : ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FK_profession, $works) ? $works[$person->FK_profession]->nom_profession : 'Profession inconnue' ?> + + + + + + + + + + + + + + + + + + + + +
    +

    Demande de crédit

    +
    Type de crédit:type_credit, $map_credit_type) ? $map_credit_type[$currentCredit->type_credit] : 'Type de crédit inconnu' ?>
    Capital:capital ?> €
    Durée:duree ?> type_credit === 'am'): ?>ansmois
    Coût total:cout_total ?> €
    Mensualité:mensualite ?> €
    Taux nominal annuel:taux_nominal_annuel ?>
    TAEG:%
    +

    Crédit hypothécaire

    +
    But du prêt hypotécaire :options_credit_hypothecaire->type_credit, $mapHouseCreditTypes) ? $mapHouseCreditTypes[$currentCredit->options_credit_hypothecaire->type_credit] : 'Type de crédit inconnu' ?>
    Prix d'achat:options_credit_hypothecaire->prix_achat ?> €
    Compromis de vente signé: + options_credit_hypothecaire->compromis_signe == '0') { + echo 'non'; + } elseif ($currentCredit->options_credit_hypothecaire->compromis_signe == '1') { + echo 'oui'; + } + ?> +
    Montant à emprunter:options_credit_hypothecaire->montant_a_emprunter ?> €
    Durée:options_credit_hypothecaire->duree ?> ans
    +

    Information de contact

    +
    +

    +
    Nom:nom ?>
    Prénom:prenom ?>
    Téléphone:telephone ?>
    Email:email ?>
    Etat civil:FK_etat_civil, $civilStatus) ? $civilStatus[$person->FK_etat_civil]->nom_etat_civil : 'etat civil inconnu' ?>
    Date de naissance:date_naissance)) ?>
    Nationalité:nationalité ?>
    Adresse:adresse ?>
    Code Postal:code_postal ?>
    Localité - Pays:localite ?> - pays ?>
    +

    Revenus et charges

    +
    Profession:
    Type de contrat: + contract_type) || $person->contract_type === ''): ?> + Non spécifié + contract_type, $contractTypes)): ?> + contract_type] ?> + + Type de contrat de travail inconnu + +
    :salaire ?> €
    Avec un co-emprunteur:
    +
    +
    +
    + Cet email a été envoyé automatiquement, merci de ne pas y répondre.
    + © Crédit Direct. Tous droits réservés. +
    +
    + + \ No newline at end of file diff --git a/templates/email/credit-reminder-mail.php b/templates/email/credit-reminder-mail.php new file mode 100644 index 0000000..1bdc97f --- /dev/null +++ b/templates/email/credit-reminder-mail.php @@ -0,0 +1,145 @@ + + + + + + Rappel de votre demande de crédit + + + + + + + +
    + + + + + + + + + + + +
    + + \ No newline at end of file diff --git a/templates/email/credit-step1-mail-back.php b/templates/email/credit-step1-mail-back.php new file mode 100644 index 0000000..41ebd4e --- /dev/null +++ b/templates/email/credit-step1-mail-back.php @@ -0,0 +1,441 @@ + 'Locataire', + 'owner' => 'Proprietaire', + 'withoutrentalcharge' => 'Sans charge locative' +]; + +$map_credit_hypothecaire_en_cours = [ + 'withmortgageloan' => 'Avec credit hypothecaire', + 'mortgagechargeiber' => 'Libre de charge hypothecaire' +]; + +$map_sans_charge_locative = [ + 'other' => 'Autre', + 'withparents' => 'Chez les parents', + 'cohabitant' => 'Cohabitant', + 'family' => 'Famille' +]; + +$show_all_mail = false; + +if($currentCredit->type_credit == 'pat') + $show_all_mail = true; + +?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $borrower, + ]; + + if (is_object($coBorrower)) { + $people['coemprunteur'] = $coBorrower; + } + + foreach ($people as $who => $person) : + ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FK_profession, $works) ? $works[$person->FK_profession]->nom_profession : 'Profession inconnue' ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + habitation_type, $map_habitation_type)) : ?> + habitation_type === 'tenant') : ?> + + + + + habitation_type === 'owner') : ?> + + + + + habitation_type === 'withoutrentalcharge') : ?> + + + + + + + + + other_credits)) : ?> + other_credits as $k => $autreCredit) : ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    Demande de credit

    +
    Type de credit:type_credit, $map_credit_type) ? $map_credit_type[$currentCredit->type_credit] : 'Type de credit inconnu' ?>
    Capital:capital ?> €
    Duree:duree ?> type_credit === 'am'): ?>ansmois
    Coût total:cout_total ?> €
    Mensualite:mensualite ?> €
    Taux nominal annuel:taux_nominal_annuel ?>
    +

    Emprunteur

    +
    Nom:nom ?>
    Prenom:prenom ?>
    Telephone:telephone ?>
    Email:email ?>
    Agence:FK_agence, $agencies) ? $agencies[$borrower->FK_agence]->Nom_agence : 'Agence inconnue' ?>
    +

    +
    Nom:nom ?>
    Prenom:prenom ?>
    Telephone:telephone ?>
    Email:email ?>
    Agence:FK_agence, $agencies) ? $agencies[$person->FK_agence]->Nom_agence : 'Agence inconnue' ?>
    etat civil:FK_etat_civil, $civilStatus) ? $civilStatus[$person->FK_etat_civil]->nom_etat_civil : 'etat civil inconnu' ?>
    Date de naissance:date_naissance ?>
    Lieu de naissance:lieu_naissance ?>
    Nationalite:nationalité ?>
    Numero de carte d'identite:num_carte_identite ?>
    Date de validite:carte_identite_validite ?>
    Numero de registre national:num_registre_national ?>
    Numero de compte bancaire:num_compte_bancaire ?>
    Adresse:adresse ?>
    Code Postal:code_postal ?>
    Localite - Pays:localite ?> - pays ?>
    Date d'emmenagement:date_emmenagement ?>
    Nombre d'enfant(s) à charge:enfant_charge ?>
    Profession:
    Type de contrat: + contract_type) || $person->contract_type === ''): ?> + Non specifie + contract_type, $contractTypes)): ?> + contract_type] ?> + + Type de contrat de travail inconnu + +
    Nom :nom_employeur ?>
    Numero d'entreprise:numero_entreprise ?>
    Adresse :adresse_employeur ?>
    Code postal :code_postal_employeur ?>
    Localite :localite_employeur ?>
    Pays :pays_employeur ?>
    Date :date_engagement ?>
    :salaire ?> €
    Chèques repas: + cheque_repas) && $person->cheque_repas !== '') : ?> + cheque_repas ?> € + + non + +
    Revenus locatifs: + revenus_locatifs) && $person->revenus_locatifs !== '') : ?> + revenus_locatifs ?> € + + non + +
    Chômage: + chomage) && $person->chomage !== '') : ?> + chomage ?> € + + non + +
    Autre: + autre_revenu_type) && $person->autre_revenu_type !== '') : ?> + autre_revenu_type ?> (autre_revenu_montant ?> €) + + non + +
    Avec un co-emprunteur:
    +

    Credits(s) et charge(s) en cours

    +
    Habitation:habitation_type, $map_habitation_type) ? $map_habitation_type[$person->habitation_type] : 'Type d\'habitation inconnu' ?>
    Montant du loyer à payer:habitation_loyer ?> €
    Credit hypothecaire en cours ?habitation_charge_hypothecaire, $map_credit_hypothecaire_en_cours) ? $map_credit_hypothecaire_en_cours[$person->habitation_charge_hypothecaire] : 'Type de charge hypothecaire inconnu' ?>
    Vous habitez:habitation_sans_charge_locative, $map_sans_charge_locative) ? $map_sans_charge_locative[$person->habitation_sans_charge_locative] : 'Type d\'habitation inconnu' ?>
    +

    Credit en cours n°

    +
    Type de creance:FK_type_creance, $existingCreditTypes) ? $existingCreditTypes[$autreCredit->FK_type_creance]->nom_creance : 'Type de creance inconnu' ?>
    Nom de l'organisme / Banque:banque ?>
    Capital emprunte:montant ?> €
    Duree du credit (en mois):duree_credit ?> mois
    Mensualite:mensualite ?> €
    Date 1ère echeance:date_premiere_echeance ?>
    Solde restant dû (approximatif):solde_restant_du ?> €
    À clôturer / Solder ?: + cloture == '0'): ?> + non + cloture == '1'): ?> + oui + +
    +

    Informations complementaires

    +
    Remarques - message à nous communiquer:remarques ?>
    \ No newline at end of file diff --git a/templates/email/credit-step1-mail-exemple.html b/templates/email/credit-step1-mail-exemple.html new file mode 100644 index 0000000..a85e6ef --- /dev/null +++ b/templates/email/credit-step1-mail-exemple.html @@ -0,0 +1,87 @@ + + + + + Demande de crédit + + +
    +
    + Crédit Direct +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    Demande de crédit

    +
    Type de crédit:Prêt personnel
    Capital:10 000 €
    Durée:48 mois
    Coût total:11 200 €
    Mensualité:233,33 €
    Taux nominal annuel:4,5%
    +

    Emprunteur

    +
    Nom:Dupont
    Prénom:Jean
    Téléphone:+33 6 12 34 56 78
    Email:jean.dupont@email.com
    +
    +
    +
    + Cet email a été envoyé automatiquement, merci de ne pas y répondre.
    + © 2024 Crédit Direct. Tous droits réservés. +
    +
    + + \ No newline at end of file diff --git a/templates/email/credit-step1-mail.php b/templates/email/credit-step1-mail.php new file mode 100644 index 0000000..a513506 --- /dev/null +++ b/templates/email/credit-step1-mail.php @@ -0,0 +1,112 @@ + + + + Demande de crédit + + + +
    +
    + Crédit Direct +
    +
    + 'Locataire', + 'owner' => 'Proprietaire', + 'withoutrentalcharge' => 'Sans charge locative' + ]; + $map_credit_hypothecaire_en_cours = [ + 'withmortgageloan' => 'Avec credit hypothecaire', + 'mortgagechargeiber' => 'Libre de charge hypothecaire' + ]; + $map_sans_charge_locative = [ + 'other' => 'Autre', + 'withparents' => 'Chez les parents', + 'cohabitant' => 'Cohabitant', + 'family' => 'Famille' + ]; + $show_all_mail = false; + if($currentCredit->type_credit == 'pat') + $show_all_mail = true; + + /* $taeg = str_replace('%', '', $currentCredit->taux_nominal_annuel); + $taux_debiteur = number_format(($taeg * 0.11) + $taeg, 2); */ + ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    Demande de crédit

    +
    Type de crédit:type_credit, $map_credit_type) ? $map_credit_type[$currentCredit->type_credit] : 'Type de crédit inconnu' ?>
    Capital:capital ?> €
    Durée:duree ?> type_credit === 'am'): ?>ansmois
    Coût total:cout_total ?> €
    Mensualité:mensualite ?> €
    Taux nominal annuel:taux_nominal_annuel ?>
    TAEG:taux_nominal_annuel ?>
    +

    Emprunteur

    +
    Nom:nom ?>
    Prénom:prenom ?>
    Téléphone:telephone ?>
    Email:email ?>
    +
    +
    +
    + Cet email a été envoyé automatiquement, merci de ne pas y répondre.
    + © Crédit Direct. Tous droits réservés. +
    +
    + + \ No newline at end of file diff --git a/templates/email/credit-step2-mail.php b/templates/email/credit-step2-mail.php new file mode 100644 index 0000000..f06a6ef --- /dev/null +++ b/templates/email/credit-step2-mail.php @@ -0,0 +1,318 @@ + + + + + Demande de crédit + + + + + + + + + +
    + + + + + + + + + + + +
    + + diff --git a/templates/email/credit-step3-mail.php b/templates/email/credit-step3-mail.php new file mode 100644 index 0000000..e69de29 diff --git a/templates/email/credit-step4-mail.php b/templates/email/credit-step4-mail.php new file mode 100644 index 0000000..29dd47a --- /dev/null +++ b/templates/email/credit-step4-mail.php @@ -0,0 +1,530 @@ + + + + + Demande de crédit + + + + + + + + + +
    + + + + + + + + + + + +
    + + \ No newline at end of file diff --git a/templates/email/credit-step4-mail_client.php b/templates/email/credit-step4-mail_client.php new file mode 100644 index 0000000..6602c5e --- /dev/null +++ b/templates/email/credit-step4-mail_client.php @@ -0,0 +1,237 @@ + + + + + Demande de crédit + + +
    +
    + Crédit Direct +
    +
    +"Prêt personnel / Tous motifs / Achats divers", + "frais_notaire"=>"Financement frais de notaire", + "but_immo"=>"Credit travaux / Renovation / Energie", + "fin_neuve"=>"Financement vehicule NEUF", + "fin_occ_m3a"=>"Financement vehicule d'occasion MOINS de 3 ans", + "fin_occ_p3a"=>"Financement vehicule d'occasion PLUS de 3 ans", + "am"=>"Credit hypothecaire classique (achat maison, construction, refinancement, regroupement, travaux, achat à l'etranger)" +]; + +$map_habitation_type = [ + 'tenant' => 'Locataire', + 'owner' => 'Proprietaire', + 'withoutrentalcharge' => 'Sans charge locative' +]; + +$map_credit_hypothecaire_en_cours = [ + 'withmortgageloan' => 'Avec credit hypothecaire', + 'mortgagechargeiber' => 'Libre de charge hypothecaire' +]; + +$map_sans_charge_locative = [ + 'other' => 'Autre', + 'withparents' => 'Chez les parents', + 'cohabitant' => 'Cohabitant', + 'family' => 'Famille' +] +?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +type_credit, ['fin_neuve', 'fin_occ_m3a', 'fin_occ_p3a'])) : ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +type_credit, ['am'])) : ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $borrower, +]; +if (is_object($coBorrower)) { + $people['coemprunteur'] = $coBorrower; +} +?> + $person) : ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    Demande de crédit

    +
    Type de crédit:type_credit, $map_credit_type) ? $map_credit_type[$currentCredit->type_credit] : 'Type de crédit inconnu' ?>
    Capital:capital ?> €
    Durée:duree ?> type_credit === 'am'): ?>ansmois
    Coût total:cout_total ?> €
    Mensualité:mensualite ?> €
    Taux nominal annuel:taux_nominal_annuel ?>
    +

    Financement véhicule

    +
    Marque + Modèle:options_credit_auto->marque ?>
    Date 1ère immatriculation:options_credit_auto->date_immatriculation ?>
    Nom du vendeur:options_credit_auto->nom_vendeur ?>
    Adresse du vendeur:options_credit_auto->adresse_vendeur ?>
    Prix d'achat du véhicule:options_credit_auto->prix_vehicule ?> €
    Montant de l'acompte:options_credit_auto->montant_accompte ?> €
    Montant de la reprise:options_credit_auto->montant_reprise ?> €
    Montant à emprunter:options_credit_auto->montant_emprunt ?> €
    Durée:options_credit_auto->duree ?> mois
    +

    Crédit hypothécaire

    +
    Type de crédit:options_credit_hypothecaire->type_credit, $mapHouseCreditTypes) ? $mapHouseCreditTypes[$currentCredit->options_credit_hypothecaire->type_credit] : 'Type de crédit inconnu' ?>
    Prix d'achat:options_credit_hypothecaire->prix_achat ?> €
    Prix de la construction TVAC:options_credit_hypothecaire->prix_construction_tvac ?> €
    Valeur du bâtiment:options_credit_hypothecaire->valeur_batiment ?> €
    Fonds propres:options_credit_hypothecaire->fonds_propre ?> €
    Compromis de vente signé: + options_credit_hypothecaire->compromis_signe == '0') { + echo 'non'; + } elseif ($currentCredit->options_credit_hypothecaire->compromis_signe == '1') { + echo 'oui'; + } + ?> +
    Montant du revenu cadastral:options_credit_hypothecaire->montant_revenu_cadastral ?> €
    Montant à emprunter:options_credit_hypothecaire->montant_a_emprunter ?> €
    Durée:options_credit_hypothecaire->duree ?> ans
    +

    +
    Nom:nom ?>
    Prénom:prenom ?>
    Type de logement:type_logement, $map_habitation_type) ? $map_habitation_type[$person->type_logement] : 'Type de logement inconnu' ?>
    Adresse:adresse ?>
    Code postal:code_postal ?>
    Ville:ville ?>
    Pays:pays ?>
    Téléphone:telephone ?>
    Email:email ?>
    +
    +
    + + \ No newline at end of file diff --git a/templates/email/credit-step5-mail.php b/templates/email/credit-step5-mail.php new file mode 100644 index 0000000..2c0fec4 --- /dev/null +++ b/templates/email/credit-step5-mail.php @@ -0,0 +1,35 @@ + + + + + Confirmation de votre demande de crédit + + +
    +
    + Crédit Direct +
    +
    +

    Confirmation de votre demande de crédit

    +

    Bonjour firstname . ' ' . $borrower->lastname; ?>,

    +

    Nous avons bien reçu votre demande de crédit et nous vous en remercions.

    +

    Un conseiller vous contactera dans les plus brefs délais pour finaliser votre dossier.

    +
    +

    Récapitulatif de votre demande

    +

    Type de crédit: options_credit_hypothecaire->type_credit, $mapHouseCreditTypes) ? $mapHouseCreditTypes[$currentCredit->options_credit_hypothecaire->type_credit] : 'Type de crédit inconnu' ?>

    +

    Montant: capital; ?> €

    +

    Durée: duree; ?> type_credit === 'am'): ?>ansmois

    +

    TAEG: taux_nominal_annuel; ?>

    +

    Mensualité: mensualite; ?> €

    +
    +

    Si vous avez des questions, n'hésitez pas à nous contacter.

    +

    Cordialement,
    L'équipe Crédit Direct

    +
    +
    +
    + Cet email a été envoyé automatiquement, merci de ne pas y répondre.
    + © Crédit Direct. Tous droits réservés. +
    +
    + + \ No newline at end of file diff --git a/templates/email/example-with-documents.php b/templates/email/example-with-documents.php new file mode 100644 index 0000000..184a841 --- /dev/null +++ b/templates/email/example-with-documents.php @@ -0,0 +1,178 @@ + + + + + Demande de crédit avec documents + + + +
    +
    + Crédit Direct +
    + +
    +

    Nouvelle demande de crédit

    + +

    Bonjour,

    + +

    Une nouvelle demande de crédit a été soumise avec les documents suivants :

    + + +

    Documents joints (version simple)

    + generateSimpleUploadedFilesLinksHTML($currentCredit->token); + ?> + + +

    Documents joints (version détaillée)

    + generateUploadedFilesLinksHTML($currentCredit->token, true); + ?> + + +

    Documents joints (version personnalisée)

    + generateUploadedFilesLinksHTML($currentCredit->token, false, 'custom-documents'); + ?> + +

    Informations de la demande

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    Nom :prenom . ' ' . $borrower->nom; ?>
    Email :email; ?>
    Téléphone :telephone; ?>
    Type de crédit :getCreditLabel($currentCredit->type_credit); ?>
    Montant :capital; ?> €
    Durée :duree; ?> mois
    + +

    Merci de traiter cette demande dans les plus brefs délais.

    + +

    Cordialement,
    L'équipe Crédit Direct

    +
    + + +
    + + diff --git a/templates/entete.html b/templates/entete.html new file mode 100644 index 0000000..28ccb2e --- /dev/null +++ b/templates/entete.html @@ -0,0 +1,314 @@ + + + + + + En-tête - ESI Credit Direct + + + +
    +
    +
    +
    + Type: + Prêt à tempérament +
    +
    + Montant: + 10.001,00€ +
    +
    + TAEG: + 7.45% +
    +
    + Durée: + 60 mois +
    +
    + Mensualité: + 199,01€ +
    +
    +
    +
    + +
    +
    + 1 + Contact +
    +
    + 2 + Revenus & charges +
    +
    + 3 + Informations personnelles +
    +
    + 4 + Coordonnées +
    +
    + +
    + +
    + +
    + +
    + +
    +
    +

    © 2024 ESI Credit Direct. Tous droits réservés.

    +
    +
    + + \ No newline at end of file diff --git a/templates/front/credit-one-step.php b/templates/front/credit-one-step.php new file mode 100644 index 0000000..18220a4 --- /dev/null +++ b/templates/front/credit-one-step.php @@ -0,0 +1,367 @@ + 'Locataire', + 'owner' => 'Proprietaire', + 'withoutrentalcharge' => 'Sans charge locative' +]; + +$map_credit_hypothecaire_en_cours = [ + 'withmortgageloan' => 'Avec credit hypothecaire', + 'mortgagechargeiber' => 'Libre de charge hypothecaire' +]; + +$map_sans_charge_locative = [ + 'other' => 'Autre', + 'withparents' => 'Chez les parents', + 'cohabitant' => 'Cohabitant', + 'family' => 'Famille' +]; +?> +
    +
    +
    +

    Introduction de votre demande de crédit

    + +
    +
    +
    +
    +

    Type de prêt

    + type_credit] ?> +
    +
    +

    Capital choisi

    + capital ?> € +
    +
    +

    Durée choisie (nombre de mensualités)

    + duree ?> type_credit === 'am'): ?>ansmois +
    +
    +
    + +
    +
    +
    +

    Montant emprunté :

    + capital ?> € + +

    Durée :

    + duree ?> type_credit === 'am'): ?>ansmois + +

    Mensualité :

    + mensualite ?> € +
    + +
    +

    Coût Total :

    + cout_total ?> € + +

    Taux nominal annuel :

    + taux_nominal_annuel ?> + +

    Taux nominal annuel + taux réel qui correspond à la mensualité :

    +
    +
    +
    + +

    Exemple représentatif : type de crédit = prêt à tempérament (tous motifs) / montant emprunté = 12.500€ / durée = 60 mois / mensualité = 245,97€ / coût total = 14758,20€ / TAEG* = 6,95% / taux débiteur fixe = 6,95%.*TAEG = Taux Annuel Effectif Global = Taux Débiteur Fixe. Sous réserve de changement des taux et d'acceptation de votre dossier par nos partenaires financiers.

    +
    +
    + +
    + +
    + Informations de contact + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + +
    + + get_results( "SELECT * FROM cdf_Etat_civil"); ?> + + +
    + +
    + + +
    + +
    + +
    +
    + + +
    +
    + + +
    +
    +
    + +
    + But du prêt hypotécaire +
    + +
    + + +
    +
    + + +
    + +
    +
    + Compromis signé +
    +
    + + +
    +
    + + +
    +
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    + +
    + Revenus et charges + +
    + +
    + + get_results( "SELECT * FROM cdf_Profession"); ?> + + +
    + +
    + + + +
    + +
    + + +
    +
    + +
    +
    J'emprunte ?
    +
    + + +
    +
    + + +
    +
    +
    + + + + +
    + + + + + +
    + + + +
    + +
    +
    +
    +
    \ No newline at end of file diff --git a/templates/front/credit-reminder.php b/templates/front/credit-reminder.php new file mode 100644 index 0000000..0314a73 --- /dev/null +++ b/templates/front/credit-reminder.php @@ -0,0 +1,67 @@ + 'Prêt à tempérament', + 'frais_notaire' => 'Financement frais de notaire', + 'but_immo' => 'Crédit travaux', + 'fin_neuve' => 'Financement véhicule NEUF', + 'fin_occ_m3a' => 'Financement véhicule d\'occasion MOINS de 3 ans', + 'fin_occ_p3a' => 'Financement véhicule d\'occasion PLUS de 3 ans', + 'am' => 'Crédit hypothécaire', + 'cied' => 'Indépendant et entreprise en difficulté' +]; + +echo 'vghvgvgjhv-2'; + +if ($credit_request) : + // Calculer le temps écoulé depuis la dernière mise à jour + $last_update = new DateTime($credit_request['last_update_date']); + $now = new DateTime(); + $interval = $now->diff($last_update); + $days_ago = $interval->days; + + // Déterminer le message en fonction de l'étape + $step_message = ''; + switch($credit_request['step']) { + case 1: + $step_message = 'Vous avez commencé une demande de crédit'; + break; + case 2: + $step_message = 'Vous avez complété les informations de base'; + break; + case 3: + $step_message = 'Vous avez renseigné vos informations personnelles'; + break; + case 4: + $step_message = 'Vous avez complété les informations de votre co-emprunteur'; + break; + case 5: + $step_message = 'Votre demande est presque terminée'; + break; + } +?> +
    +
    +
    +

    Demande de crédit en cours

    +

    + pour un + + d'un montant de € + sur mois. +

    +

    + Dernière mise à jour il y a jour 1 ? 's' : ''; ?> +

    +
    + +
    +
    + \ No newline at end of file diff --git a/templates/front/credit-step1-back.php b/templates/front/credit-step1-back.php new file mode 100644 index 0000000..08524ea --- /dev/null +++ b/templates/front/credit-step1-back.php @@ -0,0 +1,1002 @@ +type_credit == 'pat') + $show_all_form = true; + + +$form_action = $show_all_form ? '#' : get_site_url().'/credit-step2'; + +$submit_label = $show_all_form ? 'Envoyer demande' : 'Étape suivante'; + +?> + +
    +
    +
    +

    Introduction de votre demande de crédit

    + +
    + +
    +
    +
    +

    Type de prêt

    + type_credit] ?> +
    +
    +

    Capital choisi

    + capital ?> € +
    +
    +

    Durée choisie (nombre de mensualités)

    + duree ?> type_credit === 'am'): ?>ansmois +
    +
    +
    + +
    +
    +
    +

    Montant emprunté :

    + capital ?> € + +

    Durée :

    + duree ?> type_credit === 'am'): ?>ansmois + +

    Mensualité :

    + mensualite ?> € +
    + +
    +

    Coût Total :

    + cout_total ?> € + +

    Taux nominal annuel :

    + taux_nominal_annuel ?> + +

    Taux nominal annuel + taux réel qui correspond à la mensualité :

    +
    +
    +
    + +

    Exemple représentatif : type de crédit = prêt à tempérament (tous motifs) / montant emprunté = 12.500€ / durée = 60 mois / mensualité = 245,97€ / coût total = 14758,20€ / TAEG* = 6,95% / taux débiteur fixe = 6,95%.*TAEG = Taux Annuel Effectif Global = Taux Débiteur Fixe. Sous réserve de changement des taux et d'acceptation de votre dossier par nos partenaires financiers.

    +
    +
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + + +
    +
    + + type_credit == 'fin_neuve' || $currentCredit->type_credit == 'fin_occ_m3a' || $currentCredit->type_credit == 'fin_occ_p3a') : ?> +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + + type_credit == 'am') : ?> +
    + +
    + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    + Compromis signé +
    +
    + + +
    +
    + + +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + + +
    +
    J'emprunte ?
    +
    + + +
    +
    + + +
    +
    + +
    +
    +
    +

    + +

    +
    +
    +
    + Some placeholder content for the second accordion panel. This panel is hidden by default. +
    +
    +
    +
    +
    +

    + +

    +
    +
    +
    + Some placeholder content for the second accordion panel. This panel is hidden by default. +
    +
    +
    +
    +
    +

    + +

    +
    +
    +
    + Some placeholder content for the second accordion panel. This panel is hidden by default. +
    +
    +
    +
    +
    +

    + +

    +
    +
    +
    + Some placeholder content for the second accordion panel. This panel is hidden by default. +
    +
    +
    +
    + +
    +
    +
    + +
    +
    + +
    +
    +
    + Emprunteur (suite des informations) +
    + + get_results( "SELECT * FROM cdf_Etat_civil"); ?> + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + + +
    +
    + +
    +
    + + +
    +
    + + +
    +
    + + +
    + +
    + + +
    + +
    + + get_results( "SELECT * FROM cdf_Profession"); ?> + + +
    + +
    + + + +
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    Autres revenus
    +
    + + +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +
    + +
    +
    + +
    +
    +
    + Co Emprunteur +
    + +
    +
    + + +
    + +
    + + get_results( "SELECT * FROM cdf_Etat_civil"); ?> + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + +
    + + +
    + +
    + + get_results( "SELECT * FROM cdf_Profession"); ?> + + +
    + +
    + + + +
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    + + +
    +
    + + +
    +
    + + + +
    +
    Autres revenus
    +
    + + +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    + +
    +
    +
    +
    + Emprunteur + Crédits(s) et charge(s) en cours + +
    + + +
    +
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    + +
    + + +
    +
    + +
    + + + + +
    + + + +
    +
    + + get_results( "SELECT * FROM cdf_Type_creance"); ?> + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    + + +
    +
    + + +
    +
    +
    À clôturer / Solder ?
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + + +
    +
    +
    +
    +
    + +
    + +
    +
    +
    +
    + Co-Emprunteur + Crédits(s) et charge(s) en cours + +
    + + +
    +
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    + +
    + + +
    +
    + +
    +
    + + + +
    +
    + + + get_results( "SELECT * FROM cdf_Type_creance"); ?> + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    + + +
    +
    + + +
    +
    +
    À clôturer / Solder ?
    + +
    + + +
    +
    + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    +
    +
    +
    +
    + + +
    + + + + +
    + + + + +
    + + +
    +
    +
    \ No newline at end of file diff --git a/templates/front/credit-step1-bis.php b/templates/front/credit-step1-bis.php new file mode 100644 index 0000000..f65fee5 --- /dev/null +++ b/templates/front/credit-step1-bis.php @@ -0,0 +1,887 @@ +type_credit == 'pat') + $show_all_form = true; + + +$form_action = $show_all_form ? '#' : get_site_url().'/credit-step2'; + +$submit_label = $show_all_form ? 'Envoyer demande' : 'Étape suivante'; + +?> + +
    +
    +
    +

    Introduction de votre demande de crédit

    + +
    + +
    +
    +
    +

    Type de prêt

    + type_credit] ?> +
    +
    +

    Capital choisi

    + capital ?> € +
    +
    +

    Durée choisie (nombre de mensualités)

    + duree ?> type_credit === 'am'): ?>ansmois +
    +
    +
    + +
    +
    +
    +

    Montant emprunté :

    + capital ?> € + +

    Durée :

    + duree ?> type_credit === 'am'): ?>ansmois + +

    Mensualité :

    + mensualite ?> € +
    + +
    +

    Coût Total :

    + cout_total ?> € + +

    Taux nominal annuel :

    + taux_nominal_annuel ?> + +

    Taux nominal annuel + taux réel qui correspond à la mensualité :

    +
    +
    +
    + +

    Exemple représentatif : type de crédit = prêt à tempérament (tous motifs) / montant emprunté = 12.500€ / durée = 60 mois / mensualité = 245,97€ / coût total = 14758,20€ / TAEG* = 6,95% / taux débiteur fixe = 6,95%.*TAEG = Taux Annuel Effectif Global = Taux Débiteur Fixe. Sous réserve de changement des taux et d'acceptation de votre dossier par nos partenaires financiers.

    +
    +
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + +
    + + type_credit == 'fin_neuve' || $currentCredit->type_credit == 'fin_occ_m3a' || $currentCredit->type_credit == 'fin_occ_p3a') : ?> +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + + type_credit == 'am') : ?> +
    + +
    + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    + Compromis signé +
    +
    + + +
    +
    + + +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + + + +
    +
    +
    J'emprunte ?
    +
    + + +
    +
    + + +
    +
    + +
    + +
    +
    +
    + Emprunteur (suite des informations) +
    + + get_results( "SELECT * FROM cdf_Etat_civil"); ?> + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + + +
    +
    + +
    +
    + + +
    +
    + + +
    +
    + + +
    + +
    + + +
    + +
    + + get_results( "SELECT * FROM cdf_Profession"); ?> + + +
    + +
    + + + +
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    Autres revenus
    +
    + + +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    +
    + + +
    +
    +
    + Co Emprunteur +
    + +
    +
    + + +
    + +
    + + get_results( "SELECT * FROM cdf_Etat_civil"); ?> + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + +
    + + +
    + +
    + + get_results( "SELECT * FROM cdf_Profession"); ?> + + +
    + +
    + + + +
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    + + +
    +
    + + +
    +
    + + + +
    +
    Autres revenus
    +
    + + +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +
    + + +
    +
    + Emprunteur + Crédits(s) et charge(s) en cours + +
    + + +
    +
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    + +
    + + +
    +
    + +
    + +

    Si un crédit est en commun avec le co-emprunter, merci de ne l'encoder qu'une seule fois.

    + + +
    + + + +
    +
    + + get_results( "SELECT * FROM cdf_Type_creance"); ?> + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    + + +
    +
    + + +
    +
    +
    À clôturer / Solder ?
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + + +
    +
    + + +
    +
    + Co-Emprunteur + Crédits(s) et charge(s) en cours + +
    + + +
    +
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    + +
    + + +
    +
    + +
    +
    + + + +
    +
    + + + get_results( "SELECT * FROM cdf_Type_creance"); ?> + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    + + +
    +
    + + +
    +
    +
    À clôturer / Solder ?
    + +
    + + +
    +
    + + +
    +
    + + +
    + +
    + + +
    +
    + +
    + + +
    + + + + +
    + +
    + + +
    +
    +
    \ No newline at end of file diff --git a/templates/front/credit-step1.php b/templates/front/credit-step1.php new file mode 100644 index 0000000..8627234 --- /dev/null +++ b/templates/front/credit-step1.php @@ -0,0 +1,324 @@ +type_credit == 'pat') + $show_all_form = true; */ + + +$form_action = $show_all_form ? '#' : get_site_url().'/credit-step2'; + +$submit_label = $show_all_form ? 'Envoyer demande' : 'Étape suivante'; + +$exemple_info = $model->get_exemples_infos($currentCredit->type_credit); + +?> + +
    +
    +
    +
    +

    Introduction de votre demande de crédit

    +
    +
    +
    +
    + +
    +
    +
    +
    +

    Type de crédit:

    +
    +
    +
    +
    +
    +
    + Montant: + capital ?? '') ?> € +
    +
    + Taux débiteur: + taux_nominal_annuel ?? '') ?> +
    +
    + Durée: + duree ?? '') ?> type_credit === 'am'): ?>ansmois +
    +
    + Mensualité: + mensualite ?? '') ?>€ +
    +
    + Coût total: + cout_total ?? '') ?>€ +
    +
    + TAEG: + taux_nominal_annuel ?? '') ?> +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    + 1 + Contact +
    +
    + 2 + Revenus & charges +
    +
    + 3 + Informations personnelles +
    +
    + 4 + Coordonnées +
    +
    +
    +
    +
    +
    +
    + +
    +
    + + + +
    + + + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + +
    + + type_credit == 'fin_neuve' || $currentCredit->type_credit == 'fin_occ_m3a' || $currentCredit->type_credit == 'fin_occ_p3a' || $currentCredit->type_credit == 'mobil_carav') : ?> +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + + type_credit == 'am') : ?> +
    + +
    + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    + Compromis signé +
    +
    + isRadioChecked('compromis_signe', '0', $borrower); ?>> + +
    +
    + isRadioChecked('compromis_signe', '1', $borrower); ?>> + +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + Commentaires et informations complémentaires +
    + + +
    +
    + + + +
    + + + + + + +
    + +
    + +
    +
    + +
    +
    +
    +
    +

    Montant emprunté :

    + capital ?? '') ?> € + +

    Durée :

    + duree ?? '') ?> type_credit === 'am'): ?>ansmois + +

    Mensualité :

    + mensualite ?? '') ?> € +
    + +
    +

    Coût Total :

    + cout_total ?? '') ?> € + +

    Taux nominal annuel :

    + taux_nominal_annuel ?? '') ?> + +

    TAEG :

    + taux_nominal_annuel ?? '') ?> +
    +
    +
    + +
    + + + +
    +
    + +
    +
    \ No newline at end of file diff --git a/templates/front/credit-step2-a.php b/templates/front/credit-step2-a.php new file mode 100644 index 0000000..2d9b593 --- /dev/null +++ b/templates/front/credit-step2-a.php @@ -0,0 +1,302 @@ +
    +
    +
    +

    Introduction de votre demande de crédit

    +
    +
    +
    + + + +
    +
    +
    +
    + +
    +
    + 1 + Contact +
    +
    + 2 + Revenus & charges +
    +
    + 3 + Informations personnelles +
    +
    + 4 + Coordonnées +
    +
    +
    +
    +
    +
    + +
    +
    + + + + +
    + + + +
    +
    +
    J'emprunte ?
    +
    + > + +
    +
    + > + +
    +
    + +
    + +
    +
    +
    +
    +

    Emprunteur

    + Coordonnées de contact + + +
    + + get_results("SELECT * FROM cdf_Etat_civil"); ?> + + +
    + + Votre profession et Revenus + +
    + + get_results("SELECT * FROM cdf_Profession"); ?> + + +
    + +
    +
    + + + +
    + + +
    +
    +
    + + +
    + + +
    + +
    + +
    + +
    + +
    +
    +
    + + +
    +
    + + +
    +
    +
    + +
    +
    Autres revenus
    +
    + hasOtherIncome($borrower)) echo 'checked'; ?>> + +
    +
    + hasOtherIncome($borrower)) echo 'checked'; ?>> + +
    +
    + +
    +
    +
    +
    +
    + isCheckboxChecked('hasoimealvoucher', 'mealvoucher', $borrower); ?>> + +
    +
    + +
    +
    +
    +
    +
    +
    + isCheckboxChecked('hasoirentalincome', 'rentalincome', $borrower); ?>> + +
    +
    + +
    +
    +
    +
    +
    +
    + isCheckboxChecked('hasoiunemployment', 'unemployment', $borrower); ?>> + +
    +
    + +
    +
    +
    +
    +
    +
    + isCheckboxChecked('hasoiother', 'other', $borrower); ?>> + +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    + +
    +
    Etes-vous fiché à la Banque Nationale ?
    +
    + estFicheBanqueNational($borrower)) echo 'checked'; ?>> + +
    +
    + estFicheBanqueNational($borrower)) echo 'checked'; ?>> + +
    +
    + +
    +
    +
    +

    Statut du fichage

    +
    + isRadioChecked('fichage_status', 'regularise', $borrower); ?>> + +
    +
    + isRadioChecked('fichage_status', 'non_regularise', $borrower); ?>> + +
    +
    + isRadioChecked('fichage_status', 'mediation_dettes', $borrower); ?>> + +
    +
    +
    +
    + +
    +
    +
    Statut du logement
    + +
    +
    + +
    +
    +
    +
    Montant du loyer mensuel ou participation aux charges
    + +
    +
    +
    + + +
    + +
    + +
    +
    + \ No newline at end of file diff --git a/templates/front/credit-step2-b.php b/templates/front/credit-step2-b.php new file mode 100644 index 0000000..cdd56b3 --- /dev/null +++ b/templates/front/credit-step2-b.php @@ -0,0 +1,239 @@ +
    +
    +
    +

    Co Emprunteur

    + Coordonnées de contact + +
    + + +
    +
    + + +
    +
    + +
    +
    + + +
    + +
    + + get_results("SELECT * FROM cdf_Etat_civil"); ?> + + +
    + + Votre profession et Revenus + +
    + + get_results("SELECT * FROM cdf_Profession"); ?> + + +
    + +
    + +
    + + + +
    + +
    + +
    +
    + + +
    + +
    + +
    +
    + + +
    + +
    +
    + +
    +
    +
    + + +
    +
    + + +
    +
    +
    + + + + +
    +
    Autres revenus
    +
    + hasOtherIncome($coBorrower)) echo 'checked'; ?>> + +
    +
    + hasOtherIncome($coBorrower)) echo 'checked'; ?>> + +
    +
    + +
    +
    +
    +
    +
    + isCheckboxChecked('hasoimealvoucher', 'mealvoucher', $coBorrower); ?>> + +
    +
    + +
    +
    +
    +
    +
    +
    + isCheckboxChecked('cohasoirentalincome', 'rentalincome', $coBorrower); ?>> + +
    +
    + +
    +
    +
    +
    +
    +
    + isCheckboxChecked('cohasoiunemployment', 'unemployment', $coBorrower); ?>> + +
    +
    + +
    +
    +
    +
    +
    +
    + isCheckboxChecked('cohasoiother', 'other', $coBorrower); ?>> + +
    +
    + +
    +
    + +
    +
    +
    +
    +
    + +
    +
    Etes-vous fiché à la Banque Nationale ?
    +
    + estFicheBanqueNational) echo 'checked'; ?>> + +
    +
    + estFicheBanqueNational) echo 'checked'; ?>> + +
    +
    + +
    +
    +
    +

    Statut du fichage

    +
    + isRadioChecked('coFichage_status', 'regularise', $coBorrower); ?>> + +
    +
    + isRadioChecked('coFichage_status', 'non_regularise', $coBorrower); ?>> + +
    +
    + isRadioChecked('coFichage_status', 'mediation_dettes', $coBorrower); ?>> + +
    +
    +
    +
    + +
    +
    +
    Statut du logement
    + +
    +
    + +
    +
    +
    +
    Montant du loyer mensuel ou participation aux charges
    + +
    +
    +
    + +
    +
    + + diff --git a/templates/front/credit-step2-c.php b/templates/front/credit-step2-c.php new file mode 100644 index 0000000..cc06ec6 --- /dev/null +++ b/templates/front/credit-step2-c.php @@ -0,0 +1,215 @@ + + +
    +
    Avez-vous des crédits en cours ?
    +
    +
    + +
    + isRadioChecked('hascurrentloan', '0', $borrower); ?>> + +
    +
    + isRadioChecked('hascurrentloan', '1', $borrower); ?>> + +
    +
    +
    + +
    + +

    Si un crédit est en commun avec le co-emprunteur, merci de ne l'encoder qu'une seule fois.

    + + + + getCurrentLoansHTML($borrower); ?> + +
    + + + +
    +
    + + get_results( "SELECT * FROM cdf_Type_creance"); ?> + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    + + +
    +
    + + +
    +
    +
    À clôturer / Solder ?
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + + +
    + +
    + +
    +
    + + +
    + +
    Avez-vous des crédits en cours ?
    +
    +
    + +
    + isRadioChecked('cohascurrentloan', '0', $coBorrower); ?>> + +
    +
    + isRadioChecked('cohascurrentloan', '1', $coBorrower); ?>> + +
    +
    +
    +
    + +
    + + getCurrentLoansHTML($coBorrower, 'co'); ?> + +
    + + + +
    +
    + + + get_results( "SELECT * FROM cdf_Type_creance"); ?> + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    + + +
    +
    + + +
    +
    +
    À clôturer / Solder ?
    + +
    + + +
    +
    + + +
    +
    + + +
    + +
    + + + +
    +
    + +
    +
    + Étape précédente + +
    +
    +
    +
    +
    +
    + + + +
    +
    \ No newline at end of file diff --git a/templates/front/credit-step3.php b/templates/front/credit-step3.php new file mode 100644 index 0000000..0454d67 --- /dev/null +++ b/templates/front/credit-step3.php @@ -0,0 +1,263 @@ +get_exemples_infos($currentCredit->type_credit); +?> + +
    +
    +
    +

    Introduction de votre demande de crédit

    +
    +
    +
    + + + +
    +
    +
    +
    + +
    +
    + 1 + Contact +
    +
    + 2 + Revenus & charges +
    +
    + 3 + Informations personnelles +
    +
    + 4 + Coordonnées +
    +
    +
    +
    +
    +
    +
    +
    + + + + +
    + + + +
    +
    +
    +
    + Emprunteur + Données personnelles +
    + + +
    +
    + + +
    +
    + + 'Belgique', + 'LU' => 'Luxembourg', + ]; + $main_countries = [ + 'BE' => 'Belgique', + 'LU' => 'Luxembourg', + 'FR' => 'France', + 'DE' => 'Allemagne', + 'NL' => 'Pays-Bas', + ]; + // Liste de traduction FR pour les autres pays (extrait, à compléter si besoin) + $country_fr = [ + 'AD' => 'Andorre', 'AL' => 'Albanie', 'AT' => 'Autriche', 'BA' => 'Bosnie-Herzégovine', 'BG' => 'Bulgarie', 'BY' => 'Biélorussie', 'CH' => 'Suisse', 'CZ' => 'Tchéquie', 'DK' => 'Danemark', 'EE' => 'Estonie', 'ES' => 'Espagne', 'FI' => 'Finlande', 'GB' => 'Royaume-Uni', 'GR' => 'Grèce', 'HR' => 'Croatie', 'HU' => 'Hongrie', 'IE' => 'Irlande', 'IS' => 'Islande', 'IT' => 'Italie', 'LT' => 'Lituanie', 'LV' => 'Lettonie', 'MC' => 'Monaco', 'MD' => 'Moldavie', 'ME' => 'Monténégro', 'MK' => 'Macédoine du Nord', 'MT' => 'Malte', 'NO' => 'Norvège', 'PL' => 'Pologne', 'PT' => 'Portugal', 'RO' => 'Roumanie', 'RS' => 'Serbie', 'RU' => 'Russie', 'SE' => 'Suède', 'SI' => 'Slovénie', 'SK' => 'Slovaquie', 'SM' => 'Saint-Marin', 'UA' => 'Ukraine', 'VA' => 'Vatican', + // ... compléter si besoin ... + ]; + // Liste CSV (code => nom anglais) + $csv_countries = [ + 'AD' => 'Andorra', 'AE' => 'United Arab Emirates', 'AF' => 'Afghanistan', 'AG' => 'Antigua and Barbuda', 'AI' => 'Anguilla', 'AL' => 'Albania', 'AM' => 'Armenia', 'AN' => 'Netherlands Antilles', 'AO' => 'Angola', 'AQ' => 'Antarctica', 'AR' => 'Argentina', 'AS' => 'American Samoa', 'AT' => 'Austria', 'AU' => 'Australia', 'AW' => 'Aruba', 'AZ' => 'Azerbaijan', 'BA' => 'Bosnia and Herzegovina', 'BB' => 'Barbados', 'BD' => 'Bangladesh', 'BE' => 'Belgium', 'BF' => 'Burkina Faso', 'BG' => 'Bulgaria', 'BH' => 'Bahrain', 'BI' => 'Burundi', 'BJ' => 'Benin', 'BM' => 'Bermuda', 'BN' => 'Brunei', 'BO' => 'Bolivia', 'BR' => 'Brazil', 'BS' => 'Bahamas', 'BT' => 'Bhutan', 'BV' => 'Bouvet Island', 'BW' => 'Botswana', 'BY' => 'Belarus', 'BZ' => 'Belize', 'CA' => 'Canada', 'CC' => 'Cocos [Keeling] Islands', 'CD' => 'Congo [DRC]', 'CF' => 'Central African Republic', 'CG' => 'Congo [Republic]', 'CH' => 'Switzerland', 'CI' => +"Côte d'Ivoire", 'CK' => 'Cook Islands', 'CL' => 'Chile', 'CM' => 'Cameroon', 'CN' => 'China', 'CO' => 'Colombia', 'CR' => 'Costa Rica', 'CU' => 'Cuba', 'CV' => 'Cape Verde', 'CX' => 'Christmas Island', 'CY' => 'Cyprus', 'CZ' => 'Czech Republic', 'DE' => 'Germany', 'DJ' => 'Djibouti', 'DK' => 'Denmark', 'DM' => 'Dominica', 'DO' => 'Dominican Republic', 'DZ' => 'Algeria', 'EC' => 'Ecuador', 'EE' => 'Estonia', 'EG' => 'Egypt', 'EH' => 'Western Sahara', 'ER' => 'Eritrea', 'ES' => 'Spain', 'ET' => 'Ethiopia', 'FI' => 'Finland', 'FJ' => 'Fiji', 'FK' => 'Falkland Islands [Islas Malvinas]', 'FM' => 'Micronesia', 'FO' => 'Faroe Islands', 'FR' => 'France', 'GA' => 'Gabon', 'GB' => 'United Kingdom', 'GD' => 'Grenada', 'GE' => 'Georgia', 'GF' => 'French Guiana', 'GG' => 'Guernsey', 'GH' => 'Ghana', 'GI' => 'Gibraltar', 'GL' => 'Greenland', 'GM' => 'Gambia', 'GN' => 'Guinea', 'GP' => 'Guadeloupe', 'GQ' => 'Equatorial Guinea', 'GR' => 'Greece', 'GS' => 'South Georgia and the South Sandwich Islands', 'GT' => 'Guatemala', 'GU' => 'Guam', 'GW' => 'Guinea-Bissau', 'GY' => 'Guyana', 'GZ' => 'Gaza Strip', 'HK' => 'Hong Kong', 'HM' => 'Heard Island and McDonald Islands', 'HN' => 'Honduras', 'HR' => 'Croatia', 'HT' => 'Haiti', 'HU' => 'Hungary', 'ID' => 'Indonesia', 'IE' => 'Ireland', 'IL' => 'Israel', 'IM' => 'Isle of Man', 'IN' => 'India', 'IO' => 'British Indian Ocean Territory', 'IQ' => 'Iraq', 'IR' => 'Iran', 'IS' => 'Iceland', 'IT' => 'Italy', 'JE' => 'Jersey', 'JM' => 'Jamaica', 'JO' => 'Jordan', 'JP' => 'Japan', 'KE' => 'Kenya', 'KG' => 'Kyrgyzstan', 'KH' => 'Cambodia', 'KI' => 'Kiribati', 'KM' => 'Comoros', 'KN' => 'Saint Kitts and Nevis', 'KP' => 'North Korea', 'KR' => 'South Korea', 'KW' => 'Kuwait', 'KY' => 'Cayman Islands', 'KZ' => 'Kazakhstan', 'LA' => 'Laos', 'LB' => 'Lebanon', 'LC' => 'Saint Lucia', 'LI' => 'Liechtenstein', 'LK' => 'Sri Lanka', 'LR' => 'Liberia', 'LS' => 'Lesotho', 'LT' => 'Lithuania', 'LU' => 'Luxembourg', 'LV' => 'Latvia', 'LY' => 'Libya', 'MA' => 'Morocco', 'MC' => 'Monaco', 'MD' => 'Moldova', 'ME' => 'Montenegro', 'MG' => 'Madagascar', 'MH' => 'Marshall Islands', 'MK' => 'Macedonia [FYROM]', 'ML' => 'Mali', 'MM' => 'Myanmar [Burma]', 'MN' => 'Mongolia', 'MO' => 'Macau', 'MP' => 'Northern Mariana Islands', 'MQ' => 'Martinique', 'MR' => 'Mauritania', 'MS' => 'Montserrat', 'MT' => 'Malta', 'MU' => 'Mauritius', 'MV' => 'Maldives', 'MW' => 'Malawi', 'MX' => 'Mexico', 'MY' => 'Malaysia', 'MZ' => 'Mozambique', 'NA' => 'Namibia', 'NC' => 'New Caledonia', 'NE' => 'Niger', 'NF' => 'Norfolk Island', 'NG' => 'Nigeria', 'NI' => 'Nicaragua', 'NL' => 'Netherlands', 'NO' => 'Norway', 'NP' => 'Nepal', 'NR' => 'Nauru', 'NU' => 'Niue', 'NZ' => 'New Zealand', 'OM' => 'Oman', 'PA' => 'Panama', 'PE' => 'Peru', 'PF' => 'French Polynesia', 'PG' => 'Papua New Guinea', 'PH' => 'Philippines', 'PK' => 'Pakistan', 'PL' => 'Poland', 'PM' => 'Saint Pierre and Miquelon', 'PN' => 'Pitcairn Islands', 'PR' => 'Puerto Rico', 'PS' => 'Palestinian Territories', 'PT' => 'Portugal', 'PW' => 'Palau', 'PY' => 'Paraguay', 'QA' => 'Qatar', 'RE' => 'Réunion', 'RO' => 'Romania', 'RS' => 'Serbia', 'RU' => 'Russia', 'RW' => 'Rwanda', 'SA' => 'Saudi Arabia', 'SB' => 'Solomon Islands', 'SC' => 'Seychelles', 'SD' => 'Sudan', 'SE' => 'Sweden', 'SG' => 'Singapore', 'SH' => 'Saint Helena', 'SI' => 'Slovenia', 'SJ' => 'Svalbard and Jan Mayen', 'SK' => 'Slovakia', 'SL' => 'Sierra Leone', 'SM' => 'San Marino', 'SN' => 'Senegal', 'SO' => 'Somalia', 'SR' => 'Suriname', 'ST' => 'São Tomé and Príncipe', 'SV' => 'El Salvador', 'SY' => 'Syria', 'SZ' => 'Swaziland', 'TC' => 'Turks and Caicos Islands', 'TD' => 'Chad', 'TF' => 'French Southern Territories', 'TG' => 'Togo', 'TH' => 'Thailand', 'TJ' => 'Tajikistan', 'TK' => 'Tokelau', 'TL' => 'Timor-Leste', 'TM' => 'Turkmenistan', 'TN' => 'Tunisia', 'TO' => 'Tonga', 'TR' => 'Turkey', 'TT' => 'Trinidad and Tobago', 'TV' => 'Tuvalu', 'TW' => 'Taiwan', 'TZ' => 'Tanzania', 'UA' => 'Ukraine', 'UG' => 'Uganda', 'UM' => 'U.S. Minor Outlying Islands', 'US' => 'United States', 'UY' => 'Uruguay', 'UZ' => 'Uzbekistan', 'VA' => 'Vatican City', 'VC' => 'Saint Vincent and the Grenadines', 'VE' => 'Venezuela', 'VG' => 'British Virgin Islands', 'VI' => 'U.S. Virgin Islands', 'VN' => 'Vietnam', 'VU' => 'Vanuatu', 'WF' => 'Wallis and Futuna', 'WS' => 'Samoa', 'XK' => 'Kosovo', 'YE' => 'Yemen', 'YT' => 'Mayotte', 'ZA' => 'South Africa', 'ZM' => 'Zambia', 'ZW' => 'Zimbabwe', + ]; + // Construction du tableau final pour le 2e groupe + $other_countries = []; + foreach ($csv_countries as $code => $en_name) { + if (!isset($main_countries[$code])) { + $label = isset($country_fr[$code]) ? $country_fr[$code] : $en_name; + $other_countries[$code] = $label; + } + } + asort($other_countries, SORT_LOCALE_STRING); + + if($is_credit_pat) { + $main_countries = $pat_countries; + } + // Persistance de la sélection + $selected = $model->getFieldValue('nationalite', $borrower); + + ?> + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + +
    +
    + + +
    +
    + Co-Emprunteur + Données personnelles +
    + + +
    +
    + + +
    +
    + + 'Belgique', + 'LU' => 'Luxembourg', + 'FR' => 'France', + 'DE' => 'Allemagne', + 'NL' => 'Pays-Bas', + ]; + // Liste de traduction FR pour les autres pays (extrait, à compléter si besoin) + $country_fr = [ + 'AD' => 'Andorre', 'AL' => 'Albanie', 'AT' => 'Autriche', 'BA' => 'Bosnie-Herzégovine', 'BG' => 'Bulgarie', 'BY' => 'Biélorussie', 'CH' => 'Suisse', 'CZ' => 'Tchéquie', 'DK' => 'Danemark', 'EE' => 'Estonie', 'ES' => 'Espagne', 'FI' => 'Finlande', 'GB' => 'Royaume-Uni', 'GR' => 'Grèce', 'HR' => 'Croatie', 'HU' => 'Hongrie', 'IE' => 'Irlande', 'IS' => 'Islande', 'IT' => 'Italie', 'LT' => 'Lituanie', 'LV' => 'Lettonie', 'MC' => 'Monaco', 'MD' => 'Moldavie', 'ME' => 'Monténégro', 'MK' => 'Macédoine du Nord', 'MT' => 'Malte', 'NO' => 'Norvège', 'PL' => 'Pologne', 'PT' => 'Portugal', 'RO' => 'Roumanie', 'RS' => 'Serbie', 'RU' => 'Russie', 'SE' => 'Suède', 'SI' => 'Slovénie', 'SK' => 'Slovaquie', 'SM' => 'Saint-Marin', 'UA' => 'Ukraine', 'VA' => 'Vatican', + // ... compléter si besoin ... + ]; + // Liste CSV (code => nom anglais) + $csv_countries = [ + 'AD' => 'Andorra', 'AE' => 'United Arab Emirates', 'AF' => 'Afghanistan', 'AG' => 'Antigua and Barbuda', 'AI' => 'Anguilla', 'AL' => 'Albania', 'AM' => 'Armenia', 'AN' => 'Netherlands Antilles', 'AO' => 'Angola', 'AQ' => 'Antarctica', 'AR' => 'Argentina', 'AS' => 'American Samoa', 'AT' => 'Austria', 'AU' => 'Australia', 'AW' => 'Aruba', 'AZ' => 'Azerbaijan', 'BA' => 'Bosnia and Herzegovina', 'BB' => 'Barbados', 'BD' => 'Bangladesh', 'BE' => 'Belgium', 'BF' => 'Burkina Faso', 'BG' => 'Bulgaria', 'BH' => 'Bahrain', 'BI' => 'Burundi', 'BJ' => 'Benin', 'BM' => 'Bermuda', 'BN' => 'Brunei', 'BO' => 'Bolivia', 'BR' => 'Brazil', 'BS' => 'Bahamas', 'BT' => 'Bhutan', 'BV' => 'Bouvet Island', 'BW' => 'Botswana', 'BY' => 'Belarus', 'BZ' => 'Belize', 'CA' => 'Canada', 'CC' => 'Cocos [Keeling] Islands', 'CD' => 'Congo [DRC]', 'CF' => 'Central African Republic', 'CG' => 'Congo [Republic]', 'CH' => 'Switzerland', 'CI' => +"Côte d'Ivoire", 'CK' => 'Cook Islands', 'CL' => 'Chile', 'CM' => 'Cameroon', 'CN' => 'China', 'CO' => 'Colombia', 'CR' => 'Costa Rica', 'CU' => 'Cuba', 'CV' => 'Cape Verde', 'CX' => 'Christmas Island', 'CY' => 'Cyprus', 'CZ' => 'Czech Republic', 'DE' => 'Germany', 'DJ' => 'Djibouti', 'DK' => 'Denmark', 'DM' => 'Dominica', 'DO' => 'Dominican Republic', 'DZ' => 'Algeria', 'EC' => 'Ecuador', 'EE' => 'Estonia', 'EG' => 'Egypt', 'EH' => 'Western Sahara', 'ER' => 'Eritrea', 'ES' => 'Spain', 'ET' => 'Ethiopia', 'FI' => 'Finland', 'FJ' => 'Fiji', 'FK' => 'Falkland Islands [Islas Malvinas]', 'FM' => 'Micronesia', 'FO' => 'Faroe Islands', 'FR' => 'France', 'GA' => 'Gabon', 'GB' => 'United Kingdom', 'GD' => 'Grenada', 'GE' => 'Georgia', 'GF' => 'French Guiana', 'GG' => 'Guernsey', 'GH' => 'Ghana', 'GI' => 'Gibraltar', 'GL' => 'Greenland', 'GM' => 'Gambia', 'GN' => 'Guinea', 'GP' => 'Guadeloupe', 'GQ' => 'Equatorial Guinea', 'GR' => 'Greece', 'GS' => 'South Georgia and the South Sandwich Islands', 'GT' => 'Guatemala', 'GU' => 'Guam', 'GW' => 'Guinea-Bissau', 'GY' => 'Guyana', 'GZ' => 'Gaza Strip', 'HK' => 'Hong Kong', 'HM' => 'Heard Island and McDonald Islands', 'HN' => 'Honduras', 'HR' => 'Croatia', 'HT' => 'Haiti', 'HU' => 'Hungary', 'ID' => 'Indonesia', 'IE' => 'Ireland', 'IL' => 'Israel', 'IM' => 'Isle of Man', 'IN' => 'India', 'IO' => 'British Indian Ocean Territory', 'IQ' => 'Iraq', 'IR' => 'Iran', 'IS' => 'Iceland', 'IT' => 'Italy', 'JE' => 'Jersey', 'JM' => 'Jamaica', 'JO' => 'Jordan', 'JP' => 'Japan', 'KE' => 'Kenya', 'KG' => 'Kyrgyzstan', 'KH' => 'Cambodia', 'KI' => 'Kiribati', 'KM' => 'Comoros', 'KN' => 'Saint Kitts and Nevis', 'KP' => 'North Korea', 'KR' => 'South Korea', 'KW' => 'Kuwait', 'KY' => 'Cayman Islands', 'KZ' => 'Kazakhstan', 'LA' => 'Laos', 'LB' => 'Lebanon', 'LC' => 'Saint Lucia', 'LI' => 'Liechtenstein', 'LK' => 'Sri Lanka', 'LR' => 'Liberia', 'LS' => 'Lesotho', 'LT' => 'Lithuania', 'LU' => 'Luxembourg', 'LV' => 'Latvia', 'LY' => 'Libya', 'MA' => 'Morocco', 'MC' => 'Monaco', 'MD' => 'Moldova', 'ME' => 'Montenegro', 'MG' => 'Madagascar', 'MH' => 'Marshall Islands', 'MK' => 'Macedonia [FYROM]', 'ML' => 'Mali', 'MM' => 'Myanmar [Burma]', 'MN' => 'Mongolia', 'MO' => 'Macau', 'MP' => 'Northern Mariana Islands', 'MQ' => 'Martinique', 'MR' => 'Mauritania', 'MS' => 'Montserrat', 'MT' => 'Malta', 'MU' => 'Mauritius', 'MV' => 'Maldives', 'MW' => 'Malawi', 'MX' => 'Mexico', 'MY' => 'Malaysia', 'MZ' => 'Mozambique', 'NA' => 'Namibia', 'NC' => 'New Caledonia', 'NE' => 'Niger', 'NF' => 'Norfolk Island', 'NG' => 'Nigeria', 'NI' => 'Nicaragua', 'NL' => 'Netherlands', 'NO' => 'Norway', 'NP' => 'Nepal', 'NR' => 'Nauru', 'NU' => 'Niue', 'NZ' => 'New Zealand', 'OM' => 'Oman', 'PA' => 'Panama', 'PE' => 'Peru', 'PF' => 'French Polynesia', 'PG' => 'Papua New Guinea', 'PH' => 'Philippines', 'PK' => 'Pakistan', 'PL' => 'Poland', 'PM' => 'Saint Pierre and Miquelon', 'PN' => 'Pitcairn Islands', 'PR' => 'Puerto Rico', 'PS' => 'Palestinian Territories', 'PT' => 'Portugal', 'PW' => 'Palau', 'PY' => 'Paraguay', 'QA' => 'Qatar', 'RE' => 'Réunion', 'RO' => 'Romania', 'RS' => 'Serbia', 'RU' => 'Russia', 'RW' => 'Rwanda', 'SA' => 'Saudi Arabia', 'SB' => 'Solomon Islands', 'SC' => 'Seychelles', 'SD' => 'Sudan', 'SE' => 'Sweden', 'SG' => 'Singapore', 'SH' => 'Saint Helena', 'SI' => 'Slovenia', 'SJ' => 'Svalbard and Jan Mayen', 'SK' => 'Slovakia', 'SL' => 'Sierra Leone', 'SM' => 'San Marino', 'SN' => 'Senegal', 'SO' => 'Somalia', 'SR' => 'Suriname', 'ST' => 'São Tomé and Príncipe', 'SV' => 'El Salvador', 'SY' => 'Syria', 'SZ' => 'Swaziland', 'TC' => 'Turks and Caicos Islands', 'TD' => 'Chad', 'TF' => 'French Southern Territories', 'TG' => 'Togo', 'TH' => 'Thailand', 'TJ' => 'Tajikistan', 'TK' => 'Tokelau', 'TL' => 'Timor-Leste', 'TM' => 'Turkmenistan', 'TN' => 'Tunisia', 'TO' => 'Tonga', 'TR' => 'Turkey', 'TT' => 'Trinidad and Tobago', 'TV' => 'Tuvalu', 'TW' => 'Taiwan', 'TZ' => 'Tanzania', 'UA' => 'Ukraine', 'UG' => 'Uganda', 'UM' => 'U.S. Minor Outlying Islands', 'US' => 'United States', 'UY' => 'Uruguay', 'UZ' => 'Uzbekistan', 'VA' => 'Vatican City', 'VC' => 'Saint Vincent and the Grenadines', 'VE' => 'Venezuela', 'VG' => 'British Virgin Islands', 'VI' => 'U.S. Virgin Islands', 'VN' => 'Vietnam', 'VU' => 'Vanuatu', 'WF' => 'Wallis and Futuna', 'WS' => 'Samoa', 'XK' => 'Kosovo', 'YE' => 'Yemen', 'YT' => 'Mayotte', 'ZA' => 'South Africa', 'ZM' => 'Zambia', 'ZW' => 'Zimbabwe', + ]; */ + // Construction du tableau final pour le 2e groupe + /* $other_countries = []; + foreach ($csv_countries as $code => $en_name) { + if (!isset($main_countries[$code])) { + $label = isset($country_fr[$code]) ? $country_fr[$code] : $en_name; + $other_countries[$code] = $label; + } + } + asort($other_countries, SORT_LOCALE_STRING); */ + + if($is_credit_pat) { + $main_countries = $pat_countries; + } + // Persistance de la sélection + $selected = isset($_POST['conationality']) ? $_POST['conationality'] : $model->getFieldValue('nationality', $coBorrower); + ?> + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + +
    +
    + +
    +
    + +
    + Étape précédente + +
    +
    +
    +
    +
    +
    + + + +
    +
    \ No newline at end of file diff --git a/templates/front/credit-step4.php b/templates/front/credit-step4.php new file mode 100644 index 0000000..34966b6 --- /dev/null +++ b/templates/front/credit-step4.php @@ -0,0 +1,243 @@ + 'Belgique', + 'LU' => 'Luxembourg', +]; + +$selected = $model->getFieldValue('nationalite', $borrower); + +// Définir si un co-emprunteur existe +$has_co_borrower = is_object($coBorrower); + +if($has_co_borrower) { + $selectedCoBorrower = $model->getFieldValue('nationalite', $coBorrower); +} + +// Vérifier si c'est un crédit PAT +$is_credit_pat = ($currentCredit->type_credit === 'pat'); + +// Liste de traduction FR pour les autres pays +$country_fr = [ + 'AD' => 'Andorre', 'AL' => 'Albanie', 'AT' => 'Autriche', 'BA' => 'Bosnie-Herzégovine', 'BG' => 'Bulgarie', 'BY' => 'Biélorussie', 'CH' => 'Suisse', 'CZ' => 'Tchéquie', 'DK' => 'Danemark', 'EE' => 'Estonie', 'ES' => 'Espagne', 'FI' => 'Finlande', 'GB' => 'Royaume-Uni', 'GR' => 'Grèce', 'HR' => 'Croatie', 'HU' => 'Hongrie', 'IE' => 'Irlande', 'IS' => 'Islande', 'IT' => 'Italie', 'LT' => 'Lituanie', 'LV' => 'Lettonie', 'MC' => 'Monaco', 'MD' => 'Moldavie', 'ME' => 'Monténégro', 'MK' => 'Macédoine du Nord', 'MT' => 'Malte', 'NO' => 'Norvège', 'PL' => 'Pologne', 'PT' => 'Portugal', 'RO' => 'Roumanie', 'RS' => 'Serbie', 'RU' => 'Russie', 'SE' => 'Suède', 'SI' => 'Slovénie', 'SK' => 'Slovaquie', 'SM' => 'Saint-Marin', 'UA' => 'Ukraine', 'VA' => 'Vatican', +]; + +// Liste CSV (code => nom anglais) +$csv_countries = [ + 'AD' => 'Andorra', 'AE' => 'United Arab Emirates', 'AF' => 'Afghanistan', 'AG' => 'Antigua and Barbuda', 'AI' => 'Anguilla', 'AL' => 'Albania', 'AM' => 'Armenia', 'AN' => 'Netherlands Antilles', 'AO' => 'Angola', 'AQ' => 'Antarctica', 'AR' => 'Argentina', 'AS' => 'American Samoa', 'AT' => 'Austria', 'AU' => 'Australia', 'AW' => 'Aruba', 'AZ' => 'Azerbaijan', 'BA' => 'Bosnia and Herzegovina', 'BB' => 'Barbados', 'BD' => 'Bangladesh', 'BE' => 'Belgium', 'BF' => 'Burkina Faso', 'BG' => 'Bulgaria', 'BH' => 'Bahrain', 'BI' => 'Burundi', 'BJ' => 'Benin', 'BM' => 'Bermuda', 'BN' => 'Brunei', 'BO' => 'Bolivia', 'BR' => 'Brazil', 'BS' => 'Bahamas', 'BT' => 'Bhutan', 'BV' => 'Bouvet Island', 'BW' => 'Botswana', 'BY' => 'Belarus', 'BZ' => 'Belize', 'CA' => 'Canada', 'CC' => 'Cocos [Keeling] Islands', 'CD' => 'Congo [DRC]', 'CF' => 'Central African Republic', 'CG' => 'Congo [Republic]', 'CH' => 'Switzerland', 'CI' => "Côte d'Ivoire", 'CK' => 'Cook Islands', 'CL' => 'Chile', 'CM' => 'Cameroon', 'CN' => 'China', 'CO' => 'Colombia', 'CR' => 'Costa Rica', 'CU' => 'Cuba', 'CV' => 'Cape Verde', 'CX' => 'Christmas Island', 'CY' => 'Cyprus', 'CZ' => 'Czech Republic', 'DE' => 'Germany', 'DJ' => 'Djibouti', 'DK' => 'Denmark', 'DM' => 'Dominica', 'DO' => 'Dominican Republic', 'DZ' => 'Algeria', 'EC' => 'Ecuador', 'EE' => 'Estonia', 'EG' => 'Egypt', 'EH' => 'Western Sahara', 'ER' => 'Eritrea', 'ES' => 'Spain', 'ET' => 'Ethiopia', 'FI' => 'Finland', 'FJ' => 'Fiji', 'FK' => 'Falkland Islands [Islas Malvinas]', 'FM' => 'Micronesia', 'FO' => 'Faroe Islands', 'FR' => 'France', 'GA' => 'Gabon', 'GB' => 'United Kingdom', 'GD' => 'Grenada', 'GE' => 'Georgia', 'GF' => 'French Guiana', 'GG' => 'Guernsey', 'GH' => 'Ghana', 'GI' => 'Gibraltar', 'GL' => 'Greenland', 'GM' => 'Gambia', 'GN' => 'Guinea', 'GP' => 'Guadeloupe', 'GQ' => 'Equatorial Guinea', 'GR' => 'Greece', 'GS' => 'South Georgia and the South Sandwich Islands', 'GT' => 'Guatemala', 'GU' => 'Guam', 'GW' => 'Guinea-Bissau', 'GY' => 'Guyana', 'GZ' => 'Gaza Strip', 'HK' => 'Hong Kong', 'HM' => 'Heard Island and McDonald Islands', 'HN' => 'Honduras', 'HR' => 'Croatia', 'HT' => 'Haiti', 'HU' => 'Hungary', 'ID' => 'Indonesia', 'IE' => 'Ireland', 'IL' => 'Israel', 'IM' => 'Isle of Man', 'IN' => 'India', 'IO' => 'British Indian Ocean Territory', 'IQ' => 'Iraq', 'IR' => 'Iran', 'IS' => 'Iceland', 'IT' => 'Italy', 'JE' => 'Jersey', 'JM' => 'Jamaica', 'JO' => 'Jordan', 'JP' => 'Japan', 'KE' => 'Kenya', 'KG' => 'Kyrgyzstan', 'KH' => 'Cambodia', 'KI' => 'Kiribati', 'KM' => 'Comoros', 'KN' => 'Saint Kitts and Nevis', 'KP' => 'North Korea', 'KR' => 'South Korea', 'KW' => 'Kuwait', 'KY' => 'Cayman Islands', 'KZ' => 'Kazakhstan', 'LA' => 'Laos', 'LB' => 'Lebanon', 'LC' => 'Saint Lucia', 'LI' => 'Liechtenstein', 'LK' => 'Sri Lanka', 'LR' => 'Liberia', 'LS' => 'Lesotho', 'LT' => 'Lithuania', 'LU' => 'Luxembourg', 'LV' => 'Latvia', 'LY' => 'Libya', 'MA' => 'Morocco', 'MC' => 'Monaco', 'MD' => 'Moldova', 'ME' => 'Montenegro', 'MG' => 'Madagascar', 'MH' => 'Marshall Islands', 'MK' => 'Macedonia [FYROM]', 'ML' => 'Mali', 'MM' => 'Myanmar [Burma]', 'MN' => 'Mongolia', 'MO' => 'Macau', 'MP' => 'Northern Mariana Islands', 'MQ' => 'Martinique', 'MR' => 'Mauritania', 'MS' => 'Montserrat', 'MT' => 'Malta', 'MU' => 'Mauritius', 'MV' => 'Maldives', 'MW' => 'Malawi', 'MX' => 'Mexico', 'MY' => 'Malaysia', 'MZ' => 'Mozambique', 'NA' => 'Namibia', 'NC' => 'New Caledonia', 'NE' => 'Niger', 'NF' => 'Norfolk Island', 'NG' => 'Nigeria', 'NI' => 'Nicaragua', 'NL' => 'Netherlands', 'NO' => 'Norway', 'NP' => 'Nepal', 'NR' => 'Nauru', 'NU' => 'Niue', 'NZ' => 'New Zealand', 'OM' => 'Oman', 'PA' => 'Panama', 'PE' => 'Peru', 'PF' => 'French Polynesia', 'PG' => 'Papua New Guinea', 'PH' => 'Philippines', 'PK' => 'Pakistan', 'PL' => 'Poland', 'PM' => 'Saint Pierre and Miquelon', 'PN' => 'Pitcairn Islands', 'PR' => 'Puerto Rico', 'PS' => 'Palestinian Territories', 'PT' => 'Portugal', 'PW' => 'Palau', 'PY' => 'Paraguay', 'QA' => 'Qatar', 'RE' => 'Réunion', 'RO' => 'Romania', 'RS' => 'Serbia', 'RU' => 'Russia', 'RW' => 'Rwanda', 'SA' => 'Saudi Arabia', 'SB' => 'Solomon Islands', 'SC' => 'Seychelles', 'SD' => 'Sudan', 'SE' => 'Sweden', 'SG' => 'Singapore', 'SH' => 'Saint Helena', 'SI' => 'Slovenia', 'SJ' => 'Svalbard and Jan Mayen', 'SK' => 'Slovakia', 'SL' => 'Sierra Leone', 'SM' => 'San Marino', 'SN' => 'Senegal', 'SO' => 'Somalia', 'SR' => 'Suriname', 'ST' => 'São Tomé and Príncipe', 'SV' => 'El Salvador', 'SY' => 'Syria', 'SZ' => 'Swaziland', 'TC' => 'Turks and Caicos Islands', 'TD' => 'Chad', 'TF' => 'French Southern Territories', 'TG' => 'Togo', 'TH' => 'Thailand', 'TJ' => 'Tajikistan', 'TK' => 'Tokelau', 'TL' => 'Timor-Leste', 'TM' => 'Turkmenistan', 'TN' => 'Tunisia', 'TO' => 'Tonga', 'TR' => 'Turkey', 'TT' => 'Trinidad and Tobago', 'TV' => 'Tuvalu', 'TW' => 'Taiwan', 'TZ' => 'Tanzania', 'UA' => 'Ukraine', 'UG' => 'Uganda', 'UM' => 'U.S. Minor Outlying Islands', 'US' => 'United States', 'UY' => 'Uruguay', 'UZ' => 'Uzbekistan', 'VA' => 'Vatican City', 'VC' => 'Saint Vincent and the Grenadines', 'VE' => 'Venezuela', 'VG' => 'British Virgin Islands', 'VI' => 'U.S. Virgin Islands', 'VN' => 'Vietnam', 'VU' => 'Vanuatu', 'WF' => 'Wallis and Futuna', 'WS' => 'Samoa', 'XK' => 'Kosovo', 'YE' => 'Yemen', 'YT' => 'Mayotte', 'ZA' => 'South Africa', 'ZM' => 'Zambia', 'ZW' => 'Zimbabwe', +]; + +// Construction du tableau final pour le 2e groupe +$other_countries = []; +foreach ($csv_countries as $code => $en_name) { + if (!isset($main_countries[$code])) { + $label = isset($country_fr[$code]) ? $country_fr[$code] : $en_name; + $other_countries[$code] = $label; + } +} +asort($other_countries, SORT_LOCALE_STRING); + +$exemple_info = $model->get_exemples_infos($currentCredit->type_credit); +?> + +
    +
    +
    +

    Introduction de votre demande de crédit

    +
    +
    +
    + + + +
    +
    +
    +
    + +
    +
    + 1 + Contact +
    +
    + 2 + Revenus & charges +
    +
    + 3 + Informations personnelles +
    +
    + 4 + Coordonnées +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    + Emprunteur + Données personnelles + +
    + + +
    +
    + +
    +
    + + +
    +
    + + + +
    +
    + + +
    +
    + +
    + Données professionnelles + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    + + +
    + Co-Emprunteur + Données personnelles + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    + Données professionnelles + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + + +
    +
    + + Étape précédente +
    + +
    +
    +
    +
    +
    +
    +
    + + + +
    +
    \ No newline at end of file diff --git a/templates/front/credit-step5.php b/templates/front/credit-step5.php new file mode 100644 index 0000000..0177f92 --- /dev/null +++ b/templates/front/credit-step5.php @@ -0,0 +1,137 @@ +type_credit == 'am' ? true : false; + +$form_action = $show_all_form ? '#' : '/credit-step5'; + +$submit_label = $show_all_form ? 'Envoyer demande' : 'Étape suivante'; + +$taeg = str_replace('%', '', $currentCredit->taux_nominal_annuel); + +$taux_debiteur = $currentCredit->taux_nominal_annuel; + +$estateloantype = isset($_POST['estateloantype']) ? $_POST['estateloantype'] : ''; + +if (array_key_exists( + $estateloantype, + $mapHouseCreditTypes +)) { + $taux_debiteur = number_format(($taeg * 0.11) + $taeg, 2); +} + +?> + +
    +
    +
    +
    +

    Introduction de votre demande de crédit

    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    + Type: + +
    +
    + Montant: + capital ?> € +
    +
    + Taux débiteur: + taux_nominal_annuel ?> +
    +
    + Durée: + duree ?> type_credit === 'am'): ?>ansmois +
    +
    + Mensualité: + mensualite ?>€ +
    +
    + TAEG: + +
    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + +
    +
    + 1 + Contact +
    +
    + 2 + Revenus & charges +
    +
    + 3 + Informations personnelles +
    +
    + 4 + Coordonnées +
    +
    + 5 + Conclusion +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +

    Félicitations ! Votre demande de crédit a été enregistrée

    +

    Nous avons bien reçu votre demande de crédit. Un conseiller vous contactera dans les plus brefs délais pour finaliser votre dossier.

    + +
    +

    Récapitulatif de votre demande

    +
    +
    +

    Type de crédit:

    +

    Montant: capital ?> €

    +

    Durée: duree ?> type_credit === 'am'): ?>ansmois

    +
    +
    +

    TAEG: taux_nominal_annuel ?>

    +

    Mensualité: mensualite ?> €

    +

    Date de demande: format('d/m/Y') ?>

    +
    +
    +
    + + +
    +
    +
    +
    \ No newline at end of file diff --git a/templates/front/credit-steps2-c.php b/templates/front/credit-steps2-c.php new file mode 100644 index 0000000..4566e57 --- /dev/null +++ b/templates/front/credit-steps2-c.php @@ -0,0 +1,182 @@ +
    +
    +
    + +
    + + +
    +
    +
    + +
    + +

    Si un crédit est en commun avec le co-emprunter, merci de ne l'encoder qu'une seule fois.

    + + +
    + + + +
    +
    + + get_results( "SELECT * FROM cdf_Type_creance"); ?> + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    + + +
    +
    + + +
    +
    +
    À clôturer / Solder ?
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + + +
    + +
    + +
    +
    + Co-Emprunteur + Crédits(s) en cours + +
    + +
    + + +
    +
    + +
    +
    + + + +
    +
    + + + get_results( "SELECT * FROM cdf_Type_creance"); ?> + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    + + +
    +
    + + +
    +
    +
    À clôturer / Solder ?
    + +
    + + +
    +
    + + +
    +
    + + +
    + +
    + + +
    +
    + + + + + +
    +
    \ No newline at end of file diff --git a/templates/front/newSim.php b/templates/front/newSim.php new file mode 100644 index 0000000..a101b3a --- /dev/null +++ b/templates/front/newSim.php @@ -0,0 +1,311 @@ +
    + +
    +
    +

    1 Choisissez votre crédit

    + +
    + +
    + + + + + + +
    +
    +

    2 Détail de votre crédit

    + +
    + +
    Capital choisi
    + +
    +
    + +
    + +
    +
    + + 1300 + +
    +
    +
    + +
    + +
    +
    + + +
    + +
    Exemple de durée standard
    +
    +
    + + + + +
    + +
      +
    • 10 ans
    • +
    • 15 ans
    • +
    • 20 ans
    • +
    • 25 ans
    • +
    • 30 ans
    • +
    + +
      +
    • 24
    • +
    • 30
    • +
    • 36
    • +
    • 42
    • +
    • 48
    • +
    • 60
    • +
    • 72
    • +
    • 84
    • +
    • 96
    • +
    • 108
    • +
    • 120
    • +
    + +
    + +
    + +
    + + +
    +
    Votre durée
    +
    + +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    +
    + + 24 + +
    +
    +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    +

    3Résultat de votre simulation

    +
    + +
    +
    Montant emprunté :
    +
    1300
    +
    +
    +
    Durée :
    +
    24
    +
    +
    +
    Mensualité :
    +
    61.63
    +
    + +
    Taux débiteur :
    0
    +
    TAEG* :
    0
    + +
    Taux débiteur :
    0
    +
    TAEG :
    0
    + +
    +
    Coût total :
    +
    0
    +
    +
    + + + + + + + + +
    +
    +

    En un simple clic et sans engagement, demandez votre crédit

    +
    + +
    Attention, emprunter de l'argent coûte aussi de l'argent.
    +
    +
    +
    +
    + + + + + +
    + +
    + +
    + +
    + + + + + + + +
    \ No newline at end of file diff --git a/templates/front/newSteps/credi-step4.php b/templates/front/newSteps/credi-step4.php new file mode 100644 index 0000000..9a4e173 --- /dev/null +++ b/templates/front/newSteps/credi-step4.php @@ -0,0 +1,126 @@ +
    +
    +
    + + +
    +
      +
    • Coordonées
    • +
    • Emprunteur
    • +
    • Crédit
    • +
    +
    + +
    +
    + Emprunteur + Données personnelles + +
    + + +
    +
    + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    + Données professionnelles + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    + + +
    + Co-Emprunteur + Données personnelles + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    + Données professionnelles + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + + + +
    +
    +
    \ No newline at end of file diff --git a/templates/front/newSteps/credit-newstep2-a.php b/templates/front/newSteps/credit-newstep2-a.php new file mode 100644 index 0000000..2a90c20 --- /dev/null +++ b/templates/front/newSteps/credit-newstep2-a.php @@ -0,0 +1,232 @@ +
    +
    +
    + + +
    +
      +
    • Coordonées
    • +
    • Emprunteur
    • +
    • Crédit
    • +
    +
    + +
    +
    +
    J'emprunte ?
    +
    + + +
    +
    + + +
    +
    + +
    + +
    +
    +
    +

    Emprunteur

    + Coordonnées de contact +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + Votre profession et Revenus +
    + + get_results("SELECT * FROM cdf_Etat_civil"); ?> + + +
    + +
    + + get_results("SELECT * FROM cdf_Profession"); ?> + + +
    + +
    + + + +
    +
    + + +
    +
    + +
    +
    +
    + + +
    +
    + + +
    +
    +
    + +
    +
    Autres revenus
    +
    + + +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    + +
    +
    Etes-vous fichez à la Banque Nationale ?
    +
    + + +
    +
    + + +
    +
    + +
    +
    +
    +

    Statut du fichage

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    + +
    +
    +
    Statut du logement
    + +
    +
    + +
    +
    +
    +
    Montant du loyer mensuel ou participation aux charges
    + +
    +
    +
    + +
    +
    \ No newline at end of file diff --git a/templates/front/newSteps/credit-newstep2-b.php b/templates/front/newSteps/credit-newstep2-b.php new file mode 100644 index 0000000..ccd287c --- /dev/null +++ b/templates/front/newSteps/credit-newstep2-b.php @@ -0,0 +1,161 @@ +
    +
    +
    + Co Emprunteur +
    + +
    +
    + + +
    + +
    + + get_results("SELECT * FROM cdf_Etat_civil"); ?> + + +
    + +
    + + get_results("SELECT * FROM cdf_Profession"); ?> + + +
    + +
    + + + +
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + + +
    +
    Autres revenus
    +
    + + +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    \ No newline at end of file diff --git a/templates/front/newSteps/credit-step2-a.php b/templates/front/newSteps/credit-step2-a.php new file mode 100644 index 0000000..6f701dc --- /dev/null +++ b/templates/front/newSteps/credit-step2-a.php @@ -0,0 +1,237 @@ +
    +
    +
    + + +
    +
      +
    • Coordonées
    • +
    • Emprunteur
    • +
    • Crédit
    • +
    +
    + +
    +
    +
    J'emprunte ?
    +
    + + +
    +
    + + +
    +
    + +
    + +
    +
    +
    +

    Emprunteur

    + Coordonnées de contact +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + Votre profession et Revenus +
    + + get_results("SELECT * FROM cdf_Etat_civil"); ?> + + +
    + +
    + + get_results("SELECT * FROM cdf_Profession"); ?> + + +
    + +
    + + + +
    +
    + + +
    +
    + +
    +
    +
    + + +
    +
    + + +
    +
    +
    + +
    +
    Autres revenus
    +
    + + +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    + +
    +
    Etes-vous fichez à la Banque Nationale ?
    +
    + + +
    +
    + + +
    +
    + +
    +
    +
    +

    Statut du fichage

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    + +
    +
    +
    Statut du logement
    + +
    +
    + +
    +
    +
    +
    Montant du loyer mensuel ou participation aux charges
    + +
    +
    +
    + + +
    + +
    + +
    +
    \ No newline at end of file diff --git a/templates/front/newSteps/credit-step2-b.php b/templates/front/newSteps/credit-step2-b.php new file mode 100644 index 0000000..fe230be --- /dev/null +++ b/templates/front/newSteps/credit-step2-b.php @@ -0,0 +1,212 @@ +
    +
    +
    + Co Emprunteur + Coordonnées de contact + +
    + + +
    +
    + + +
    +
    + +
    +
    + + +
    + +
    + + get_results("SELECT * FROM cdf_Etat_civil"); ?> + + +
    + +
    + + get_results("SELECT * FROM cdf_Profession"); ?> + + +
    + +
    + + + +
    + +
    + + +
    +
    + +
    +
    +
    + + +
    +
    + + +
    +
    +
    + + + + +
    +
    Autres revenus
    +
    + + +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    + +
    +
    +
    +
    +
    + +
    +
    Etes-vous fichez à la Banque Nationale ?
    +
    + + +
    +
    + + +
    +
    + +
    +
    +
    +

    Statut du fichage

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    + +
    +
    +
    Statut du logement
    + +
    +
    + +
    +
    +
    +
    Montant du loyer mensuel ou participation aux charges
    + +
    +
    +
    + +
    +
    + diff --git a/templates/front/newSteps/credit-step3.php b/templates/front/newSteps/credit-step3.php new file mode 100644 index 0000000..26eb6fd --- /dev/null +++ b/templates/front/newSteps/credit-step3.php @@ -0,0 +1,99 @@ +
    +
    + + + + +
    +
      +
    • Coordonées
    • +
    • Emprunteur
    • +
    • Crédit
    • +
    +
    + +
    +
    + Emprunteur + Données personnelles +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    + + +
    +
    + Co-Emprunteur + Données personnelles +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    + + + + + +
    +
    \ No newline at end of file diff --git a/templates/front/newSteps/credit-steps2-c.php b/templates/front/newSteps/credit-steps2-c.php new file mode 100644 index 0000000..4566e57 --- /dev/null +++ b/templates/front/newSteps/credit-steps2-c.php @@ -0,0 +1,182 @@ +
    +
    +
    + +
    + + +
    +
    +
    + +
    + +

    Si un crédit est en commun avec le co-emprunter, merci de ne l'encoder qu'une seule fois.

    + + +
    + + + +
    +
    + + get_results( "SELECT * FROM cdf_Type_creance"); ?> + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    + + +
    +
    + + +
    +
    +
    À clôturer / Solder ?
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + + +
    + +
    + +
    +
    + Co-Emprunteur + Crédits(s) en cours + +
    + +
    + + +
    +
    + +
    +
    + + + +
    +
    + + + get_results( "SELECT * FROM cdf_Type_creance"); ?> + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    + + +
    +
    + + +
    +
    +
    À clôturer / Solder ?
    + +
    + + +
    +
    + + +
    +
    + + +
    + +
    + + +
    +
    + + + + + +
    +
    \ No newline at end of file diff --git a/templates/front/old/credit-one-step.php b/templates/front/old/credit-one-step.php new file mode 100644 index 0000000..5a61847 --- /dev/null +++ b/templates/front/old/credit-one-step.php @@ -0,0 +1,591 @@ + 'Locataire', + 'owner' => 'Proprietaire', + 'withoutrentalcharge' => 'Sans charge locative' +]; + +$map_credit_hypothecaire_en_cours = [ + 'withmortgageloan' => 'Avec credit hypothecaire', + 'mortgagechargeiber' => 'Libre de charge hypothecaire' +]; + +$map_sans_charge_locative = [ + 'other' => 'Autre', + 'withparents' => 'Chez les parents', + 'cohabitant' => 'Cohabitant', + 'family' => 'Famille' +]; + +$taeg = str_replace('%', '', $currentCredit->taux_nominal_annuel); +$taux_debiteur = number_format(($taeg * 0.11) + $taeg, 2); + +$exemple_info = $model->get_exemples_infos($currentCredit->type_credit); + +?> +
    +
    +
    +
    +

    Introduction de votre demande de crédit

    +
    +
    +
    +
    + +
    +
    +
    +
    +

    Type de crédit:

    +
    +
    +
    +
    +
    +
    + Montant: + capital ?? '') ?> € +
    +
    + Taux débiteur: + taux_nominal_annuel ?? '') ?> +
    +
    + Durée: + duree ?? '') ?> + type_credit === 'am'): ?>ansmois +
    +
    + Mensualité: + mensualite ?? '') ?>€ +
    +
    + Coût total: + cout_total ?? '') ?>€ +
    +
    + TAEG: + % +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    + +
    + +
    + Informations de contact + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + +
    + + +
    +
    + + 'Belgique', + 'LU' => 'Luxembourg', + 'FR' => 'France', + 'DE' => 'Allemagne', + 'NL' => 'Pays-Bas', + ]; + // Liste de traduction FR pour les autres pays (extrait, à compléter si besoin) + $country_fr = [ + 'AD' => 'Andorre', 'AL' => 'Albanie', 'AT' => 'Autriche', 'BA' => 'Bosnie-Herzégovine', 'BG' => 'Bulgarie', 'BY' => 'Biélorussie', 'CH' => 'Suisse', 'CZ' => 'Tchéquie', 'DK' => 'Danemark', 'EE' => 'Estonie', 'ES' => 'Espagne', 'FI' => 'Finlande', 'GB' => 'Royaume-Uni', 'GR' => 'Grèce', 'HR' => 'Croatie', 'HU' => 'Hongrie', 'IE' => 'Irlande', 'IS' => 'Islande', 'IT' => 'Italie', 'LT' => 'Lituanie', 'LV' => 'Lettonie', 'MC' => 'Monaco', 'MD' => 'Moldavie', 'ME' => 'Monténégro', 'MK' => 'Macédoine du Nord', 'MT' => 'Malte', 'NO' => 'Norvège', 'PL' => 'Pologne', 'PT' => 'Portugal', 'RO' => 'Roumanie', 'RS' => 'Serbie', 'RU' => 'Russie', 'SE' => 'Suède', 'SI' => 'Slovénie', 'SK' => 'Slovaquie', 'SM' => 'Saint-Marin', 'UA' => 'Ukraine', 'VA' => 'Vatican', + // ... compléter si besoin ... + ]; + // Liste CSV (code => nom anglais) + $csv_countries = [ + 'AD' => 'Andorra', 'AE' => 'United Arab Emirates', 'AF' => 'Afghanistan', 'AG' => 'Antigua and Barbuda', 'AI' => 'Anguilla', 'AL' => 'Albania', 'AM' => 'Armenia', 'AN' => 'Netherlands Antilles', 'AO' => 'Angola', 'AQ' => 'Antarctica', 'AR' => 'Argentina', 'AS' => 'American Samoa', 'AT' => 'Austria', 'AU' => 'Australia', 'AW' => 'Aruba', 'AZ' => 'Azerbaijan', 'BA' => 'Bosnia and Herzegovina', 'BB' => 'Barbados', 'BD' => 'Bangladesh', 'BE' => 'Belgium', 'BF' => 'Burkina Faso', 'BG' => 'Bulgaria', 'BH' => 'Bahrain', 'BI' => 'Burundi', 'BJ' => 'Benin', 'BM' => 'Bermuda', 'BN' => 'Brunei', 'BO' => 'Bolivia', 'BR' => 'Brazil', 'BS' => 'Bahamas', 'BT' => 'Bhutan', 'BV' => 'Bouvet Island', 'BW' => 'Botswana', 'BY' => 'Belarus', 'BZ' => 'Belize', 'CA' => 'Canada', 'CC' => 'Cocos [Keeling] Islands', 'CD' => 'Congo [DRC]', 'CF' => 'Central African Republic', 'CG' => 'Congo [Republic]', 'CH' => 'Switzerland', 'CI' => +"Côte d'Ivoire", 'CK' => 'Cook Islands', 'CL' => 'Chile', 'CM' => 'Cameroon', 'CN' => 'China', 'CO' => 'Colombia', 'CR' => 'Costa Rica', 'CU' => 'Cuba', 'CV' => 'Cape Verde', 'CX' => 'Christmas Island', 'CY' => 'Cyprus', 'CZ' => 'Czech Republic', 'DE' => 'Germany', 'DJ' => 'Djibouti', 'DK' => 'Denmark', 'DM' => 'Dominica', 'DO' => 'Dominican Republic', 'DZ' => 'Algeria', 'EC' => 'Ecuador', 'EE' => 'Estonia', 'EG' => 'Egypt', 'EH' => 'Western Sahara', 'ER' => 'Eritrea', 'ES' => 'Spain', 'ET' => 'Ethiopia', 'FI' => 'Finland', 'FJ' => 'Fiji', 'FK' => 'Falkland Islands [Islas Malvinas]', 'FM' => 'Micronesia', 'FO' => 'Faroe Islands', 'FR' => 'France', 'GA' => 'Gabon', 'GB' => 'United Kingdom', 'GD' => 'Grenada', 'GE' => 'Georgia', 'GF' => 'French Guiana', 'GG' => 'Guernsey', 'GH' => 'Ghana', 'GI' => 'Gibraltar', 'GL' => 'Greenland', 'GM' => 'Gambia', 'GN' => 'Guinea', 'GP' => 'Guadeloupe', 'GQ' => 'Equatorial Guinea', 'GR' => 'Greece', 'GS' => 'South Georgia and the South Sandwich Islands', 'GT' => 'Guatemala', 'GU' => 'Guam', 'GW' => 'Guinea-Bissau', 'GY' => 'Guyana', 'GZ' => 'Gaza Strip', 'HK' => 'Hong Kong', 'HM' => 'Heard Island and McDonald Islands', 'HN' => 'Honduras', 'HR' => 'Croatia', 'HT' => 'Haiti', 'HU' => 'Hungary', 'ID' => 'Indonesia', 'IE' => 'Ireland', 'IL' => 'Israel', 'IM' => 'Isle of Man', 'IN' => 'India', 'IO' => 'British Indian Ocean Territory', 'IQ' => 'Iraq', 'IR' => 'Iran', 'IS' => 'Iceland', 'IT' => 'Italy', 'JE' => 'Jersey', 'JM' => 'Jamaica', 'JO' => 'Jordan', 'JP' => 'Japan', 'KE' => 'Kenya', 'KG' => 'Kyrgyzstan', 'KH' => 'Cambodia', 'KI' => 'Kiribati', 'KM' => 'Comoros', 'KN' => 'Saint Kitts and Nevis', 'KP' => 'North Korea', 'KR' => 'South Korea', 'KW' => 'Kuwait', 'KY' => 'Cayman Islands', 'KZ' => 'Kazakhstan', 'LA' => 'Laos', 'LB' => 'Lebanon', 'LC' => 'Saint Lucia', 'LI' => 'Liechtenstein', 'LK' => 'Sri Lanka', 'LR' => 'Liberia', 'LS' => 'Lesotho', 'LT' => 'Lithuania', 'LU' => 'Luxembourg', 'LV' => 'Latvia', 'LY' => 'Libya', 'MA' => 'Morocco', 'MC' => 'Monaco', 'MD' => 'Moldova', 'ME' => 'Montenegro', 'MG' => 'Madagascar', 'MH' => 'Marshall Islands', 'MK' => 'Macedonia [FYROM]', 'ML' => 'Mali', 'MM' => 'Myanmar [Burma]', 'MN' => 'Mongolia', 'MO' => 'Macau', 'MP' => 'Northern Mariana Islands', 'MQ' => 'Martinique', 'MR' => 'Mauritania', 'MS' => 'Montserrat', 'MT' => 'Malta', 'MU' => 'Mauritius', 'MV' => 'Maldives', 'MW' => 'Malawi', 'MX' => 'Mexico', 'MY' => 'Malaysia', 'MZ' => 'Mozambique', 'NA' => 'Namibia', 'NC' => 'New Caledonia', 'NE' => 'Niger', 'NF' => 'Norfolk Island', 'NG' => 'Nigeria', 'NI' => 'Nicaragua', 'NL' => 'Netherlands', 'NO' => 'Norway', 'NP' => 'Nepal', 'NR' => 'Nauru', 'NU' => 'Niue', 'NZ' => 'New Zealand', 'OM' => 'Oman', 'PA' => 'Panama', 'PE' => 'Peru', 'PF' => 'French Polynesia', 'PG' => 'Papua New Guinea', 'PH' => 'Philippines', 'PK' => 'Pakistan', 'PL' => 'Poland', 'PM' => 'Saint Pierre and Miquelon', 'PN' => 'Pitcairn Islands', 'PR' => 'Puerto Rico', 'PS' => 'Palestinian Territories', 'PT' => 'Portugal', 'PW' => 'Palau', 'PY' => 'Paraguay', 'QA' => 'Qatar', 'RE' => 'Réunion', 'RO' => 'Romania', 'RS' => 'Serbia', 'RU' => 'Russia', 'RW' => 'Rwanda', 'SA' => 'Saudi Arabia', 'SB' => 'Solomon Islands', 'SC' => 'Seychelles', 'SD' => 'Sudan', 'SE' => 'Sweden', 'SG' => 'Singapore', 'SH' => 'Saint Helena', 'SI' => 'Slovenia', 'SJ' => 'Svalbard and Jan Mayen', 'SK' => 'Slovakia', 'SL' => 'Sierra Leone', 'SM' => 'San Marino', 'SN' => 'Senegal', 'SO' => 'Somalia', 'SR' => 'Suriname', 'ST' => 'São Tomé and Príncipe', 'SV' => 'El Salvador', 'SY' => 'Syria', 'SZ' => 'Swaziland', 'TC' => 'Turks and Caicos Islands', 'TD' => 'Chad', 'TF' => 'French Southern Territories', 'TG' => 'Togo', 'TH' => 'Thailand', 'TJ' => 'Tajikistan', 'TK' => 'Tokelau', 'TL' => 'Timor-Leste', 'TM' => 'Turkmenistan', 'TN' => 'Tunisia', 'TO' => 'Tonga', 'TR' => 'Turkey', 'TT' => 'Trinidad and Tobago', 'TV' => 'Tuvalu', 'TW' => 'Taiwan', 'TZ' => 'Tanzania', 'UA' => 'Ukraine', 'UG' => 'Uganda', 'UM' => 'U.S. Minor Outlying Islands', 'US' => 'United States', 'UY' => 'Uruguay', 'UZ' => 'Uzbekistan', 'VA' => 'Vatican City', 'VC' => 'Saint Vincent and the Grenadines', 'VE' => 'Venezuela', 'VG' => 'British Virgin Islands', 'VI' => 'U.S. Virgin Islands', 'VN' => 'Vietnam', 'VU' => 'Vanuatu', 'WF' => 'Wallis and Futuna', 'WS' => 'Samoa', 'XK' => 'Kosovo', 'YE' => 'Yemen', 'YT' => 'Mayotte', 'ZA' => 'South Africa', 'ZM' => 'Zambia', 'ZW' => 'Zimbabwe', + ]; + // Construction du tableau final pour le 2e groupe + $other_countries = []; + foreach ($csv_countries as $code => $en_name) { + if (!isset($main_countries[$code])) { + $label = isset($country_fr[$code]) ? $country_fr[$code] : $en_name; + $other_countries[$code] = $label; + } + } + asort($other_countries, SORT_LOCALE_STRING); + // Persistance de la sélection + $selected = $model->getFieldValue('nationalite', $borrower); + ?> + +
    + +
    + + get_results( "SELECT * FROM cdf_Etat_civil"); ?> + + +
    + +
    + + +
    + +
    + +
    +
    + + +
    +
    + + +
    +
    +
    + +
    + But du prêt hypotécaire +
    + +
    + + +
    +
    + + +
    + +
    +
    + Compromis signé +
    +
    + + +
    +
    + + +
    +
    + +
    + + +
    +
    + + +
    +
    +
    +
    + + +
    +
    + + +
    + +
    +
    +
    + +
    + Revenus et charges + +
    + +
    + + get_results( "SELECT * FROM cdf_Profession"); ?> + + +
    + +
    + +
    + + + +
    + +
    + +
    +
    + + +
    + +
    + +
    + + +
    +
    + +
    +
    J'emprunte ?
    +
    + + +
    +
    + + +
    +
    +
    + + + + +
    +
    + Commentaires et informations complémentaires +
    + + +
    +
    +
    + +
    + + + + + +
    + + + + + + + + + + + + + +
    + +
    +
    + +
    +
    +
    +
    +

    Montant emprunté :

    + capital ?? '') ?> € + +

    Durée :

    + duree ?? '') ?> + type_credit === 'am'): ?>ansmois + +

    Mensualité :

    + mensualite ?? '') ?> € +
    + +
    +

    Coût Total :

    + cout_total ?? '') ?> € + +

    Taux débiteur :

    + taux_nominal_annuel ?? '') ?> + +

    Taeg :

    + % + + +
    +
    +
    + + + +
    + +
    + +
    +
    +
    \ No newline at end of file diff --git a/templates/front/old/credit-reminder.php b/templates/front/old/credit-reminder.php new file mode 100644 index 0000000..0314a73 --- /dev/null +++ b/templates/front/old/credit-reminder.php @@ -0,0 +1,67 @@ + 'Prêt à tempérament', + 'frais_notaire' => 'Financement frais de notaire', + 'but_immo' => 'Crédit travaux', + 'fin_neuve' => 'Financement véhicule NEUF', + 'fin_occ_m3a' => 'Financement véhicule d\'occasion MOINS de 3 ans', + 'fin_occ_p3a' => 'Financement véhicule d\'occasion PLUS de 3 ans', + 'am' => 'Crédit hypothécaire', + 'cied' => 'Indépendant et entreprise en difficulté' +]; + +echo 'vghvgvgjhv-2'; + +if ($credit_request) : + // Calculer le temps écoulé depuis la dernière mise à jour + $last_update = new DateTime($credit_request['last_update_date']); + $now = new DateTime(); + $interval = $now->diff($last_update); + $days_ago = $interval->days; + + // Déterminer le message en fonction de l'étape + $step_message = ''; + switch($credit_request['step']) { + case 1: + $step_message = 'Vous avez commencé une demande de crédit'; + break; + case 2: + $step_message = 'Vous avez complété les informations de base'; + break; + case 3: + $step_message = 'Vous avez renseigné vos informations personnelles'; + break; + case 4: + $step_message = 'Vous avez complété les informations de votre co-emprunteur'; + break; + case 5: + $step_message = 'Votre demande est presque terminée'; + break; + } +?> +
    +
    +
    +

    Demande de crédit en cours

    +

    + pour un + + d'un montant de € + sur mois. +

    +

    + Dernière mise à jour il y a jour 1 ? 's' : ''; ?> +

    +
    + +
    +
    + \ No newline at end of file diff --git a/templates/front/old/credit-step1-back.php b/templates/front/old/credit-step1-back.php new file mode 100644 index 0000000..08524ea --- /dev/null +++ b/templates/front/old/credit-step1-back.php @@ -0,0 +1,1002 @@ +type_credit == 'pat') + $show_all_form = true; + + +$form_action = $show_all_form ? '#' : get_site_url().'/credit-step2'; + +$submit_label = $show_all_form ? 'Envoyer demande' : 'Étape suivante'; + +?> + +
    +
    +
    +

    Introduction de votre demande de crédit

    + +
    + +
    +
    +
    +

    Type de prêt

    + type_credit] ?> +
    +
    +

    Capital choisi

    + capital ?> € +
    +
    +

    Durée choisie (nombre de mensualités)

    + duree ?> type_credit === 'am'): ?>ansmois +
    +
    +
    + +
    +
    +
    +

    Montant emprunté :

    + capital ?> € + +

    Durée :

    + duree ?> type_credit === 'am'): ?>ansmois + +

    Mensualité :

    + mensualite ?> € +
    + +
    +

    Coût Total :

    + cout_total ?> € + +

    Taux nominal annuel :

    + taux_nominal_annuel ?> + +

    Taux nominal annuel + taux réel qui correspond à la mensualité :

    +
    +
    +
    + +

    Exemple représentatif : type de crédit = prêt à tempérament (tous motifs) / montant emprunté = 12.500€ / durée = 60 mois / mensualité = 245,97€ / coût total = 14758,20€ / TAEG* = 6,95% / taux débiteur fixe = 6,95%.*TAEG = Taux Annuel Effectif Global = Taux Débiteur Fixe. Sous réserve de changement des taux et d'acceptation de votre dossier par nos partenaires financiers.

    +
    +
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + + +
    +
    + + type_credit == 'fin_neuve' || $currentCredit->type_credit == 'fin_occ_m3a' || $currentCredit->type_credit == 'fin_occ_p3a') : ?> +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + + type_credit == 'am') : ?> +
    + +
    + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    + Compromis signé +
    +
    + + +
    +
    + + +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + + +
    +
    J'emprunte ?
    +
    + + +
    +
    + + +
    +
    + +
    +
    +
    +

    + +

    +
    +
    +
    + Some placeholder content for the second accordion panel. This panel is hidden by default. +
    +
    +
    +
    +
    +

    + +

    +
    +
    +
    + Some placeholder content for the second accordion panel. This panel is hidden by default. +
    +
    +
    +
    +
    +

    + +

    +
    +
    +
    + Some placeholder content for the second accordion panel. This panel is hidden by default. +
    +
    +
    +
    +
    +

    + +

    +
    +
    +
    + Some placeholder content for the second accordion panel. This panel is hidden by default. +
    +
    +
    +
    + +
    +
    +
    + +
    +
    + +
    +
    +
    + Emprunteur (suite des informations) +
    + + get_results( "SELECT * FROM cdf_Etat_civil"); ?> + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + + +
    +
    + +
    +
    + + +
    +
    + + +
    +
    + + +
    + +
    + + +
    + +
    + + get_results( "SELECT * FROM cdf_Profession"); ?> + + +
    + +
    + + + +
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    Autres revenus
    +
    + + +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +
    + +
    +
    + +
    +
    +
    + Co Emprunteur +
    + +
    +
    + + +
    + +
    + + get_results( "SELECT * FROM cdf_Etat_civil"); ?> + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + +
    + + +
    + +
    + + get_results( "SELECT * FROM cdf_Profession"); ?> + + +
    + +
    + + + +
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    + + +
    +
    + + +
    +
    + + + +
    +
    Autres revenus
    +
    + + +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    + +
    +
    +
    +
    + Emprunteur + Crédits(s) et charge(s) en cours + +
    + + +
    +
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    + +
    + + +
    +
    + +
    + + + + +
    + + + +
    +
    + + get_results( "SELECT * FROM cdf_Type_creance"); ?> + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    + + +
    +
    + + +
    +
    +
    À clôturer / Solder ?
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + + +
    +
    +
    +
    +
    + +
    + +
    +
    +
    +
    + Co-Emprunteur + Crédits(s) et charge(s) en cours + +
    + + +
    +
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    + +
    + + +
    +
    + +
    +
    + + + +
    +
    + + + get_results( "SELECT * FROM cdf_Type_creance"); ?> + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    + + +
    +
    + + +
    +
    +
    À clôturer / Solder ?
    + +
    + + +
    +
    + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    +
    +
    +
    +
    + + +
    + + + + +
    + + + + +
    + + +
    +
    +
    \ No newline at end of file diff --git a/templates/front/old/credit-step1-bis.php b/templates/front/old/credit-step1-bis.php new file mode 100644 index 0000000..f65fee5 --- /dev/null +++ b/templates/front/old/credit-step1-bis.php @@ -0,0 +1,887 @@ +type_credit == 'pat') + $show_all_form = true; + + +$form_action = $show_all_form ? '#' : get_site_url().'/credit-step2'; + +$submit_label = $show_all_form ? 'Envoyer demande' : 'Étape suivante'; + +?> + +
    +
    +
    +

    Introduction de votre demande de crédit

    + +
    + +
    +
    +
    +

    Type de prêt

    + type_credit] ?> +
    +
    +

    Capital choisi

    + capital ?> € +
    +
    +

    Durée choisie (nombre de mensualités)

    + duree ?> type_credit === 'am'): ?>ansmois +
    +
    +
    + +
    +
    +
    +

    Montant emprunté :

    + capital ?> € + +

    Durée :

    + duree ?> type_credit === 'am'): ?>ansmois + +

    Mensualité :

    + mensualite ?> € +
    + +
    +

    Coût Total :

    + cout_total ?> € + +

    Taux nominal annuel :

    + taux_nominal_annuel ?> + +

    Taux nominal annuel + taux réel qui correspond à la mensualité :

    +
    +
    +
    + +

    Exemple représentatif : type de crédit = prêt à tempérament (tous motifs) / montant emprunté = 12.500€ / durée = 60 mois / mensualité = 245,97€ / coût total = 14758,20€ / TAEG* = 6,95% / taux débiteur fixe = 6,95%.*TAEG = Taux Annuel Effectif Global = Taux Débiteur Fixe. Sous réserve de changement des taux et d'acceptation de votre dossier par nos partenaires financiers.

    +
    +
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + +
    + + type_credit == 'fin_neuve' || $currentCredit->type_credit == 'fin_occ_m3a' || $currentCredit->type_credit == 'fin_occ_p3a') : ?> +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + + type_credit == 'am') : ?> +
    + +
    + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    + Compromis signé +
    +
    + + +
    +
    + + +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + + + +
    +
    +
    J'emprunte ?
    +
    + + +
    +
    + + +
    +
    + +
    + +
    +
    +
    + Emprunteur (suite des informations) +
    + + get_results( "SELECT * FROM cdf_Etat_civil"); ?> + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + + +
    +
    + +
    +
    + + +
    +
    + + +
    +
    + + +
    + +
    + + +
    + +
    + + get_results( "SELECT * FROM cdf_Profession"); ?> + + +
    + +
    + + + +
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    Autres revenus
    +
    + + +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    +
    + + +
    +
    +
    + Co Emprunteur +
    + +
    +
    + + +
    + +
    + + get_results( "SELECT * FROM cdf_Etat_civil"); ?> + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + +
    + + +
    + +
    + + get_results( "SELECT * FROM cdf_Profession"); ?> + + +
    + +
    + + + +
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    + + +
    +
    + + +
    +
    + + + +
    +
    Autres revenus
    +
    + + +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +
    + + +
    +
    + Emprunteur + Crédits(s) et charge(s) en cours + +
    + + +
    +
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    + +
    + + +
    +
    + +
    + +

    Si un crédit est en commun avec le co-emprunter, merci de ne l'encoder qu'une seule fois.

    + + +
    + + + +
    +
    + + get_results( "SELECT * FROM cdf_Type_creance"); ?> + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    + + +
    +
    + + +
    +
    +
    À clôturer / Solder ?
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + + +
    +
    + + +
    +
    + Co-Emprunteur + Crédits(s) et charge(s) en cours + +
    + + +
    +
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    + +
    + + +
    +
    + +
    +
    + + + +
    +
    + + + get_results( "SELECT * FROM cdf_Type_creance"); ?> + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    + + +
    +
    + + +
    +
    +
    À clôturer / Solder ?
    + +
    + + +
    +
    + + +
    +
    + + +
    + +
    + + +
    +
    + +
    + + +
    + + + + +
    + +
    + + +
    +
    +
    \ No newline at end of file diff --git a/templates/front/old/credit-step1.php b/templates/front/old/credit-step1.php new file mode 100644 index 0000000..8627234 --- /dev/null +++ b/templates/front/old/credit-step1.php @@ -0,0 +1,324 @@ +type_credit == 'pat') + $show_all_form = true; */ + + +$form_action = $show_all_form ? '#' : get_site_url().'/credit-step2'; + +$submit_label = $show_all_form ? 'Envoyer demande' : 'Étape suivante'; + +$exemple_info = $model->get_exemples_infos($currentCredit->type_credit); + +?> + +
    +
    +
    +
    +

    Introduction de votre demande de crédit

    +
    +
    +
    +
    + +
    +
    +
    +
    +

    Type de crédit:

    +
    +
    +
    +
    +
    +
    + Montant: + capital ?? '') ?> € +
    +
    + Taux débiteur: + taux_nominal_annuel ?? '') ?> +
    +
    + Durée: + duree ?? '') ?> type_credit === 'am'): ?>ansmois +
    +
    + Mensualité: + mensualite ?? '') ?>€ +
    +
    + Coût total: + cout_total ?? '') ?>€ +
    +
    + TAEG: + taux_nominal_annuel ?? '') ?> +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    + 1 + Contact +
    +
    + 2 + Revenus & charges +
    +
    + 3 + Informations personnelles +
    +
    + 4 + Coordonnées +
    +
    +
    +
    +
    +
    +
    + +
    +
    + + + +
    + + + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + +
    + + type_credit == 'fin_neuve' || $currentCredit->type_credit == 'fin_occ_m3a' || $currentCredit->type_credit == 'fin_occ_p3a' || $currentCredit->type_credit == 'mobil_carav') : ?> +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + + type_credit == 'am') : ?> +
    + +
    + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    + Compromis signé +
    +
    + isRadioChecked('compromis_signe', '0', $borrower); ?>> + +
    +
    + isRadioChecked('compromis_signe', '1', $borrower); ?>> + +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + Commentaires et informations complémentaires +
    + + +
    +
    + + + +
    + + + + + + +
    + +
    + +
    +
    + +
    +
    +
    +
    +

    Montant emprunté :

    + capital ?? '') ?> € + +

    Durée :

    + duree ?? '') ?> type_credit === 'am'): ?>ansmois + +

    Mensualité :

    + mensualite ?? '') ?> € +
    + +
    +

    Coût Total :

    + cout_total ?? '') ?> € + +

    Taux nominal annuel :

    + taux_nominal_annuel ?? '') ?> + +

    TAEG :

    + taux_nominal_annuel ?? '') ?> +
    +
    +
    + +
    + + + +
    +
    + +
    +
    \ No newline at end of file diff --git a/templates/front/old/credit-step2-a.php b/templates/front/old/credit-step2-a.php new file mode 100644 index 0000000..69fb476 --- /dev/null +++ b/templates/front/old/credit-step2-a.php @@ -0,0 +1,301 @@ +
    +
    +
    +

    Introduction de votre demande de crédit

    +
    +
    +
    + + + +
    +
    +
    +
    + +
    +
    + 1 + Contact +
    +
    + 2 + Revenus & charges +
    +
    + 3 + Informations personnelles +
    +
    + 4 + Coordonnées +
    +
    +
    +
    +
    +
    + +
    +
    + + + + +
    + + +
    +
    +
    J'emprunte ?
    +
    + > + +
    +
    + > + +
    +
    + +
    + +
    +
    +
    +
    +

    Emprunteur

    + Coordonnées de contact + + +
    + + get_results("SELECT * FROM cdf_Etat_civil"); ?> + + +
    + + Votre profession et Revenus + +
    + + get_results("SELECT * FROM cdf_Profession"); ?> + + +
    + +
    +
    + + + +
    + + +
    +
    +
    + + +
    + + +
    + +
    + +
    + +
    + +
    +
    +
    + + +
    +
    + + +
    +
    +
    + +
    +
    Autres revenus
    +
    + hasOtherIncome) echo 'checked'; ?>> + +
    +
    + hasOtherIncome) echo 'checked'; ?>> + +
    +
    + +
    +
    +
    +
    +
    + isCheckboxChecked('hasoimealvoucher', 'mealvoucher', $borrower); ?>> + +
    +
    + +
    +
    +
    +
    +
    +
    + isCheckboxChecked('hasoirentalincome', 'rentalincome', $borrower); ?>> + +
    +
    + +
    +
    +
    +
    +
    +
    + isCheckboxChecked('hasoiunemployment', 'unemployment', $borrower); ?>> + +
    +
    + +
    +
    +
    +
    +
    +
    + isCheckboxChecked('hasoiother', 'other', $borrower); ?>> + +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    + +
    +
    Etes-vous fiché à la Banque Nationale ?
    +
    + estFicheBanqueNational) echo 'checked'; ?>> + +
    +
    + estFicheBanqueNational) echo 'checked'; ?>> + +
    +
    + +
    +
    +
    +

    Statut du fichage

    +
    + isRadioChecked('fichage_status', 'regularise', $borrower); ?>> + +
    +
    + isRadioChecked('fichage_status', 'non_regularise', $borrower); ?>> + +
    +
    + isRadioChecked('fichage_status', 'mediation_dettes', $borrower); ?>> + +
    +
    +
    +
    + +
    +
    +
    Statut du logement
    + +
    +
    + +
    +
    +
    +
    Montant du loyer mensuel ou participation aux charges
    + +
    +
    +
    + + +
    + +
    + +
    +
    + \ No newline at end of file diff --git a/templates/front/old/credit-step2-b.php b/templates/front/old/credit-step2-b.php new file mode 100644 index 0000000..38553c6 --- /dev/null +++ b/templates/front/old/credit-step2-b.php @@ -0,0 +1,243 @@ +
    + + + + +
    +
    +

    Co Emprunteur

    + Coordonnées de contact + +
    + + +
    +
    + + +
    +
    + +
    +
    + + +
    + +
    + + get_results("SELECT * FROM cdf_Etat_civil"); ?> + + +
    + + Votre profession et Revenus + +
    + + get_results("SELECT * FROM cdf_Profession"); ?> + + +
    + +
    + +
    + + + +
    + +
    + +
    +
    + + +
    + +
    + +
    +
    + + +
    + +
    +
    + +
    +
    +
    + + +
    +
    + + +
    +
    +
    + + + + +
    +
    Autres revenus
    +
    + hasOtherIncome) echo 'checked'; ?>> + +
    +
    + hasOtherIncome) echo 'checked'; ?>> + +
    +
    + +
    +
    +
    +
    +
    + isCheckboxChecked('hasoimealvoucher', 'mealvoucher', $coBorrower); ?>> + +
    +
    + +
    +
    +
    +
    +
    +
    + isCheckboxChecked('cohasoirentalincome', 'rentalincome', $coBorrower); ?>> + +
    +
    + +
    +
    +
    +
    +
    +
    + isCheckboxChecked('cohasoiunemployment', 'unemployment', $coBorrower); ?>> + +
    +
    + +
    +
    +
    +
    +
    +
    + isCheckboxChecked('cohasoiother', 'other', $coBorrower); ?>> + +
    +
    + +
    +
    + +
    +
    +
    +
    +
    + +
    +
    Etes-vous fiché à la Banque Nationale ?
    +
    + estFicheBanqueNational) echo 'checked'; ?>> + +
    +
    + estFicheBanqueNational) echo 'checked'; ?>> + +
    +
    + +
    +
    +
    +

    Statut du fichage

    +
    + isRadioChecked('coFichage_status', 'regularise', $coBorrower); ?>> + +
    +
    + isRadioChecked('coFichage_status', 'non_regularise', $coBorrower); ?>> + +
    +
    + isRadioChecked('coFichage_status', 'mediation_dettes', $coBorrower); ?>> + +
    +
    +
    +
    + +
    +
    +
    Statut du logement
    + +
    +
    + +
    +
    +
    +
    Montant du loyer mensuel ou participation aux charges
    + +
    +
    +
    + +
    +
    + + diff --git a/templates/front/old/credit-step2-c.php b/templates/front/old/credit-step2-c.php new file mode 100644 index 0000000..cc06ec6 --- /dev/null +++ b/templates/front/old/credit-step2-c.php @@ -0,0 +1,215 @@ + + +
    +
    Avez-vous des crédits en cours ?
    +
    +
    + +
    + isRadioChecked('hascurrentloan', '0', $borrower); ?>> + +
    +
    + isRadioChecked('hascurrentloan', '1', $borrower); ?>> + +
    +
    +
    + +
    + +

    Si un crédit est en commun avec le co-emprunteur, merci de ne l'encoder qu'une seule fois.

    + + + + getCurrentLoansHTML($borrower); ?> + +
    + + + +
    +
    + + get_results( "SELECT * FROM cdf_Type_creance"); ?> + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    + + +
    +
    + + +
    +
    +
    À clôturer / Solder ?
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + + +
    + +
    + +
    +
    + + +
    + +
    Avez-vous des crédits en cours ?
    +
    +
    + +
    + isRadioChecked('cohascurrentloan', '0', $coBorrower); ?>> + +
    +
    + isRadioChecked('cohascurrentloan', '1', $coBorrower); ?>> + +
    +
    +
    +
    + +
    + + getCurrentLoansHTML($coBorrower, 'co'); ?> + +
    + + + +
    +
    + + + get_results( "SELECT * FROM cdf_Type_creance"); ?> + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    + + +
    +
    + + +
    +
    +
    À clôturer / Solder ?
    + +
    + + +
    +
    + + +
    +
    + + +
    + +
    + + + +
    +
    + +
    +
    + Étape précédente + +
    +
    +
    +
    +
    +
    + + + +
    +
    \ No newline at end of file diff --git a/templates/front/old/credit-step3.php b/templates/front/old/credit-step3.php new file mode 100644 index 0000000..0454d67 --- /dev/null +++ b/templates/front/old/credit-step3.php @@ -0,0 +1,263 @@ +get_exemples_infos($currentCredit->type_credit); +?> + +
    +
    +
    +

    Introduction de votre demande de crédit

    +
    +
    +
    + + + +
    +
    +
    +
    + +
    +
    + 1 + Contact +
    +
    + 2 + Revenus & charges +
    +
    + 3 + Informations personnelles +
    +
    + 4 + Coordonnées +
    +
    +
    +
    +
    +
    +
    +
    + + + + +
    + + + +
    +
    +
    +
    + Emprunteur + Données personnelles +
    + + +
    +
    + + +
    +
    + + 'Belgique', + 'LU' => 'Luxembourg', + ]; + $main_countries = [ + 'BE' => 'Belgique', + 'LU' => 'Luxembourg', + 'FR' => 'France', + 'DE' => 'Allemagne', + 'NL' => 'Pays-Bas', + ]; + // Liste de traduction FR pour les autres pays (extrait, à compléter si besoin) + $country_fr = [ + 'AD' => 'Andorre', 'AL' => 'Albanie', 'AT' => 'Autriche', 'BA' => 'Bosnie-Herzégovine', 'BG' => 'Bulgarie', 'BY' => 'Biélorussie', 'CH' => 'Suisse', 'CZ' => 'Tchéquie', 'DK' => 'Danemark', 'EE' => 'Estonie', 'ES' => 'Espagne', 'FI' => 'Finlande', 'GB' => 'Royaume-Uni', 'GR' => 'Grèce', 'HR' => 'Croatie', 'HU' => 'Hongrie', 'IE' => 'Irlande', 'IS' => 'Islande', 'IT' => 'Italie', 'LT' => 'Lituanie', 'LV' => 'Lettonie', 'MC' => 'Monaco', 'MD' => 'Moldavie', 'ME' => 'Monténégro', 'MK' => 'Macédoine du Nord', 'MT' => 'Malte', 'NO' => 'Norvège', 'PL' => 'Pologne', 'PT' => 'Portugal', 'RO' => 'Roumanie', 'RS' => 'Serbie', 'RU' => 'Russie', 'SE' => 'Suède', 'SI' => 'Slovénie', 'SK' => 'Slovaquie', 'SM' => 'Saint-Marin', 'UA' => 'Ukraine', 'VA' => 'Vatican', + // ... compléter si besoin ... + ]; + // Liste CSV (code => nom anglais) + $csv_countries = [ + 'AD' => 'Andorra', 'AE' => 'United Arab Emirates', 'AF' => 'Afghanistan', 'AG' => 'Antigua and Barbuda', 'AI' => 'Anguilla', 'AL' => 'Albania', 'AM' => 'Armenia', 'AN' => 'Netherlands Antilles', 'AO' => 'Angola', 'AQ' => 'Antarctica', 'AR' => 'Argentina', 'AS' => 'American Samoa', 'AT' => 'Austria', 'AU' => 'Australia', 'AW' => 'Aruba', 'AZ' => 'Azerbaijan', 'BA' => 'Bosnia and Herzegovina', 'BB' => 'Barbados', 'BD' => 'Bangladesh', 'BE' => 'Belgium', 'BF' => 'Burkina Faso', 'BG' => 'Bulgaria', 'BH' => 'Bahrain', 'BI' => 'Burundi', 'BJ' => 'Benin', 'BM' => 'Bermuda', 'BN' => 'Brunei', 'BO' => 'Bolivia', 'BR' => 'Brazil', 'BS' => 'Bahamas', 'BT' => 'Bhutan', 'BV' => 'Bouvet Island', 'BW' => 'Botswana', 'BY' => 'Belarus', 'BZ' => 'Belize', 'CA' => 'Canada', 'CC' => 'Cocos [Keeling] Islands', 'CD' => 'Congo [DRC]', 'CF' => 'Central African Republic', 'CG' => 'Congo [Republic]', 'CH' => 'Switzerland', 'CI' => +"Côte d'Ivoire", 'CK' => 'Cook Islands', 'CL' => 'Chile', 'CM' => 'Cameroon', 'CN' => 'China', 'CO' => 'Colombia', 'CR' => 'Costa Rica', 'CU' => 'Cuba', 'CV' => 'Cape Verde', 'CX' => 'Christmas Island', 'CY' => 'Cyprus', 'CZ' => 'Czech Republic', 'DE' => 'Germany', 'DJ' => 'Djibouti', 'DK' => 'Denmark', 'DM' => 'Dominica', 'DO' => 'Dominican Republic', 'DZ' => 'Algeria', 'EC' => 'Ecuador', 'EE' => 'Estonia', 'EG' => 'Egypt', 'EH' => 'Western Sahara', 'ER' => 'Eritrea', 'ES' => 'Spain', 'ET' => 'Ethiopia', 'FI' => 'Finland', 'FJ' => 'Fiji', 'FK' => 'Falkland Islands [Islas Malvinas]', 'FM' => 'Micronesia', 'FO' => 'Faroe Islands', 'FR' => 'France', 'GA' => 'Gabon', 'GB' => 'United Kingdom', 'GD' => 'Grenada', 'GE' => 'Georgia', 'GF' => 'French Guiana', 'GG' => 'Guernsey', 'GH' => 'Ghana', 'GI' => 'Gibraltar', 'GL' => 'Greenland', 'GM' => 'Gambia', 'GN' => 'Guinea', 'GP' => 'Guadeloupe', 'GQ' => 'Equatorial Guinea', 'GR' => 'Greece', 'GS' => 'South Georgia and the South Sandwich Islands', 'GT' => 'Guatemala', 'GU' => 'Guam', 'GW' => 'Guinea-Bissau', 'GY' => 'Guyana', 'GZ' => 'Gaza Strip', 'HK' => 'Hong Kong', 'HM' => 'Heard Island and McDonald Islands', 'HN' => 'Honduras', 'HR' => 'Croatia', 'HT' => 'Haiti', 'HU' => 'Hungary', 'ID' => 'Indonesia', 'IE' => 'Ireland', 'IL' => 'Israel', 'IM' => 'Isle of Man', 'IN' => 'India', 'IO' => 'British Indian Ocean Territory', 'IQ' => 'Iraq', 'IR' => 'Iran', 'IS' => 'Iceland', 'IT' => 'Italy', 'JE' => 'Jersey', 'JM' => 'Jamaica', 'JO' => 'Jordan', 'JP' => 'Japan', 'KE' => 'Kenya', 'KG' => 'Kyrgyzstan', 'KH' => 'Cambodia', 'KI' => 'Kiribati', 'KM' => 'Comoros', 'KN' => 'Saint Kitts and Nevis', 'KP' => 'North Korea', 'KR' => 'South Korea', 'KW' => 'Kuwait', 'KY' => 'Cayman Islands', 'KZ' => 'Kazakhstan', 'LA' => 'Laos', 'LB' => 'Lebanon', 'LC' => 'Saint Lucia', 'LI' => 'Liechtenstein', 'LK' => 'Sri Lanka', 'LR' => 'Liberia', 'LS' => 'Lesotho', 'LT' => 'Lithuania', 'LU' => 'Luxembourg', 'LV' => 'Latvia', 'LY' => 'Libya', 'MA' => 'Morocco', 'MC' => 'Monaco', 'MD' => 'Moldova', 'ME' => 'Montenegro', 'MG' => 'Madagascar', 'MH' => 'Marshall Islands', 'MK' => 'Macedonia [FYROM]', 'ML' => 'Mali', 'MM' => 'Myanmar [Burma]', 'MN' => 'Mongolia', 'MO' => 'Macau', 'MP' => 'Northern Mariana Islands', 'MQ' => 'Martinique', 'MR' => 'Mauritania', 'MS' => 'Montserrat', 'MT' => 'Malta', 'MU' => 'Mauritius', 'MV' => 'Maldives', 'MW' => 'Malawi', 'MX' => 'Mexico', 'MY' => 'Malaysia', 'MZ' => 'Mozambique', 'NA' => 'Namibia', 'NC' => 'New Caledonia', 'NE' => 'Niger', 'NF' => 'Norfolk Island', 'NG' => 'Nigeria', 'NI' => 'Nicaragua', 'NL' => 'Netherlands', 'NO' => 'Norway', 'NP' => 'Nepal', 'NR' => 'Nauru', 'NU' => 'Niue', 'NZ' => 'New Zealand', 'OM' => 'Oman', 'PA' => 'Panama', 'PE' => 'Peru', 'PF' => 'French Polynesia', 'PG' => 'Papua New Guinea', 'PH' => 'Philippines', 'PK' => 'Pakistan', 'PL' => 'Poland', 'PM' => 'Saint Pierre and Miquelon', 'PN' => 'Pitcairn Islands', 'PR' => 'Puerto Rico', 'PS' => 'Palestinian Territories', 'PT' => 'Portugal', 'PW' => 'Palau', 'PY' => 'Paraguay', 'QA' => 'Qatar', 'RE' => 'Réunion', 'RO' => 'Romania', 'RS' => 'Serbia', 'RU' => 'Russia', 'RW' => 'Rwanda', 'SA' => 'Saudi Arabia', 'SB' => 'Solomon Islands', 'SC' => 'Seychelles', 'SD' => 'Sudan', 'SE' => 'Sweden', 'SG' => 'Singapore', 'SH' => 'Saint Helena', 'SI' => 'Slovenia', 'SJ' => 'Svalbard and Jan Mayen', 'SK' => 'Slovakia', 'SL' => 'Sierra Leone', 'SM' => 'San Marino', 'SN' => 'Senegal', 'SO' => 'Somalia', 'SR' => 'Suriname', 'ST' => 'São Tomé and Príncipe', 'SV' => 'El Salvador', 'SY' => 'Syria', 'SZ' => 'Swaziland', 'TC' => 'Turks and Caicos Islands', 'TD' => 'Chad', 'TF' => 'French Southern Territories', 'TG' => 'Togo', 'TH' => 'Thailand', 'TJ' => 'Tajikistan', 'TK' => 'Tokelau', 'TL' => 'Timor-Leste', 'TM' => 'Turkmenistan', 'TN' => 'Tunisia', 'TO' => 'Tonga', 'TR' => 'Turkey', 'TT' => 'Trinidad and Tobago', 'TV' => 'Tuvalu', 'TW' => 'Taiwan', 'TZ' => 'Tanzania', 'UA' => 'Ukraine', 'UG' => 'Uganda', 'UM' => 'U.S. Minor Outlying Islands', 'US' => 'United States', 'UY' => 'Uruguay', 'UZ' => 'Uzbekistan', 'VA' => 'Vatican City', 'VC' => 'Saint Vincent and the Grenadines', 'VE' => 'Venezuela', 'VG' => 'British Virgin Islands', 'VI' => 'U.S. Virgin Islands', 'VN' => 'Vietnam', 'VU' => 'Vanuatu', 'WF' => 'Wallis and Futuna', 'WS' => 'Samoa', 'XK' => 'Kosovo', 'YE' => 'Yemen', 'YT' => 'Mayotte', 'ZA' => 'South Africa', 'ZM' => 'Zambia', 'ZW' => 'Zimbabwe', + ]; + // Construction du tableau final pour le 2e groupe + $other_countries = []; + foreach ($csv_countries as $code => $en_name) { + if (!isset($main_countries[$code])) { + $label = isset($country_fr[$code]) ? $country_fr[$code] : $en_name; + $other_countries[$code] = $label; + } + } + asort($other_countries, SORT_LOCALE_STRING); + + if($is_credit_pat) { + $main_countries = $pat_countries; + } + // Persistance de la sélection + $selected = $model->getFieldValue('nationalite', $borrower); + + ?> + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + +
    +
    + + +
    +
    + Co-Emprunteur + Données personnelles +
    + + +
    +
    + + +
    +
    + + 'Belgique', + 'LU' => 'Luxembourg', + 'FR' => 'France', + 'DE' => 'Allemagne', + 'NL' => 'Pays-Bas', + ]; + // Liste de traduction FR pour les autres pays (extrait, à compléter si besoin) + $country_fr = [ + 'AD' => 'Andorre', 'AL' => 'Albanie', 'AT' => 'Autriche', 'BA' => 'Bosnie-Herzégovine', 'BG' => 'Bulgarie', 'BY' => 'Biélorussie', 'CH' => 'Suisse', 'CZ' => 'Tchéquie', 'DK' => 'Danemark', 'EE' => 'Estonie', 'ES' => 'Espagne', 'FI' => 'Finlande', 'GB' => 'Royaume-Uni', 'GR' => 'Grèce', 'HR' => 'Croatie', 'HU' => 'Hongrie', 'IE' => 'Irlande', 'IS' => 'Islande', 'IT' => 'Italie', 'LT' => 'Lituanie', 'LV' => 'Lettonie', 'MC' => 'Monaco', 'MD' => 'Moldavie', 'ME' => 'Monténégro', 'MK' => 'Macédoine du Nord', 'MT' => 'Malte', 'NO' => 'Norvège', 'PL' => 'Pologne', 'PT' => 'Portugal', 'RO' => 'Roumanie', 'RS' => 'Serbie', 'RU' => 'Russie', 'SE' => 'Suède', 'SI' => 'Slovénie', 'SK' => 'Slovaquie', 'SM' => 'Saint-Marin', 'UA' => 'Ukraine', 'VA' => 'Vatican', + // ... compléter si besoin ... + ]; + // Liste CSV (code => nom anglais) + $csv_countries = [ + 'AD' => 'Andorra', 'AE' => 'United Arab Emirates', 'AF' => 'Afghanistan', 'AG' => 'Antigua and Barbuda', 'AI' => 'Anguilla', 'AL' => 'Albania', 'AM' => 'Armenia', 'AN' => 'Netherlands Antilles', 'AO' => 'Angola', 'AQ' => 'Antarctica', 'AR' => 'Argentina', 'AS' => 'American Samoa', 'AT' => 'Austria', 'AU' => 'Australia', 'AW' => 'Aruba', 'AZ' => 'Azerbaijan', 'BA' => 'Bosnia and Herzegovina', 'BB' => 'Barbados', 'BD' => 'Bangladesh', 'BE' => 'Belgium', 'BF' => 'Burkina Faso', 'BG' => 'Bulgaria', 'BH' => 'Bahrain', 'BI' => 'Burundi', 'BJ' => 'Benin', 'BM' => 'Bermuda', 'BN' => 'Brunei', 'BO' => 'Bolivia', 'BR' => 'Brazil', 'BS' => 'Bahamas', 'BT' => 'Bhutan', 'BV' => 'Bouvet Island', 'BW' => 'Botswana', 'BY' => 'Belarus', 'BZ' => 'Belize', 'CA' => 'Canada', 'CC' => 'Cocos [Keeling] Islands', 'CD' => 'Congo [DRC]', 'CF' => 'Central African Republic', 'CG' => 'Congo [Republic]', 'CH' => 'Switzerland', 'CI' => +"Côte d'Ivoire", 'CK' => 'Cook Islands', 'CL' => 'Chile', 'CM' => 'Cameroon', 'CN' => 'China', 'CO' => 'Colombia', 'CR' => 'Costa Rica', 'CU' => 'Cuba', 'CV' => 'Cape Verde', 'CX' => 'Christmas Island', 'CY' => 'Cyprus', 'CZ' => 'Czech Republic', 'DE' => 'Germany', 'DJ' => 'Djibouti', 'DK' => 'Denmark', 'DM' => 'Dominica', 'DO' => 'Dominican Republic', 'DZ' => 'Algeria', 'EC' => 'Ecuador', 'EE' => 'Estonia', 'EG' => 'Egypt', 'EH' => 'Western Sahara', 'ER' => 'Eritrea', 'ES' => 'Spain', 'ET' => 'Ethiopia', 'FI' => 'Finland', 'FJ' => 'Fiji', 'FK' => 'Falkland Islands [Islas Malvinas]', 'FM' => 'Micronesia', 'FO' => 'Faroe Islands', 'FR' => 'France', 'GA' => 'Gabon', 'GB' => 'United Kingdom', 'GD' => 'Grenada', 'GE' => 'Georgia', 'GF' => 'French Guiana', 'GG' => 'Guernsey', 'GH' => 'Ghana', 'GI' => 'Gibraltar', 'GL' => 'Greenland', 'GM' => 'Gambia', 'GN' => 'Guinea', 'GP' => 'Guadeloupe', 'GQ' => 'Equatorial Guinea', 'GR' => 'Greece', 'GS' => 'South Georgia and the South Sandwich Islands', 'GT' => 'Guatemala', 'GU' => 'Guam', 'GW' => 'Guinea-Bissau', 'GY' => 'Guyana', 'GZ' => 'Gaza Strip', 'HK' => 'Hong Kong', 'HM' => 'Heard Island and McDonald Islands', 'HN' => 'Honduras', 'HR' => 'Croatia', 'HT' => 'Haiti', 'HU' => 'Hungary', 'ID' => 'Indonesia', 'IE' => 'Ireland', 'IL' => 'Israel', 'IM' => 'Isle of Man', 'IN' => 'India', 'IO' => 'British Indian Ocean Territory', 'IQ' => 'Iraq', 'IR' => 'Iran', 'IS' => 'Iceland', 'IT' => 'Italy', 'JE' => 'Jersey', 'JM' => 'Jamaica', 'JO' => 'Jordan', 'JP' => 'Japan', 'KE' => 'Kenya', 'KG' => 'Kyrgyzstan', 'KH' => 'Cambodia', 'KI' => 'Kiribati', 'KM' => 'Comoros', 'KN' => 'Saint Kitts and Nevis', 'KP' => 'North Korea', 'KR' => 'South Korea', 'KW' => 'Kuwait', 'KY' => 'Cayman Islands', 'KZ' => 'Kazakhstan', 'LA' => 'Laos', 'LB' => 'Lebanon', 'LC' => 'Saint Lucia', 'LI' => 'Liechtenstein', 'LK' => 'Sri Lanka', 'LR' => 'Liberia', 'LS' => 'Lesotho', 'LT' => 'Lithuania', 'LU' => 'Luxembourg', 'LV' => 'Latvia', 'LY' => 'Libya', 'MA' => 'Morocco', 'MC' => 'Monaco', 'MD' => 'Moldova', 'ME' => 'Montenegro', 'MG' => 'Madagascar', 'MH' => 'Marshall Islands', 'MK' => 'Macedonia [FYROM]', 'ML' => 'Mali', 'MM' => 'Myanmar [Burma]', 'MN' => 'Mongolia', 'MO' => 'Macau', 'MP' => 'Northern Mariana Islands', 'MQ' => 'Martinique', 'MR' => 'Mauritania', 'MS' => 'Montserrat', 'MT' => 'Malta', 'MU' => 'Mauritius', 'MV' => 'Maldives', 'MW' => 'Malawi', 'MX' => 'Mexico', 'MY' => 'Malaysia', 'MZ' => 'Mozambique', 'NA' => 'Namibia', 'NC' => 'New Caledonia', 'NE' => 'Niger', 'NF' => 'Norfolk Island', 'NG' => 'Nigeria', 'NI' => 'Nicaragua', 'NL' => 'Netherlands', 'NO' => 'Norway', 'NP' => 'Nepal', 'NR' => 'Nauru', 'NU' => 'Niue', 'NZ' => 'New Zealand', 'OM' => 'Oman', 'PA' => 'Panama', 'PE' => 'Peru', 'PF' => 'French Polynesia', 'PG' => 'Papua New Guinea', 'PH' => 'Philippines', 'PK' => 'Pakistan', 'PL' => 'Poland', 'PM' => 'Saint Pierre and Miquelon', 'PN' => 'Pitcairn Islands', 'PR' => 'Puerto Rico', 'PS' => 'Palestinian Territories', 'PT' => 'Portugal', 'PW' => 'Palau', 'PY' => 'Paraguay', 'QA' => 'Qatar', 'RE' => 'Réunion', 'RO' => 'Romania', 'RS' => 'Serbia', 'RU' => 'Russia', 'RW' => 'Rwanda', 'SA' => 'Saudi Arabia', 'SB' => 'Solomon Islands', 'SC' => 'Seychelles', 'SD' => 'Sudan', 'SE' => 'Sweden', 'SG' => 'Singapore', 'SH' => 'Saint Helena', 'SI' => 'Slovenia', 'SJ' => 'Svalbard and Jan Mayen', 'SK' => 'Slovakia', 'SL' => 'Sierra Leone', 'SM' => 'San Marino', 'SN' => 'Senegal', 'SO' => 'Somalia', 'SR' => 'Suriname', 'ST' => 'São Tomé and Príncipe', 'SV' => 'El Salvador', 'SY' => 'Syria', 'SZ' => 'Swaziland', 'TC' => 'Turks and Caicos Islands', 'TD' => 'Chad', 'TF' => 'French Southern Territories', 'TG' => 'Togo', 'TH' => 'Thailand', 'TJ' => 'Tajikistan', 'TK' => 'Tokelau', 'TL' => 'Timor-Leste', 'TM' => 'Turkmenistan', 'TN' => 'Tunisia', 'TO' => 'Tonga', 'TR' => 'Turkey', 'TT' => 'Trinidad and Tobago', 'TV' => 'Tuvalu', 'TW' => 'Taiwan', 'TZ' => 'Tanzania', 'UA' => 'Ukraine', 'UG' => 'Uganda', 'UM' => 'U.S. Minor Outlying Islands', 'US' => 'United States', 'UY' => 'Uruguay', 'UZ' => 'Uzbekistan', 'VA' => 'Vatican City', 'VC' => 'Saint Vincent and the Grenadines', 'VE' => 'Venezuela', 'VG' => 'British Virgin Islands', 'VI' => 'U.S. Virgin Islands', 'VN' => 'Vietnam', 'VU' => 'Vanuatu', 'WF' => 'Wallis and Futuna', 'WS' => 'Samoa', 'XK' => 'Kosovo', 'YE' => 'Yemen', 'YT' => 'Mayotte', 'ZA' => 'South Africa', 'ZM' => 'Zambia', 'ZW' => 'Zimbabwe', + ]; */ + // Construction du tableau final pour le 2e groupe + /* $other_countries = []; + foreach ($csv_countries as $code => $en_name) { + if (!isset($main_countries[$code])) { + $label = isset($country_fr[$code]) ? $country_fr[$code] : $en_name; + $other_countries[$code] = $label; + } + } + asort($other_countries, SORT_LOCALE_STRING); */ + + if($is_credit_pat) { + $main_countries = $pat_countries; + } + // Persistance de la sélection + $selected = isset($_POST['conationality']) ? $_POST['conationality'] : $model->getFieldValue('nationality', $coBorrower); + ?> + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + +
    +
    + +
    +
    + +
    + Étape précédente + +
    +
    +
    +
    +
    +
    + + + +
    +
    \ No newline at end of file diff --git a/templates/front/old/credit-step4.php b/templates/front/old/credit-step4.php new file mode 100644 index 0000000..2bf4484 --- /dev/null +++ b/templates/front/old/credit-step4.php @@ -0,0 +1,243 @@ + 'Belgique', + 'LU' => 'Luxembourg', +]; + +$selected = $model->getFieldValue('nationalite', $borrower); + +if($has_co_borrower) { + $selectedCoBorrower = $model->getFieldValue('nationalite', $coBorrower); +} + +$exemple_info = $model->get_exemples_infos($currentCredit->type_credit); +/* $main_countries = [ + 'BE' => 'Belgique', + 'LU' => 'Luxembourg', + 'FR' => 'France', + 'DE' => 'Allemagne', + 'NL' => 'Pays-Bas', +]; +// Liste de traduction FR pour les autres pays (extrait, à compléter si besoin) +$country_fr = [ + 'AD' => 'Andorre', 'AL' => 'Albanie', 'AT' => 'Autriche', 'BA' => 'Bosnie-Herzégovine', 'BG' => 'Bulgarie', 'BY' => 'Biélorussie', 'CH' => 'Suisse', 'CZ' => 'Tchéquie', 'DK' => 'Danemark', 'EE' => 'Estonie', 'ES' => 'Espagne', 'FI' => 'Finlande', 'GB' => 'Royaume-Uni', 'GR' => 'Grèce', 'HR' => 'Croatie', 'HU' => 'Hongrie', 'IE' => 'Irlande', 'IS' => 'Islande', 'IT' => 'Italie', 'LT' => 'Lituanie', 'LV' => 'Lettonie', 'MC' => 'Monaco', 'MD' => 'Moldavie', 'ME' => 'Monténégro', 'MK' => 'Macédoine du Nord', 'MT' => 'Malte', 'NO' => 'Norvège', 'PL' => 'Pologne', 'PT' => 'Portugal', 'RO' => 'Roumanie', 'RS' => 'Serbie', 'RU' => 'Russie', 'SE' => 'Suède', 'SI' => 'Slovénie', 'SK' => 'Slovaquie', 'SM' => 'Saint-Marin', 'UA' => 'Ukraine', 'VA' => 'Vatican', + // ... compléter si besoin ... +]; +// Liste CSV (code => nom anglais) +$csv_countries = [ + 'AD' => 'Andorra', 'AE' => 'United Arab Emirates', 'AF' => 'Afghanistan', 'AG' => 'Antigua and Barbuda', 'AI' => 'Anguilla', 'AL' => 'Albania', 'AM' => 'Armenia', 'AN' => 'Netherlands Antilles', 'AO' => 'Angola', 'AQ' => 'Antarctica', 'AR' => 'Argentina', 'AS' => 'American Samoa', 'AT' => 'Austria', 'AU' => 'Australia', 'AW' => 'Aruba', 'AZ' => 'Azerbaijan', 'BA' => 'Bosnia and Herzegovina', 'BB' => 'Barbados', 'BD' => 'Bangladesh', 'BE' => 'Belgium', 'BF' => 'Burkina Faso', 'BG' => 'Bulgaria', 'BH' => 'Bahrain', 'BI' => 'Burundi', 'BJ' => 'Benin', 'BM' => 'Bermuda', 'BN' => 'Brunei', 'BO' => 'Bolivia', 'BR' => 'Brazil', 'BS' => 'Bahamas', 'BT' => 'Bhutan', 'BV' => 'Bouvet Island', 'BW' => 'Botswana', 'BY' => 'Belarus', 'BZ' => 'Belize', 'CA' => 'Canada', 'CC' => 'Cocos [Keeling] Islands', 'CD' => 'Congo [DRC]', 'CF' => 'Central African Republic', 'CG' => 'Congo [Republic]', 'CH' => 'Switzerland', 'CI' => +"Côte d'Ivoire", 'CK' => 'Cook Islands', 'CL' => 'Chile', 'CM' => 'Cameroon', 'CN' => 'China', 'CO' => 'Colombia', 'CR' => 'Costa Rica', 'CU' => 'Cuba', 'CV' => 'Cape Verde', 'CX' => 'Christmas Island', 'CY' => 'Cyprus', 'CZ' => 'Czech Republic', 'DE' => 'Germany', 'DJ' => 'Djibouti', 'DK' => 'Denmark', 'DM' => 'Dominica', 'DO' => 'Dominican Republic', 'DZ' => 'Algeria', 'EC' => 'Ecuador', 'EE' => 'Estonia', 'EG' => 'Egypt', 'EH' => 'Western Sahara', 'ER' => 'Eritrea', 'ES' => 'Spain', 'ET' => 'Ethiopia', 'FI' => 'Finland', 'FJ' => 'Fiji', 'FK' => 'Falkland Islands [Islas Malvinas]', 'FM' => 'Micronesia', 'FO' => 'Faroe Islands', 'FR' => 'France', 'GA' => 'Gabon', 'GB' => 'United Kingdom', 'GD' => 'Grenada', 'GE' => 'Georgia', 'GF' => 'French Guiana', 'GG' => 'Guernsey', 'GH' => 'Ghana', 'GI' => 'Gibraltar', 'GL' => 'Greenland', 'GM' => 'Gambia', 'GN' => 'Guinea', 'GP' => 'Guadeloupe', 'GQ' => 'Equatorial Guinea', 'GR' => 'Greece', 'GS' => 'South Georgia and the South Sandwich Islands', 'GT' => 'Guatemala', 'GU' => 'Guam', 'GW' => 'Guinea-Bissau', 'GY' => 'Guyana', 'GZ' => 'Gaza Strip', 'HK' => 'Hong Kong', 'HM' => 'Heard Island and McDonald Islands', 'HN' => 'Honduras', 'HR' => 'Croatia', 'HT' => 'Haiti', 'HU' => 'Hungary', 'ID' => 'Indonesia', 'IE' => 'Ireland', 'IL' => 'Israel', 'IM' => 'Isle of Man', 'IN' => 'India', 'IO' => 'British Indian Ocean Territory', 'IQ' => 'Iraq', 'IR' => 'Iran', 'IS' => 'Iceland', 'IT' => 'Italy', 'JE' => 'Jersey', 'JM' => 'Jamaica', 'JO' => 'Jordan', 'JP' => 'Japan', 'KE' => 'Kenya', 'KG' => 'Kyrgyzstan', 'KH' => 'Cambodia', 'KI' => 'Kiribati', 'KM' => 'Comoros', 'KN' => 'Saint Kitts and Nevis', 'KP' => 'North Korea', 'KR' => 'South Korea', 'KW' => 'Kuwait', 'KY' => 'Cayman Islands', 'KZ' => 'Kazakhstan', 'LA' => 'Laos', 'LB' => 'Lebanon', 'LC' => 'Saint Lucia', 'LI' => 'Liechtenstein', 'LK' => 'Sri Lanka', 'LR' => 'Liberia', 'LS' => 'Lesotho', 'LT' => 'Lithuania', 'LU' => 'Luxembourg', 'LV' => 'Latvia', 'LY' => 'Libya', 'MA' => 'Morocco', 'MC' => 'Monaco', 'MD' => 'Moldova', 'ME' => 'Montenegro', 'MG' => 'Madagascar', 'MH' => 'Marshall Islands', 'MK' => 'Macedonia [FYROM]', 'ML' => 'Mali', 'MM' => 'Myanmar [Burma]', 'MN' => 'Mongolia', 'MO' => 'Macau', 'MP' => 'Northern Mariana Islands', 'MQ' => 'Martinique', 'MR' => 'Mauritania', 'MS' => 'Montserrat', 'MT' => 'Malta', 'MU' => 'Mauritius', 'MV' => 'Maldives', 'MW' => 'Malawi', 'MX' => 'Mexico', 'MY' => 'Malaysia', 'MZ' => 'Mozambique', 'NA' => 'Namibia', 'NC' => 'New Caledonia', 'NE' => 'Niger', 'NF' => 'Norfolk Island', 'NG' => 'Nigeria', 'NI' => 'Nicaragua', 'NL' => 'Netherlands', 'NO' => 'Norway', 'NP' => 'Nepal', 'NR' => 'Nauru', 'NU' => 'Niue', 'NZ' => 'New Zealand', 'OM' => 'Oman', 'PA' => 'Panama', 'PE' => 'Peru', 'PF' => 'French Polynesia', 'PG' => 'Papua New Guinea', 'PH' => 'Philippines', 'PK' => 'Pakistan', 'PL' => 'Poland', 'PM' => 'Saint Pierre and Miquelon', 'PN' => 'Pitcairn Islands', 'PR' => 'Puerto Rico', 'PS' => 'Palestinian Territories', 'PT' => 'Portugal', 'PW' => 'Palau', 'PY' => 'Paraguay', 'QA' => 'Qatar', 'RE' => 'Réunion', 'RO' => 'Romania', 'RS' => 'Serbia', 'RU' => 'Russia', 'RW' => 'Rwanda', 'SA' => 'Saudi Arabia', 'SB' => 'Solomon Islands', 'SC' => 'Seychelles', 'SD' => 'Sudan', 'SE' => 'Sweden', 'SG' => 'Singapore', 'SH' => 'Saint Helena', 'SI' => 'Slovenia', 'SJ' => 'Svalbard and Jan Mayen', 'SK' => 'Slovakia', 'SL' => 'Sierra Leone', 'SM' => 'San Marino', 'SN' => 'Senegal', 'SO' => 'Somalia', 'SR' => 'Suriname', 'ST' => 'São Tomé and Príncipe', 'SV' => 'El Salvador', 'SY' => 'Syria', 'SZ' => 'Swaziland', 'TC' => 'Turks and Caicos Islands', 'TD' => 'Chad', 'TF' => 'French Southern Territories', 'TG' => 'Togo', 'TH' => 'Thailand', 'TJ' => 'Tajikistan', 'TK' => 'Tokelau', 'TL' => 'Timor-Leste', 'TM' => 'Turkmenistan', 'TN' => 'Tunisia', 'TO' => 'Tonga', 'TR' => 'Turkey', 'TT' => 'Trinidad and Tobago', 'TV' => 'Tuvalu', 'TW' => 'Taiwan', 'TZ' => 'Tanzania', 'UA' => 'Ukraine', 'UG' => 'Uganda', 'UM' => 'U.S. Minor Outlying Islands', 'US' => 'United States', 'UY' => 'Uruguay', 'UZ' => 'Uzbekistan', 'VA' => 'Vatican City', 'VC' => 'Saint Vincent and the Grenadines', 'VE' => 'Venezuela', 'VG' => 'British Virgin Islands', 'VI' => 'U.S. Virgin Islands', 'VN' => 'Vietnam', 'VU' => 'Vanuatu', 'WF' => 'Wallis and Futuna', 'WS' => 'Samoa', 'XK' => 'Kosovo', 'YE' => 'Yemen', 'YT' => 'Mayotte', 'ZA' => 'South Africa', 'ZM' => 'Zambia', 'ZW' => 'Zimbabwe', +]; +// Construction du tableau final pour le 2e groupe +$other_countries = []; +foreach ($csv_countries as $code => $en_name) { + if (!isset($main_countries[$code])) { + $label = isset($country_fr[$code]) ? $country_fr[$code] : $en_name; + $other_countries[$code] = $label; + } +} +asort($other_countries, SORT_LOCALE_STRING); */ +?> + +
    +
    +
    +

    Introduction de votre demande de crédit

    +
    +
    +
    + + + +
    +
    +
    +
    + +
    +
    + 1 + Contact +
    +
    + 2 + Revenus & charges +
    +
    + 3 + Informations personnelles +
    +
    + 4 + Coordonnées +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    + Emprunteur + Données personnelles + +
    + + +
    +
    + +
    +
    + + +
    +
    + + + +
    +
    + + +
    +
    + +
    + Données professionnelles + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    + + +
    + Co-Emprunteur + Données personnelles + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    + Données professionnelles + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + + +
    +
    + + Étape précédente +
    + +
    +
    +
    +
    +
    +
    +
    + + + +
    +
    \ No newline at end of file diff --git a/templates/front/old/credit-step5.php b/templates/front/old/credit-step5.php new file mode 100644 index 0000000..0177f92 --- /dev/null +++ b/templates/front/old/credit-step5.php @@ -0,0 +1,137 @@ +type_credit == 'am' ? true : false; + +$form_action = $show_all_form ? '#' : '/credit-step5'; + +$submit_label = $show_all_form ? 'Envoyer demande' : 'Étape suivante'; + +$taeg = str_replace('%', '', $currentCredit->taux_nominal_annuel); + +$taux_debiteur = $currentCredit->taux_nominal_annuel; + +$estateloantype = isset($_POST['estateloantype']) ? $_POST['estateloantype'] : ''; + +if (array_key_exists( + $estateloantype, + $mapHouseCreditTypes +)) { + $taux_debiteur = number_format(($taeg * 0.11) + $taeg, 2); +} + +?> + +
    +
    +
    +
    +

    Introduction de votre demande de crédit

    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    + Type: + +
    +
    + Montant: + capital ?> € +
    +
    + Taux débiteur: + taux_nominal_annuel ?> +
    +
    + Durée: + duree ?> type_credit === 'am'): ?>ansmois +
    +
    + Mensualité: + mensualite ?>€ +
    +
    + TAEG: + +
    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + +
    +
    + 1 + Contact +
    +
    + 2 + Revenus & charges +
    +
    + 3 + Informations personnelles +
    +
    + 4 + Coordonnées +
    +
    + 5 + Conclusion +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +

    Félicitations ! Votre demande de crédit a été enregistrée

    +

    Nous avons bien reçu votre demande de crédit. Un conseiller vous contactera dans les plus brefs délais pour finaliser votre dossier.

    + +
    +

    Récapitulatif de votre demande

    +
    +
    +

    Type de crédit:

    +

    Montant: capital ?> €

    +

    Durée: duree ?> type_credit === 'am'): ?>ansmois

    +
    +
    +

    TAEG: taux_nominal_annuel ?>

    +

    Mensualité: mensualite ?> €

    +

    Date de demande: format('d/m/Y') ?>

    +
    +
    +
    + + +
    +
    +
    +
    \ No newline at end of file diff --git a/templates/front/old/credit-steps2-c.php b/templates/front/old/credit-steps2-c.php new file mode 100644 index 0000000..4566e57 --- /dev/null +++ b/templates/front/old/credit-steps2-c.php @@ -0,0 +1,182 @@ +
    +
    +
    + +
    + + +
    +
    +
    + +
    + +

    Si un crédit est en commun avec le co-emprunter, merci de ne l'encoder qu'une seule fois.

    + + +
    + + + +
    +
    + + get_results( "SELECT * FROM cdf_Type_creance"); ?> + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    + + +
    +
    + + +
    +
    +
    À clôturer / Solder ?
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + + +
    + +
    + +
    +
    + Co-Emprunteur + Crédits(s) en cours + +
    + +
    + + +
    +
    + +
    +
    + + + +
    +
    + + + get_results( "SELECT * FROM cdf_Type_creance"); ?> + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    + + +
    +
    + + +
    +
    +
    À clôturer / Solder ?
    + +
    + + +
    +
    + + +
    +
    + + +
    + +
    + + +
    +
    + + + + + + + \ No newline at end of file diff --git a/templates/front/old/newSim.php b/templates/front/old/newSim.php new file mode 100644 index 0000000..df1b42b --- /dev/null +++ b/templates/front/old/newSim.php @@ -0,0 +1,311 @@ +
    + +
    +
    +

    1 Choisisez votre crédit

    + +
    + +
    + + + + + + +
    +
    +

    2 Détail de votre crédit

    + +
    + +
    Capital choisi
    + +
    +
    + +
    + +
    +
    + + 1300 + +
    +
    +
    + +
    + +
    +
    + + +
    + +
    Exemple de durée standard
    +
    +
    + + + + +
    + +
      +
    • 10 ans
    • +
    • 15 ans
    • +
    • 20 ans
    • +
    • 25 ans
    • +
    • 30 ans
    • +
    + +
      +
    • 24
    • +
    • 30
    • +
    • 36
    • +
    • 42
    • +
    • 48
    • +
    • 60
    • +
    • 72
    • +
    • 84
    • +
    • 96
    • +
    • 108
    • +
    • 120
    • +
    + +
    + +
    + +
    + + +
    +
    Votre durée
    +
    + +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    +
    + + 24 + +
    +
    +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    +

    3Résultat de votre simulation

    +
    + +
    +
    Montant emprunté :
    +
    1300
    +
    +
    +
    Durée :
    +
    24
    +
    +
    +
    Mensualité :
    +
    61.63
    +
    + +
    Taux débiteur :
    0
    +
    TAEG* :
    0
    + +
    Taux débiteur :
    0
    +
    TAEG :
    0
    + +
    +
    Coût total :
    +
    0
    +
    +
    + + + + + + + + +
    +
    +

    En un simple clic et sans engagement, demander votre crédit

    +
    + +
    Attention, emprunter de l'argent coûte aussi de l'argent.
    +
    +
    +
    +
    + + + + + +
    + +
    + +
    + +
    + + + + + + + +
    \ No newline at end of file diff --git a/templates/front/old/simulateur.php b/templates/front/old/simulateur.php new file mode 100644 index 0000000..eb4fb62 --- /dev/null +++ b/templates/front/old/simulateur.php @@ -0,0 +1,87 @@ +
    +
    + +

    Simulez votre crédit en ligne

    +
    + + +
    +
    +
    + + +
    +
    + +
    +
    +
    + +
    +
    +
    + + +
    +
    +
    + +
    +
    +
    + +
    +
      +
    • 24
    • +
    • 30
    • +
    • 36
    • +
    • 42
    • +
    • 48
    • +
    • 60
    • +
    • 72
    • +
    • 84
    • +
    • 96
    • +
    • 108
    • +
    • 120
    • +
    +
    +
    + +
    +
    Montant emprunté :
    1300
    +
    Durée :
    24
    +
    Mensualité :
    61.63
    + +
    + +
    +
    Coût total :
    31200
    + + + +
    + +
    +
    +
    + +
    Attention, emprunter de l'argent coûte aussi de l'argent.
    +
    +
    +
    Montant emprunté :
    1300
    +
    Durée :
    24
    +
    Mensualité :
    61.63
    + +
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/templates/front/simulateur.php b/templates/front/simulateur.php new file mode 100644 index 0000000..eb4fb62 --- /dev/null +++ b/templates/front/simulateur.php @@ -0,0 +1,87 @@ +
    +
    + +

    Simulez votre crédit en ligne

    +
    + + +
    +
    +
    + + +
    +
    + +
    +
    +
    + +
    +
    +
    + + +
    +
    +
    + +
    +
    +
    + +
    +
      +
    • 24
    • +
    • 30
    • +
    • 36
    • +
    • 42
    • +
    • 48
    • +
    • 60
    • +
    • 72
    • +
    • 84
    • +
    • 96
    • +
    • 108
    • +
    • 120
    • +
    +
    +
    + +
    +
    Montant emprunté :
    1300
    +
    Durée :
    24
    +
    Mensualité :
    61.63
    + +
    + +
    +
    Coût total :
    31200
    + + + +
    + +
    +
    +
    + +
    Attention, emprunter de l'argent coûte aussi de l'argent.
    +
    +
    +
    Montant emprunté :
    1300
    +
    Durée :
    24
    +
    Mensualité :
    61.63
    + +
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/templates/modules/credit-manager-edit-form.php b/templates/modules/credit-manager-edit-form.php new file mode 100644 index 0000000..8c2db8b --- /dev/null +++ b/templates/modules/credit-manager-edit-form.php @@ -0,0 +1,183 @@ + 0; + +if ($is_edit_mode) { + // Récupérer les données du crédit depuis la base de données + $credit_manager = new credit_manager(); + $credit_data = $credit_manager->get_credit_by_id($credit_id); + + // Si pas de données trouvées, initialiser avec des valeurs vides + if (!$credit_data) { + $credit_data = (object) array( + 'title' => '', + 'nom' => '', + 'prenom' => '', + 'adresse' => '', + 'localite' => '', + 'email' => '', + 'telephone' => '', + 'gsm' => '', + 'societe_credit' => '', + 'montant' => '', + 'date' => '', + 'signature' => '', + 'numero_dossier' => '', + 'code' => '', + 'remarques' => '' + ); + } +} +?> + + + + + admin_url('admin-ajax.php'), + 'nonce' => wp_create_nonce('credit_manager_action') +)); +?> + diff --git a/templates/modules/credit-reminder-btn.php b/templates/modules/credit-reminder-btn.php new file mode 100644 index 0000000..9b9555b --- /dev/null +++ b/templates/modules/credit-reminder-btn.php @@ -0,0 +1,9 @@ + +
    +
    + Credit Direct +
    1
    +
    +
    \ No newline at end of file diff --git a/templates/modules/credit-reminder-modal.php b/templates/modules/credit-reminder-modal.php new file mode 100644 index 0000000..967da63 --- /dev/null +++ b/templates/modules/credit-reminder-modal.php @@ -0,0 +1,56 @@ +checkOngoingCreditRequest(); + +if ($credit_request) { + $last_update = \Carbon\Carbon::parse($credit_request['last_update_date']); + $now = \Carbon\Carbon::now(); + $interval = $now->diffInDays($last_update); + + if ($interval <= 60) { // 2 mois maximum + $step = $credit_request['step']; + $type_credit = isset($credit_request['type_credit']) ? $credit_request['type_credit'] : null; + + // Récupérer les phrases depuis ACF + $phrases = get_field('phrases_reprises_credit', 'option'); + $message = ''; + + // Chercher la phrase correspondant à l'étape + if ($phrases) { + foreach ($phrases as $phrase) { + if ($phrase['n_etape'] == $step) { + $message = $phrase['texte']; + break; + } + } + } + + // Message par défaut si aucune phrase n'est trouvée + if (empty($message)) { + $message = 'Votre demande de crédit est en attente. Continuez votre démarche pour finaliser votre demande.'; + } +?> + +
    +
    +
    +

    Vous avez une demande de crédit en cours

    + +
    + + +
    +
    + + \ No newline at end of file