Magento - 根据用户输入报价/订购产品项目属性

Vit*_*min 63 php magento

摘要

我想创建一个未保存到产品的产品属性,或者像普通产品属性一样显示在产品编辑页面上.相反,我希望它保存到订单/报价项目并显示在订单,发票等.在将产品添加到购物车之前,它还应该由前端的客户配置.

细节

  • 自定义选项一样,表单元素应添加到前端产品页面.
    • 自定义选项不同,这不是实际的产品属性.它不应显示在管理产品页面或属性集上.
    • 客户需要提供有效值.我需要能够进行服务器端验证.
    • 我想要一个.phtml模板生成它的html.目前,我能够以令人满意的(设计)结果覆盖app/design/frontend/base/default/catalog/product/view/type/default.phtml.但是,我不知道如何捕获,验证并最终保存其价值.
  • 此表单元素的值应与quote/order产品项一起保存.
    • 此值应显示在任何和所有发票,订单,销售电子邮件中.
    • 我想用模板控制输出,或者至少能够返回用于显示值的字符串

我的问题

  1. <input>当产品添加到购物车时,以及稍后在结账过程中,如何验证并最终将前端产品页面上的值保存到报价项目中?
  2. 如何在订单,发票,销售电子邮件和此类页面上显示此值?
  3. 如何过滤订单集合以获取具有我的值设置为特定值的项目的订单?

更新1

我发现我可以在诸如此类的事件中在catalog/product模型上运行此代码(并且可能sales/quote_item也是如此)sales_quote_item_qty_set_after

$infoBuyRequest = $product->getCustomOption('info_buyRequest');
$buyRequest = new Varien_Object(unserialize($infoBuyRequest->getValue()));
$myData = $buyRequest->getMyData();
Run Code Online (Sandbox Code Playgroud)

通过这种方式,我能够从<input>产品页面上检索我的自定义客户提供的数据.

我怀疑这info_buyRequest是与报价和订单项目一起保存的.如果是这样,这部分解决了我的问题1和2.但是,我仍然不知道在哪里运行此代码是合适的,我不知道如何在后端订单/报价/报告页面上显示它.另外我相信,因为它作为序列化值存储在数据库中,根据我的自定义数据获取报价/订单项集合将是最困难的.

Vin*_*nai 140

Magento提供了添加非产品属性或产品自定义选项的选项的功能.它们在产品和报价项目上设置了选项代码additional_options.

您需要执行两个步骤,每个步骤都可以通过事件观察器进行处理.如果您希望其他选项进行重新排序,您还需要观察第三个事件.

添加引用项的选项

第一步是添加事件观察器,以便在加载的产品添加到购物车之前设置其他选项.一种选择是使用该catalog_product_load_after事件.

<catalog_product_load_after>
    <observers>
        <extra_options>
            <type>model</type>
            <class>extra_options/observer</class>
            <method>catalogProductLoadAfter</method>
        </extra_options>
    </observers>
</catalog_product_load_after>
Run Code Online (Sandbox Code Playgroud)

在事件观察者中,您可以添加其他检查,请求的页面确实是添加到购物车操作.此观察者方法的要点是将选择的特殊选项添加到additional_options产品模型上的选项中.

