Resultó que este es un error Mage_Sales_Model_Quote_Item::compare()
que se introdujo en Magento CE 1.9.2 / EE 1.14.2. El método se usa para comparar artículos para decidir si son el mismo producto y se pueden combinar (durante el inicio de sesión y al agregar productos al carrito).
Al comparar todas las opciones personalizadas, debe omitir las opciones que no son representativas ( _notRepresentOptions
), es decir, la opción info_buyRequest .
En versiones anteriores de Magento, se veía así:
foreach ($this->getOptions() as $option) {
if (in_array($option->getCode(), $this->_notRepresentOptions)) {
continue;
}
Y funcionó correctamente. Ahora se ve así:
foreach ($this->getOptions() as $option) {
if (in_array($option->getCode(), $this->_notRepresentOptions)
&& !$item->getProduct()->hasCustomOptions()
) {
continue;
}
y la comprobación adicional de hasCustomOptions()
causa el error descrito. ¿Por qué? Parece que el cheque se ha agregado para mantener siempre separados los productos con opciones personalizadas. No creo que tenga sentido, al menos no en la forma en que se implementa, pero habrá alguna razón de la que no estoy al tanto.
Sin embargo, $item->getProduct()->hasCustomOptions()
siempre devuelve verdadero para los artículos de cotización
Este es el método:
public function hasCustomOptions()
{
if (count($this->_customOptions)) {
return true;
} else {
return false;
}
}
Pero $this->_customOptions
también contiene elinfo_buyRequest
opción del artículo de presupuesto.
Para una solución discreta, traté de eliminar la info_buyRequest
opción de todos los productos en un observador ensales_quote_merge_before
, sin éxito.
La razón radica en Mage_Sales_Model_Quote_Item_Abstract::getProduct()
que la opción se copia nuevamente del artículo de presupuesto:
public function getProduct()
{
$product = $this->_getData('product');
[...]
if (is_array($this->_optionsByCode)) {
$product->setCustomOptions($this->_optionsByCode);
}
return $product;
}
Solución
Creé una reescritura Mage_Sales_Model_Quote_Item
con una anulación para getProduct()
no incluir la info_buyRequest
opción en este punto:
public function getProduct()
{
$product = parent::getProduct();
$options = $product->getCustomOptions();
if (isset($options['info_buyRequest'])) {
unset($options['info_buyRequest']);
$product->setCustomOptions($options);
}
return $product;
}
Esto causó problemas con los productos combinados, la alternativa a continuación o el parche oficial descrito por @ AnnaVölkl es una mejor solución
Alternativa
También puede eliminar la infracción && !$item->getProduct()->hasCustomOptions()
en el compare()
método si está reescribiendo el modelo del artículo de todos modos. No sé qué problema trató de resolver, pero creó más ...
Actualización 29 de enero de 2016
Informé esto a Magento y obtuve la respuesta de que no podían reproducir el problema, por lo que el parche no entrará en la edición de la comunidad (Presentación APPSEC-1321).
Esto significa que, si tiene el problema, debe aplicar el parche empresarial SUPEE-6190 después de cada actualización o utilizar una reescritura de clase en su lugar.