Jump to content

Le numéro du bon de livraison n'est pas généré.


Recommended Posts

Bonjour à tous.

 

Je suis face à un problème assez particulier après avoir mis à jour ma boutique de la version 1.5.2 (ouch) à la version 1.6.1.6.

En fait, mes commandes n'ont un bon de livraison disponible qu'après l'envoi (statut "En cours de livraison").

Avant, ce bon de livraison était disponible dès "Préparation en cours".

 

Je suis donc allé éditer les statuts des commandes afin que le bon de livraison se génère dès que le paiement est accepté.

Mais toujours rien avant que je mette "En cours de livraison".

Pire encore, il m'est impossible de modifier dans le Back Office les options du statut "Préparation en cours".

En réalité, quand j'envoie le formulaire, la mise à jour se fait en base de données, mais quand je clique à nouveau sur modifier, tout est comme avant.

J'ai pensé à un problème de cache du navigateur, mais non, j'ai eu beau vider le cache de prestashop et du navigateur, rien n'y fait. Ces données viennent pourtant bien de quelque part. Bref.

 

Mon plus gros problème est le suivant :

Quand je consulte la base de données, je vois bien que les commandes qui ne sont pas encore en cours de livraison n'ont pas de numéro de bon de livraison (table préfixe + "order_invoice", champ "delivery_number").

J'ai donc cherché à quel moment ce numéro était créé et envoyé en base de données.

Je suis rapidement tombé sur la fonction setDeliverySlip() de la classe Order.php.

Cette fonction me renseigne sur le fait qu'une facture DOIT pré-exister à mon bon de livraison.

C'est le cas de toutes mes commandes dès le paiement, le problème ne vient donc pas de là.

 

J'ai donc cherché où cette fonction était appelée, et je n'ai trouvé qu'une seule occurrence !

Dans la fonction changeIdOrderState de la classe OrderHistory.php.

Voici la partie concernée :

        if ($new_os->invoice && !$order->invoice_number) {
            $order->setInvoice($use_existing_payment);
        } elseif ($new_os->delivery && !$order->delivery_number) {
            $order->setDeliverySlip();
        }

Il me semble que ce n'est pas optimum.

De ce que je vois, si le nouveau statut implique la création d'une facture et que la commande n'en a pas encore, celle-ci est créée.

Sinon, on s'occupe du bon de livraison.

Pourquoi sinon ?

Pourquoi ne pas s'occuper du bon de livraison AUSSI ?

Il serait peut-être préférable de faire ceci :

        if ($new_os->invoice && !$order->invoice_number) {
            $order->setInvoice($use_existing_payment);
        }
        if ($new_os->delivery && !$order->delivery_number && $order->invoice_number) {
            $order->setDeliverySlip();
        }

Ainsi, la facture ET le bon de livraison peuvent être créés en même temps.

 

Quoi qu'il en soit, ça ne résout pas mon problème.

Malgré cette modification, malgré de nombreux changement de statut sur les commandes concernées, malgré avoir vérifié en base de données que mon statut demande bien la création d'un bon de livraison, rien n'y fait.

Tant que je n'ai pas passé la commande en cours de livraison, mon bon de livraison n'est pas créé et son numéro n'est pas renseigné en base de données.

Et à partir de là, je ne comprends plus.

Si tout est bon, pourquoi le résultat ne correspond pas ?

 

 

 

PS : Ah oui, dernière chose.

Si je demande au site de générer le pdf du bon de livraison, concrètement en allant sur la page suivante :

http://www.monsite.com/admin/index.php?controller=AdminPdf&token=trucbidule&submitAction=generateDeliverySlipPDF&id_order=XXXX 

Et que je remplace le id_order par celui de la commande dont je veux le bon de livraison, j'obtiens un bon de livraison de numéro LI000000 avec les bonnes informations à l'intérieur.

L'outil de génération des PDF n'est donc pas en cause.

Edited by Stabbquadd (see edit history)
Link to comment
Share on other sites

Bonsoir,

 

