Résumé
Je souhaite créer un attribut de produit qui n'est pas enregistré dans les produits ou affiché sur la page de modification du produit comme des attributs de produit ordinaires. Au lieu de cela, je veux qu'il soit enregistré dans les articles de commande/devis et affiché sur les commandes, les factures, etc. Il doit également être configurable par le client dans le frontend avant d'ajouter un produit au panier.
Détails
Mes questions
<input>
sur la page du produit frontal à l'article de devis lorsque le produit est ajouté au panier, et plus tard dans le processus de commande à l'article de commande?mise à jour 1
J'ai découvert que je peux exécuter ce code sur un catalog/product
modèle (et probablement sales/quote_item
également) lors d'événements tels que sales_quote_item_qty_set_after
$infoBuyRequest = $product->getCustomOption('info_buyRequest');
$buyRequest = new Varien_Object(unserialize($infoBuyRequest->getValue()));
$myData = $buyRequest->getMyData();
De cette façon, j'ai pu récupérer mes données personnalisées, fournies par le client, à partir de mon <input>
sur la page du produit.
Je soupçonne cela info_buyRequest
est enregistré avec les éléments de devis et de commande. Si c'est le cas, cela partiellement a résolu mes problèmes 1 et 2. Cependant, je ne sais toujours pas où il convient d'exécuter ce code, et je ne sais pas comment l'afficher sur les pages backend order/quote/report. Je crois également que cela est stocké en tant que valeur sérialisée dans la base de données, il sera plus difficile d'obtenir des collections d'articles de devis/commande en fonction de mes données personnalisées.
Magento offre la possibilité d'ajouter des options qui ne sont pas des attributs de produit ou des options personnalisées de produit. Ils sont définis sur le produit et citent les articles avec le code d'option additional_options
.
Il y a deux étapes à suivre, chacune pouvant être gérée via un observateur d'événement. Si vous souhaitez que les options supplémentaires soient réorganisées, vous devrez également observer un troisième événement.
La première étape consiste à ajouter l'observateur d'événements pour définir les options supplémentaires sur le produit chargé avant son ajout au panier. Une option consiste à utiliser l'événement catalog_product_load_after
.
<catalog_product_load_after>
<observers>
<extra_options>
<type>model</type>
<class>extra_options/observer</class>
<method>catalogProductLoadAfter</method>
</extra_options>
</observers>
</catalog_product_load_after>
Dans le cas où l'observateur peut ajouter des vérifications supplémentaires, la page demandée est en effet une action d'ajout au panier. Le point principal de cette méthode d'observation est d'ajouter la sélection de vos options spéciales à l'option additional_options
Sur le modèle de produit.
public function catalogProductLoadAfter(Varien_Event_Observer $observer)
{
// set the additional options on the product
$action = Mage::app()->getFrontController()->getAction();
if ($action->getFullActionName() == 'checkout_cart_add')
{
// assuming you are posting your custom form values in an array called extra_options...
if ($options = $action->getRequest()->getParam('extra_options'))
{
$product = $observer->getProduct();
// add to the additional options array
$additionalOptions = array();
if ($additionalOption = $product->getCustomOption('additional_options'))
{
$additionalOptions = (array) unserialize($additionalOption->getValue());
}
foreach ($options as $key => $value)
{
$additionalOptions[] = array(
'label' => $key,
'value' => $value,
);
}
// add the additional options array with the option code additional_options
$observer->getProduct()
->addCustomOption('additional_options', serialize($additionalOptions));
}
}
}
Les options supplémentaires seront automatiquement déplacées du produit vers l'élément de devis. Avec cet observateur en place, vos options apparaîtront dans le panier et la revue de paiement.
Pour les faire persister, un observateur supplémentaire est nécessaire (uniquement depuis Magento 1.5).
<sales_convert_quote_item_to_order_item>
<observers>
<extra_options>
<type>model</type>
<class>extra_options/observer</class>
<method>salesConvertQuoteItemToOrderItem</method>
</extra_options>
</observers>
</sales_convert_quote_item_to_order_item>
Ici, nous déplaçons l'option de l'article de devis à l'article de commande.
public function salesConvertQuoteItemToOrderItem(Varien_Event_Observer $observer)
{
$quoteItem = $observer->getItem();
if ($additionalOptions = $quoteItem->getOptionByCode('additional_options')) {
$orderItem = $observer->getOrderItem();
$options = $orderItem->getProductOptions();
$options['additional_options'] = unserialize($additionalOptions->getValue());
$orderItem->setProductOptions($options);
}
}
À partir de ce moment, les options supplémentaires seront visibles dans l'historique des commandes client dans le frontend et les e-mails de commande, ainsi que dans la vue de commande de l'interface d'administration, les factures, les envois, les creditmemos et les PDF.
Afin de reporter les oprions sur la nouvelle commande lors d'une nouvelle commande, vous devez prendre soin de les copier. Voici une possibilité en utilisant l'événement checkout_cart_product_add_after
.
<checkout_cart_product_add_after>
<observers>
<extra_options>
<type>singleton</type>
<class>extra_options/observer</class>
<method>checkoutCartProductAddAfter</method>
</extra_options>
</observers>
</checkout_cart_product_add_after>
L'analyse des options supplémentaires et la création du tableau d'options supplémentaires doivent être déplacées dans une fonction distincte pour éviter la duplication de code, mais pour cet exemple, je vais laisser la logique requise pour chaque méthode en place pour plus de clarté.
public function checkoutCartProductAddAfter(Varien_Event_Observer $observer)
{
$action = Mage::app()->getFrontController()->getAction();
if ($action->getFullActionName() == 'sales_order_reorder')
{
$item = $observer->getQuoteItem();
$buyInfo = $item->getBuyRequest();
if ($options = $buyInfo->getExtraOptions())
{
$additionalOptions = array();
if ($additionalOption = $item->getOptionByCode('additional_options'))
{
$additionalOptions = (array) unserialize($additionalOption->getValue());
}
foreach ($options as $key => $value)
{
$additionalOptions[] = array(
'label' => $key,
'value' => $value,
);
}
$item->addOption(array(
'code' => 'additional_options',
'value' => serialize($additionalOptions)
));
}
}
}
Aucun mécanisme n'est en place pour traduire ces étiquettes ou valeurs d'option. Voici quelques idées qui pourraient être utiles à cet égard.
Dans un observateur d'événement quote_item_load_after, récupérez le tableau d'options supplémentaires et définissez $option['print_value'] = $helper->__($option['value']);
. Si print_value
Est défini, Magento l'utilisera pour le rendu de l'affichage.
La même chose peut être faite avec les articles commandés.
Il n'existe pas de print_label
, Mais vous pouvez définir un index personnalisé (label_source
Peut-être) et définir l'étiquette à la volée en utilisant cela comme source, par exemple $option['label'] = $helper->__($option['label_source']);
.
Au-delà de cela, vous devrez probablement recourir à la modification des modèles (grep pour getItemOptions()
), ou remplacer les classes de blocs (grep additional_options
).
Il est possible d'ajouter des champs personnalisés à l'élément Devis. Comment ajouter des champs personnalisés pour les éléments de ligne de commande dans Magento pour commencer. J'ai utilisé ces instructions récemment pour ajouter des champs personnalisés à un élément de devis Magento et le concept est bien, mais il y a quelques pratiques dans cet article qui ne sont pas géniales. Choses que je ferais différemment:
En général, il est préférable d'éviter de modifier le noyau Magento et d'appliquer vos personnalisations via un module car cela rend les mises à niveau plus faciles/possibles à l'avenir. Si vous n'avez pas créé votre propre extension avant moduleCreator peut vous aider à générer le passe-partout nécessaire.
Ma solution dans Magento 1.8
Définir l'option pour citer l'article
$quoteItem = $cart->getQuote()->getItemById($itemId);
$quoteItem->addOption(array('label' => 'buymode', 'code' => 'buymode', 'value' => $data['buymode']));
$quoteItem->save();
Option d'accès depuis QuoteItem
$quoteItem->getOptionByCode('buymode')->getValue();
Option de transfert vers OrderItem
S'inscrire à l'événement sales_convert_quote_item_to_order_item
public function onConvertQuoteItemToOrderItem($observer) {
$orderItem = $observer->getOrderItem();
$quoteItem = $observer->getItem();
$options = $orderItem->getProductOptions();
$options['buymode'] = $quoteItem->getOptionByCode('buymode')->getValue();
$orderItem->setProductOptions($options);
}
Option d'accès depuis OrderItem
$orderItem->getProductOptionByCode('buymode')