Amélioration trigger check champ tva

This commit is contained in:
Jean-Philippe Staelen 2026-01-14 16:19:55 +01:00
parent cf40b88b97
commit ce1be909de
3 changed files with 238 additions and 14 deletions

View File

@ -15,13 +15,16 @@ class PEPPOL_Plugin {
* Méthode appelée lors de l'activation du plugin.
*
* Elle délègue au modèle principal la création de la table
* `esi_peppol_invoices`.
* `esi_peppol_invoices` et détecte automatiquement les champs TVA.
*
* @return void
*/
public static function activate(): void {
// Création / mise à jour de la table principale des factures
PEPPOL_Main_model::create_table();
// Détection automatique des champs TVA (billing -> shipping)
self::auto_detect_vat_field_on_install();
}
public function desactivate() {
@ -683,6 +686,91 @@ class PEPPOL_Plugin {
wp_send_json_error($payload_response, 200);
}
/**
* Détecte automatiquement les champs TVA lors de l'installation.
* Limite la recherche aux champs billing et shipping dans cet ordre.
* Utilise la fonction helper PEPPOL_Woo_Helper::esi_detect_vat_fields_billing_shipping().
*
* @return string|null La clé du champ TVA détecté, ou null si aucun trouvé
*/
public static function auto_detect_vat_field_on_install(): ?string {
// Ne pas détecter si un champ est déjà sauvegardé
$existing_field = get_option('esi_peppol_vat_field_key', '');
if ($existing_field !== '') {
return $existing_field;
}
// Vérifier si WooCommerce est disponible
if (!function_exists('wc_get_orders')) {
// Marquer que la détection a été tentée (même si WooCommerce n'est pas disponible)
update_option('esi_peppol_vat_field_auto_detected', true);
return null;
}
// Récupérer les dernières commandes pour scanner les champs TVA
$orders = wc_get_orders([
'limit' => 50,
'orderby' => 'date',
'order' => 'DESC',
'status' => ['completed', 'processing', 'on-hold'],
]);
$vat_fields_found = [];
// Utiliser la fonction helper pour détecter les champs TVA dans chaque commande
foreach ($orders as $order) {
if (!$order instanceof \WC_Order) {
continue;
}
$fields = \ESI_PEPPOL\helpers\PEPPOL_Woo_Helper::esi_detect_vat_fields_billing_shipping($order);
// Compter les occurrences de chaque champ
foreach ($fields as $field) {
$key = $field['key'];
if (!isset($vat_fields_found[$key])) {
$vat_fields_found[$key] = [
'key' => $key,
'count' => 0,
'group' => $field['group'],
];
}
$vat_fields_found[$key]['count']++;
}
}
// Si aucun champ trouvé, marquer que la détection a été effectuée et retourner null
if (empty($vat_fields_found)) {
update_option('esi_peppol_vat_field_auto_detected', true);
return null;
}
// Trier : d'abord par groupe (billing avant shipping), puis par nombre d'occurrences
usort($vat_fields_found, function ($a, $b) {
// Priorité au groupe billing
if ($a['group'] === 'billing' && $b['group'] !== 'billing') {
return -1;
}
if ($a['group'] !== 'billing' && $b['group'] === 'billing') {
return 1;
}
// Si même groupe, trier par nombre d'occurrences
return $b['count'] - $a['count'];
});
// Prendre le premier champ trouvé (priorité billing)
$selected_field = reset($vat_fields_found);
$vat_field_key = $selected_field['key'];
// Sauvegarder le champ détecté
update_option('esi_peppol_vat_field_key', $vat_field_key);
// Marquer que la détection a été effectuée à l'installation
update_option('esi_peppol_vat_field_auto_detected', true);
return $vat_field_key;
}
/**
* Handler AJAX pour détecter les champs TVA dans les commandes WooCommerce.
*
@ -1075,16 +1163,31 @@ class PEPPOL_Plugin {
/**
* Retourne un message d'avertissement à propos du numéro de TVA
* de la boutique si celui-ci n'est pas encore renseigné dans
* les réglages WooCommerce.
* les réglages WooCommerce, ou si aucun champ TVA client n'a été détecté.
*
* - Message d'invitation initial : aucune configuration ESI Peppol
* n'a encore été saisie.
* - Message de rappel : les identifiants ESI Peppol sont déjà
* enregistrés mais la TVA reste vide.
* - Message si aucun champ TVA client détecté : proposer la détection dans settings.
*
* @return string|null
*/
public static function get_vat_notice_message(): ?string {
// Vérifier d'abord si un champ TVA client a été détecté
$vat_field_key = (string) get_option('esi_peppol_vat_field_key', '');
$auto_detected = (bool) get_option('esi_peppol_vat_field_auto_detected', false);
// Si aucun champ TVA détecté, proposer la détection dans settings
if ($vat_field_key === '' && $auto_detected) {
$settings_url = admin_url('admin.php?page=esi-peppol-settings');
return sprintf(
/* translators: %s: URL vers la page de réglages */
__('Aucun champ TVA client n\'a été détecté automatiquement. Vous pouvez utiliser l\'outil de détection dans <a href="%s">ESI Peppol > Configuration</a> pour rechercher manuellement les champs TVA dans vos commandes.', 'esi_peppol'),
esc_url($settings_url)
);
}
$vat_number = (string) get_option('woocommerce_store_vat_number', '');
if ($vat_number !== '') {
@ -1111,7 +1214,8 @@ class PEPPOL_Plugin {
/**
* Affiche un message d'avertissement dans l'admin WordPress
* si le numéro de TVA de la boutique n'est pas renseigné.
* si le numéro de TVA de la boutique n'est pas renseigné ou
* si aucun champ TVA client n'a été détecté.
*
* Hooké sur admin_notices.
*
@ -1130,10 +1234,18 @@ class PEPPOL_Plugin {
$api_key = (string) \get_option('esi_peppol_api_key', '');
$password = (string) \get_option('esi_peppol_password', '');
$vat_field_key = (string) \get_option('esi_peppol_vat_field_key', '');
$auto_detected = (bool) \get_option('esi_peppol_vat_field_auto_detected', false);
// Si aucun champ TVA détecté, utiliser notice-warning
if ($vat_field_key === '' && $auto_detected) {
$notice_class = 'notice-warning';
} else {
$notice_class = ($api_key === '' && $password === '') ? 'notice-info' : 'notice-warning';
}
echo '<div class="notice ' . \esc_attr($notice_class) . '"><p>' .
\esc_html($vat_notice_message) .
\wp_kses_post($vat_notice_message) .
'</p></div>';
}

View File

@ -187,4 +187,106 @@ class PEPPOL_Woo_Helper {
];
}
/**
* Détecte tous les champs TVA dans une commande, limités aux groupes billing et shipping.
* Retourne un tableau de tous les champs trouvés avec leur groupe et leur valeur.
*
* @param \WC_Order $order La commande à analyser
* @return array Tableau de champs TVA trouvés : ['key' => string, 'value' => string, 'group' => 'billing'|'shipping']
*/
public static function esi_detect_vat_fields_billing_shipping( \WC_Order $order ): array {
$vat_fields_found = [];
$patterns = ['vat', 'tva', 'btw', 'ust', 'mwst', 'piva', 'moms', 'mva'];
// Ordre de recherche : billing d'abord, puis shipping
$search_groups = ['billing', 'shipping'];
foreach ($search_groups as $group) {
// Chercher dans les meta keys du groupe (billing ou shipping)
foreach ($order->get_meta_data() as $meta) {
$k = (string) $meta->key;
$k_lower = strtolower($k);
// Vérifier que la clé commence par le groupe recherché (avec ou sans underscore)
$group_prefix = $group . '_';
$group_prefix_underscore = '_' . $group . '_';
if (strpos($k_lower, $group_prefix) !== 0 && strpos($k_lower, $group_prefix_underscore) !== 0) {
continue;
}
// Vérifier si la clé contient un pattern TVA
$found = false;
foreach ($patterns as $p) {
if (strpos($k_lower, $p) !== false) {
$found = true;
break;
}
}
if ($found) {
$v = $meta->value;
if (is_string($v)) {
$v = trim($v);
}
if (!empty($v)) {
if (!isset($vat_fields_found[$k])) {
$vat_fields_found[$k] = [
'key' => $k,
'value' => $v,
'group' => $group,
];
}
}
}
}
// Chercher aussi dans les champs de checkout du groupe
if (function_exists('WC') && WC()->checkout()) {
$fields = WC()->checkout()->get_checkout_fields();
$group_fields = $fields[$group] ?? [];
foreach ($group_fields as $key => $def) {
$k = strtolower($key);
$found = false;
foreach ($patterns as $p) {
if (strpos($k, $p) !== false) {
$found = true;
break;
}
}
if (!$found) {
$label = strtolower((string) ($def['label'] ?? ''));
foreach ($patterns as $p) {
if (preg_match('/\b' . $p . '\b/i', $label)) {
$found = true;
break;
}
}
}
if ($found) {
// Essayer avec et sans préfixe underscore
foreach ([$key, '_' . $key] as $meta_key) {
$val = $order->get_meta($meta_key, true);
if (!empty($val)) {
if (!isset($vat_fields_found[$meta_key])) {
$vat_fields_found[$meta_key] = [
'key' => $meta_key,
'value' => is_string($val) ? trim($val) : $val,
'group' => $group,
];
}
}
}
}
}
}
}
return array_values($vat_fields_found);
}
}

View File

@ -158,6 +158,7 @@ if ($logo_email_id) {
<td>
<?php
$saved_vat_field = get_option('esi_peppol_vat_field_key', '');
$auto_detected = (bool) get_option('esi_peppol_vat_field_auto_detected', false);
?>
<div class="esi-peppol-vat-field-wrapper">
<button type="button"
@ -166,16 +167,25 @@ if ($logo_email_id) {
<?php esc_html_e('Détecter les champs TVA', 'esi_peppol'); ?>
</button>
<div id="esi-peppol-vat-fields-result" style="margin-top: 15px;"></div>
<?php if ($saved_vat_field) : ?>
<p class="description" style="margin-top: 10px;">
<?php
printf(
/* translators: %s: nom du champ TVA sauvegardé */
esc_html__('Champ TVA actuellement utilisé : %s', 'esi_peppol'),
'<strong>' . esc_html($saved_vat_field) . '</strong>'
);
?>
<div style="margin-top: 15px; padding: 10px; background-color: #f0f0f1; border-left: 4px solid #2271b1;">
<p style="margin: 0;">
<strong><?php esc_html_e('Champ TVA détecté :', 'esi_peppol'); ?></strong>
<code style="margin-left: 5px; padding: 2px 6px; background-color: #fff; border: 1px solid #c3c4c7;"><?php echo esc_html($saved_vat_field); ?></code>
</p>
<?php if ($auto_detected) : ?>
<p style="margin: 5px 0 0 0; font-size: 12px; color: #646970;">
<?php esc_html_e('✓ Détecté automatiquement lors de l\'installation', 'esi_peppol'); ?>
</p>
<?php endif; ?>
</div>
<?php elseif ($auto_detected) : ?>
<div style="margin-top: 15px; padding: 10px; background-color: #fff3cd; border-left: 4px solid #dba617;">
<p style="margin: 0;">
<?php esc_html_e('Aucun champ TVA n\'a été détecté automatiquement lors de l\'installation. Utilisez le bouton ci-dessus pour rechercher manuellement les champs TVA dans vos commandes.', 'esi_peppol'); ?>
</p>
</div>
<?php endif; ?>
</div>
<p class="description">