文章目录
- 测试环境
- 需求描述
- 实现步骤
- 实际效果
- 思路说明
测试环境
Odoo 版本: odoo13 和 odoo16
Python 版本:3.6.9
操作系统:Ubuntu 18.04
需求描述
- 添加变体描述,显示在 form 视图;
- 在网站上动态显示产品变体描述。
实现步骤
- 创建模块 product_vat_16;
- 在产品变体
product.product
上添加字段 variant_desc 作为变体描述字段;
odoo13 和 odoo16 同代码:
class ProductProduct(models.Model):
_inherit = 'product.product'
variant_desc = fields.Text('Variant Description')
个人理解:
product.template
和product.product
,product.template
是产品,个人理解为产品模板,通用型的;porduct.product
是产品变体,也可以说是个性化产品。所以变体描述添加在这个模型中。
如果添加到 product.template
中的话,每个变体描述都是一样的内容,不管修改哪个最后所有的产品的变体描述都是最后一次修改的内容。
- 对应的 form 视图上显示该字段;
odoo16:
<record id="view_product_product_variant_desc_form" model="ir.ui.view">
<field name="name">product.product.desc.form</field>
<field name="model">product.product</field>
<field name="inherit_id" ref="product.product_normal_form_view"/>
<field name="arch" type="xml">
<page name="invoicing" position="after">
<page name="variant_desc" string="Variant Description">
<group>
<label for="variant_desc" string=""/>
<div>
<field name="variant_desc"/>
</div>
</group>
</page>
</page>
</field>
</record>
odoo13:
<record id="view_product_product_desc_form" model="ir.ui.view">
<field name="name">product.product.desc.form</field>
<field name="model">product.product</field>
<field name="inherit_id" ref="product.product_normal_form_view"/>
<field name="arch" type="xml">
<page name="purchase" position="after">
<page name="variant_desc" string="Variant Description">
<group>
<field name="vat_desc2"/>
</group>
</page>
</page>
</field>
</record>
- 如何在网站上动态显示变体描述内容;(修改网站上售卖产品的 qweb 模板)
odoo16:
在 ADD TO CART (加入购物车)下面显示变体描述的内容:
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<template id="inherit_website_template" inherit_id="website_sale.product">
<xpath expr="//div[@id='wrap']/section/div[@id='product_detail_main']/div[@id='product_details']/form//div[@id='o_wsale_cta_wrapper']" position="after">
<div>
<span class="oe_variant_desc"/>
</div>
</xpath>
</template>
</odoo>
odoo13:
在 ADD TO CART (加入购物车)上面显示变体描述的内容:
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<template id="inherit_website_template2" inherit_id="website_sale.product">
<xpath expr="//div[@id='wrap']/section//div[@id='product_details']/form//div/t[1]" position="after">
<span class="oe_variant_desc"/>
</xpath>
</template>
</odoo>
- 网页上的返回内容中添加变体内容;
odoo13 和 odoo16 同:
class ProductTemplate(models.Model):
_inherit = 'product.template'
def _get_combination_info(self, combination=False, product_id=False, add_qty=1, pricelist=False,
parent_combination=False, only_template=False):
res = super()._get_combination_info(combination=combination, product_id=product_id, add_qty=add_qty, pricelist=pricelist,
parent_combination=parent_combination, only_template=only_template)
if res.get('product_id'):
product = self.env['product.product'].browse(res.get('product_id'))
res.update({'vat_desc2': product.vat_desc2})
return res
- 根据不同的属性组合显示不同的变体描述,需要修改js,继承修改后的 js 文件;
odoo16:
odoo.define('product_vat_v16.product_variant', function (require) {
'use strict';
var VariantMixin = require('website_sale.VariantMixin');
const newOnChangeCombination = VariantMixin._onChangeCombination;
VariantMixin._onChangeCombination = function (ev, $parent, combination) {
var $variant_desc = $parent.find(".oe_variant_desc");
$variant_desc.text(combination.variant_desc);
newOnChangeCombination.apply(this, [ev, $parent, combination]);
};
});
odoo13:
odoo.define('product_vat_v13.product_variant', function (require) {
'use strict';
var publicWidget = require('web.public.widget');
var VariantMixin = require('sale.VariantMixin');
publicWidget.registry.WebsiteSale = publicWidget.Widget.extend(VariantMixin, {
selector: '.oe_website_sale',
events: _.extend({}, VariantMixin.events || {}, {
'click input.js_product_change': 'onChangeVariant',
'change .js_main_product [data-attribute_exclusions]': 'onChangeVariant',
'change oe_optional_products_modal [data-attribute_exclusions]': 'onChangeVariant',
}),
// override to get the variant desc when access first
start: function () {
var self = this;
var def = this._super.apply(this, arguments);
_.each(this.$('div.js_product'), function (product) {
$('input.js_product_change', product).first().trigger('change');
});
// This has to be triggered to compute the "out of stock" feature and the hash variant changes
this.triggerVariantChange(this.$el);
return def;
},
// change product attribute method start from this method
onChangeVariant: function (ev) {
return VariantMixin.onChangeVariant.apply(this, arguments);
},
// change product variant attributes and change the desc at the same time
_onChangeCombination: function (ev, $parent, combination) {
var $vat_desc2 = $parent.find(".oe_variant_desc");
$vat_desc2.text(combination.vat_desc2);
},
});
});
引入 js 文件到 assets_fontend.xml:
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<template id="assets_frontend" name="Website Variant Desc" inherit_id="web.assets_frontend">
<xpath expr="." position="inside">
<script type="text/javascript" src="/product_vat_v13/static/src/js/product_variant.js"/>
</xpath>
</template>
</data>
</odoo>
- 增加中文翻译。
实际效果
-
新增产品的变体的属性如下;
-
新增变体描述如下;
-
网站上显示变体描述。
思路说明
-
如何判断需要修改哪个 qweb 模块?
在产品页面,点击转到网站的时候,地址栏会显示一个当前页面渲染的地址,通过这个地址找到对应的渲染页面。 -
在网站上如何实现属性联动后变体描述也能对应的修改?
一个思路,在变体上,价格跟图片是联动,就是选择不同的属性组合后,价格跟图片会自动跟着改变。参考这个代码去摸索。
odoo16是比较新的版本,我比较熟悉odoo13,所以先在13上面摸索,掌握关键后在16上复现。