amélioration diverse
This commit is contained in:
parent
7d5032ffdf
commit
3f9a113663
131
app/config.php
131
app/config.php
@ -1 +1,132 @@
|
||||
<?php
|
||||
/**
|
||||
* Configuration du plugin ESI Peppol
|
||||
*
|
||||
* @package ESI_PEPPOL
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration de l'API ESI Peppol
|
||||
*/
|
||||
return [
|
||||
/**
|
||||
* URL de base de l'API ESIPeppol (production)
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
'api_base_url' => 'https://peppol.esi-web.be/api',
|
||||
|
||||
/**
|
||||
* URL de base de l'API ESIPeppol (environnement de test)
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
'api_test_base_url' => 'https://demo.esi-peppol.be/api',
|
||||
|
||||
/**
|
||||
* Active l'utilisation de l'environnement de test
|
||||
* Si true, utilise api_test_base_url, sinon utilise api_base_url
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
'is_test_environment' => true,
|
||||
|
||||
/**
|
||||
* Timeout pour les requêtes API (en secondes)
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
'api_timeout' => 20,
|
||||
|
||||
/**
|
||||
* Configuration des factures
|
||||
*/
|
||||
'invoice' => [
|
||||
/**
|
||||
* Nombre de jours avant l'échéance par défaut
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
'default_due_days' => 30,
|
||||
|
||||
/**
|
||||
* Préfixe pour la référence externe (ex: 'WC-' pour WooCommerce)
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
'external_reference_prefix' => 'WC-',
|
||||
|
||||
/**
|
||||
* Termes de paiement par défaut
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
'default_payment_terms' => 'Paiement à 30 jours nets',
|
||||
],
|
||||
|
||||
/**
|
||||
* Configuration des identifiants de produits
|
||||
*/
|
||||
'item_ids' => [
|
||||
/**
|
||||
* Préfixe pour les identifiants de produits
|
||||
* Format: {prefix}{SKU ou ID}
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
'product_prefix' => 'P_',
|
||||
|
||||
/**
|
||||
* Préfixe pour les frais de livraison
|
||||
* Format: {prefix}{line_number}
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
'shipping_prefix' => 'SHIPCQT_',
|
||||
|
||||
/**
|
||||
* Préfixe pour les frais supplémentaires
|
||||
* Format: {prefix}{line_number}
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
'fee_prefix' => 'FEE_',
|
||||
],
|
||||
|
||||
/**
|
||||
* Configuration des unités de mesure
|
||||
*/
|
||||
'units' => [
|
||||
/**
|
||||
* Code d'unité de mesure par défaut (C62 = "Unit")
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
'default_unit_of_measure' => 'C62',
|
||||
],
|
||||
|
||||
/**
|
||||
* Configuration de la taxe (TVA)
|
||||
*/
|
||||
'tax' => [
|
||||
/**
|
||||
* Identifiant du schéma de taxe
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
'scheme_id' => 'VAT',
|
||||
|
||||
/**
|
||||
* Nom du schéma de taxe
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
'scheme_name' => 'Value Added Tax',
|
||||
],
|
||||
];
|
||||
|
||||
@ -8,22 +8,80 @@ use ESI_PEPPOL\helpers\PEPPOL_Woo_Helper;
|
||||
class PEPPOL_peppol_controller {
|
||||
|
||||
/**
|
||||
* URL de base de l'API ESIPeppol.
|
||||
* Cache de la configuration chargée.
|
||||
*
|
||||
* @var array<string,mixed>|null
|
||||
*/
|
||||
private const API_BASE_URL = 'https://demo.esi-peppol.be/api';
|
||||
private static $config_cache = null;
|
||||
|
||||
/**
|
||||
* Charge la configuration depuis le fichier config.php.
|
||||
*
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
protected static function get_config(): array {
|
||||
if (self::$config_cache === null) {
|
||||
$config_file = ESI_PEPPOL_DIR . 'app/config.php';
|
||||
if (file_exists($config_file)) {
|
||||
self::$config_cache = require $config_file;
|
||||
} else {
|
||||
self::$config_cache = [];
|
||||
}
|
||||
}
|
||||
|
||||
return self::$config_cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère une valeur de configuration avec une valeur par défaut.
|
||||
*
|
||||
* @param string $key Clé de configuration (peut être un chemin avec des points, ex: 'invoice.default_due_days').
|
||||
* @param mixed $default Valeur par défaut si la clé n'existe pas.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected static function get_config_value(string $key, $default = null) {
|
||||
$config = self::get_config();
|
||||
|
||||
// Support pour les clés imbriquées (ex: 'invoice.default_due_days')
|
||||
if (strpos($key, '.') !== false) {
|
||||
$keys = explode('.', $key);
|
||||
$value = $config;
|
||||
|
||||
foreach ($keys as $k) {
|
||||
if (!is_array($value) || !isset($value[$k])) {
|
||||
return $default;
|
||||
}
|
||||
$value = $value[$k];
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
return isset($config[$key]) ? $config[$key] : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retourne l'URL de base de l'API (filtrable).
|
||||
* Utilise l'URL de test si is_test_environment est activé, sinon l'URL de production.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function get_base_url(): string {
|
||||
$is_test = (bool) self::get_config_value('is_test_environment', false);
|
||||
|
||||
if ($is_test) {
|
||||
$api_base_url = self::get_config_value('api_test_base_url', 'https://demo.esi-peppol.be/api');
|
||||
} else {
|
||||
$api_base_url = self::get_config_value('api_base_url', 'https://peppol.esi-web.be/api');
|
||||
}
|
||||
|
||||
/**
|
||||
* Filtre pour surcharger l'URL de base de l'API ESIPeppol.
|
||||
*
|
||||
* @param string $base_url URL de base actuelle.
|
||||
*/
|
||||
return (string) \apply_filters('esi_peppol_api_base_url', self::API_BASE_URL);
|
||||
return (string) \apply_filters('esi_peppol_api_base_url', $api_base_url);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -91,7 +149,7 @@ class PEPPOL_peppol_controller {
|
||||
|
||||
$wp_args = [
|
||||
'method' => $method,
|
||||
'timeout' => 20,
|
||||
'timeout' => (int) self::get_config_value('api_timeout', 20),
|
||||
'headers' => $headers,
|
||||
];
|
||||
|
||||
@ -295,8 +353,8 @@ class PEPPOL_peppol_controller {
|
||||
'vat_category_code' => 'S',
|
||||
'taxable_amount' => 0.0,
|
||||
'vat_amount' => 0.0,
|
||||
'tax_scheme_id' => 'VAT',
|
||||
'tax_scheme_name' => 'Value Added Tax',
|
||||
'tax_scheme_id' => self::get_config_value('tax.scheme_id', 'VAT'),
|
||||
'tax_scheme_name' => self::get_config_value('tax.scheme_name', 'Value Added Tax'),
|
||||
];
|
||||
}
|
||||
|
||||
@ -322,8 +380,8 @@ class PEPPOL_peppol_controller {
|
||||
'vat_category_code' => 'S',
|
||||
'taxable_amount' => 0.0,
|
||||
'vat_amount' => 0.0,
|
||||
'tax_scheme_id' => 'VAT',
|
||||
'tax_scheme_name' => 'Value Added Tax',
|
||||
'tax_scheme_id' => self::get_config_value('tax.scheme_id', 'VAT'),
|
||||
'tax_scheme_name' => self::get_config_value('tax.scheme_name', 'Value Added Tax'),
|
||||
];
|
||||
}
|
||||
|
||||
@ -359,8 +417,8 @@ class PEPPOL_peppol_controller {
|
||||
'vat_category_code' => 'S',
|
||||
'taxable_amount' => 0.0,
|
||||
'vat_amount' => 0.0,
|
||||
'tax_scheme_id' => 'VAT',
|
||||
'tax_scheme_name' => 'Value Added Tax',
|
||||
'tax_scheme_id' => self::get_config_value('tax.scheme_id', 'VAT'),
|
||||
'tax_scheme_name' => self::get_config_value('tax.scheme_name', 'Value Added Tax'),
|
||||
];
|
||||
}
|
||||
|
||||
@ -380,8 +438,8 @@ class PEPPOL_peppol_controller {
|
||||
'vat_category_code' => 'E',
|
||||
'taxable_amount' => 0.0,
|
||||
'vat_amount' => 0.0,
|
||||
'tax_scheme_id' => 'VAT',
|
||||
'tax_scheme_name' => 'Value Added Tax',
|
||||
'tax_scheme_id' => self::get_config_value('tax.scheme_id', 'VAT'),
|
||||
'tax_scheme_name' => self::get_config_value('tax.scheme_name', 'Value Added Tax'),
|
||||
];
|
||||
}
|
||||
|
||||
@ -457,18 +515,20 @@ class PEPPOL_peppol_controller {
|
||||
? $order->get_date_created()->date('Y-m-d')
|
||||
: \gmdate('Y-m-d');
|
||||
|
||||
// Par défaut, échéance à +30 jours (filtrable)
|
||||
// Par défaut, échéance configurable (filtrable)
|
||||
$default_due_days = (int) self::get_config_value('invoice.default_due_days', 30);
|
||||
$due_date = \apply_filters(
|
||||
'esi_peppol_invoice_due_date',
|
||||
(new \DateTimeImmutable($invoice_date))
|
||||
->modify('+30 days')
|
||||
->modify('+' . $default_due_days . ' days')
|
||||
->format('Y-m-d'),
|
||||
$order
|
||||
);
|
||||
|
||||
$external_reference_prefix = self::get_config_value('invoice.external_reference_prefix', 'WC-');
|
||||
$external_reference = \apply_filters(
|
||||
'esi_peppol_external_reference',
|
||||
'WC-' . $order_number,
|
||||
$external_reference_prefix . $order_number,
|
||||
$order
|
||||
);
|
||||
|
||||
@ -482,9 +542,10 @@ class PEPPOL_peppol_controller {
|
||||
$order
|
||||
);
|
||||
|
||||
$default_payment_terms = self::get_config_value('invoice.default_payment_terms', __('Paiement à 30 jours nets', 'esi_peppol'));
|
||||
$payment_terms = \apply_filters(
|
||||
'esi_peppol_payment_terms',
|
||||
__('Paiement à 30 jours nets', 'esi_peppol'),
|
||||
$default_payment_terms,
|
||||
$order
|
||||
);
|
||||
|
||||
@ -628,7 +689,7 @@ class PEPPOL_peppol_controller {
|
||||
$is_zero_vat_amount = ($vat_amount == 0.0);
|
||||
$vat_category_code = $is_zero_vat_amount ? 'E' : 'S';
|
||||
|
||||
$unit_of_measure = 'C62'; // "Unit" code par défaut
|
||||
$unit_of_measure = self::get_config_value('units.default_unit_of_measure', 'C62'); // "Unit" code par défaut
|
||||
|
||||
if ($product && $product->get_meta('unit_of_measure')) {
|
||||
$unit_of_measure = (string) $product->get_meta('unit_of_measure');
|
||||
@ -636,9 +697,10 @@ class PEPPOL_peppol_controller {
|
||||
|
||||
$seller_item_id = '';
|
||||
if ($product) {
|
||||
// Pour les produits : P_ + SKU si existant, sinon P_ + ID produit
|
||||
// Pour les produits : préfixe configurable + SKU si existant, sinon préfixe + ID produit
|
||||
$product_prefix = self::get_config_value('item_ids.product_prefix', 'P_');
|
||||
$base_id = $product->get_sku() ?: (string) $product->get_id();
|
||||
$seller_item_id = 'P_' . $base_id;
|
||||
$seller_item_id = $product_prefix . $base_id;
|
||||
}
|
||||
|
||||
// Description courte sans balises HTML pour compatibilité PEPPOL
|
||||
@ -740,8 +802,9 @@ class PEPPOL_peppol_controller {
|
||||
$is_zero_vat_amount = ($vat_amount == 0.0);
|
||||
$vat_category_code = $is_zero_vat_amount ? 'E' : 'S';
|
||||
|
||||
// Identifiant vendeur pour les frais de livraison : préfixe SHIPCQT_ + n° de ligne
|
||||
$seller_item_id = 'SHIPCQT_' . $line_number;
|
||||
// Identifiant vendeur pour les frais de livraison : préfixe configurable + n° de ligne
|
||||
$shipping_prefix = self::get_config_value('item_ids.shipping_prefix', 'SHIPCQT_');
|
||||
$seller_item_id = $shipping_prefix . $line_number;
|
||||
|
||||
$line = [
|
||||
'line_number' => $line_number,
|
||||
@ -749,7 +812,7 @@ class PEPPOL_peppol_controller {
|
||||
'item_description' => '',
|
||||
'seller_item_id' => $seller_item_id,
|
||||
'quantity' => $quantity,
|
||||
'unit_of_measure' => 'C62',
|
||||
'unit_of_measure' => self::get_config_value('units.default_unit_of_measure', 'C62'),
|
||||
'unit_price' => round($unit_price, 2),
|
||||
'vat_rate' => $vat_rate,
|
||||
'vat_category_code' => $vat_category_code,
|
||||
@ -826,8 +889,9 @@ class PEPPOL_peppol_controller {
|
||||
$is_zero_vat_amount = ($vat_amount == 0.0);
|
||||
$vat_category_code = $is_zero_vat_amount ? 'E' : 'S';
|
||||
|
||||
// Identifiant vendeur pour les frais supplémentaires : préfixe FEE_ + n° de ligne
|
||||
$seller_item_id = 'FEE_' . $line_number;
|
||||
// Identifiant vendeur pour les frais supplémentaires : préfixe configurable + n° de ligne
|
||||
$fee_prefix = self::get_config_value('item_ids.fee_prefix', 'FEE_');
|
||||
$seller_item_id = $fee_prefix . $line_number;
|
||||
|
||||
$line = [
|
||||
'line_number' => $line_number,
|
||||
@ -835,7 +899,7 @@ class PEPPOL_peppol_controller {
|
||||
'item_description' => '',
|
||||
'seller_item_id' => $seller_item_id,
|
||||
'quantity' => $quantity,
|
||||
'unit_of_measure' => 'C62',
|
||||
'unit_of_measure' => self::get_config_value('units.default_unit_of_measure', 'C62'),
|
||||
'unit_price' => round($unit_price, 2),
|
||||
'vat_rate' => $vat_rate,
|
||||
'vat_category_code' => $vat_category_code,
|
||||
@ -915,8 +979,8 @@ class PEPPOL_peppol_controller {
|
||||
'total_amount_excluding_vat' => round($total_excl_vat, 2),
|
||||
'total_vat_amount' => round($total_vat, 2),
|
||||
'total_amount_including_vat' => round($total_incl_vat, 2),
|
||||
'total_paid_amount' => 0.0,
|
||||
'total_payable_amount' => round($order->get_total(), 2),
|
||||
'total_paid_amount' => round($order->get_total(), 2),
|
||||
'total_payable_amount' => 0,
|
||||
'amount_due' => round($order->get_total(), 2),
|
||||
];
|
||||
|
||||
|
||||
@ -142,7 +142,7 @@ if ($logo_email_id) {
|
||||
printf(
|
||||
wp_kses_post(
|
||||
/* translators: %s: URL de la documentation */
|
||||
__('Configurez cette URL dans votre profil d\'entreprise via l\'interface d\'administration Filament de l\'API ESI Peppol. Les webhooks permettent de recevoir des notifications automatiques lorsque le statut d\'un document change. <a href="%s" target="_blank" rel="noopener noreferrer">En savoir plus</a>.', 'esi_peppol')
|
||||
__('Configurez cette URL dans votre profil d\'entreprise sur la plateforme https://peppol.esi-web.be/. Les webhooks permettent de recevoir des notifications automatiques lorsque le statut d\'un document change. <a href="%s" target="_blank" rel="noopener noreferrer">En savoir plus</a>.', 'esi_peppol')
|
||||
),
|
||||
esc_url('https://demo.esi-peppol.be/api-demo.html#webhooks')
|
||||
);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user