Копирование динамических пользовательских опций для цитирования товара, заказа товара

13

У меня есть наблюдатель, который добавляет динамические настраиваемые параметры на страницу сведений о продукте, которая вызывается для catalog_controller_product_viewсобытия. Это позволяет клиенту выбрать из выпадающего списка существующих кодов лицензии.

public function addLicenseOptions(Varien_Event_Observer $observer) {
    $product = $observer->getEvent()->getProduct();
    if ($product->isSubscriptionProduct()) {
        $optionModel = Mage::getModel('catalog/product_option')
            ->setTitle('License Code')
            ->setProductId($product->getId())
            ->setStoreId($product->getStoreId())
            ->setId('license_code')
            ->setType('drop_down')
            ->setPrice(null)
            ->setPriceType(null)
            ->setIsRequire(true);

        $customer = Mage::getSingleton('customer/session')->getCustomer();
        if ($customer->getId()) {
            $linksPurchased = Mage::getResourceModel('downloadable/link_purchased_collection')
                        ->addFieldToFilter('customer_id', $customer->getId());

            if ($linksPurchased->count() > 0) {
                foreach ($linksPurchased as $linkPurchased) {
                    $valueModel = Mage::getModel('catalog/product_option_value')
                        ->setTitle($linkPurchased->getData('key_code'))
                        ->setProduct($product)
                        ->setOption($optionModel)
                        ->setId($linkPurchased->getData('license_code'))
                        ->setPrice(null)
                        ->setPriceType('fixed')
                        ->setSku(null);
                    $optionModel->addValue($valueModel);
                }
                $product->setHasOptions(1);
                $product->addOption($optionModel);
            }
        }
    }
}

Но когда я размещаю заказ, выбранные параметры сохраняются только в info_buyRequest. Есть ли способ заставить его сохранить, как если бы это была опция продукта, созданная в админке?

Лаура
источник

Ответы:

6

Я сделал нечто подобное, но не совсем. Может быть, это поможет.
моей задачей было установить флажок на каждой странице продукта gift wrap. Если этот флажок установлен, отдел продаж будет знать, как обернуть продукт (у них был только один вариант обертывания).
Поэтому я сделал это для того, чтобы иметь возможность портировать wrapзначение флажка от продукта к котировке на заказ. (Я мог бы использовать пользовательскую опцию, но уродливо добавлять одну опцию к нескольким тысячам товаров).

У меня был наблюдатель на событие sales_convert_quote_item_to_order_item.

public function checkGiftWrap($observer)
{
    $orderItem = $observer->getEvent()->getOrderItem();
    $item = $observer->getEvent()->getItem();
    $wrap = $item->getOptionByCode('wrap');
    if ($wrap){
        $options = $orderItem->getProductOptions();
        $options['wrap'] = unserialize($wrap->getValue());
        $orderItem->setProductOptions($options);
    }
    return $this;
}

Я переписал Mage_Catalog_Helper_Product_Configuration::getCustomOptionsпомощника, чтобы сказать Magento, что мой вариант важен и должен рассматривать его отдельно

<?php
class [Namespace]_[Module]_Helper_Product_Configuration extends Mage_Catalog_Helper_Product_Configuration
{
    public function getCustomOptions(Mage_Catalog_Model_Product_Configuration_Item_Interface $item){
        $options = parent::getCustomOptions($item);
        $wrap = $item->getOptionByCode('wrap');
        if ($wrap){
            $options = array_merge($options, array(unserialize($wrap->getValue())));
        }
        return $options;
    }
}

По той же причине я переписал, Mage_Sales_Block_Order_Item_Renderer_Default::getItemOptionsпоэтому мой вариант будет отображаться в корзине

<?php
class [Namespace]_[Module]_Block_Sales_Order_Item_Renderer_Default extends Mage_Sales_Block_Order_Item_Renderer_Default
{
    public function getItemOptions(){
        $result = parent::getItemOptions();
        $options = $this->getOrderItem()->getProductOptions();
        if (isset($options['wrap'])){
            $result = array_merge($result, array($options['wrap']));
        }
        return $result;
    }
}

