Copiando opções personalizadas dinâmicas para cotar item, item de pedido

13

Eu tenho um observador que está adicionando opções personalizadas dinâmicas à página de detalhes do produto, chamada no catalog_controller_product_viewevento. Isso permite que o cliente selecione uma lista suspensa de seus códigos de licença existentes.

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

Mas, quando faço o pedido, as opções selecionadas são salvas apenas no info_buyRequest. Existe uma maneira de salvá-lo como se fosse uma opção de produto criada no administrador?

Laura
fonte

Respostas:

6

Eu fiz algo semelhante, mas não exatamente. Talvez ajude.
minha tarefa era ter uma caixa de seleção em cada página do produto chamada gift wrap. Se marcada, a equipe de vendas saberia encapsular o produto (eles tinham apenas uma única opção de encapsulamento).
Então eu fiz isso para poder portar o wrapvalor da caixa de seleção de produto para cotação para pedido. (Eu poderia ter usado uma opção personalizada, mas é feio adicionar uma opção a alguns milhares de produtos).

Eu tinha um observador para o evento 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;
}

Reescrevi o Mage_Catalog_Helper_Product_Configuration::getCustomOptionsajudante para dizer ao Magento que minha opção é importante e deve tratá-la separadamente

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

Pela mesma razão que eu reescrevi Mage_Sales_Block_Order_Item_Renderer_Default::getItemOptions, minha opção será exibida no carrinho

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

e a coluna do nome do administrador da grade de itens do pedido:

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

[EDIT]
Parece que perdi alguma coisa. Eu só implementei a opção de adicionar um embrulho para presente quando o produto estiver no carrinho.
Mas acho que você pode usar o mesmo código em um evento antes ou depois de adicionar o item ao carrinho.

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

É isso aí. Espero que você possa obter algo útil com isso.

Marius
fonte
Onde estou tendo problemas é conseguir a opção. Quando eu chamo $ item-> getOptionByCode ('license_code'), estou recebendo um nulo. Minhas opções nem aparecem quando eu chamo o seguinte: $ helper = Mage :: helper ('catalog / product_configuration'); $ opções = $ helper-> getCustomOptions ($ quoteItem); Como você está configurando a opção 'wrap'?
Laura
@Laura. Vou verificar se perdi alguma coisa e volto para você.
Marius
@Laura. Verifiquei duas vezes e perdi alguma coisa. Para mim, a opção de adicionar embrulho para presente é mostrada apenas no carrinho. Esqueci que mudei isso porque o cliente solicitou. Atualizei a resposta com o código que usei em uma ação personalizada. Talvez você possa adicioná-lo em um observador de eventos do carrinho.
Marius
Acabei analisando a solicitação de compra, afinal. O problema é que as opções definidas no meu bloco de código original não foram transferidas para o item de cotação, fora da solicitação de compra.
Laura
@Marius eu quero adicionar produto no carrinho com on the fly gerar opção sem add na opção de produto no lado de administração como possível
Pushpendra Singh
4

Amarrando a resposta de Marius, aqui está uma coisa que eu inventei:

Eu tenho um controlador personalizado que lida com a configuração de um tipo de produto personalizado. Este controlador é adicionado additional_optionsdurante a adição ao carrinho.

// 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();

Em um observador do evento sales_convert_quote_item_to_order_item, pego o additional_optionse defino como opções no item do pedido:

// 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;

Ao usar, additional_optionsvocê não precisa se preocupar com o fato de vários blocos / modelos renderizarem as opções (embora você possa preferir um formato alterado), pois esses blocos chamarão $options['additional_options']Veja Aqui

pspahn
fonte