Intéressant en effet ta remarque sur la possibilité de générer en même temps le BL et la Facture, même si dans la progression logique la plus courante, la préparation génère le BL mais n'intervient qu'une fois la commande validée "pour de vrai" (Paiement accepté etc ... ) .

 

Effectivement j'ai eu des clients qui souhaitaient avoir un accès immédiat au BL ou avaient une foultitude de statuts...

 

Le BL LI000000 Me laisse penser que ta migration n'a pas mis à jour le n° du dernier BL (maj manuelle via /install/upgrade.... ? ou bidouille dans/avec  ps_configuration ?)

 

Quoiqu'il en soit et puisque tu sembles jongler facilement avec ta BDD, cela vaut la peine de jeter un oeil à (ps)_configuration et chercher la clef PS_DELIVERY_NUMBER .

Celle-ci est censée contenir l'id du prochain BL généré. En cas de chevauchement c'est généralement pas glop.

 

Tu peux la renseigner directement depuis le BO dans Commandes -> Bons de livraison

 

Tu peux obtenir la valeur à fixer en exécutant cette requete : "select max(delivery_number)+1 FROM ps_orders" (si ps est ton préfixe...)

 

Pour info il en est de même pour le numéro de facture, bien que pour les factures le code de presta semble déja aller chercher le max id par défaut.

 

En revanche aucune idée de la raison qui fait que tu ne peux éditer et modifier un statut/état particulier. Ca ressemble à une maj manuelle (pas via autoupgrade) mais pas finalisée, car tout ne se fait pas dans ce cas. Ou plutôt même un import table par table d'une version convertie dans une install propre et neuve, non ?

 

 

Dis nous déja ce que donne la manip sur PS_DELIVERY_NUMBER  toujours...

Link to comment
Share on other sites

Bonjour Broceliande, comment va ma Bretagne ?

 

Très bien vu pour le PS_DELIVERY_NUMBER, sa valeur est NULL.

Tout comme le champ id_shop pour l'intégralité des enregistrements de la table ps_configuration sauf un, PS_SHOP_ENABLE.

Néanmoins, je tiens à préciser que j'ai utiliser le 1-click upgrade, et que je n'ai plus rien touché d'autre après que la correction des quelques erreurs de thème.

 

De manière à moitié amusante, le bon de livraison trouve son numéro une fois la commande passée en cours de livraison.

Car en effet, en passant la commande à "En cours de livraison", les numéros de BL se suivent bien sagement comme il faut, même avec ceux générés avant la MAJ.

Pourquoi ne pas passer toujours par cette méthode ?

Bref, j'ai renseigné dans le BO le numéro du prochain BL en prenant le max (delivery_number) +1 de la table ps_orders.

J'ai vérifié et il s'est bien inscrit en BDD.

J'ai donc passé une commande de test...

Et le bon de livraison ne s'est pas généré avant l'étape "En cours de livraison"...

Et la valeur de la clé PS_DELIVERY_NUMBER est repassé à NULL.

Mince, j'y avais cru pourtant !

 

Mais en fait, voici ce que j'ai trouvé dans la classe Order.php à la ligne 1384, au sein de la fonction setDeliveryNumber() :

        $number = Configuration::get('PS_DELIVERY_NUMBER', null, null, $id_shop);
        // If delivery slip start number has been set, you clean the value of this configuration
        if ($number) {
            Configuration::updateValue('PS_DELIVERY_NUMBER', false, false, null, $id_shop);
        }

J'insiste sur le "If delivery slip start number has been set, you clean the value of this configuration".

Je sais bien que ça pourrait vouloir dire qu'on la nettoie pour la mettre à jour, seulement on passe à la fonction de configuration la nouvelle valeur "false".

Il semble donc intentionnel que cette clé n'ait plus de valeur.

Visiblement, cette clé de configuration n'est plus utilisée.

 

Le reste de la fonction est cohérent, puisqu'en l'absence de clé de configuration pour le DELIVERY_NUMBER, il utilise la requête suivante :

(SELECT new_number FROM (SELECT (MAX(`delivery_number`) + 1) AS new_number FROM `'._DB_PREFIX_.'order_invoice`) AS result)

