2012-02-17 15 views
7

He fijado una opción personalizada para mi producto en Magento como desplegable es decirMagento cambio personalizada El valor de opción antes de añadir a la cesta

Tamaño: pequeño, mediano, grande

En la página del producto muestro información adicional para cada opción usando javascript.

Pequeño - Medida de la cintura 30, Chest 36, Longitud 42 ...
Medium - Medida de la cintura 32, Chest 38, Longitud 44 ...
Large - Medida de la cintura 34, Chest 40, Longitud 48 ...

Cuando agrego el producto al carrito, obtengo el título de Tamaño (Pequeño, Mediano o Grande) en el carro, pero también quiero mostrar esta información adicional (Cintura 30, Cofre 36, Longitud 42 ...) y obtenerlo guardado con el pedido.

¿Cuál es la mejor manera de hacerlo? Gracias por adelantado.

+0

¿Está ahorrando estos datos adicionales de alguna manera? Cuando comprueba la administración para el pedido, ¿aparece la cintura, el cofre, la longitud, etc.? – seanbreeden

+0

Lo siento, si no hubiera sido lo suficientemente claro. Solo muestro esta información si JavaScript está codificado en un archivo phtml. por ejemplo, si (val == small) luego muestra Waist 30, Chest 36, Length 42 ... Ahora quiero agregar esta información adicional al pedido para que se almacene para cada artículo. – Farrukh

Respuesta

0

Vaya a Admin -> Catalog -> Attributes -> Manage Attributes. Ubique su atributo de la lista. En su caso, es probablemente size. Haga clic en él y vaya al Manage Labels/Options. Desde allí puede agregar la información adicional a cada valor. Puede cambiar la etiqueta a "Cintura pequeña 30, Cofre 36, Longitud 42" y repetir para cada valor de atributo que desee cambiar.

+1

Sean, gracias por la respuesta, pero no es el atributo, es la opción personalizada. Desafortunadamente, no puedo seguir este método porque también hay un registro de otros problemas involucrados. Si puede guiarme para cambiar de forma problemática el valor de la opción personalizada, hará mi vida mucho más fácil. – Farrukh

28

Las opciones personalizadas solo se almacenan en el presupuesto como ID y valores de la opción. Cada vez que se representan las opciones, básicamente se vuelven a cargar desde la base de datos.
Si modifica los valores, deberá guardarlos y eso los establecerá para todos.

Dicho esto, soluciono el problema añadiendo una opción personalizada adicional con el valor modificado sobre la marcha, utilizando un observador de eventos. Para esto utilizo opciones adicionales.
Luego elimino la opción personalizada original del elemento de cita.

Hasta 1.4 Magento se encargó del resto, pero desde entonces debe copiar las opciones adicionales a la posición de pedido manualmente, y también debe tener cuidado de que se establezca nuevamente si se reordena un artículo.

Aquí hay una configuración de ejemplo de observador.

<frontend> 
    <events> 
     <checkout_cart_product_add_after> 
      <observers> 
       <customoptions> 
        <type>singleton</type> 
        <class>customoptions/observer</class> 
        <method>checkoutCartProductAddAfter</method> 
       </customoptions> 
      </observers> 
     </checkout_cart_product_add_after> 
     <sales_convert_quote_item_to_order_item> 
      <observers> 
       <customoptions> 
        <type>singleton</type> 
        <class>customoptions/observer</class> 
        <method>salesConvertQuoteItemToOrderItem</method> 
       </customoptions> 
      </observers> 
     </sales_convert_quote_item_to_order_item> 
    </events> 
</frontend> 

El resto se maneja en la clase observador.

/** 
* Add additional options to order item product options (this is missing in the core) 
* 
* @param Varien_Event_Observer $observer 
*/ 
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); 
    } 
} 

