Ajustement detect tva
This commit is contained in:
parent
feaa43c289
commit
9ed2c2009e
@ -708,8 +708,7 @@ class PEPPOL_Plugin {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Détecte automatiquement les champs TVA lors de l'installation.
|
* 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_get_vat_meta_keys().
|
||||||
* 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é
|
* @return string|null La clé du champ TVA détecté, ou null si aucun trouvé
|
||||||
*/
|
*/
|
||||||
@ -721,66 +720,22 @@ class PEPPOL_Plugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Vérifier si WooCommerce est disponible
|
// Vérifier si WooCommerce est disponible
|
||||||
if (!function_exists('wc_get_orders')) {
|
if (!function_exists('wc_get_order')) {
|
||||||
// Marquer que la détection a été tentée (même si WooCommerce n'est pas disponible)
|
// 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);
|
update_option('esi_peppol_vat_field_auto_detected', true);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Récupérer les dernières commandes pour scanner les champs TVA
|
$vat_keys = \ESI_PEPPOL\helpers\PEPPOL_Woo_Helper::esi_get_vat_meta_keys(50);
|
||||||
$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
|
// Si aucun champ trouvé, marquer que la détection a été effectuée et retourner null
|
||||||
if (empty($vat_fields_found)) {
|
if (empty($vat_keys)) {
|
||||||
update_option('esi_peppol_vat_field_auto_detected', true);
|
update_option('esi_peppol_vat_field_auto_detected', true);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trier : d'abord par groupe (billing avant shipping), puis par nombre d'occurrences
|
// Prendre la première clé trouvée
|
||||||
usort($vat_fields_found, function ($a, $b) {
|
$vat_field_key = reset($vat_keys);
|
||||||
// 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é
|
// Sauvegarder le champ détecté
|
||||||
update_option('esi_peppol_vat_field_key', $vat_field_key);
|
update_option('esi_peppol_vat_field_key', $vat_field_key);
|
||||||
@ -815,109 +770,14 @@ class PEPPOL_Plugin {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Récupérer les dernières commandes pour scanner les champs TVA
|
$vat_keys = \ESI_PEPPOL\helpers\PEPPOL_Woo_Helper::esi_get_vat_meta_keys();
|
||||||
$orders = wc_get_orders([
|
$vat_fields_found = array_map(function ($key) {
|
||||||
'limit' => 50,
|
return [
|
||||||
'orderby' => 'date',
|
'key' => $key,
|
||||||
'order' => 'DESC',
|
'count' => 0,
|
||||||
'status' => ['completed', 'processing', 'on-hold'],
|
'sample_value' => null,
|
||||||
]);
|
];
|
||||||
|
}, $vat_keys);
|
||||||
$vat_fields_found = [];
|
|
||||||
|
|
||||||
foreach ($orders as $order) {
|
|
||||||
if (!$order instanceof \WC_Order) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Utiliser la fonction helper pour scanner tous les champs TVA possibles
|
|
||||||
$vat_candidates = [];
|
|
||||||
|
|
||||||
// Scanner les meta keys contenant vat/tva
|
|
||||||
foreach ($order->get_meta_data() as $meta) {
|
|
||||||
$k = (string) $meta->key;
|
|
||||||
if (preg_match('/\b(vat|tva)\b/i', $k) || preg_match('/(vat|tva)/i', $k)) {
|
|
||||||
$v = $meta->value;
|
|
||||||
if (is_string($v)) {
|
|
||||||
$v = trim($v);
|
|
||||||
}
|
|
||||||
if (!empty($v)) {
|
|
||||||
if (!isset($vat_candidates[$k])) {
|
|
||||||
$vat_candidates[$k] = [
|
|
||||||
'key' => $k,
|
|
||||||
'value' => $v,
|
|
||||||
'count' => 0,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
$vat_candidates[$k]['count']++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scanner les champs de checkout
|
|
||||||
if (function_exists('WC') && WC()->checkout()) {
|
|
||||||
$fields = WC()->checkout()->get_checkout_fields();
|
|
||||||
$patterns = ['vat', 'tva', 'btw', 'ust', 'mwst', 'piva', 'moms', 'mva'];
|
|
||||||
|
|
||||||
foreach ($fields as $group_fields) {
|
|
||||||
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) {
|
|
||||||
foreach ([$key, '_' . $key] as $meta_key) {
|
|
||||||
$val = $order->get_meta($meta_key, true);
|
|
||||||
if (!empty($val)) {
|
|
||||||
if (!isset($vat_candidates[$meta_key])) {
|
|
||||||
$vat_candidates[$meta_key] = [
|
|
||||||
'key' => $meta_key,
|
|
||||||
'value' => trim((string) $val),
|
|
||||||
'count' => 0,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
$vat_candidates[$meta_key]['count']++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ajouter les candidats trouvés
|
|
||||||
foreach ($vat_candidates as $candidate) {
|
|
||||||
$key = $candidate['key'];
|
|
||||||
if (!isset($vat_fields_found[$key])) {
|
|
||||||
$vat_fields_found[$key] = [
|
|
||||||
'key' => $key,
|
|
||||||
'count' => 0,
|
|
||||||
'sample_value' => $candidate['value'],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
$vat_fields_found[$key]['count'] += $candidate['count'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trier par nombre d'occurrences (décroissant)
|
|
||||||
usort($vat_fields_found, function ($a, $b) {
|
|
||||||
return $b['count'] - $a['count'];
|
|
||||||
});
|
|
||||||
|
|
||||||
wp_send_json_success([
|
wp_send_json_success([
|
||||||
'fields' => array_values($vat_fields_found),
|
'fields' => array_values($vat_fields_found),
|
||||||
|
|||||||
@ -187,6 +187,114 @@ class PEPPOL_Woo_Helper {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne les IDs des commandes ayant un meta_key TVA/VAT.
|
||||||
|
* Compatible HPOS et legacy.
|
||||||
|
*
|
||||||
|
* @param int $limit 0 pour aucune limite.
|
||||||
|
* @param string $order ASC|DESC
|
||||||
|
* @param array $statuses Statuts Woo (sans préfixe wc-).
|
||||||
|
* @return int[]
|
||||||
|
*/
|
||||||
|
public static function esi_get_order_ids_with_vat_meta(
|
||||||
|
int $limit = 0,
|
||||||
|
string $order = 'DESC',
|
||||||
|
array $statuses = ['completed', 'processing', 'on-hold']
|
||||||
|
): array {
|
||||||
|
global $wpdb;
|
||||||
|
|
||||||
|
$order = strtoupper($order) === 'ASC' ? 'ASC' : 'DESC';
|
||||||
|
$like_tva = '%tva%';
|
||||||
|
$like_vat = '%vat%';
|
||||||
|
$exclude_key = 'is_vat_exempt';
|
||||||
|
|
||||||
|
$statuses = array_map(function ($status) {
|
||||||
|
$status = (string) $status;
|
||||||
|
return strpos($status, 'wc-') === 0 ? $status : 'wc-' . $status;
|
||||||
|
}, $statuses);
|
||||||
|
|
||||||
|
$status_placeholders = implode(',', array_fill(0, count($statuses), '%s'));
|
||||||
|
|
||||||
|
$is_hpos = class_exists('\Automattic\WooCommerce\Utilities\OrderUtil')
|
||||||
|
&& \Automattic\WooCommerce\Utilities\OrderUtil::custom_orders_table_usage_is_enabled();
|
||||||
|
|
||||||
|
if ($is_hpos) {
|
||||||
|
$orders_table = $wpdb->prefix . 'wc_orders';
|
||||||
|
$orders_meta_table = $wpdb->prefix . 'wc_orders_meta';
|
||||||
|
|
||||||
|
$sql = "
|
||||||
|
SELECT DISTINCT o.id
|
||||||
|
FROM {$orders_table} o
|
||||||
|
INNER JOIN {$orders_meta_table} om ON om.order_id = o.id
|
||||||
|
WHERE o.type = 'shop_order'
|
||||||
|
AND (om.meta_key LIKE %s OR om.meta_key LIKE %s)
|
||||||
|
AND om.meta_key != %s
|
||||||
|
AND o.status IN ({$status_placeholders})
|
||||||
|
ORDER BY o.date_created_gmt {$order}
|
||||||
|
";
|
||||||
|
} else {
|
||||||
|
$sql = "
|
||||||
|
SELECT DISTINCT p.ID
|
||||||
|
FROM {$wpdb->posts} p
|
||||||
|
INNER JOIN {$wpdb->postmeta} pm ON pm.post_id = p.ID
|
||||||
|
WHERE p.post_type = 'shop_order'
|
||||||
|
AND (pm.meta_key LIKE %s OR pm.meta_key LIKE %s)
|
||||||
|
AND pm.meta_key != %s
|
||||||
|
AND p.post_status IN ({$status_placeholders})
|
||||||
|
ORDER BY p.post_date {$order}
|
||||||
|
";
|
||||||
|
}
|
||||||
|
|
||||||
|
$params = array_merge([$like_tva, $like_vat, $exclude_key], $statuses);
|
||||||
|
if ($limit > 0) {
|
||||||
|
$sql .= ' LIMIT %d';
|
||||||
|
$params[] = $limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$prepared_sql = $wpdb->prepare($sql, $params);
|
||||||
|
$ids = $wpdb->get_col($prepared_sql);
|
||||||
|
|
||||||
|
return array_map('intval', $ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne les meta_key TVA/VAT distinctes.
|
||||||
|
* Compatible HPOS et legacy.
|
||||||
|
*
|
||||||
|
* @param int $limit
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
public static function esi_get_vat_meta_keys( int $limit = 50 ): array {
|
||||||
|
global $wpdb;
|
||||||
|
|
||||||
|
$like_tva = '%tva%';
|
||||||
|
$like_vat = '%vat%';
|
||||||
|
$exclude_key = 'is_vat_exempt';
|
||||||
|
|
||||||
|
$is_hpos = class_exists('\Automattic\WooCommerce\Utilities\OrderUtil')
|
||||||
|
&& \Automattic\WooCommerce\Utilities\OrderUtil::custom_orders_table_usage_is_enabled();
|
||||||
|
|
||||||
|
$meta_table = $is_hpos ? $wpdb->prefix . 'wc_orders_meta' : $wpdb->postmeta;
|
||||||
|
|
||||||
|
$sql = "
|
||||||
|
SELECT DISTINCT meta_key
|
||||||
|
FROM {$meta_table}
|
||||||
|
WHERE (meta_key LIKE %s OR meta_key LIKE %s)
|
||||||
|
AND meta_key <> %s
|
||||||
|
LIMIT %d
|
||||||
|
";
|
||||||
|
|
||||||
|
$prepared_sql = $wpdb->prepare($sql, $like_tva, $like_vat, $exclude_key, $limit);
|
||||||
|
$keys = $wpdb->get_col($prepared_sql);
|
||||||
|
|
||||||
|
$keys = array_values(array_unique(array_map('strval', $keys)));
|
||||||
|
$keys = array_values(array_filter($keys, function ($key) {
|
||||||
|
return $key !== 'is_vat_exempt';
|
||||||
|
}));
|
||||||
|
|
||||||
|
return $keys;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Détecte tous les champs TVA dans une commande, limités aux groupes billing et shipping.
|
* 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.
|
* Retourne un tableau de tous les champs trouvés avec leur groupe et leur valeur.
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user