摘要
我想创建一个未保存到产品的产品属性,或者像普通产品属性一样显示在产品编辑页面上。相反,我希望它保存到订单/报价项目并显示在订单,发票等。在将产品添加到购物车之前,客户还应该可以配置它。
详情
我的问题
<input>
的价值从前端产品页面保存到报价项目?更新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();
通过这种方式,我可以从产品页面上的<input>
检索我自定义的客户提供的数据。
我怀疑此info_buyRequest
与报价和订单项一起保存。如果是这样,这个部分解决了我的问题1和2.但是,我仍然不知道在哪里运行此代码是合适的,我不知道如何在后端订单/报价/报告页面上显示它。另外我相信,因为它作为序列化值存储在数据库中,根据我的自定义数据获取报价/订单项集合将是最困难的。
答案 0 :(得分: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>
在事件观察者中,您可以添加其他检查,请求的页面确实是添加到购物车的操作。此观察者方法的要点是将特殊选项的选择添加到产品模型上的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));
}
}
}
其他选项将自动从产品移至报价项目。有了这个观察员,您的选项将显示在购物车和结帐审核中。
为了让它们持续存在,需要一个额外的观察者(仅在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>
这里我们将选项从报价项目移动到订单项目。
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);
}
}
从这一点开始,其他选项将显示在前端和订单电子邮件中的客户订单历史记录中,以及管理界面订单视图,发票,货件,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>
应该将额外选项的解析和构建附加选项数组移动到单独的函数中以避免代码重复,但是对于此示例,为了清楚起见,我将为每个方法留下所需的逻辑。
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)
));
}
}
}
没有适当的机制来翻译这些选项标签或值。以下是一些在这方面可能有用的想法。
在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
)。
答案 1 :(得分:11)
可以在Quote项中添加自定义字段。开始在Magento How to add custom fields for Order Line Items开始。我最近使用这些指令将自定义字段添加到Magento引用项目,概念很好,但该文章中有一些不太好的做法。我会采取不同的做法:
通常最好避免修改Magento核心,并通过模块应用您的自定义,因为它将来更容易/可能进行升级。如果您在moduleCreator之前没有创建自己的扩展程序可以帮助您生成必要的样板文件。
答案 2 :(得分:1)
我在Magento 1.8中的解决方案
设置引用项目的选项
$quoteItem = $cart->getQuote()->getItemById($itemId);
$quoteItem->addOption(array('label' => 'buymode', 'code' => 'buymode', 'value' => $data['buymode']));
$quoteItem->save();
来自QuoteItem的访问选项
$quoteItem->getOptionByCode('buymode')->getValue();
将选项转移到OrderItem
注册活动sales_convert_quote_item_to_order_item
public function onConvertQuoteItemToOrderItem($observer) {
$orderItem = $observer->getOrderItem();
$quoteItem = $observer->getItem();
$options = $orderItem->getProductOptions();
$options['buymode'] = $quoteItem->getOptionByCode('buymode')->getValue();
$orderItem->setProductOptions($options);
}
来自OrderItem的访问选项
$orderItem->getProductOptionByCode('buymode')