web-dev-qa-db-fra.com

Magento - Attribut de devis / commande d'article de produit basé sur l'entrée de l'utilisateur

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

  • Tout comme avec Options personnalisées , un élément de formulaire doit être ajouté à la page du produit frontal.
    • Contrairement à Options personnalisées, il ne s'agit pas d'un attribut de produit réel . Il ne doit pas être affiché sur les pages de produits d'administration ou les jeux d'attributs.
    • Le client est tenu de fournir une valeur valide. J'ai besoin de pouvoir faire une validation côté serveur.
    • Je veux avoir un modèle .phtml générant son html. Actuellement, je suis capable de remplacer app/design/frontend/base/default/catalog/product/view/type/default.phtml avec satisfaisant (design ) résultats. Cependant, je ne sais pas comment capturer, valider et éventuellement enregistrer sa valeur.
  • La valeur de cet élément de formulaire doit être enregistrée avec l'élément de produit de devis/commande.
    • Cette valeur doit être affichée sur toutes les factures, commandes, e-mails de vente.
    • Je veux contrôler la sortie avec un modèle, ou au moins être en mesure de renvoyer la chaîne utilisée pour afficher la valeur

Mes questions

  1. Comment valider et éventuellement enregistrer la valeur à partir d'un <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?
  2. Comment afficher cette valeur sur la commande, la facture, les e-mails de vente et ces pages?
  3. Comment filtrer une collection de commandes pour récupérer les commandes dont les articles ont ma valeur définie sur une valeur spécifique?

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.

63
Vitamin

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.

Ajouter des options pour citer un article

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.

Ajouter des options pour commander l'article

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.

Ajouter un support pour les réordonnances

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)
            ));
        }
    }
}

Traduction:

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).

140
Vinai

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:

  1. Utilisez un script de configuration pour ajouter des champs à la base de données plutôt que de le faire directement.
  2. Utilisez l'objet Request de Magento plutôt que d'accéder directement à $ _REQUEST.
  3. Utilisez des extensions et des réécritures plutôt que de modifier le cœur de Magento.
  4. Apportez les modifications à config.xml à partir d'une extension plutôt que de modifier le noyau.

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.

11
Jim OHalloran

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')
1
wutzebaer