и столбец имени администратора для сетки элементов заказа:

<?php
class [Namespace]_[Module]_Block_Adminhtml_Sales_Items_Column_Name extends Mage_Adminhtml_Block_Sales_Items_Column_Name
{
    public function getOrderOptions(){
        $result = parent::getOrderOptions();
        if ($options = $this->getItem()->getProductOptions()) {
            if (isset($options['wrap'])) {
                $result = array_merge($result, array($options['wrap']));
            }
        }
        return $result;
    }
}

[РЕДАКТИРОВАТЬ]
Это швы, я что-то пропустил. Я реализовал возможность добавить подарочную упаковку только после того, как товар окажется в корзине.
Но я думаю, что вы можете использовать тот же код в событии до или после добавления товара в корзину.

$data = array();
$data['label'] = Mage::helper('helper_alias')->__('Giftwrapping');
$data['value'] = Mage::helper('helper_alias')->__('Yes');
$product->addCustomOption('wrap', serialize($data));
$item->addOption($product->getCustomOption('wrap'));
$item->save(); //this line should be called only if it's not called by default after your event is dispatched.

Вот и все. Я надеюсь, что вы можете извлечь из этого что-то полезное.

Мариус
источник
Где у меня проблемы, это получить возможность. Когда я вызываю $ item-> getOptionByCode ('license_code'), я получаю ноль. Мои параметры даже не отображаются, когда я вызываю следующее: $ helper = Mage :: helper ('catalog / product_configuration'); $ options = $ helper-> getCustomOptions ($ quoteItem); Как вы настраиваете «обтекание»?
Лора
@Laura. Я проверю, пропустил ли я что-то и вернусь к вам.
Мариус
@Laura. Я дважды проверил, и это швы, я что-то пропустил. Для меня опция добавления подарочной упаковки показана только в корзине. Я забыл, что изменил это, потому что клиент запросил это. Я обновил ответ кодом, который использовал в настраиваемом действии. Может быть, вы можете добавить его в корзину событий наблюдателя.
Мариус
В конце концов я разобрался с запросом на покупку. Проблема в том, что параметры, которые я устанавливаю в своем исходном блоке кода, вообще не переносились в элемент котировки вне запроса на покупку.
Лора
@Marus Я хочу добавить товар в корзину с возможностью генерации на лету, без добавления опции продукта в админке, как это возможно
Pushpendra Singh
4

Привязывая к ответу Мариуса, вот что я придумал:

У меня есть собственный контроллер, который обрабатывает конфигурацию пользовательского типа продукта. Этот контроллер добавляет additional_optionsво время добавления в корзину.

// My_Module_CartController::addToCartAction
// Get your product model
$product = $this->getProduct();

// Create options
$options = array();
$options['my_option'] = array(
    'label' => 'My Label',
    'value' => 'my_value'
);

$cartRequest = array(
    'product' => $product->getId(),
    'qty' => '1'
);

$cart = Mage::getModel('checkout/cart');
$cart->init();

// Add options
$product->addCustomOption('additional_options', serialize($options));

// Add to cart
$cart->addProduct($product, $cartRequest);
$cart->save();

В наблюдателе за событием sales_convert_quote_item_to_order_itemя затем хватаю additional_optionsи устанавливаю в качестве параметров позиции заказа:

// My_Module_Model_Order_Observer::convertQuoteToOrder(Varien_Event_Observer $o)
// Get quote and order items
$orderItem = $o->getEvent()->getOrderItem();
$quoteItem = $o->getEvent()->getItem();

// Get serialized options set on product earlier
$myOptions = $item->getProduct()->getCustomOption('additional_options')->getValue();

// Add these options into the order item's options
$options = $orderItem->getProductOptions();
$options['additional_options'] = unserialize($myOptions);
$orderItem->setProductOptions($options);

return $this;

При использовании additional_optionsвам не нужно беспокоиться о различных блоках / шаблонах, отображающих параметры (хотя вы можете предпочесть измененный формат), так как эти блоки будут вызывать $options['additional_options']См. Здесь

pspahn
источник