credit-direct/app/controllers/credit_manager.php
2025-12-18 09:44:42 +01:00

1101 lines
44 KiB
PHP

<?php
class CRED_credit_manager extends CRED_base {
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 $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
}