public function catalogProductLoadAfter(Varien_Event_Observer $observer)
{
    // set the additional options on the product
    $action = Mage::app()->getFrontController()->getAction();
    if ($action->getFullActionName() == 'checkout_cart_add')
    {
        // assuming you are posting your custom form values in an array called extra_options...
        if ($options = $action->getRequest()->getParam('extra_options'))
        {
            $product = $observer->getProduct();

            // add to the additional options array
            $additionalOptions = array();
            if ($additionalOption = $product->getCustomOption('additional_options'))
            {
                $additionalOptions = (array) unserialize($additionalOption->getValue());
            }
            foreach ($options as $key => $value)
            {
                $additionalOptions[] = array(
                    'label' => $key,
                    'value' => $value,
                );
            }
            // add the additional options array with the option code additional_options
            $observer->getProduct()
                ->addCustomOption('additional_options', serialize($additionalOptions));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

其他选项将自动从产品移动到报价项目.有了这个观察员,您的选项将显示在购物车和结帐审核中.

向订单商品添加选项

为了使它们持续存在,需要一个额外的观察者(仅在Magento 1.5之后).

<sales_convert_quote_item_to_order_item>
    <observers>
        <extra_options>
            <type>model</type>
            <class>extra_options/observer</class>
            <method>salesConvertQuoteItemToOrderItem</method>
        </extra_options>
    </observers>
</sales_convert_quote_item_to_order_item>
Run Code Online (Sandbox Code Playgroud)

在这里,我们将选项从报价项移动到订单项.

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

从这一点开始,其他选项将显示在前端和订单电子邮件中的客户订单历史记录中,以及管理界面订单视图,发票,货件,creditmemos和PDF中.

添加对重新排序的支持

为了在重新排序期间将oprions转移到新订单,您需要注意将它们复制.这是使用该checkout_cart_product_add_after事件的一种可能性.

<checkout_cart_product_add_after>
    <observers>
        <extra_options>
            <type>singleton</type>
            <class>extra_options/observer</class>
            <method>checkoutCartProductAddAfter</method>
        </extra_options>
    </observers>
</checkout_cart_product_add_after>
Run Code Online (Sandbox Code Playgroud)

应该将额外选项的解析和构建附加选项数组移动到单独的函数中以避免代码重复,但是对于这个示例,为了清楚起见,我将为每个方法留下所需的逻辑.

public function checkoutCartProductAddAfter(Varien_Event_Observer $observer)
{
    $action = Mage::app()->getFrontController()->getAction();
    if ($action->getFullActionName() == 'sales_order_reorder')
    {
        $item = $observer->getQuoteItem();
        $buyInfo = $item->getBuyRequest();
        if ($options = $buyInfo->getExtraOptions())
        {
            $additionalOptions = array();
            if ($additionalOption = $item->getOptionByCode('additional_options'))
            {
                $additionalOptions = (array) unserialize($additionalOption->getValue());
            }
            foreach ($options as $key => $value)
            {
                $additionalOptions[] = array(
                    'label' => $key,
                    'value' => $value,
                );
            }
            $item->addOption(array(
                'code' => 'additional_options',
                'value' => serialize($additionalOptions)
            ));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

翻译:

没有机制来翻译这些选项标签或值.以下是一些在这方面可能有用的想法.

在quote_item_load_after事件观察器中,获取其他选项数组并进行设置$option['print_value'] = $helper->__($option['value']);.如果print_value设置,Magento将使用它来渲染显示.
订单商品也可以这样做.

没有这样的东西print_label,但你可以设置一个自定义索引(label_source可能)并使用它作为源动态设置标签,例如$option['label'] = $helper->__($option['label_source']);.

除此之外,您可能不得不求助于修改模板(grep for getItemOptions())或覆盖块类(grep additional_options).


Jim*_*ran 11

可以向Quote项添加自定义字段. 如何为 Magento中的订单行项添加自定义字段以开始使用.我最近使用这些指令将自定义字段添加到Magento引用项目,概念很好,但该文章中有一些不太好的做法.我做的事情不同:

  1. 使用安装脚本将字段添加到数据库而不是直接执行.
  2. 使用Magento的Request对象而不是直接访问$ _REQUEST.
  3. 使用扩展和重写而不是修改Magento核心.
  4. 从扩展中对config.xml进行更改,而不是修改核心.

通常,最好避免修改Magento核心,并通过模块应用您的自定义,因为它将来更容易/可能进行升级.如果您尚未创建自己的扩展,那么moduleCreator可以帮助您生成必要的样板.