Mais pourquoi cette fonction n'est-elle pas utilisée plus tôt dans mes commandes ?

En fait elle n'est appelée qu'une seule fois, par la fonction... setDelivery() !

De l'intérêt de créer une fonction qui ne sert à être appelée que par une autre fonction... Bref.

Cette fonction, setDelivery(), n'est elle aussi appelée que par une seule autre fonction, changeIdOrderState(), mais de la classe OrderHistory.php cette fois-ci.

Au sein d'une petite ligne toute timide :

        // updates delivery date even if it was already set by another state change
        if ($new_os->delivery) {
            $order->setDelivery();
        }

Et malheureusement, je retombe sur le même problème.

$new_os->delivery correspond à la valeur de delivery dans la table ps_order_state à  l'enregistrement id_order_state correspondant.

Or, delivery est à 1 pour les id_order_state 2, 3, 4, 5 et 12, ce qui correspond à "Paiement accepté", "Préparation en cours", "En cours de livraison", "Livré", et "Paiement à distance accepté".

Une fois de plus, tout va bien, mais ça ne fonctionne pas :(

Retour à la case départ...

 

 

Parenthèse concernant la ligne chronologique des commandes.

Je ne comprends pas l'intérêt de faire traîner la création du bon de livraison.
Après tout la facture est générée immédiatement, et contrairement à elle, le bon de livraison n'engage à rien !

Il ne prouve pas que la commande a été payée ou quoi.

Il dit juste que, dans cette commande, il y a ces éléments.

Que la commande ait été payée ou pas, peu importe.

AMHA, un bon de livraison, c'est comme un panier, mais qui a été validé, c'est tout.

Link to comment
Share on other sites

En fouillant un peu plus, j'ai trouvé quelque chose qui m'intrigue.

 

Tout d'abord j'ai compris pourquoi il ne s'agissait pas d'une erreur lorsque j'ai cité la fonction changeIdOrderState de la classe OrderHistory.php.

        if ($new_os->invoice && !$order->invoice_number) {
            $order->setInvoice($use_existing_payment);
        } elseif ($new_os->delivery && !$order->delivery_number) {
            $order->setDeliverySlip();
        }

En fait la fonction setDeliverySlip() ne sert à créer un BL que si une facture n'a pas encore été faite avant.

C'est la raison pour laquelle il y a le elseif, donc à ne pas changer.

 

Plus loin dans la classe, j'ai trouvé le morceau qui créé le BL après la facture :

        // updates delivery date even if it was already set by another state change
        if ($new_os->delivery) {
            $order->setDelivery();
        }

La fonction setDelivery() est bien là pour créer le BL lorsque l'état de la commande le demande, après la facture.

Mais je pense que le problème vient de cette fonction, voici l'extrait en question :

       // Get all invoice
        $order_invoice_collection = $this->getInvoicesCollection();
        foreach ($order_invoice_collection as $order_invoice) {
            /** @var OrderInvoice $order_invoice */
            if ($order_invoice->delivery_number) {
                continue;
            }

            // Set delivery number on invoice
            $order_invoice->delivery_number = 0;
            $order_invoice->delivery_date = date('Y-m-d H:i:s');
            // Update Order Invoice
            $order_invoice->update();
            $this->setDeliveryNumber($order_invoice->id, $this->id_shop);
            $this->delivery_number = $this->getDeliveryNumber($order_invoice->id);
        }

On voit que la boucle foreach parcourt les factures de la commande et fait appel à la fonction setDeliveryNumber(), qui est bien celle qui créé le numéro de BL.

Seulement voilà, cette partie de la boucle n'est effective que si la commande possède déjà un numéro de BL !

if ($order_invoice->delivery_number) { continue; }

Si la commande n'a pas encore de numéro de BL, alors la boucle passe à la commande suivante.

Et donc ne créé jamais le numéro de BL.

 

Cependant je ne comprends pas encore pourquoi lorsque je passe la commande à "En cours de livraison", le numéro de BL est créé.

Edited by Stabbquadd (see edit history)
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...