EsiPeppol-Woocommerce/assets/js/admin.js

511 lines
25 KiB
JavaScript

(function ($) {
'use strict';
$(function () {
// Bouton de test de connexion sur la page de configuration
var $testBtn = $('#esi-peppol-test-connection');
if ($testBtn.length && typeof window.esiPeppolAdmin !== 'undefined') {
var $result = $('#esi-peppol-test-result');
$testBtn.on('click', function (e) {
e.preventDefault();
var apiKey = $('#esi_peppol_api_key').val();
var password = $('#esi_peppol_password').val();
$result.removeClass().empty();
if (!apiKey || !password) {
var msgMissing = window.esiPeppolAdmin.i18n_missing || "Veuillez renseigner l'API Key et le Password avant de tester la connexion.";
$result
.addClass('notice notice-error')
.html('<p>' + msgMissing + '</p>');
return;
}
$testBtn.prop('disabled', true).addClass('updating-message');
$.post(window.esiPeppolAdmin.ajax_url, {
action: 'esi_peppol_test_connection',
nonce: window.esiPeppolAdmin.nonce,
api_key: apiKey,
password: password
})
.done(function (response) {
if (response && response.success) {
var msg = (response.data && response.data.message)
? response.data.message
: (window.esiPeppolAdmin.i18n_success || "Connexion réussie à l'API ESIPeppol.");
$result
.addClass('notice notice-success is-dismissible')
.html('<p>' + msg + '</p>');
} else {
var errMsg = (response && response.data && response.data.message)
? response.data.message
: (window.esiPeppolAdmin.i18n_error || 'La connexion a échoué.');
$result
.addClass('notice notice-error')
.html('<p>' + errMsg + '</p>');
}
})
.fail(function () {
var msgNetwork = window.esiPeppolAdmin.i18n_network || 'Erreur de communication avec le serveur WordPress.';
$result
.addClass('notice notice-error')
.html('<p>' + msgNetwork + '</p>');
})
.always(function () {
$testBtn.prop('disabled', false).removeClass('updating-message');
});
});
}
// DataTables pour le tableau du journal des échanges (invoices / documents envoyés)
var $logsTable = $('#esi-peppol-logs-table');
if ($logsTable.length && $.fn.DataTable) {
$logsTable.DataTable({
pageLength: 25,
order: [[0, 'desc']],
language: {
url: 'https://cdn.datatables.net/plug-ins/1.13.8/i18n/fr-FR.json'
}
});
}
// Actions AJAX sur la page de logs : renvoyer / vérifier le statut
if ($logsTable.length && typeof window.esiPeppolAdmin !== 'undefined') {
var $logsResult = $('#esi-peppol-logs-result');
var showLogsNotice = function (type, title, message, detail) {
var classes = 'notice';
if (type === 'success') {
classes += ' notice-success is-dismissible';
} else if (type === 'error') {
classes += ' notice-error';
} else {
classes += ' notice-info';
}
var html = '<div class="' + classes + '">';
if (title) {
html += '<p><strong>' + title + '</strong> ' + (message || '') + '</p>';
} else if (message) {
html += '<p>' + message + '</p>';
}
if (detail) {
html += '<p><em>' + (window.esiPeppolAdmin.i18n_logs_detail_lbl || "Détail retour API") + ':</em> ' + detail + '</p>';
}
html += '</div>';
$logsResult
.empty()
.append(html);
};
$logsTable.on('click', '.esi-peppol-log-resend', function (e) {
e.preventDefault();
var $btn = $(this);
var orderId = $btn.data('order-id');
if (!orderId) {
return;
}
$btn.prop('disabled', true).addClass('updating-message');
$.post(window.esiPeppolAdmin.ajax_url, {
action: 'esi_peppol_resend_invoice',
nonce: window.esiPeppolAdmin.logs_nonce_resend,
order_id: orderId
})
.done(function (response) {
var data = response && response.data ? response.data : {};
var ok = !!(response && response.success);
var title = ok
? (window.esiPeppolAdmin.i18n_logs_ok_title || 'OK')
: (window.esiPeppolAdmin.i18n_logs_ko_title || 'Pas OK');
var message = data.message || (ok
? (window.esiPeppolAdmin.i18n_logs_resend_ok || 'Document renvoyé avec succès.')
: (window.esiPeppolAdmin.i18n_logs_resend_ko || 'L\'envoi du document a échoué.'));
var detail = data.detail || '';
showLogsNotice(ok ? 'success' : 'error', title, message, detail);
})
.fail(function () {
showLogsNotice(
'error',
window.esiPeppolAdmin.i18n_logs_ko_title || 'Pas OK',
window.esiPeppolAdmin.i18n_network || 'Erreur de communication avec le serveur WordPress.',
''
);
})
.always(function () {
$btn.prop('disabled', false).removeClass('updating-message');
});
});
$logsTable.on('click', '.esi-peppol-log-status', function (e) {
e.preventDefault();
var $btn = $(this);
var orderId = $btn.data('order-id');
if (!orderId) {
return;
}
$btn.prop('disabled', true).addClass('updating-message');
$.post(window.esiPeppolAdmin.ajax_url, {
action: 'esi_peppol_check_invoice_status',
nonce: window.esiPeppolAdmin.logs_nonce_status,
order_id: orderId
})
.done(function (response) {
var data = response && response.data ? response.data : {};
var ok = !!(response && response.success);
var title = ok
? (window.esiPeppolAdmin.i18n_logs_ok_title || 'OK')
: (window.esiPeppolAdmin.i18n_logs_ko_title || 'Pas OK');
var message = data.message || (window.esiPeppolAdmin.i18n_logs_status_lbl || 'Statut actuel du document');
var detail = data.detail || '';
showLogsNotice(ok ? 'success' : 'error', title, message, detail);
})
.fail(function () {
showLogsNotice(
'error',
window.esiPeppolAdmin.i18n_logs_ko_title || 'Pas OK',
window.esiPeppolAdmin.i18n_network || 'Erreur de communication avec le serveur WordPress.',
''
);
})
.always(function () {
$btn.prop('disabled', false).removeClass('updating-message');
});
});
}
// Toggle affichage du mot de passe sur la page de configuration
$('.esi-peppol-password-toggle').on('click', function (e) {
e.preventDefault();
var $btn = $(this);
var targetSelector = $btn.data('target');
var $input = $(targetSelector);
if (!$input.length) {
return;
}
var isPassword = $input.attr('type') === 'password';
$input.attr('type', isPassword ? 'text' : 'password');
// Texte du bouton
$btn.text(isPassword ? 'Masquer' : 'Afficher');
});
// Gestion du logo email avec la médiathèque WordPress
var $uploadLogoBtn = $('#esi-peppol-upload-logo');
var $removeLogoBtn = $('#esi-peppol-remove-logo');
var $logoPreview = $('#esi-peppol-logo-preview');
var $logoIdInput = $('#esi_peppol_logo_email_id');
if ($uploadLogoBtn.length && typeof wp !== 'undefined' && wp.media) {
var mediaUploader;
$uploadLogoBtn.on('click', function (e) {
e.preventDefault();
// Si le sélecteur existe déjà, on le réutilise
if (mediaUploader) {
mediaUploader.open();
return;
}
// Créer le sélecteur de média
mediaUploader = wp.media({
title: 'Choisir un logo',
button: {
text: 'Utiliser ce logo'
},
multiple: false,
library: {
type: 'image'
}
});
// Quand une image est sélectionnée
mediaUploader.on('select', function () {
var attachment = mediaUploader.state().get('selection').first().toJSON();
// Mettre à jour l'input hidden avec l'ID
$logoIdInput.val(attachment.id);
// Afficher la preview
var imageUrl = attachment.sizes && attachment.sizes.medium
? attachment.sizes.medium.url
: attachment.url;
$logoPreview.html('<img src="' + imageUrl + '" alt="Logo email" />').show();
$removeLogoBtn.show();
});
// Ouvrir le sélecteur
mediaUploader.open();
});
// Bouton pour supprimer le logo
$removeLogoBtn.on('click', function (e) {
e.preventDefault();
$logoIdInput.val('');
$logoPreview.empty().hide();
$removeLogoBtn.hide();
});
}
// Gestion de la modal de détails des logs
var $modal = $('#esi-peppol-log-details-modal');
var $modalOverlay = $modal.find('.esi-peppol-modal-overlay');
var $modalClose = $modal.find('.esi-peppol-modal-close');
var $modalContent = $modal.find('.esi-peppol-modal-content');
var $modalLoading = $('#esi-peppol-log-details-loading');
var $modalDetailsContent = $('#esi-peppol-log-details-content');
// Fonction pour ouvrir la modal
function openLogDetailsModal() {
$modal.fadeIn(200);
$('body').css('overflow', 'hidden');
}
// Fonction pour fermer la modal
function closeLogDetailsModal() {
$modal.fadeOut(200);
$('body').css('overflow', '');
$modalDetailsContent.hide().empty();
$modalLoading.show();
}
// Fermer la modal en cliquant sur l'overlay ou le bouton de fermeture
$modalOverlay.on('click', closeLogDetailsModal);
$modalClose.on('click', closeLogDetailsModal);
// Fermer la modal avec la touche Escape
$(document).on('keydown', function (e) {
if (e.key === 'Escape' && $modal.is(':visible')) {
closeLogDetailsModal();
}
});
// Empêcher la fermeture en cliquant sur le contenu de la modal
$modalContent.on('click', function (e) {
e.stopPropagation();
});
// Gestion du clic sur le bouton "Détail"
if ($logsTable.length && typeof window.esiPeppolAdmin !== 'undefined') {
$logsTable.on('click', '.esi-peppol-log-detail', function (e) {
e.preventDefault();
var $btn = $(this);
var logId = $btn.data('log-id');
if (!logId) {
return;
}
// Ouvrir la modal
openLogDetailsModal();
$modalLoading.show();
$modalDetailsContent.hide().empty();
// Charger les détails via AJAX
$.post(window.esiPeppolAdmin.ajax_url, {
action: 'esi_peppol_get_log_details',
nonce: window.esiPeppolAdmin.logs_nonce_details,
log_id: logId
})
.done(function (response) {
$modalLoading.hide();
if (response && response.success && response.data) {
var data = response.data;
var html = '';
// 1. Succès + message erreur
html += '<div class="esi-peppol-log-details-section">';
html += '<h3>Statut</h3>';
html += '<table class="widefat">';
html += '<tr><th style="width: 200px;">Succès</th><td>' + (data.success ? '<span style="color:green;font-weight:bold;">Oui</span>' : '<span style="color:red;font-weight:bold;">Non</span>') + '</td></tr>';
html += '<tr><th>Message</th><td>' + (data.message || '-') + '</td></tr>';
if (data.order_info && data.order_info.number) {
var orderLink = data.order_info.edit_link || '#';
html += '<tr><th>Commande</th><td><a href="' + orderLink + '" target="_blank">#' + data.order_info.number + '</a></td></tr>';
} else if (data.id_order) {
html += '<tr><th>Commande</th><td>#' + data.id_order + '</td></tr>';
}
html += '</table>';
html += '</div>';
// 2. Données client
if (data.customer_data || (data.order_info && (data.order_info.billing_name || data.order_info.billing_company))) {
html += '<div class="esi-peppol-log-details-section">';
html += '<h3>' + (window.esiPeppolAdmin.i18n_logs_customer_data || 'Données client') + '</h3>';
html += '<table class="widefat">';
// Utiliser customer_data depuis le payload si disponible, sinon order_info
var customer = data.customer_data || {};
var orderInfo = data.order_info || {};
var customerName = customer.name || orderInfo.billing_company || orderInfo.billing_name || '-';
var customerLegalName = customer.legal_name || customer.name || orderInfo.billing_company || orderInfo.billing_name || '-';
var customerVat = customer.vat_number || orderInfo.billing_vat_number || '-';
var customerEmail = (customer.contact && customer.contact.contact_email) || orderInfo.billing_email || '-';
var customerPhone = (customer.contact && customer.contact.contact_phone) || orderInfo.billing_phone || '-';
var address = customer.address || {};
var addressLine1 = address.address_line_1 || orderInfo.billing_address_1 || '-';
var addressLine2 = address.address_line_2 || orderInfo.billing_address_2 || '';
var city = address.city || orderInfo.billing_city || '-';
var postalCode = address.postal_code || orderInfo.billing_postcode || '-';
var countryCode = address.country_code || orderInfo.billing_country || '-';
html += '<tr><th style="width: 200px;">Nom / Raison sociale</th><td>' + customerName + '</td></tr>';
if (customerLegalName && customerLegalName !== customerName) {
html += '<tr><th>Nom légal</th><td>' + customerLegalName + '</td></tr>';
}
html += '<tr><th>Numéro TVA</th><td>' + customerVat + '</td></tr>';
html += '<tr><th>Email</th><td>' + customerEmail + '</td></tr>';
if (customerPhone && customerPhone !== '-') {
html += '<tr><th>Téléphone</th><td>' + customerPhone + '</td></tr>';
}
html += '<tr><th>Adresse</th><td>';
html += addressLine1;
if (addressLine2) {
html += '<br>' + addressLine2;
}
html += '<br>' + postalCode + ' ' + city;
html += '<br>' + countryCode;
html += '</td></tr>';
html += '</table>';
html += '</div>';
}
// 3. Détails TVA par taux
if (data.vat_totals && Array.isArray(data.vat_totals) && data.vat_totals.length > 0) {
html += '<div class="esi-peppol-log-details-section">';
html += '<h3>' + (window.esiPeppolAdmin.i18n_logs_vat_details || 'Détails TVA') + '</h3>';
html += '<table class="widefat">';
html += '<thead><tr><th>Taux TVA</th><th>Montant HTVA</th><th>Montant TVA</th><th>Montant TVAC</th></tr></thead>';
html += '<tbody>';
data.vat_totals.forEach(function(vat) {
var vatRate = parseFloat(vat.vat_rate || 0);
var taxableAmount = parseFloat(vat.taxable_amount || 0);
var vatAmount = parseFloat(vat.vat_amount || 0);
var totalInclVat = taxableAmount + vatAmount;
html += '<tr>';
html += '<td>' + vatRate.toFixed(2) + ' %</td>';
html += '<td>' + taxableAmount.toFixed(2) + ' €</td>';
html += '<td>' + vatAmount.toFixed(2) + ' €</td>';
html += '<td>' + totalInclVat.toFixed(2) + ' €</td>';
html += '</tr>';
});
html += '</tbody>';
html += '</table>';
html += '</div>';
}
// 4. Totaux (HTVA, TVAC, TVA)
if (data.invoice_totals) {
html += '<div class="esi-peppol-log-details-section">';
html += '<h3>' + (window.esiPeppolAdmin.i18n_logs_totals || 'Totaux') + '</h3>';
html += '<table class="widefat">';
var totalHTVA = parseFloat(data.invoice_totals.total_amount_excluding_vat || 0);
var totalTVA = parseFloat(data.invoice_totals.total_vat_amount || 0);
var totalTVAC = parseFloat(data.invoice_totals.total_amount_including_vat || 0);
html += '<tr><th style="width: 200px;">Total HTVA</th><td><strong>' + totalHTVA.toFixed(2) + ' €</strong></td></tr>';
html += '<tr><th>Total TVA</th><td><strong>' + totalTVA.toFixed(2) + ' €</strong></td></tr>';
html += '<tr><th>Total TVAC</th><td><strong>' + totalTVAC.toFixed(2) + ' €</strong></td></tr>';
if (data.invoice_totals.total_payable_amount) {
var payableAmount = parseFloat(data.invoice_totals.total_payable_amount || 0);
html += '<tr><th>Montant à payer</th><td>' + payableAmount.toFixed(2) + ' €</td></tr>';
}
html += '</table>';
html += '</div>';
}
$modalDetailsContent.html(html).show();
} else {
var errorMsg = (response && response.data && response.data.message)
? response.data.message
: (window.esiPeppolAdmin.i18n_logs_error || 'Erreur lors du chargement des détails.');
$modalDetailsContent.html('<p class="esi-peppol-error">' + errorMsg + '</p>').show();
}
})
.fail(function () {
$modalLoading.hide();
var errorMsg = window.esiPeppolAdmin.i18n_network || 'Erreur de communication avec le serveur WordPress.';
$modalDetailsContent.html('<p class="esi-peppol-error">' + errorMsg + '</p>').show();
});
});
}
// Bouton pour copier l'URL du webhook
var $copyWebhookBtn = $('.esi-peppol-copy-webhook-url');
if ($copyWebhookBtn.length) {
$copyWebhookBtn.on('click', function (e) {
e.preventDefault();
var $target = $($(this).data('target'));
if ($target.length) {
var textToCopy = $target.text() || $target.val() || '';
if (textToCopy) {
// Utiliser l'API Clipboard moderne si disponible
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(textToCopy).then(function () {
var $btn = $(e.currentTarget);
var originalText = $btn.text();
$btn.text('✓ Copié').prop('disabled', true);
setTimeout(function () {
$btn.text(originalText).prop('disabled', false);
}, 2000);
}).catch(function (err) {
console.error('Erreur lors de la copie:', err);
});
} else {
// Fallback pour les anciens navigateurs
try {
// Créer un élément temporaire pour la copie
var $temp = $('<textarea>');
$('body').append($temp);
$temp.val(textToCopy).select();
document.execCommand('copy');
$temp.remove();
var $btn = $(e.currentTarget);
var originalText = $btn.text();
$btn.text('✓ Copié').prop('disabled', true);
setTimeout(function () {
$btn.text(originalText).prop('disabled', false);
}, 2000);
} catch (err) {
console.error('Erreur lors de la copie:', err);
}
}
}
}
});
}
});
})(jQuery);