/** 
* Manipulate the custom product options 
* 
* @param Varien_Event_Observer $observer 
* @return void 
*/ 
public function checkoutCartProductAddAfter(Varien_Event_Observer $observer) 
{ 
    $item = $observer->getQuoteItem(); 
    $infoArr = array(); 

    if ($info = $item->getProduct()->getCustomOption('info_buyRequest')) { 
     $infoArr = unserialize($info->getValue()); 
    } 

    // Set additional options in case of a reorder 
    if ($infoArr && isset($infoArr['additional_options'])) { 
     // An additional options array is set on the buy request - this is a reorder 
     $item->addOption(array(
      'code' => 'additional_options', 
      'value' => serialize($infoArr['additional_options']) 
     )); 
     return; 
    } 

    $options = Mage::helper('catalog/product_configuration')->getCustomOptions($item); 

    foreach ($options as $option) 
    { 
     // The only way to identify a custom option without 
     // hardcoding ID's is the label :-(
     // But manipulating options this way is hackish anyway 
     if ('Size' === $option['label']) 
     { 
      $optId = $option['option_id']; 

      // Add replacement custom option with modified value 
      $additionalOptions = array(array(
       'code' => 'my_code', 
       'label' => $option['label'], 
       'value' => $option['value'] . ' YOUR EXTRA TEXT', 
       'print_value' => $option['print_value'] . ' YOUR EXTRA TEXT', 
      )); 
      $item->addOption(array(
       'code' => 'additional_options', 
       'value' => serialize($additionalOptions), 
      )); 

      // Update info_buyRequest to reflect changes 
      if ($infoArr && 
       isset($infoArr['options']) && 
       isset($infoArr['options'][$optId])) 
       { 
       // Remove real custom option 
       unset($infoArr['options'][$optId]); 

       // Add replacement additional option for reorder (see above) 
       $infoArr['additional_options'] = $additionalOptions; 

       $info->setValue(serialize($infoArr)); 
       $item->addOption($info); 
      } 

      // Remove real custom option id from option_ids list 
      if ($optionIdsOption = $item->getProduct()->getCustomOption('option_ids')) { 
       $optionIds = explode(',', $optionIdsOption->getValue()); 
       if (false !== ($idx = array_search($optId, $optionIds))) { 
        unset($optionIds[$idx]); 
        $optionIdsOption->setValue(implode(',', $optionIds)); 
        $item->addOption($optionIdsOption); 
       } 
      } 

      // Remove real custom option 
      $item->removeOption('option_' . $optId); 
     } 
    } 

Esto es en pocas palabras. Agregue la comprobación de errores y se encargue de casos especiales, como volver a agregar el mismo producto al carrito según sea necesario.
Espero que esto comience a trabajar con opciones personalizadas de productos. No está nada mal una vez que te hayas familiarizado con ellos.

+0

Gracias Vinai por la ayuda. Voy a intentar esto. – Farrukh

+0

Aquí hay otra respuesta basada en este enfoque con un toque diferente y más detalles: http://stackoverflow.com/a/9496266/485589 – Vinai

+0

me será de ayuda si estoy configurando la opción de suma en sales_quote_collect_totals_antes. Porque mi sales_convert_quote_item_to_order_item no llama. todos –

-1

Solo para agregar una pequeña solución a la gran solución de Vinai. La solución rompe la lógica de obtener una cotización elemento por producto.

La función getItemByProduct en Mage_Sales_Model_Quote_Item llama a la función representProduct que compara las opciones de cita y producto. Si ambos objetos tienen una lista idéntica de opciones, devuelve el objeto de cotización de lo contrario es falso.

Dado que ambos objetos tienen diferentes opciones ahora que hemos agregado nuestra opción personalizada, la función devolverá falsa.

Una forma de resolver este problema es reescribir Mage_Sales_Model_Quote_Item clase y agregar su código de opción personalizado a la variable local $ _notRepresentOptions en el constructor.

class Custom_Options_Model_Sales_Quote_Item extends Mage_Sales_Model_Quote_Item { 

/** 
* Initialize resource model 
* 
*/ 
protected function _construct() 
{   
    $this->_notRepresentOptions = array_merge($this->_notRepresentOptions, array('additional_options')); 

    parent::_construct(); 
} 

}

Cuestiones relacionadas