Je suis tombé sur différentes façons de créer un envoi par programmation. Elles sont
//Type 1
$converter=Mage::getModel('sales/convert_order');
$shipment=$converter->toShipment($order);
// snip
//Type 2
$shipment = Mage::getModel('sales/service_order', $order)
->prepareShipment($this->_getItemQtys($order));
// snip
//Type 3
$shipment = Mage::getModel('sales/service_order', $order)->prepareShipment($itemQty);
$shipment = new Mage_Sales_Model_Order_Shipment_Api();
$shipmentId = $shipment->create($orderId);
// snip
Quelle est la différence entre ces méthodes? Parmi les trois méthodes, il convient de créer des envois et d’ajouter des numéros de suivi.
magento-1.7
orders
shipment
blakcaps
la source
la source
Réponses:
Je vais tenter le coup. Prenons-les un à la fois:
Méthode 1
$converter
ci-dessus est chargé à partir de la classeMage_Sales_Model_Convert_Order
, qui utilise un assistant principal appelécopyFieldset
pour copier les détails de la commande dans un objet d'expédition. $ order doit être de type array ouVarien_Object
.Cette méthode est en réalité au cœur de la méthode 3, comme elle l’utilise
Mage::getModel('sales/convert_order')
dans son appel de constructeur.Différenciateur clé de cette méthode - il peut prendre un tableau ou un objet
$order
et générer un$shipment
objet de base . Il s'agit d'une méthode de niveau inférieur utilisée exclusivement par les méthodes que vous avez décrites dans Méthode 2, Méthode 3.Méthode 2
Cela semble être le moyen le plus populaire dans le noyau de Magento de générer un envoi tel qu'il est utilisé à la fois dans les contrôleurs d'envoi et de facturation.
$order
est utilisé comme argument de constructeur pour l'instanciation deMage_Sales_Model_Service_Order
, en le définissant comme une propriété protégée sur l'objet.Vous appelez
prepareShipment
et passez une quantité. Comme cette méthode utilise la classe de convertisseur de la Méthode 1, vousn'avez pas besoin de spécifier plus de détails, tels que les éléments de commande, lesdétails de quantité d'envoi d'articles dans l'prepareShipment
argument, appelé ici avec$this->_getItemQtys
. Pour l'utiliser dans votre propre contexte, il vous suffit de transmettre la quantité d'éléments d'un tableau au format suivant:Différenciateur clé de cette méthode - il vous restitue un objet $ shipping, mais avec tous les éléments convertis. C'est plug-and-play.
Méthode 3
Je n'ai pas pu trouver la preuve de l'utilisation de cette méthode dans le Core. Cela ressemble à un bidouillage, pour être honnête. Voici la méthode:
L'étape 1 est identique à la méthode 2 ci-dessus. Aucune différence. Cependant, vous récupérez un
$shipment
objet, qui est remplacé par une insantiation directe deMage_Sales_Model_Order_Shipment_Api
. Ceci est non standard. La meilleure façon d'obtenir un envoi Api Object serait d'appelerMage::getModel('sales/order_shipment_api')
.Ensuite, il utilise cet nouvel objet API d'envoi, écrasé, pour créer un envoi à partir d'une
$orderId
variable qui n'a pas été définie dans votre code. Encore une fois, cela semble être une solution de contournement.En regardant
Mage_Sales_Model_Order_Shipment_Api::create()
, cela semble être un guichet unique pour générer un envoi, car les détails les plus élémentaires nécessaires pour créer l'envoi ne sont qu'une commandeincrement_id
.C'est un hack qui ne devrait pas être utilisé par aucun module ou extension. Cette API est censée être utilisée par les fonctionnalités exposées via les requêtes d'API XML RPC / SOAP et est intentionnellement de base pour éliminer les requêtes d'API à plusieurs étapes.
La méthode 3 finit par atteindre le plus concret, cependant, et via un appel à Mage_Sales_Model_Order, elle appelle
prepareShipment
, ce qui est une abstraction d’ordre supérieur pour la méthode habituelle 2 ci-dessus:Différenciateur clé ici - si vous avez besoin d'un envoi, que cela ne vous dérange pas et que vous n'ayez qu'un incrément_id - utilisez cette méthode. Également des informations utiles si vous préférez gérer cela via l'API SOAP.
J'espère que ça aide.
la source
L'essentiel ici est que les méthodes 1 et 2 ne fonctionnent pas ...
Je suis d'accord avec @philwinkle cependant, la méthode 3 est hacky. Les fonctions de l'API ne doivent pas vraiment être appelées dans un contexte non-API. Vous ne savez jamais ce que les futures versions pourront apporter à ce type de code.
Alors qu'est-ce que cela laisse? Eh bien, les méthodes 1 et 2 ne sont pas cassées exactement. C'est juste qu'ils ne font qu'une partie du travail. Voici à quoi ils devraient ressembler:
Remarque: par souci de brièveté, les extraits de code suivants ajouteront tous les articles éligibles à l'envoi. Si vous souhaitez simplement expédier une partie d'une commande, vous devrez modifier certaines parties du code. J'espère cependant vous en avoir donné suffisamment pour continuer.
Méthode 1
Si vous regardez le code dans
app/code/core/Mage/Sales/Model/Order/Shipment/Api.php
(tel qu'utilisé dans la méthode 3), vous verrez qu'en plus,$convertor->toShipment($order)
il appelle également$item = $convertor->itemToShipmentItem($orderItem)
,$item->setQty($qty)
et$shipment->addItem($item)
pour chaque poste de commande éligible. Eh oui, Magento est vraiment paresseux, il faut le cajoler à travers tous. Unique. Étape. Ensuite, vous devez parcourir quelques étapes supplémentaires pour enregistrer l’envoi dans la base de données.Donc, la méthode 1 devrait ressembler à ceci:
Méthode 2
Tout d’abord, vous avez un appel
$this->_getItemQtys()
qui ne fonctionnera évidemment que dans certaines classes (celles qui ont ou héritent d’une fonction _getItemQtys, natch). Cela doit donc changer et, comme pour la méthode 1, vous devez également préciser le processus.En regardant dans
app/code/core/Mage/Adminhtml/controllers/Sales/Order/ShipmentController.php
c'est une situation un peu mieux avec cette approche - il semble que les éléments sont convertis en même temps que l'expédition elle - même. Mais vous ne récupérez toujours qu'un objet transitoire que vous devez enregistrer vous-même dans la base de données, comme suit:Je vous recommande également d’ajouter un petit contrôle d’erreur, par exemple pour vous assurer que votre envoi contient bien les articles qui vous ont été présentés
register()
.Quel est le meilleur?
Je dirais que c'est une question d'opinion. Je n'ai fait aucun test de référence, mais je suis assez confiant que la différence de vitesse entre les deux méthodes serait négligeable. En ce qui concerne la taille et la lisibilité du code, il n'y a pas beaucoup entre eux.
J'aime bien la méthode 2 pour ne pas avoir à convertir explicitement tous les articles de la commande, mais vous devez quand même les parcourir pour en extraire les quantités. Pour une belle petite empreinte de code, la méthode 3 serait ma préférée! Mais en tant qu’ingénieur logiciel, je ne peux pas le recommander. Donc, je vais dodue pour la méthode 2.
la source
Les gars Aucun de ce qui précède n'a travaillé sur mon problème. Ce qui suit a fonctionné pour moi. Mettez-le ici au cas où cela pourrait vous aider.
la source