Crear una opción personalizada al guardar el producto

18

Estoy trabajando en crear una opción personalizada para mis productos automáticamente cada vez que se crea un producto. Lo que tengo hasta ahora es un observador que dispara el catalog_product_save_beforeevento y ejecuta el siguiente código:

    //check that we haven't made the option already
    $options = $product->getProductOptions();
    foreach ($options as $option) {
        if ($option['title'] == 'Auto Date & Time' && $option['type'] == 'date_time' && !$option['is_delete']) {
            //we've already added the option
            return;
        }
    }
    $options[] = array(
        'title' => $product->getDateLabel(),
        'type' => 'date_time',
        'is_require' => 1,
        'sort_order' => 0,
        'is_delete' => '',
        'previous_type' => '',
        'previous_group' => '',
        'price' => '0.00',
        'price_type' => 'fixed',
        'sku' => ''
    );
    $product->setProductOptions($options);
    $product->setCanSaveCustomOptions(true);
    //this line doesnt make sense here, but it works ... kinda
    $product->save();

Si dejo la entrada $product->save(), termino con 2 opciones personalizadas que se crean, a pesar de que compruebo para verificar la segunda vez que se activa el evento, la declaración de devolución se llama en el bucle foreach.

Si lo saco. No se crean opciones personalizadas.

¿Alguien puede decirme qué estoy haciendo mal?
Estoy trabajando con Magento 1.7

Jason Neumann
fuente
Hola, dado que está utilizando el evento catalog_product_save_before, no necesitará llamar al -> guardar, ya que el producto no se guardará después de que se complete el evento. ¿Qué sucede si eliminas esa llamada guardada en tu observador?
ProxiBlue
Si elimino la llamada para guardar (), no se crean opciones personalizadas.
Jason Neumann

Respuestas:

12

Hasta que encuentre el problema exacto aquí está la solución. En catalog_product_save_beforesu lugar, use el evento catalog_product_prepare_save. La desventaja de esto es que el prepare_saveevento se envía solo cuando se guarda un producto desde la interfaz de administración o la API. Entonces, si está guardando desde un código personalizado, esto no se activará a menos que lo active manualmente.

Tengo el presentimiento de que el problema tiene algo que ver con el Mage_Catalog_Model_Product::_beforeSave()método. Allí hay un procesamiento de las opciones personalizadas.
Pero catalog_product_save_beforese envía después de que se produce este procesamiento, por lo que, aunque se procesan las opciones personalizadas, en Mage_Catalog_Model_Product::_beforeSave()realidad están vacías porque el evento aún no se activó, por lo que no se agregaron.
Si mueve la línea parent::_beforeSave();en el método que mencioné en la parte superior del método, las opciones se agregan (todavía dos veces, pero se agregan). Publicaré más cuando / si encuentro el problema.

[EDITAR] Lo
encontré. De alguna manera estaba justo en las líneas de arriba.
Como dije, el problema es que catalog_product_save_beforese envía después de que se procesan las opciones personalizadas. Pero es por eso que no funciona.
Las opciones personalizadas se guardan en Mage_Catalog_Model_Product::_afterSave()este código:

$this->getOptionInstance()->setProduct($this)
            ->saveOptions();

Pero $this->getOptionInstance()se llena con opciones _beforeSavecuando la matriz de opciones está vacía en su caso. Por lo tanto ... nada que salvar.
Si aún desea utilizar catalog_product_save_beforeel código aquí, debería funcionar.

//check that we haven't made the option already
$options = $product->getOptions();
if ($options){
    foreach ($options as $option) {
        if ($option['title'] == 'Auto Date & Time' && $option['type'] == 'date_time' && !$option['is_delete']) {
            //we've already added the option
            return;
        }
    }
}
$option = array(
    'title' => 'Auto Date & Time',
    'type' => 'date_time',
    'is_require' => 1,
    'sort_order' => 0,
    'is_delete' => '',
    'previous_type' => '',
    'previous_group' => '',
    'price' => '0.00',
    'price_type' => 'fixed',
    'sku' => ''
);
//don't use it like this because it has no effect
//$product->setProductOptions($options);
$product->setCanSaveCustomOptions(true);
//use it this way. Populate `$product->getOptionInstance()` directly
$product->getOptionInstance()->addOption($option);
//don't forget to state that the product has custom options
$product->setHasOptions(true);
Marius
fuente
Hola, @Marius, ¿puedo usar en catalog_product_prepare_savelugar de catalog_product_save_beforey cómo puedo actualizar la opción si se requiere algún cambio?
Zaheerabbas
0

Acabo de tener el mismo problema, la respuesta de Mario funcionó muy bien. Sin embargo, me llevó algo de tiempo descubrir cómo actualizar una opción personalizada. Con el conocimiento de que $ product-> getOptionInstance () -> addOption () funciona para guardar una opción, y establecer "is_delete" en 1 elimina una opción al guardar, se me ocurrió este código:

$oldOptions = $product->getOptionInstance()->getOptions();
foreach ($oldOptions as $key => $option){
    if($option['title'] == "Custom Option Title") {
        $oldOptions[$key]['is_delete'] = 1;                 
        $product->getOptionInstance()->addOption($oldOptions[$key]);
    }
}

Después de eliminar, puede agregar su opción personalizada actualizada con este código:

$newOption = array(
    'title' => "Custom Option Title",
    'type' => 'radio',
    'is_require' => 1,
    'sort_order' => 20,
    'values' => array(
        array(
            'title' => "Value 1 Title",
            'price' => 42.00,
            'price_type' => 'fixed',
            'sku' => "",
            'sort_order' => '1'
        ),
        array(
            'title' => "Value 2 Title",
            'price' => 50,
            'price_type' => 'percent',
            'sku' => "",
            'sort_order' => '2'
        )
    )
);
$product->getOptionInstance()->addOption($newOption);
Andreas Riedmüller
fuente
0

Para crear una opción personalizada en magento mientras se guarda el producto, estos son pasos muy fáciles.

   $product = Mage::getModel("catalog/product")->load($productid);

    $options[] = array(
            'title' => 'Pet',
            'type' => 'field',
            'is_require' => 0,
            'sort_order' => 0,
        );
    $options[] = array(
            'title' => 'Date',
            'type' => 'field',
            'is_require' => 1,
            'sort_order' => 2,
        );

    $product->setProductOptions(($options));
    $product->setCanSaveCustomOptions(true);
    $product->save();`

Si ya se ha creado una opción personalizada, puede eliminarla siguiendo el código

$product = Mage::getModel("catalog/product")->load($productid);

    $customOptions = $product->getOptions();

    foreach ($customOptions as $option) {
        $option->delete();
    }

    $product->setHasOptions(0);
    $product->save();

Gracias

Mage2Solutions
fuente