Bonjour,
J'ai bien étudié votre cas d'utilisation et voici, je pense la meilleure approche pour votre marketplace.
L'événement onBeforeInvoiceNumberGenerate ne peut effectivement que modifier le numéro de facture, mais pas empêcher la génération de l'order_invoice_id. C'est pourquoi vous constatez que l'ID est consommé.
La solution recommandée est d'utiliser l'événement onBeforeOrderUpdate pour empêcher complètement la génération de l'invoice_id dans le cas 2 (100% warehouse ≠ 1).
Voici comment procéder :
Dans votre plugin, implémentez la fonction onBeforeOrderUpdate :
function onBeforeOrderUpdate(&$order, &$do) {
// Vérifiez d'abord si on est sur un changement de statut vers un statut de facturation
$config = hikashop_config();
$valid_statuses = explode(',', $config->get('invoice_order_statuses','confirmed,shipped'));
// Si le nouveau statut n'est pas un statut de facturation, on ne fait rien
if(empty($order->order_status) || !in_array($order->order_status, $valid_statuses))
return;
// Vérifiez si on a déjà un invoice_id (rien à faire dans ce cas)
if(!empty($order->order_invoice_id) || !empty($order->old->order_invoice_id))
return;
// Chargez les produits de la commande si nécessaire
$orderClass = hikashop_get('class.order');
$fullOrder = $orderClass->loadFullOrder($order->order_id, false, false);
// Vérifiez si tous les produits sont warehouse ≠ 1
$all_external = true;
if(!empty($fullOrder->products)) {
foreach($fullOrder->products as $product) {
// Récupérez le warehouse du produit (adaptez selon votre logique)
if($product->product_warehouse_id == 1) {
$all_external = false;
break;
}
}
}
// Si 100% externe (warehouse ≠ 1), empêchez la facturation HikaShop
if($all_external) {
// Définir ces valeurs empêche la génération automatique de l'invoice
$order->order_invoice_id = -1; // Valeur spéciale pour marquer "pas de facture"
$order->order_invoice_number = ''; // Ou une valeur vide
$order->order_invoice_created = 0;
}
}Après la sauvegarde de la commande, vous pouvez utiliser onAfterOrderUpdate pour remettre order_invoice_id à 0 si vous avez utilisé -1 :
function onAfterOrderUpdate(&$order, &$send_email) {
if(isset($order->order_invoice_id) && $order->order_invoice_id == -1) {
// Réinitialisez dans la base de données
$db = JFactory::getDBO();
$db->setQuery('UPDATE '.hikashop_table('order').' SET order_invoice_id = 0, order_invoice_number = "", order_invoice_created = 0 WHERE order_id = '.(int)$order->order_id);
$db->execute();
// Mettez à jour l'objet ordre aussi
$order->order_invoice_id = 0;
$order->order_invoice_number = '';
$order->order_invoice_created = 0;
}
}Pourquoi cette approche ?
1. Elle empêche la consommation d'un numéro de facture pour les commandes 100% externes
2. Elle conserve la numérotation continue pour les factures marketplace
3. Elle n'a pas d'effets de bord car order_invoice_id = 0 est le comportement attendu pour une commande sans facture
Alternative plus simple :
Si vous préférez, vous pouvez simplement définir order_invoice_number (via onBeforeInvoiceNumberGenerate) à une valeur spéciale comme "EXTERNE" pour les commandes 100% warehouse ≠ 1, et les exclure de votre comptabilité marketplace. L'invoice_id sera consommé mais au moins vous aurez une trace claire.