Products & Pricelists

product
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/19.0/product
VERSION
VERSION 1.2
CATEGORY
CATEGORYSales/Sales
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo S.A.
MAINTAINERS
MAINTAINERSOdoo S.A.
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Thibault Delavallée, Xavier Morel, Aaron Bohy, Arnold Moyaux, Julien Castiaux, Victor Feyens, Andrea Grazioso (agr-odoo), Sébastien Theys, svs-odoo, Achraf (abz), Tiffany Chang (tic), Rémy Voet (ryv), Gorash, Mathieu Duckerts-Antoine, Pierre Paridans, William Braeckman, odoo, Miquel Raïch, Ahmad Khanalizadeh, Víctor Martínez, JF Aubert, Aurelien van Delft (avd), Hubert Van De Walle, Valentin Chevalier, Renaud Thiry, niyasraphy, alsh-odoo, David, Adrien Widart (awt), Maximilien (malb), Victor Piryns (pivi), Mahamadasif Ansari, Gauthier Wala (gawa), Andrew Gavgavian, Levi Siuzdak (sile), Dylan Kiss (dyki), Valeriya(vchu), tanghulu0608, Anita (anko), SilvioC2C, Nguyễn Đại Dương, Sarah Bellefroid, Arnaud Sibille, omra-odoo, stefanorigano (SRI), Adam Heinz, Louis (loti), reka-odoo, kcv-odoo, odoostan, dere-odoo, Lina (liew), Aungkokolin1997, manv-afk, Patricia Daloze (pda), Xavier Luyckx (xlu), yagp-odoo, Sanchit Gupta, Stéphane Diez, Mohammad Abdulmoneim, gteboul, sabr, Julien Schwanen, Victor Miguel Armenta Carrillo, sben-odoo, Arthur Nanson, Christopher Maloney (cmal), David Van Droogenbroeck (DROD), Mohammad Abdulmoneim (abdu), djameltouati, khsr-odoo, Pierre Lamotte (pila), wt, Michaël Mattiello, kasm, Carmine, Shrey Mehta, chha-odoo, MaximeNoirhomme, bona-odoo, Vincent Sevestre, plha-odoo, Krzysztof Magusiak (krma), kkuj-odoo, Mahdi Alijani (malj), nipl-odoo, krip-odoo, bhna-odoo, rare-odoo, agbr-odoo, mohannedah, Lulu Grimalkin (lugr), temo-odoo, igbe, Quentin Colla (qucol), path-odoo, Amr Elkhatieb, Nisarg (nipl), hossamelgendy1, Waleed Elgamal, Samiul Hoque, Merlin Guillaume, Mazen, srap-odoo, saurabh, Nguyen Nguyen (ngtpn), Stephane Vanmeerhaeghe (stva), Youssef (abyo), ELCO, Przemysław Duryło, chpa-odoo, panj-odoo, Oussema Heni, Mathias Mathy, jeanschoenlaub, Abhishek Yadav, kukor-odoo
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 01:51:44
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - html_editor
    - uom
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
This is the base module for managing products and pricelists in Odoo.
========================================================================

Products support variants, different pricing methods, vendors information,
make to stock/order, different units of measure, packaging and properties.

Pricelists support:
-------------------
    * Multiple-level of discount (by product, category, quantities)
    * Compute price based on different criteria:
        * Other pricelist
        * Cost price
        * List price
        * Vendor price

Pricelists preferences by product and/or partners.

Print product labels with barcode.
    

Code Analysis

Views touched (75)
XML IDNameModelTypeStatus
attribute_tree_view product.attribute.list product.attribute list New
inherits_website_sale_country_group_form res.country.group.form.inherit.product res.country.group group Inherits base.view_country_group_form
product.product_combo_view_form product.combo.form product.combo form New
product.product_combo_view_tree product.combo.list product.combo list New
product_attribute_search product.attribute.view.search product.attribute search New
product_attribute_value_list product.attribute.value.list product.attribute.value list New
product_attribute_view_form product.attribute.form product.attribute form New
product_category_form_view product.category.form product.category form New
product_category_list_view product.category.list product.category list New
product_category_search_view product.category.search product.category search New
product_document_form product.document.form product.document form New
product_document_kanban product.document.kanban product.document kanban New
product_document_list product.document.list product.document list New
product_document_search product.document.search product.document search New
product_kanban_view Product Kanban product.product kanban New
product_label_layout_form product.label.layout.form product.label.layout form New
product_normal_form_view product.product.form product.product xpath Inherits product.product_template_form_view
product_pricelist_item_form_view product.pricelist.item.form product.pricelist.item form New
product_pricelist_item_product_product_form_view product.pricelist.item.product.product.form.inherit product.pricelist.item field Inherits product.product_pricelist_item_product_template_form_view
product_pricelist_item_product_template_form_view product.pricelist.item.product.template.form.inherit product.pricelist.item field Inherits product.product_pricelist_item_form_view
product_pricelist_item_tree_view product.pricelist.item.list product.pricelist.item list New
product_pricelist_item_tree_view_from_product product.pricelist.item.list product.pricelist.item list New
product_pricelist_item_view_search product.pricelist.item.search product.pricelist.item search New
product_pricelist_view product.pricelist.form product.pricelist form New
product_pricelist_view_kanban product.pricelist.kanban product.pricelist kanban New
product_pricelist_view_search product.pricelist.search product.pricelist search New
product_pricelist_view_tree product.pricelist.list product.pricelist list New
product_product_tree_view product.product.list product.product list New
product_product_view_activity product.product.activity product.product activity New
product_product_view_form_normalized product.product.view.form.normalized product.product form New
product_product_view_tree_tag product.product.view.list.tag product.product list New
product_search_form_view product.product.search product.product field Inherits product.product_template_search_view
product_supplierinfo_form_view product.supplierinfo.form.view product.supplierinfo form New
product_supplierinfo_search_view product.supplierinfo.search.view product.supplierinfo search New
product_supplierinfo_tree_view product.supplierinfo.list.view product.supplierinfo list New
product_supplierinfo_view_kanban product.supplierinfo.kanban product.supplierinfo kanban New
product_tag_form_view product.tag.form product.tag form New
product_tag_tree_view product.tag.list product.tag list New
product_template_attribute_line_form product.template.attribute.line.form product.template.attribute.line form New
product_template_attribute_line_view_tree product.template.attribute.line.view.list product.template.attribute.line list New
product_template_attribute_value_view_form product.template.attribute.value.view.form. product.template.attribute.value form New
product_template_attribute_value_view_search product.template.attribute.value search New
product_template_attribute_value_view_tree product.template.attribute.value.view.list product.template.attribute.value list New
product_template_form_view product.template.common.form product.template form New
product_template_kanban_view Product.template.product.kanban product.template kanban New
product_template_list_view_purchasable product.template.list.purchasable product.template xpath Inherits product.product_template_tree_view
product_template_list_view_sellable product.template.list.sellable product.template xpath Inherits product.product_template_tree_view
product_template_only_form_view product.template.product.form product.template xpath Inherits product.product_template_form_view
product_template_search_view product.template.search product.template search New
product_template_tree_view product.template.product.list product.template list New
product_template_view_activity product.template.activity product.template activity New
product_template_view_tree_tag product.template.view.list.tag product.template list New
product_uom_list_view product.uom.list product.uom list New
product_variant_easy_edit_view product.product.view.form.easy product.product form New
product_view_kanban_catalog product.view.kanban.catalog product.product kanban New
product_view_search_catalog product.view.search.catalog product.product search New
report_packagingbarcode report_packagingbarcode ir.ui.view qweb New
report_pricelist report_pricelist ir.ui.view qweb New
report_pricelist_page report_pricelist_page ir.ui.view qweb New
report_productlabel report_productlabel ir.ui.view qweb New
report_productlabel_dymo report_productlabel_dymo ir.ui.view qweb New
report_producttemplatelabel2x7 report_producttemplatelabel2x7 ir.ui.view qweb New
report_producttemplatelabel4x12 report_producttemplatelabel4x12 ir.ui.view qweb New
report_producttemplatelabel4x12noprice report_producttemplatelabel4x12noprice ir.ui.view qweb New
report_producttemplatelabel4x7 report_producttemplatelabel4x7 ir.ui.view qweb New
report_producttemplatelabel_dymo report_producttemplatelabel_dymo ir.ui.view qweb New
report_simple_label2x7 report_simple_label2x7 ir.ui.view qweb New
report_simple_label4x12 report_simple_label4x12 ir.ui.view qweb New
report_simple_label4x12_no_price report_simple_label4x12_no_price ir.ui.view qweb New
report_simple_label4x7 report_simple_label4x7 ir.ui.view qweb New
report_simple_label_dymo report_simple_label_dymo ir.ui.view qweb New
res_config_settings_view_form res.config.settings.view.form.inherit.product res.config.settings xpath Inherits base_setup.res_config_settings_view_form
uom_uom_form_view_inherit uom.uom.form.inherit uom.uom xpath Inherits uom.product_uom_form_view
update_product_attribute_value_form update.product.attribute.value.form update.product.attribute.value form New
view_partner_property_form res.partner.product.property.form.inherit res.partner group Inherits base.view_partner_form
Models touched (33)

New fields (0)

No new fields.

Public methods (1)
  • create(self, vals_list)
    @api.model_create_multi
    Create product.document for attachments added in products chatters

New fields (10)
  • active Boolean
    default=True help='If unchecked, it will allow you to hide the attribute without removing it.'
  • attribute_line_ids One2many → product.template.attribute.line
    comodel_name='product.template.attribute.line' inverse_name='attribute_id' string='Lines'
  • create_variant Selection
    default='always' help='- Instantly: All possible variants are created as soon as the attribute and its values are added to a product.\n - Dynamically: Each variant is created only when its corresponding attributes and values are added to a sales order.\n - Never: Variants are never created for the attribute.\n Note: this cannot be changed once the attribute is used on a product.' required=True selection=[('always', 'Instantly'), ('dynamic', 'Dynamically'), ('no_variant', 'Never')] string='Variant Creation'
  • display_type Selection
    default='radio' help='The display type used in the Product Configurator.' required=True selection=[('radio', 'Radio'), ('pills', 'Pills'), ('select', 'Select'), ('color', 'Color'), ('multi', 'Multi-checkbox'), ('image', 'Image')]
  • name Char
    required=True string='Attribute' translate=True
  • number_related_products Integer
    compute='_compute_number_related_products'
  • product_tmpl_ids Many2many → product.template
    comodel_name='product.template' compute='_compute_products' store=True string='Related Products'
  • sequence Integer
    default=20 help='Determine the display order' index=True string='Sequence'
  • template_value_ids One2many → product.template.attribute.value
    comodel_name='product.template.attribute.value' inverse_name='attribute_id' string='Template Values'
  • value_ids One2many → product.attribute.value
    comodel_name='product.attribute.value' copy=True inverse_name='attribute_id' string='Values'
Public methods (3)
  • action_archive(self)
  • action_open_product_template_attribute_lines(self)
    @api.readonly
  • write(self, vals)
    Override to make sure attribute type can't be changed if it's used on a product template. This is important to prevent because changing the type would make existing combinations invalid without recomputing them, and recomputing them might take too long and we don't want to change products without the user knowing about it.

New fields (3)
  • custom_product_template_attribute_value_id Many2one → product.template.attribute.value
    comodel_name='product.template.attribute.value' ondelete='restrict' required=True string='Attribute Value'
  • custom_value Char
    string='Custom Value'
  • name Char
    compute='_compute_name' string='Name'
Public methods (0)

No public methods.

New fields (13)
  • active Boolean
    default=True
  • attribute_id Many2one → product.attribute
    comodel_name='product.attribute' help='The attribute cannot be changed once the value is used on at least one product.' index=True ondelete='cascade' required=True string='Attribute'
  • color Integer
    default=_get_default_color string='Color Index'
  • default_extra_price Float
  • default_extra_price_changed Boolean
    compute='_compute_default_extra_price_changed'
  • display_type Selection
    related='attribute_id.display_type'
  • html_color Char
    help="Here you can set a specific HTML color index (e.g. #ff0000) to display the color if the attribute type is 'Color'." string='Color'
  • image Image
    help='You can upload an image that will be used as the color of the attribute value.' max_height=70 max_width=70 string='Image'
  • is_custom Boolean
    help='Allow customers to set their own value' string='Free text'
  • is_used_on_products Boolean
    compute='_compute_is_used_on_products' string='Used on Products'
  • name Char
    required=True string='Value' translate=True
  • pav_attribute_line_ids Many2many → product.template.attribute.line
    comodel_name='product.template.attribute.line' copy=False relation='product_attribute_value_product_template_attribute_line_rel' string='Lines'
  • sequence Integer
    help='Determine the display order' index=True string='Sequence'
Public methods (5)
  • action_add_to_products(self)
    @api.readonly
  • action_update_prices(self)
    @api.readonly
  • check_is_used_on_products(self)
  • unlink(self)
  • write(self, vals)

New fields (0)

No new fields.

Public methods (1)
  • action_add_from_catalog(self)
    @api.readonly

New fields (7)
  • child_id One2many → product.category
    args: 'product.category', 'parent_id', 'Child Categories'
  • complete_name Char
    compute='_compute_complete_name' recursive=True store=True args: 'Complete Name'
  • name Char
    index='trigram' required=True args: 'Name'
  • parent_id Many2one → product.category
    index=True ondelete='cascade' args: 'product.category', 'Parent Category'
  • parent_path Char
    index=True
  • product_count Integer
    compute='_compute_product_count' help='The number of products under this category (Does not consider the children categories)' args: '# Products'
  • product_properties_definition PropertiesDefinition
    args: 'Product Properties'
Public methods (2)
  • copy_data(self, default=None)
  • name_create(self, name)
    @api.model

New fields (7)
  • base_price Float
    compute='_compute_base_price' help='The minimum price among the products in this combo. This value will be used to prorate the price of this combo with respect to the other combos in a combo product. This heuristic ensures that whatever product the user chooses in a combo, it will always be the same price.' min_display_digits='Product Price' string='Combo Price'
  • combo_item_count Integer
    compute='_compute_combo_item_count' string='Product Count'
  • combo_item_ids One2many → product.combo.item
    comodel_name='product.combo.item' copy=True inverse_name='combo_id'
  • company_id Many2one → res.company
    comodel_name='res.company' index=True string='Company'
  • currency_id Many2one → res.currency
    comodel_name='res.currency' compute='_compute_currency_id'
  • name Char
    required=True string='Name'
  • sequence Integer
    copy=False default=10
Public methods (0)

No public methods.

New fields (6)
  • combo_id Many2one → product.combo
    comodel_name='product.combo' index=True ondelete='cascade' required=True
  • company_id Many2one
    precompute=True related='combo_id.company_id' store=True
  • currency_id Many2one → res.currency
    comodel_name='res.currency' related='product_id.currency_id'
  • extra_price Float
    default=0.0 min_display_digits='Product Price' string='Extra Price'
  • lst_price Float
    min_display_digits='Product Price' related='product_id.lst_price' string='Original Price'
  • product_id Many2one → product.product
    check_company=True comodel_name='product.product' domain=[('type', '!=', 'combo')] ondelete='restrict' required=True string='Options'
Public methods (0)

No public methods.

New fields (3)
  • active Boolean
    default=True
  • ir_attachment_id Many2one → ir.attachment
    ondelete='cascade' required=True string='Related attachment' args: 'ir.attachment'
  • sequence Integer
    default=10
Public methods (3)
  • copy_data(self, default=None)
  • create(self, vals_list)
    @api.model_create_multi
  • unlink(self)

New fields (8)
  • columns Integer
    compute='_compute_dimensions'
  • custom_quantity Integer
    default=1 required=True args: 'Copies'
  • extra_html Html
    default='' args: 'Extra Content'
  • pricelist_id Many2one → product.pricelist
    string='Pricelist' args: 'product.pricelist'
  • print_format Selection
    default='2x7xprice' required=True string='Format' args: [('dymo', 'Dymo'), ('2x7xprice', '2 x 7 with price'), ('4x7xprice', '4 x 7 with price'), ('4x12', '4 x 12'), ('4x12xprice', '4 x 12 with price')]
  • product_ids Many2many → product.product
    args: 'product.product'
  • product_tmpl_ids Many2many → product.template
    args: 'product.template'
  • rows Integer
    compute='_compute_dimensions'
Public methods (1)
  • process(self)

New fields (7)
  • active Boolean
    default=True help='If unchecked, it will allow you to hide the pricelist without removing it.' string='Active'
  • company_id Many2one → res.company
    comodel_name='res.company' default=<expr> tracking=5
  • country_group_ids Many2many → res.country.group
    column1='pricelist_id' column2='res_country_group_id' comodel_name='res.country.group' relation='res_country_group_pricelist_rel' string='Country Groups' tracking=10
  • currency_id Many2one → res.currency
    comodel_name='res.currency' default=_default_currency_id required=True tracking=1
  • item_ids One2many → product.pricelist.item
    comodel_name='product.pricelist.item' copy=True domain=<expr> inverse_name='pricelist_id' string='Pricelist Rules'
  • name Char
    required=True string='Pricelist Name' translate=True
  • sequence Integer
    default=16
Public methods (4)
  • action_open_pricelist_report(self)
    @api.readonly
  • copy_data(self, default=None)
  • get_import_templates(self)
    @api.model
  • write(self, vals)

New fields (28)
  • applied_on Selection
    default='3_global' help='Pricelist Item applicable on selected option' required=True selection=[('3_global', 'All Products'), ('2_product_category', 'Product Category'), ('1_product', 'Product'), ('0_product_variant', 'Product Variant')] string='Apply On'
  • base Selection
    default='list_price' help='Base price for computation.\nSales Price: The base price will be the Sales Price.\nCost Price: The base price will be the cost price.\nOther Pricelist: Computation of the base price based on another Pricelist.' required=True selection=[('list_price', 'Sales Price'), ('standard_price', 'Cost'), ('pricelist', 'Other Pricelist')] string='Based on'
  • base_pricelist_id Many2one → product.pricelist
    check_company=True args: 'product.pricelist', 'Other Pricelist'
  • categ_id Many2one → product.category
    comodel_name='product.category' help='Specify a product category if this rule only applies to products belonging to this category or its children categories. Keep empty otherwise.' ondelete='cascade' string='Category'
  • company_id Many2one → res.company
    comodel_name='res.company' compute='_compute_company_id' store=True
  • compute_price Selection
    default='fixed' help='Use the discount rules and activate the discount settings in order to show discount to customer.' index=True required=True selection=[('percentage', 'Discount'), ('formula', 'Formula'), ('fixed', 'Fixed Price')]
  • currency_id Many2one → res.currency
    comodel_name='res.currency' compute='_compute_currency_id' store=True
  • date_end Datetime
    help='Ending datetime for the pricelist item validation\nThe displayed value depends on the timezone set in your preferences.' string='End Date'
  • date_start Datetime
    help='Starting datetime for the pricelist item validation\nThe displayed value depends on the timezone set in your preferences.' string='Start Date'
  • display_applied_on Selection
    default='1_product' help='Pricelist Item applicable on selected option' required=True selection=[('1_product', 'Product'), ('2_product_category', 'Category')]
  • fixed_price Float
    min_display_digits='Product Price' string='Fixed Price'
  • is_pricelist_required Boolean
    compute='_compute_is_pricelist_required'
  • min_quantity Float
    default=0 digits='Product Unit' help='For the rule to apply, bought/sold quantity must be greater than or equal to the minimum quantity specified in this field.\nExpressed in the default unit of measure of the product.' string='Min. Quantity'
  • name Char
    compute='_compute_name' help='Explicit rule name for this pricelist line.' string='Name'
  • percent_price Float
    help='You can apply a mark-up by setting a negative discount.' string='Percentage Price'
  • price Char
    compute='_compute_price_label' help='Explicit rule name for this pricelist line.' string='Price'
  • price_discount Float
    default=0 digits=(16, 2) help='You can apply a mark-up by setting a negative discount.' string='Price Discount'
  • price_markup Float
    compute='_compute_price_markup' digits=(16, 2) help='You can apply a mark-up on the cost' inverse='_inverse_price_markup' store=True string='Markup'
  • price_max_margin Float
    help='Specify the maximum amount of margin over the base price.' min_display_digits='Product Price' string='Max. Price Margin'
  • price_min_margin Float
    help='Specify the minimum amount of margin over the base price.' min_display_digits='Product Price' string='Min. Price Margin'
  • price_round Float
    help='Sets the price so that it is a multiple of this value.\nRounding is applied after the discount and before the surcharge.\nTo have prices that end in 9.99, round off to 10.00 and set an extra at -0.01' min_display_digits='Product Price' string='Price Rounding'
  • price_surcharge Float
    help='Specify the fixed amount to add or subtract (if negative) to the amount calculated with the discount.' min_display_digits='Product Price' string='Extra Fee'
  • pricelist_id Many2one → product.pricelist
    comodel_name='product.pricelist' default=_default_pricelist_id index=True ondelete='cascade' required=False string='Pricelist'
  • product_id Many2one → product.product
    check_company=True comodel_name='product.product' domain="[('product_tmpl_id', '=', product_tmpl_id)]" help='Specify a product if this rule only applies to one product. Keep empty otherwise.' index='btree_not_null' ondelete='cascade' string='Variant'
  • product_tmpl_id Many2one → product.template
    check_company=True comodel_name='product.template' help='Specify a template if this rule only applies to one product template. Keep empty otherwise.' index='btree_not_null' ondelete='cascade' string='Product'
  • product_uom_name Char
    related='product_tmpl_id.uom_name'
  • product_variant_count Integer
    related='product_tmpl_id.product_variant_count'
  • rule_tip Char
    compute='_compute_rule_tip'
Public methods (2)
  • create(self, vals_list)
    @api.model_create_multi
  • write(self, vals)

New fields (37)
  • active Boolean
    default=True help='If unchecked, it will allow you to hide the product without removing it.' args: 'Active'
  • additional_product_tag_ids Many2many → product.tag
    comodel_name='product.tag' domain="[('id', 'not in', product_tag_ids)]" relation='product_tag_product_product_rel' string='Variant Tags'
  • all_product_tag_ids Many2many → product.tag
    compute='_compute_all_product_tag_ids' search='_search_all_product_tag_ids' args: 'product.tag'
  • barcode Char
    copy=False help='International Article Number used for product identification.' index='btree_not_null' args: 'Barcode'
  • can_image_1024_be_zoomed Boolean
    compute='_compute_can_image_1024_be_zoomed' args: 'Can Image 1024 be zoomed'
  • can_image_variant_1024_be_zoomed Boolean
    compute='_compute_can_image_variant_1024_be_zoomed' store=True args: 'Can Variant Image 1024 be zoomed'
  • code Char
    compute='_compute_product_code' args: 'Reference'
  • combination_indices Char
    compute='_compute_combination_indices' index=True store=True
  • default_code Char
    index=True args: 'Internal Reference'
  • image_1024 Image
    compute='_compute_image_1024' args: 'Image 1024'
  • image_128 Image
    compute='_compute_image_128' args: 'Image 128'
  • image_1920 Image
    compute='_compute_image_1920' inverse='_set_image_1920' args: 'Image'
  • image_256 Image
    compute='_compute_image_256' args: 'Image 256'
  • image_512 Image
    compute='_compute_image_512' args: 'Image 512'
  • image_variant_1024 Image
    max_height=1024 max_width=1024 related='image_variant_1920' store=True args: 'Variant Image 1024'
  • image_variant_128 Image
    max_height=128 max_width=128 related='image_variant_1920' store=True args: 'Variant Image 128'
  • image_variant_1920 Image
    max_height=1920 max_width=1920 args: 'Variant Image'
  • image_variant_256 Image
    max_height=256 max_width=256 related='image_variant_1920' store=True args: 'Variant Image 256'
  • image_variant_512 Image
    max_height=512 max_width=512 related='image_variant_1920' store=True args: 'Variant Image 512'
  • import_attribute_values Char
    compute='_compute_import_attribute_values' copy=False inverse='_inverse_import_attribute_values' store=False string='Product Values'
  • is_favorite Boolean
    readonly=False related='product_tmpl_id.is_favorite' store=True
  • is_in_selected_section_of_order Boolean
    search='_search_is_in_selected_section_of_order'
  • is_product_variant Boolean
    compute='_compute_is_product_variant'
  • lst_price Float
    compute='_compute_product_lst_price' help="The sale price is managed from the product template. Click on the 'Configure Variants' button to set the extra attribute prices." inverse='_set_product_lst_price' min_display_digits='Product Price' args: 'Sales\xa0Price'
  • partner_ref Char
    compute='_compute_partner_ref' args: 'Customer Ref'
  • price_extra Float
    compute='_compute_product_price_extra' help='This is the sum of the extra price of all attributes' min_display_digits='Product Price' args: 'Variant Price Extra'
  • pricelist_rule_ids One2many → product.pricelist.item
    comodel_name='product.pricelist.item' compute='_compute_pricelist_rule_ids' inverse='_inverse_pricelist_rule_ids' inverse_name='product_id' readonly=False string='Pricelist Rules'
  • product_document_count Integer
    compute='_compute_product_document_count' string='Documents Count'
  • product_document_ids One2many → product.document
    comodel_name='product.document' domain=<expr> inverse_name='res_id' string='Documents'
  • product_template_attribute_value_ids Many2many → product.template.attribute.value
    ondelete='restrict' relation='product_variant_combination' string='Attribute Values' args: 'product.template.attribute.value'
  • product_template_variant_value_ids Many2many → product.template.attribute.value
    domain=[('attribute_line_id.value_count', '>', 1)] ondelete='restrict' relation='product_variant_combination' string='Variant Values' args: 'product.template.attribute.value'
  • product_tmpl_id Many2one → product.template
    bypass_search_access=True index=True ondelete='cascade' required=True args: 'product.template', 'Product Template'
  • product_uom_ids One2many → product.uom
    store=True args: 'product.uom', 'product_id', 'Unit Barcode'
  • standard_price Float
    company_dependent=True groups='base.group_user' help='Value of the product (automatically computed in AVCO).\n Used to value the product when the purchase cost is not known (e.g. inventory adjustment).\n Used to compute margins on sale orders.' min_display_digits='Product Price' args: 'Cost'
  • volume Float
    digits='Volume' args: 'Volume'
  • weight Float
    digits='Stock Weight' args: 'Weight'
  • write_date Datetime
    compute='_compute_write_date' store=True
Public methods (15)
  • action_archive(self)
  • action_open_documents(self)
    @api.readonly
  • action_open_label_layout(self)
    @api.readonly
  • action_unarchive(self)
  • copy(self, default=None)
    Variants are generated depending on the configuration of attributes and values on the template, so copying them does not make sense. For convenience the template is copied instead and its first variant is returned.
  • create(self, vals_list)
    @api.model_create_multi
  • get_contextual_price(self)
  • get_empty_list_help(self, help_message)
    @api.model
  • get_product_multiline_description_sale(self)
    Compute a multiline description of this product, in the context of sales (do not use for purchases or other display reasons that don't intend to use "description_sale"). It will often be used as the default description of a sale order line referencing this product.
  • load(self, fields, data)
    @api.model
  • name_search(self, name='', domain=None, operator='ilike', limit=100)
    @api.model
  • open_product_template(self)
    Utility method used to add an "Open Template" button in product views
  • unlink(self)
  • view_header_get(self, view_id, view_type)
    @api.model
  • write(self, vals)

New fields (17)
  • company_id Many2one → res.company
    default=<expr> index=1 args: 'res.company', 'Company'
  • currency_id Many2one → res.currency
    default=<expr> required=True args: 'res.currency', 'Currency'
  • date_end Date
    help='End date for this vendor price' args: 'End Date'
  • date_start Date
    help='Start date for this vendor price' args: 'Start Date'
  • delay Integer
    default=1 help='Lead time in days between the confirmation of the purchase order and the receipt of the products in your warehouse. Used by the scheduler for automatic computation of the purchase order planning.' required=True args: 'Lead Time'
  • discount Float
    digits='Discount' readonly=False string='Discount (%)'
  • min_qty Float
    default=0.0 digits='Product Unit' help='The quantity to purchase from this vendor to benefit from the unit price. If a vendor unit is set, quantity should be specified in this unit, otherwise it should be specified in the default unit of the product.' required=True args: 'Quantity'
  • partner_id Many2one → res.partner
    check_company=True ondelete='cascade' required=True args: 'res.partner', 'Vendor'
  • price Float
    default=0.0 help='The price to purchase a product' min_display_digits='Product Price' args: 'Unit Price'
  • price_discounted Float
    compute='_compute_price_discounted' args: 'Discounted Price'
  • product_code Char
    help="This vendor's product code will be used when printing a request for quotation. Keep empty to use the internal one." args: 'Vendor Product Code'
  • product_id Many2one → product.product
    check_company=True compute='_compute_product_id' domain="[('product_tmpl_id', '=', product_tmpl_id)] if product_tmpl_id else []" help='If not set, the vendor price will apply to all variants of this product.' precompute=True readonly=False store=True args: 'product.product', 'Product Variant'
  • product_name Char
    help="This vendor's product name will be used when printing a request for quotation. Keep empty to use the internal one." args: 'Vendor Product Name'
  • product_tmpl_id Many2one → product.template
    check_company=True compute='_compute_product_tmpl_id' index=True ondelete='cascade' precompute=True readonly=False required=True store=True args: 'product.template', 'Product Template'
  • product_uom_id Many2one → uom.uom
    compute='_compute_product_uom_id' precompute=True readonly=False required=True store=True args: 'uom.uom', 'Unit'
  • product_variant_count Integer
    related='product_tmpl_id.product_variant_count' args: 'Variant Count'
  • sequence Integer
    default=1 help='Assigns the priority to the list of product vendor.' args: 'Sequence'
Public methods (3)
  • create(self, vals_list)
    @api.model_create_multi
  • get_import_templates(self)
    @api.model
  • write(self, vals)

New fields (8)
  • color Char
    default='#3C3C3C' string='Color'
  • image Image
    max_height=200 max_width=200 string='Image'
  • name Char
    required=True string='Name' translate=True
  • product_ids Many2many → product.product
    compute='_compute_product_ids' search='_search_product_ids' string='All Product Variants using this Tag' args: 'product.product'
  • product_product_ids Many2many → product.product
    comodel_name='product.product' default=_get_default_variant_id domain="[('attribute_line_ids', '!=', False), ('product_tmpl_id', 'not in', product_template_ids)]" relation='product_tag_product_product_rel' string='Product Variants'
  • product_template_ids Many2many → product.template
    comodel_name='product.template' default=_get_default_template_id relation='product_tag_product_template_rel' string='Product Templates'
  • sequence Integer
    default=10
  • visible_to_customers Boolean
    default=True help='Whether the tag is displayed to customers.' string='Visible to customers'
Public methods (1)
  • copy_data(self, default=None)

New fields (46)
  • active Boolean
    default=True help='If unchecked, it will allow you to hide the product without removing it.' args: 'Active'
  • attribute_line_ids One2many → product.template.attribute.line
    copy=True args: 'product.template.attribute.line', 'product_tmpl_id', 'Product Attributes'
  • barcode Char
    compute='_compute_barcode' inverse='_set_barcode' search='_search_barcode' args: 'Barcode'
  • can_image_1024_be_zoomed Boolean
    compute='_compute_can_image_1024_be_zoomed' store=True args: 'Can Image 1024 be zoomed'
  • categ_id Many2one → product.category
    comodel_name='product.category' group_expand='_read_group_categ_id' string='Product Category' tracking=True
  • color Integer
    args: 'Color Index'
  • combo_ids Many2many → product.combo
    check_company=True comodel_name='product.combo' string='Combo Choices'
  • company_id Many2one → res.company
    index=True args: 'res.company', 'Company'
  • cost_currency_id Many2one → res.currency
    compute='_compute_cost_currency_id' args: 'res.currency', 'Cost Currency'
  • currency_id Many2one → res.currency
    compute='_compute_currency_id' args: 'res.currency', 'Currency'
  • default_code Char
    compute='_compute_default_code' inverse='_set_default_code' store=True args: 'Internal Reference'
  • description Html
    translate=True args: 'Description'
  • description_purchase Text
    translate=True args: 'Purchase Description'
  • description_sale Text
    help='A description of the Product that you want to communicate to your customers. This description will be copied to every Sales Order, Delivery Order and Customer Invoice/Credit Note' translate=True args: 'Sales Description'
  • has_configurable_attributes Boolean
    compute='_compute_has_configurable_attributes' store=True args: 'Is a configurable product'
  • import_attribute_values Char
    compute='_compute_import_attribute_values' copy=False inverse='_inverse_import_attribute_values' store=False string='Product Values'
  • is_dynamically_created Boolean
    compute='_compute_is_dynamically_created' args: 'Is Dynamically Created'
  • is_favorite Boolean
    string='Favorite'
  • is_product_variant Boolean
    compute='_compute_is_product_variant' string='Is a product variant'
  • list_price Float
    default=1.0 help='Price at which the product is sold to customers.' min_display_digits='Product Price' tracking=True args: 'Sales Price'
  • name Char
    index='trigram' required=True translate=True args: 'Name'
  • pricelist_rule_ids One2many → product.pricelist.item
    comodel_name='product.pricelist.item' domain=<expr> inverse_name='product_tmpl_id' string='Pricelist Rules'
  • product_document_count Integer
    compute='_compute_product_document_count' string='Documents Count'
  • product_document_ids One2many → product.document
    comodel_name='product.document' domain=<expr> inverse_name='res_id' string='Documents'
  • product_properties Properties
    copy=True definition='categ_id.product_properties_definition' args: 'Properties'
  • product_tag_ids Many2many → product.tag
    comodel_name='product.tag' relation='product_tag_product_template_rel' string='Tags'
  • product_tooltip Char
    compute='_compute_product_tooltip'
  • product_variant_count Integer
    compute='_compute_product_variant_count' args: '# Product Variants'
  • product_variant_id Many2one → product.product
    compute='_compute_product_variant_id' args: 'product.product', 'Product'
  • product_variant_ids One2many → product.product
    required=True args: 'product.product', 'product_tmpl_id', 'Products'
  • purchase_ok Boolean
    compute='_compute_purchase_ok' default=True readonly=False store=True args: 'Purchase'
  • sale_ok Boolean
    default=True args: 'Sales'
  • seller_ids One2many → product.supplierinfo
    depends_context=('company') args: 'product.supplierinfo', 'product_tmpl_id', 'Vendors'
  • sequence Integer
    default=1 help='Gives the sequence order when displaying a product list' args: 'Sequence'
  • service_tracking Selection
    compute='_compute_service_tracking' default='no' readonly=False required=True selection=[('no', 'Nothing')] store=True string='Create on Order'
  • standard_price Float
    compute='_compute_standard_price' groups='base.group_user' help='Value of the product (automatically computed in AVCO).\n Used to value the product when the purchase cost is not known (e.g. inventory adjustment).\n Used to compute margins on sale orders.' inverse='_set_standard_price' min_display_digits='Product Price' search='_search_standard_price' args: 'Cost'
  • type Selection
    default='consu' help='Goods are tangible materials and merchandise you provide.\nA service is a non-material product you provide.' required=True selection=[('consu', 'Goods'), ('service', 'Service'), ('combo', 'Combo')] string='Product Type'
  • uom_id Many2one → uom.uom
    default=_get_default_uom_id help='Default unit of measure used for all stock operations.' required=True tracking=True args: 'uom.uom', 'Unit'
  • uom_ids Many2many → uom.uom
    domain="[('id', '!=', uom_id)]" help='Additional packagings for this product which can be used for sales' string='Packagings' args: 'uom.uom'
  • uom_name Char
    readonly=True related='uom_id.name' string='Unit Name'
  • valid_product_template_attribute_line_ids Many2many → product.template.attribute.line
    compute='_compute_valid_product_template_attribute_line_ids' string='Valid Product Attribute Lines' args: 'product.template.attribute.line'
  • variant_seller_ids One2many → product.supplierinfo
    args: 'product.supplierinfo', 'product_tmpl_id'
  • volume Float
    compute='_compute_volume' digits='Volume' inverse='_set_volume' store=True args: 'Volume'
  • volume_uom_name Char
    compute='_compute_volume_uom_name' string='Volume unit of measure label'
  • weight Float
    compute='_compute_weight' digits='Stock Weight' inverse='_set_weight' store=True args: 'Weight'
  • weight_uom_name Char
    compute='_compute_weight_uom_name' string='Weight unit of measure label'
Public methods (14)
  • action_open_documents(self)
    @api.readonly
  • action_open_label_layout(self)
  • copy(self, default=None)
  • copy_data(self, default=None)
  • create(self, vals_list)
    @api.model_create_multi
    Store the initial standard price in order to be able to retrieve the cost of a product template for a given date
  • default_get(self, fields)
    @api.model
  • get_contextual_price(self, product=None)
  • get_empty_list_help(self, help_message)
    @api.model
  • get_import_templates(self)
    @api.model
  • get_single_product_variant(self)
    Method used by the product configurator to check if the product is configurable or not. We need to open the product configurator if the product: - is configurable (see has_configurable_attributes) - has optional products (method is extended in sale to return optional products info) Note: self.ensure_one()
  • has_dynamic_attributes(self)
    Return whether this `product.template` has at least one dynamic attribute. :return: True if at least one dynamic attribute, False otherwise :rtype: bool
  • load(self, fields, data)
    @api.model
    Data import for products depends on the presence of variants. If 'import_attribute_values' is present, then the product.template files will be created, followed by the product.product files. Everything is done from the same file. The required fields are always imported; however, other fields are imported when the product.product files are created.
  • name_search(self, name='', domain=None, operator='ilike', limit=100)
    @api.model
  • write(self, vals)

New fields (3)
  • product_template_attribute_value_id Many2one → product.template.attribute.value
    comodel_name='product.template.attribute.value' index=True ondelete='cascade' string='Attribute Value'
  • product_tmpl_id Many2one → product.template
    comodel_name='product.template' index=True ondelete='cascade' required=True string='Product Template'
  • value_ids Many2many → product.template.attribute.value
    comodel_name='product.template.attribute.value' domain="[('product_tmpl_id', '=', product_tmpl_id), ('ptav_active', '=', True)]" relation='product_attr_exclusion_value_ids_rel' string='Attribute Values'
Public methods (3)
  • create(self, vals_list)
    @api.model_create_multi
  • unlink(self)
  • write(self, vals)

New fields (7)
  • active Boolean
    default=True
  • attribute_id Many2one → product.attribute
    comodel_name='product.attribute' index=True ondelete='restrict' required=True string='Attribute'
  • product_template_value_ids One2many → product.template.attribute.value
    comodel_name='product.template.attribute.value' inverse_name='attribute_line_id' string='Product Attribute Values'
  • product_tmpl_id Many2one → product.template
    comodel_name='product.template' index=True ondelete='cascade' required=True string='Product Template'
  • sequence Integer
    default=10 args: 'Sequence'
  • value_count Integer
    compute='_compute_value_count' store=True
  • value_ids Many2many → product.attribute.value
    comodel_name='product.attribute.value' domain="[('attribute_id', '=', attribute_id)]" ondelete='restrict' relation='product_attribute_value_product_template_attribute_line_rel' string='Values'
Public methods (4)
  • action_open_attribute_values(self)
    @api.readonly
  • create(self, vals_list)
    @api.model_create_multi
    Override to: - Activate archived lines having the same configuration (if they exist) instead of creating new lines. - Set up related values and related variants. Reactivating existing lines allows to re-use existing variants when possible, keeping their configuration and avoiding duplication.
  • unlink(self)
    Override to: - Archive the line if unlink is not possible. - Clean up related values and related variants. Archiving is typically needed when the line has values that can't be deleted because they are referenced elsewhere (on a variant that can't be deleted, on a sales order line, ...).
  • write(self, vals)
    Override to: - Add constraints to prevent doing changes that are not supported such as modifying the template or the attribute of existing lines. - Clean up related values and related variants when archiving or when updating `value_ids`.

New fields (15)
  • attribute_id Many2one
    index=True related='attribute_line_id.attribute_id' store=True
  • attribute_line_id Many2one → product.template.attribute.line
    comodel_name='product.template.attribute.line' index=True ondelete='cascade' required=True
  • color Integer
    default=_get_default_color string='Color'
  • currency_id Many2one
    related='attribute_line_id.product_tmpl_id.currency_id'
  • display_type Selection
    related='product_attribute_value_id.display_type'
  • exclude_for One2many → product.template.attribute.exclusion
    comodel_name='product.template.attribute.exclusion' help='Make this attribute value not compatible with other values of the product or some attribute values of optional and accessory products.' inverse_name='product_template_attribute_value_id' string='Exclude for'
  • html_color Char
    related='product_attribute_value_id.html_color' string='HTML Color Index'
  • image Image
    related='product_attribute_value_id.image'
  • is_custom Boolean
    related='product_attribute_value_id.is_custom'
  • name Char
    related='product_attribute_value_id.name' string='Value'
  • price_extra Float
    default=0.0 help='Extra price for the variant with this attribute value on sale price. eg. 200 price extra, 1000 + 200 = 1200.' min_display_digits='Product Price' string='Extra Price'
  • product_attribute_value_id Many2one → product.attribute.value
    comodel_name='product.attribute.value' index=True ondelete='cascade' required=True string='Attribute Value'
  • product_tmpl_id Many2one
    index=True related='attribute_line_id.product_tmpl_id' store=True
  • ptav_active Boolean
    default=True string='Active'
  • ptav_product_variant_ids Many2many → product.product
    comodel_name='product.product' readonly=True relation='product_variant_combination' string='Related Variants'
Public methods (3)
  • create(self, vals_list)
    @api.model_create_multi
  • unlink(self)
    Override to: - Clean up the variants that use any of the values in self: - Remove the value from the variant if the value belonged to an attribute line with only one value. - Unlink or archive all related variants. - Archive the value if unlink is not possible. Archiving is typically needed when the value is referenced elsewhere (on a variant that can't be deleted, on a sales order line, ...).
  • write(self, vals)

New fields (4)
  • barcode Char
    copy=False index='btree_not_null' required=True
  • company_id Many2one → res.company
    default=<expr> args: 'res.company', 'Company'
  • product_id Many2one → product.product
    index=True ondelete='cascade' required=True args: 'product.product', 'Product'
  • uom_id Many2one → uom.uom
    index=True ondelete='cascade' required=True args: 'uom.uom', 'Unit'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (1)
  • get_html(self, data)
    @api.readonly@api.model

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (2)
  • create(self, vals_list)
    @api.model_create_multi
  • write(self, vals)
    Delay the automatic creation of pricelists post-company update. This makes sure that the pricelist(s) automatically created are created with the right currency.

New fields (6)
  • group_product_pricelist Boolean
    implied_group='product.group_product_pricelist' args: 'Pricelists'
  • group_product_variant Boolean
    implied_group='product.group_product_variant' args: 'Variants'
  • group_uom Boolean
    implied_group='uom.group_uom' args: 'Units of Measure & Packagings'
  • module_loyalty Boolean
    args: 'Promotions, Coupons, Gift Card & Loyalty Program'
  • product_volume_volume_in_cubic_feet Selection
    config_parameter='product.volume_in_cubic_feet' default='0' args: [('0', 'Cubic Meters (m³)'), ('1', 'Cubic Feet (ft³)')], 'Volume unit of measure'
  • product_weight_in_lbs Selection
    config_parameter='product.weight_in_lbs' default='0' args: [('0', 'Kilograms (kg)'), ('1', 'Pounds (lb)')], 'Weight unit of measure'
Public methods (1)
  • set_values(self)

New fields (1)
  • pricelist_ids Many2many → product.pricelist
    column1='res_country_group_id' column2='pricelist_id' comodel_name='product.pricelist' relation='res_country_group_pricelist_rel' string='Pricelists'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (1)
  • write(self, vals)
    Archive pricelist when the linked currency is archived.

New fields (2)
  • property_product_pricelist Many2one → product.pricelist
    comodel_name='product.pricelist' company_dependent=False compute='_compute_product_pricelist' domain=<expr> help='Used for sales to the current partner' inverse='_inverse_product_pricelist' string='Pricelist'
  • specific_property_product_pricelist Many2one → product.pricelist
    comodel_name='product.pricelist' company_dependent=True
Public methods (0)

No public methods.

New fields (1)
  • product_uom_ids One2many → product.uom
    domain=_domain_product_uoms string='Barcodes' args: 'product.uom', 'uom_id'
Public methods (1)
  • action_open_packaging_barcodes(self)

New fields (4)
  • attribute_value_id Many2one → product.attribute.value
    required=True args: 'product.attribute.value'
  • message Char
    compute='_compute_message'
  • mode Selection
    selection=[('add', 'Add to existing products'), ('update_extra_price', 'Update the extra price on existing products')]
  • product_count Integer
    compute='_compute_product_count'
Public methods (1)
  • action_confirm(self)
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/18.0/product
VERSION
VERSION 1.2
CATEGORY
CATEGORYSales/Sales
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Martin Trigaux, Fabien Pinckaers, Xavier Morel, Atul Patel, Aaron Bohy, Damien Bouvy, Yannick Tivisse, Odoo Online, Romain Derie, Arnold Moyaux, Xavier-Do, Victor Feyens, Andrea Grazioso (agr-odoo), William Henrotin, svs-odoo, Lois Rilo, Brice bib Bartoletti, Prakash Prajapati, Tiffany Chang (tic), Rémy Voet (ryv), Gorash, Mathieu Duckerts-Antoine, Pierre Paridans, Miquel Raïch, william-andre, Víctor Martínez, Bruno Zanotti, Antoine Vandevenne (anv), Aurelien van Delft (avd), Mathieu Walravens, Valentin Chevalier, Vincent Larcin, niyasraphy, David Monnom (moda), alsh-odoo, Louis Wicket (wil), David, Victor Piryns (pivi), Mahamadasif Ansari, Gauthier Wala (gawa), pash-odoo, Levi Siuzdak (sile), Dylan Kiss (dyki), Antoine (ande), Valeriya(vchu), Chong Wang (cwg), Martin Maes, Anita (anko), Xavier Bol (xbo), Brieuc-brd, SilvioC2C, Paweł Fertyk, Sarah Bellefroid, Louis Travaux, Arnaud Sibille, omra-odoo, Walid (wasa), Paul Stroobant, Adam Heinz, Hesham, Youssef Bashandy, Ethan Vincent, lase@odoo.com, Benjamin Hanquin (beha), Maryam Kia, Louis (loti), axtr, reka-odoo, Nathaniel (naja), vava-odoo, kcv-odoo, odoostan, adsh-odoo, mega, dere-odoo, Lina (liew), sami odoo, Louis (wil), Aungkokolin1997, manv-afk, mathysPaul, Sanchit Gupta, Mohammad Abdulmoneim, Ryan Cen, gteboul, Antoine (anso), sabr, Manushi Shah, Léo Gizard, Julien Schwanen, Victor Miguel Armenta Carrillo, sben-odoo, Christopher Maloney (cmal), David Van Droogenbroeck (DROD), djameltouati, khsr-odoo, Lucas Lefèvre (lul), Pierre Pulinckx (pipu), laro-odoo, Bastien PIERRE, jeep-odoo, kasm, Carmine, Shrey Mehta, Bastien (bvdn), chha-odoo, MaximeNoirhomme, Vincent Sevestre, plha-odoo, Krzysztof Magusiak (krma), rupa-odoo, PaoloYam, Marie Lejeune, Matias Peralta, krip-odoo, Rushil Patel, mohannedah, Lulu Grimalkin (lugr), sjai-odoo, Laurent Smet (LAS), rkka-odoo, Samiul Hoque, shrm-odoo, Kamran Poladov, Przemysław Duryło, vagu-odoo
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 01:25:58
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - html_editor
    - uom
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
This is the base module for managing products and pricelists in Odoo.
========================================================================

Products support variants, different pricing methods, vendors information,
make to stock/order, different units of measure, packaging and properties.

Pricelists support:
-------------------
    * Multiple-level of discount (by product, category, quantities)
    * Compute price based on different criteria:
        * Other pricelist
        * Cost price
        * List price
        * Vendor price

Pricelists preferences by product and/or partners.

Print product labels with barcode.
    

Code Analysis

Views touched (74)
XML IDNameModelTypeStatus
attribute_tree_view product.attribute.list product.attribute list New
inherits_website_sale_country_group_form res.country.group.form.inherit.product res.country.group group Inherits base.view_country_group_form
product.product_combo_view_form product.combo.form product.combo form New
product.product_combo_view_tree product.combo.list product.combo list New
product_attribute_search product.attribute.view.search product.attribute search New
product_attribute_value_list product.attribute.value.list product.attribute.value list New
product_attribute_view_form product.attribute.form product.attribute form New
product_category_form_view product.category.form product.category form New
product_category_list_view product.category.list product.category list New
product_category_search_view product.category.search product.category search New
product_document_form product.document.form product.document form New
product_document_kanban product.document.kanban product.document kanban New
product_document_list product.document.list product.document list New
product_document_search product.document.search product.document search New
product_kanban_view Product Kanban product.product kanban New
product_label_layout_form product.label.layout.form product.label.layout form New
product_normal_form_view product.product.form product.product form Inherits product.product_template_form_view
product_packaging_form_view product.packaging.form.view product.packaging form New
product_packaging_form_view2 product.packaging.form.view2 product.packaging xpath Inherits product.product_packaging_form_view
product_packaging_search_view product.packaging.search product.packaging search New
product_packaging_tree_view product.packaging.list.view product.packaging list New
product_packaging_tree_view2 product.packaging.list.view2 product.packaging xpath Inherits product.product_packaging_tree_view
product_pricelist_item_form_view product.pricelist.item.form product.pricelist.item form New
product_pricelist_item_tree_view product.pricelist.item.list product.pricelist.item list New
product_pricelist_item_tree_view_from_product product.pricelist.item.list product.pricelist.item list New
product_pricelist_item_view_search product.pricelist.item.search product.pricelist.item search New
product_pricelist_view product.pricelist.form product.pricelist form New
product_pricelist_view_kanban product.pricelist.kanban product.pricelist kanban New
product_pricelist_view_search product.pricelist.search product.pricelist search New
product_pricelist_view_tree product.pricelist.list product.pricelist list New
product_product_tree_view product.product.list product.product list New
product_product_view_activity product.product.activity product.product activity New
product_product_view_form_normalized product.product.view.form.normalized product.product form New
product_product_view_tree_tag product.product.view.list.tag product.product list New
product_search_form_view product.product.search product.product field Inherits product.product_template_search_view
product_supplierinfo_form_view product.supplierinfo.form.view product.supplierinfo form New
product_supplierinfo_search_view product.supplierinfo.search.view product.supplierinfo search New
product_supplierinfo_tree_view product.supplierinfo.list.view product.supplierinfo list New
product_supplierinfo_view_kanban product.supplierinfo.kanban product.supplierinfo kanban New
product_tag_form_view product.tag.form product.tag form New
product_tag_tree_view product.tag.list product.tag list New
product_template_attribute_line_form product.template.attribute.line.form product.template.attribute.line form New
product_template_attribute_line_view_tree product.template.attribute.line.view.list product.template.attribute.line list New
product_template_attribute_value_view_form product.template.attribute.value.view.form. product.template.attribute.value form New
product_template_attribute_value_view_search product.template.attribute.value search New
product_template_attribute_value_view_tree product.template.attribute.value.view.list product.template.attribute.value list New
product_template_form_view product.template.common.form product.template form New
product_template_kanban_view Product.template.product.kanban product.template kanban New
product_template_only_form_view product.template.product.form product.template xpath Inherits product.product_template_form_view
product_template_search_view product.template.search product.template search New
product_template_tree_view product.template.product.list product.template list New
product_template_view_activity product.template.activity product.template activity New
product_template_view_tree_tag product.template.view.list.tag product.template list New
product_variant_easy_edit_view product.product.view.form.easy product.product form New
product_view_kanban_catalog product.view.kanban.catalog product.product kanban New
product_view_search_catalog product.view.search.catalog product.product search New
report_packagingbarcode report_packagingbarcode ir.ui.view qweb New
report_pricelist report_pricelist ir.ui.view qweb New
report_pricelist_page report_pricelist_page ir.ui.view qweb New
report_productlabel report_productlabel ir.ui.view qweb New
report_productlabel_dymo report_productlabel_dymo ir.ui.view qweb New
report_producttemplatelabel2x7 report_producttemplatelabel2x7 ir.ui.view qweb New
report_producttemplatelabel4x12 report_producttemplatelabel4x12 ir.ui.view qweb New
report_producttemplatelabel4x12noprice report_producttemplatelabel4x12noprice ir.ui.view qweb New
report_producttemplatelabel4x7 report_producttemplatelabel4x7 ir.ui.view qweb New
report_producttemplatelabel_dymo report_producttemplatelabel_dymo ir.ui.view qweb New
report_simple_label2x7 report_simple_label2x7 ir.ui.view qweb New
report_simple_label4x12 report_simple_label4x12 ir.ui.view qweb New
report_simple_label4x12_no_price report_simple_label4x12_no_price ir.ui.view qweb New
report_simple_label4x7 report_simple_label4x7 ir.ui.view qweb New
report_simple_label_dymo report_simple_label_dymo ir.ui.view qweb New
res_config_settings_view_form res.config.settings.view.form.inherit.product res.config.settings xpath Inherits base_setup.res_config_settings_view_form
update_product_attribute_value_form update.product.attribute.value.form update.product.attribute.value form New
view_partner_property_form res.partner.product.property.form.inherit res.partner group Inherits base.view_partner_form
Models touched (34)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (1)
  • create(self, vals_list)
    @api.model_create_multi
    Create product.document for attachments added in products chatters

New fields (10)
  • active Boolean
    default=True help='If unchecked, it will allow you to hide the attribute without removing it.'
  • attribute_line_ids One2many → product.template.attribute.line
    comodel_name='product.template.attribute.line' inverse_name='attribute_id' string='Lines'
  • create_variant Selection
    default='always' help='- Instantly: All possible variants are created as soon as the attribute and its values are added to a product.\n - Dynamically: Each variant is created only when its corresponding attributes and values are added to a sales order.\n - Never: Variants are never created for the attribute.\n Note: this cannot be changed once the attribute is used on a product.' required=True selection=[('always', 'Instantly'), ('dynamic', 'Dynamically'), ('no_variant', 'Never')] string='Variant Creation'
  • display_type Selection
    default='radio' help='The display type used in the Product Configurator.' required=True selection=[('radio', 'Radio'), ('pills', 'Pills'), ('select', 'Select'), ('color', 'Color'), ('multi', 'Multi-checkbox')]
  • name Char
    required=True string='Attribute' translate=True
  • number_related_products Integer
    compute='_compute_number_related_products'
  • product_tmpl_ids Many2many → product.template
    comodel_name='product.template' compute='_compute_products' store=True string='Related Products'
  • sequence Integer
    default=20 help='Determine the display order' index=True string='Sequence'
  • template_value_ids One2many → product.template.attribute.value
    comodel_name='product.template.attribute.value' inverse_name='attribute_id' string='Template Values'
  • value_ids One2many → product.attribute.value
    comodel_name='product.attribute.value' copy=True inverse_name='attribute_id' string='Values'
Public methods (3)
  • action_archive(self)
  • action_open_product_template_attribute_lines(self)
  • write(self, vals)
    Override to make sure attribute type can't be changed if it's used on a product template. This is important to prevent because changing the type would make existing combinations invalid without recomputing them, and recomputing them might take too long and we don't want to change products without the user knowing about it.

New fields (3)
  • custom_product_template_attribute_value_id Many2one → product.template.attribute.value
    comodel_name='product.template.attribute.value' ondelete='restrict' required=True string='Attribute Value'
  • custom_value Char
    string='Custom Value'
  • name Char
    compute='_compute_name' string='Name'
Public methods (0)

No public methods.

New fields (13)
  • active Boolean
    default=True
  • attribute_id Many2one → product.attribute
    comodel_name='product.attribute' help='The attribute cannot be changed once the value is used on at least one product.' index=True ondelete='cascade' required=True string='Attribute'
  • color Integer
    default=_get_default_color string='Color Index'
  • default_extra_price Float
  • default_extra_price_changed Boolean
    compute='_compute_default_extra_price_changed'
  • display_type Selection
    related='attribute_id.display_type'
  • html_color Char
    help="Here you can set a specific HTML color index (e.g. #ff0000) to display the color if the attribute type is 'Color'." string='Color'
  • image Image
    help='You can upload an image that will be used as the color of the attribute value.' max_height=70 max_width=70 string='Image'
  • is_custom Boolean
    help='Allow customers to set their own value' string='Free text'
  • is_used_on_products Boolean
    compute='_compute_is_used_on_products' string='Used on Products'
  • name Char
    required=True string='Value' translate=True
  • pav_attribute_line_ids Many2many → product.template.attribute.line
    comodel_name='product.template.attribute.line' copy=False relation='product_attribute_value_product_template_attribute_line_rel' string='Lines'
  • sequence Integer
    help='Determine the display order' index=True string='Sequence'
Public methods (5)
  • action_add_to_products(self)
  • action_update_prices(self)
  • check_is_used_on_products(self)
  • unlink(self)
  • write(self, vals)

New fields (0)

No new fields.

Public methods (1)
  • action_add_from_catalog(self)

New fields (7)
  • child_id One2many → product.category
    args: 'product.category', 'parent_id', 'Child Categories'
  • complete_name Char
    compute='_compute_complete_name' recursive=True store=True args: 'Complete Name'
  • name Char
    index='trigram' required=True args: 'Name'
  • parent_id Many2one → product.category
    index=True ondelete='cascade' args: 'product.category', 'Parent Category'
  • parent_path Char
    index=True
  • product_count Integer
    compute='_compute_product_count' help='The number of products under this category (Does not consider the children categories)' args: '# Products'
  • product_properties_definition PropertiesDefinition
    args: 'Product Properties'
Public methods (1)
  • name_create(self, name)
    @api.model

New fields (7)
  • base_price Float
    compute='_compute_base_price' help='The minimum price among the products in this combo. This value will be used to prorate the price of this combo with respect to the other combos in a combo product. This heuristic ensures that whatever product the user chooses in a combo, it will always be the same price.' min_display_digits='Product Price' string='Combo Price'
  • combo_item_count Integer
    compute='_compute_combo_item_count' string='Product Count'
  • combo_item_ids One2many → product.combo.item
    comodel_name='product.combo.item' copy=True inverse_name='combo_id'
  • company_id Many2one → res.company
    comodel_name='res.company' index=True string='Company'
  • currency_id Many2one → res.currency
    comodel_name='res.currency' compute='_compute_currency_id'
  • name Char
    required=True string='Name'
  • sequence Integer
    copy=False default=10
Public methods (0)

No public methods.

New fields (6)
  • combo_id Many2one → product.combo
    comodel_name='product.combo' ondelete='cascade' required=True
  • company_id Many2one
    precompute=True related='combo_id.company_id' store=True
  • currency_id Many2one → res.currency
    comodel_name='res.currency' related='product_id.currency_id'
  • extra_price Float
    default=0.0 min_display_digits='Product Price' string='Extra Price'
  • lst_price Float
    min_display_digits='Product Price' related='product_id.lst_price' string='Original Price'
  • product_id Many2one → product.product
    check_company=True comodel_name='product.product' domain=[('type', '!=', 'combo')] ondelete='restrict' required=True string='Product'
Public methods (0)

No public methods.

New fields (3)
  • active Boolean
    default=True
  • ir_attachment_id Many2one → ir.attachment
    ondelete='cascade' required=True string='Related attachment' args: 'ir.attachment'
  • sequence Integer
    default=10
Public methods (3)
  • copy_data(self, default=None)
  • create(self, vals_list)
    @api.model_create_multi
  • unlink(self)

New fields (8)
  • columns Integer
    compute='_compute_dimensions'
  • custom_quantity Integer
    default=1 required=True args: 'Quantity'
  • extra_html Html
    default='' args: 'Extra Content'
  • pricelist_id Many2one → product.pricelist
    string='Pricelist' args: 'product.pricelist'
  • print_format Selection
    default='2x7xprice' required=True string='Format' args: [('dymo', 'Dymo'), ('2x7xprice', '2 x 7 with price'), ('4x7xprice', '4 x 7 with price'), ('4x12', '4 x 12'), ('4x12xprice', '4 x 12 with price')]
  • product_ids Many2many → product.product
    args: 'product.product'
  • product_tmpl_ids Many2many → product.template
    args: 'product.template'
  • rows Integer
    compute='_compute_dimensions'
Public methods (1)
  • process(self)

New fields (7)
  • barcode Char
    copy=False help='Barcode used for packaging identification. Scan this packaging barcode from a transfer in the Barcode app to move all the contained units' args: 'Barcode'
  • company_id Many2one → res.company
    index=True args: 'res.company', 'Company'
  • name Char
    required=True args: 'Product Packaging'
  • product_id Many2one → product.product
    check_company=True ondelete='cascade' required=True string='Product' args: 'product.product'
  • product_uom_id Many2one → uom.uom
    readonly=True related='product_id.uom_id' args: 'uom.uom'
  • qty Float
    default=1 digits='Product Unit of Measure' help='Quantity of products contained in the packaging.' args: 'Contained Quantity'
  • sequence Integer
    default=1 help='The first in the sequence is the default one.' args: 'Sequence'
Public methods (0)

No public methods.

New fields (7)
  • active Boolean
    default=True help='If unchecked, it will allow you to hide the pricelist without removing it.' string='Active'
  • company_id Many2one → res.company
    comodel_name='res.company' default=<expr> tracking=5
  • country_group_ids Many2many → res.country.group
    column1='pricelist_id' column2='res_country_group_id' comodel_name='res.country.group' relation='res_country_group_pricelist_rel' string='Country Groups' tracking=10
  • currency_id Many2one → res.currency
    comodel_name='res.currency' default=_default_currency_id required=True tracking=1
  • item_ids One2many → product.pricelist.item
    comodel_name='product.pricelist.item' copy=True domain=['&', '|', ('product_tmpl_id', '=', None), ('product_tmpl_id.active', '=', True), '|', ('product_id', '=', None), ('product_id.active', '=', True)] inverse_name='pricelist_id' string='Pricelist Rules'
  • name Char
    required=True string='Pricelist Name' translate=True
  • sequence Integer
    default=16
Public methods (4)
  • action_open_pricelist_report(self)
  • copy_data(self, default=None)
  • get_import_templates(self)
    @api.model
  • write(self, values)

New fields (27)
  • applied_on Selection
    default='3_global' help='Pricelist Item applicable on selected option' required=True selection=[('3_global', 'All Products'), ('2_product_category', 'Product Category'), ('1_product', 'Product'), ('0_product_variant', 'Product Variant')] string='Apply On'
  • base Selection
    default='list_price' help='Base price for computation.\nSales Price: The base price will be the Sales Price.\nCost Price: The base price will be the cost price.\nOther Pricelist: Computation of the base price based on another Pricelist.' required=True selection=[('list_price', 'Sales Price'), ('standard_price', 'Cost'), ('pricelist', 'Other Pricelist')] string='Based on'
  • base_pricelist_id Many2one → product.pricelist
    check_company=True args: 'product.pricelist', 'Other Pricelist'
  • categ_id Many2one → product.category
    comodel_name='product.category' help='Specify a product category if this rule only applies to products belonging to this category or its children categories. Keep empty otherwise.' ondelete='cascade' string='Category'
  • company_id Many2one
    related='pricelist_id.company_id' store=True
  • compute_price Selection
    default='fixed' help='Use the discount rules and activate the discount settings in order to show discount to customer.' index=True required=True selection=[('percentage', 'Discount'), ('formula', 'Formula'), ('fixed', 'Fixed Price')]
  • currency_id Many2one
    related='pricelist_id.currency_id' store=True
  • date_end Datetime
    help='Ending datetime for the pricelist item validation\nThe displayed value depends on the timezone set in your preferences.' string='End Date'
  • date_start Datetime
    help='Starting datetime for the pricelist item validation\nThe displayed value depends on the timezone set in your preferences.' string='Start Date'
  • display_applied_on Selection
    default='1_product' help='Pricelist Item applicable on selected option' required=True selection=[('1_product', 'Product'), ('2_product_category', 'Category')]
  • fixed_price Float
    min_display_digits='Product Price' string='Fixed Price'
  • min_quantity Float
    default=0 digits='Product Unit of Measure' help='For the rule to apply, bought/sold quantity must be greater than or equal to the minimum quantity specified in this field.\nExpressed in the default unit of measure of the product.' string='Min. Quantity'
  • name Char
    compute='_compute_name' help='Explicit rule name for this pricelist line.' string='Name'
  • percent_price Float
    help='You can apply a mark-up by setting a negative discount.' string='Percentage Price'
  • price Char
    compute='_compute_price_label' help='Explicit rule name for this pricelist line.' string='Price'
  • price_discount Float
    default=0 digits=(16, 2) help='You can apply a mark-up by setting a negative discount.' string='Price Discount'
  • price_markup Float
    compute='_compute_price_markup' digits=(16, 2) help='You can apply a mark-up on the cost' inverse='_inverse_price_markup' store=True string='Markup'
  • price_max_margin Float
    help='Specify the maximum amount of margin over the base price.' min_display_digits='Product Price' string='Max. Price Margin'
  • price_min_margin Float
    help='Specify the minimum amount of margin over the base price.' min_display_digits='Product Price' string='Min. Price Margin'
  • price_round Float
    help='Sets the price so that it is a multiple of this value.\nRounding is applied after the discount and before the surcharge.\nTo have prices that end in 9.99, round off to 10.00 and set an extra at -0.01' min_display_digits='Product Price' string='Price Rounding'
  • price_surcharge Float
    help='Specify the fixed amount to add or subtract (if negative) to the amount calculated with the discount.' min_display_digits='Product Price' string='Extra Fee'
  • pricelist_id Many2one → product.pricelist
    comodel_name='product.pricelist' default=_default_pricelist_id index=True ondelete='cascade' required=True string='Pricelist'
  • product_id Many2one → product.product
    check_company=True comodel_name='product.product' domain="[('product_tmpl_id', '=', product_tmpl_id)]" help='Specify a product if this rule only applies to one product. Keep empty otherwise.' ondelete='cascade' string='Variant'
  • product_tmpl_id Many2one → product.template
    check_company=True comodel_name='product.template' help='Specify a template if this rule only applies to one product template. Keep empty otherwise.' ondelete='cascade' string='Product'
  • product_uom Char
    related='product_tmpl_id.uom_name'
  • product_variant_count Integer
    related='product_tmpl_id.product_variant_count'
  • rule_tip Char
    compute='_compute_rule_tip'
Public methods (2)
  • create(self, vals_list)
    @api.model_create_multi
  • write(self, values)

New fields (34)
  • active Boolean
    default=True help='If unchecked, it will allow you to hide the product without removing it.' args: 'Active'
  • additional_product_tag_ids Many2many → product.tag
    comodel_name='product.tag' domain="[('id', 'not in', product_tag_ids)]" relation='product_tag_product_product_rel' string='Variant Tags'
  • all_product_tag_ids Many2many → product.tag
    compute='_compute_all_product_tag_ids' search='_search_all_product_tag_ids' args: 'product.tag'
  • barcode Char
    copy=False help='International Article Number used for product identification.' index='btree_not_null' args: 'Barcode'
  • can_image_1024_be_zoomed Boolean
    compute='_compute_can_image_1024_be_zoomed' args: 'Can Image 1024 be zoomed'
  • can_image_variant_1024_be_zoomed Boolean
    compute='_compute_can_image_variant_1024_be_zoomed' store=True args: 'Can Variant Image 1024 be zoomed'
  • code Char
    compute='_compute_product_code' args: 'Reference'
  • combination_indices Char
    compute='_compute_combination_indices' index=True store=True
  • default_code Char
    index=True args: 'Internal Reference'
  • image_1024 Image
    compute='_compute_image_1024' args: 'Image 1024'
  • image_128 Image
    compute='_compute_image_128' args: 'Image 128'
  • image_1920 Image
    compute='_compute_image_1920' inverse='_set_image_1920' args: 'Image'
  • image_256 Image
    compute='_compute_image_256' args: 'Image 256'
  • image_512 Image
    compute='_compute_image_512' args: 'Image 512'
  • image_variant_1024 Image
    max_height=1024 max_width=1024 related='image_variant_1920' store=True args: 'Variant Image 1024'
  • image_variant_128 Image
    max_height=128 max_width=128 related='image_variant_1920' store=True args: 'Variant Image 128'
  • image_variant_1920 Image
    max_height=1920 max_width=1920 args: 'Variant Image'
  • image_variant_256 Image
    max_height=256 max_width=256 related='image_variant_1920' store=True args: 'Variant Image 256'
  • image_variant_512 Image
    max_height=512 max_width=512 related='image_variant_1920' store=True args: 'Variant Image 512'
  • is_product_variant Boolean
    compute='_compute_is_product_variant'
  • lst_price Float
    compute='_compute_product_lst_price' help="The sale price is managed from the product template. Click on the 'Configure Variants' button to set the extra attribute prices." inverse='_set_product_lst_price' min_display_digits='Product Price' args: 'Sales\xa0Price'
  • packaging_ids One2many → product.packaging
    help='Gives the different ways to package the same product.' args: 'product.packaging', 'product_id', 'Product Packages'
  • partner_ref Char
    compute='_compute_partner_ref' args: 'Customer Ref'
  • price_extra Float
    compute='_compute_product_price_extra' help='This is the sum of the extra price of all attributes' min_display_digits='Product Price' args: 'Variant Price Extra'
  • pricelist_item_count Integer
    compute='_compute_variant_item_count' args: 'Number of price rules'
  • product_document_count Integer
    compute='_compute_product_document_count' string='Documents Count'
  • product_document_ids One2many → product.document
    comodel_name='product.document' domain=<expr> inverse_name='res_id' string='Documents'
  • product_template_attribute_value_ids Many2many → product.template.attribute.value
    ondelete='restrict' relation='product_variant_combination' string='Attribute Values' args: 'product.template.attribute.value'
  • product_template_variant_value_ids Many2many → product.template.attribute.value
    domain=[('attribute_line_id.value_count', '>', 1)] ondelete='restrict' relation='product_variant_combination' string='Variant Values' args: 'product.template.attribute.value'
  • product_tmpl_id Many2one → product.template
    auto_join=True index=True ondelete='cascade' required=True args: 'product.template', 'Product Template'
  • standard_price Float
    company_dependent=True groups='base.group_user' help='Value of the product (automatically computed in AVCO).\n Used to value the product when the purchase cost is not known (e.g. inventory adjustment).\n Used to compute margins on sale orders.' min_display_digits='Product Price' args: 'Cost'
  • volume Float
    digits='Volume' args: 'Volume'
  • weight Float
    digits='Stock Weight' args: 'Weight'
  • write_date Datetime
    compute='_compute_write_date' store=True
Public methods (15)
  • action_open_documents(self)
  • action_open_label_layout(self)
  • copy(self, default=None)
    Variants are generated depending on the configuration of attributes and values on the template, so copying them does not make sense. For convenience the template is copied instead and its first variant is returned.
  • create(self, vals_list)
    @api.model_create_multi
  • get_contextual_price(self)
  • get_empty_list_help(self, help_message)
    @api.model
  • get_product_multiline_description_sale(self)
    Compute a multiline description of this product, in the context of sales (do not use for purchases or other display reasons that don't intend to use "description_sale"). It will often be used as the default description of a sale order line referencing this product.
  • init(self)
    Ensure there is at most one active variant for each combination. There could be no variant for a combination if using dynamic attributes.
  • name_search(self, name='', args=None, operator='ilike', limit=100)
    @api.model
  • open_pricelist_rules(self)
  • open_product_template(self)
    Utility method used to add an "Open Template" button in product views
  • toggle_active(self)
    Archiving related product.template if there is not any more active product.product (and vice versa, unarchiving the related product template if there is now an active product.product)
  • unlink(self)
  • view_header_get(self, view_id, view_type)
    @api.model
  • write(self, values)

New fields (17)
  • company_id Many2one → res.company
    default=<expr> index=1 args: 'res.company', 'Company'
  • currency_id Many2one → res.currency
    default=<expr> required=True args: 'res.currency', 'Currency'
  • date_end Date
    help='End date for this vendor price' args: 'End Date'
  • date_start Date
    help='Start date for this vendor price' args: 'Start Date'
  • delay Integer
    default=1 help='Lead time in days between the confirmation of the purchase order and the receipt of the products in your warehouse. Used by the scheduler for automatic computation of the purchase order planning.' required=True args: 'Delivery Lead Time'
  • discount Float
    digits='Discount' readonly=False string='Discount (%)'
  • min_qty Float
    default=0.0 digits='Product Unit of Measure' help='The quantity to purchase from this vendor to benefit from the price, expressed in the vendor Product Unit of Measure if not any, in the default unit of measure of the product otherwise.' required=True args: 'Quantity'
  • partner_id Many2one → res.partner
    check_company=True ondelete='cascade' required=True args: 'res.partner', 'Vendor'
  • price Float
    default=0.0 help='The price to purchase a product' min_display_digits='Product Price' required=True args: 'Price'
  • price_discounted Float
    compute='_compute_price_discounted' args: 'Discounted Price'
  • product_code Char
    help="This vendor's product code will be used when printing a request for quotation. Keep empty to use the internal one." args: 'Vendor Product Code'
  • product_id Many2one → product.product
    check_company=True default=_default_product_id domain="[('product_tmpl_id', '=', product_tmpl_id)] if product_tmpl_id else []" help='If not set, the vendor price will apply to all variants of this product.' args: 'product.product', 'Product Variant'
  • product_name Char
    help="This vendor's product name will be used when printing a request for quotation. Keep empty to use the internal one." args: 'Vendor Product Name'
  • product_tmpl_id Many2one → product.template
    check_company=True index=True ondelete='cascade' args: 'product.template', 'Product Template'
  • product_uom Many2one → uom.uom
    related='product_tmpl_id.uom_po_id' args: 'uom.uom', 'Unit of Measure'
  • product_variant_count Integer
    related='product_tmpl_id.product_variant_count' args: 'Variant Count'
  • sequence Integer
    default=1 help='Assigns the priority to the list of product vendor.' args: 'Sequence'
Public methods (3)
  • create(self, vals_list)
    @api.model_create_multi
  • get_import_templates(self)
    @api.model
  • write(self, vals)

New fields (6)
  • color Char
    default='#3C3C3C' string='Color'
  • name Char
    required=True string='Name' translate=True
  • product_ids Many2many → product.product
    compute='_compute_product_ids' search='_search_product_ids' string='All Product Variants using this Tag' args: 'product.product'
  • product_product_ids Many2many → product.product
    comodel_name='product.product' default=_get_default_variant_id domain="[('attribute_line_ids', '!=', False), ('product_tmpl_id', 'not in', product_template_ids)]" relation='product_tag_product_product_rel' string='Product Variants'
  • product_template_ids Many2many → product.template
    comodel_name='product.template' default=_get_default_template_id relation='product_tag_product_template_rel' string='Product Templates'
  • sequence Integer
    default=10
Public methods (1)
  • copy_data(self, default=None)

New fields (46)
  • active Boolean
    default=True help='If unchecked, it will allow you to hide the product without removing it.' args: 'Active'
  • attribute_line_ids One2many → product.template.attribute.line
    copy=True args: 'product.template.attribute.line', 'product_tmpl_id', 'Product Attributes'
  • barcode Char
    compute='_compute_barcode' inverse='_set_barcode' search='_search_barcode' args: 'Barcode'
  • can_image_1024_be_zoomed Boolean
    compute='_compute_can_image_1024_be_zoomed' store=True args: 'Can Image 1024 be zoomed'
  • categ_id Many2one → product.category
    change_default=True default=_get_default_category_id group_expand='_read_group_categ_id' required=True args: 'product.category', 'Product Category'
  • color Integer
    args: 'Color Index'
  • combo_ids Many2many → product.combo
    check_company=True comodel_name='product.combo' string='Combo Choices'
  • company_id Many2one → res.company
    index=True args: 'res.company', 'Company'
  • cost_currency_id Many2one → res.currency
    compute='_compute_cost_currency_id' args: 'res.currency', 'Cost Currency'
  • currency_id Many2one → res.currency
    compute='_compute_currency_id' args: 'res.currency', 'Currency'
  • default_code Char
    compute='_compute_default_code' inverse='_set_default_code' store=True args: 'Internal Reference'
  • description Html
    translate=True args: 'Description'
  • description_purchase Text
    translate=True args: 'Purchase Description'
  • description_sale Text
    help='A description of the Product that you want to communicate to your customers. This description will be copied to every Sales Order, Delivery Order and Customer Invoice/Credit Note' translate=True args: 'Sales Description'
  • has_configurable_attributes Boolean
    compute='_compute_has_configurable_attributes' store=True args: 'Is a configurable product'
  • is_favorite Boolean
    string='Favorite'
  • is_product_variant Boolean
    compute='_compute_is_product_variant' string='Is a product variant'
  • list_price Float
    default=1.0 help='Price at which the product is sold to customers.' min_display_digits='Product Price' tracking=True args: 'Sales Price'
  • name Char
    index='trigram' required=True translate=True args: 'Name'
  • packaging_ids One2many → product.packaging
    compute='_compute_packaging_ids' help='Gives the different ways to package the same product.' inverse='_set_packaging_ids' string='Product Packages' args: 'product.packaging'
  • pricelist_item_count Integer
    compute='_compute_item_count' args: 'Number of price rules'
  • product_document_count Integer
    compute='_compute_product_document_count' string='Documents Count'
  • product_document_ids One2many → product.document
    comodel_name='product.document' domain=<expr> inverse_name='res_id' string='Documents'
  • product_properties Properties
    copy=True definition='categ_id.product_properties_definition' args: 'Properties'
  • product_tag_ids Many2many → product.tag
    comodel_name='product.tag' relation='product_tag_product_template_rel' string='Tags'
  • product_tooltip Char
    compute='_compute_product_tooltip'
  • product_variant_count Integer
    compute='_compute_product_variant_count' args: '# Product Variants'
  • product_variant_id Many2one → product.product
    compute='_compute_product_variant_id' args: 'product.product', 'Product'
  • product_variant_ids One2many → product.product
    required=True args: 'product.product', 'product_tmpl_id', 'Products'
  • purchase_ok Boolean
    compute='_compute_purchase_ok' default=True readonly=False store=True args: 'Purchase'
  • sale_ok Boolean
    default=True args: 'Sales'
  • seller_ids One2many → product.supplierinfo
    depends_context=('company') args: 'product.supplierinfo', 'product_tmpl_id', 'Vendors'
  • sequence Integer
    default=1 help='Gives the sequence order when displaying a product list' args: 'Sequence'
  • service_tracking Selection
    compute='_compute_service_tracking' default='no' readonly=False required=True selection=[('no', 'Nothing')] store=True string='Create on Order'
  • standard_price Float
    compute='_compute_standard_price' groups='base.group_user' help='Value of the product (automatically computed in AVCO).\n Used to value the product when the purchase cost is not known (e.g. inventory adjustment).\n Used to compute margins on sale orders.' inverse='_set_standard_price' min_display_digits='Product Price' search='_search_standard_price' args: 'Cost'
  • type Selection
    default='consu' help='Goods are tangible materials and merchandise you provide.\nA service is a non-material product you provide.' required=True selection=[('consu', 'Goods'), ('service', 'Service'), ('combo', 'Combo')] string='Product Type'
  • uom_category_id Many2one → uom.category
    related='uom_id.category_id' string='UoM Category' args: 'uom.category'
  • uom_id Many2one → uom.uom
    default=_get_default_uom_id help='Default unit of measure used for all stock operations.' required=True args: 'uom.uom', 'Unit of Measure'
  • uom_name Char
    readonly=True related='uom_id.name' string='Unit of Measure Name'
  • uom_po_id Many2one → uom.uom
    compute='_compute_uom_po_id' domain="[('category_id', '=', uom_category_id)]" help='Default unit of measure used for purchase orders. It must be in the same category as the default unit of measure.' precompute=True readonly=False required=True store=True args: 'uom.uom', 'Purchase Unit'
  • valid_product_template_attribute_line_ids Many2many → product.template.attribute.line
    compute='_compute_valid_product_template_attribute_line_ids' string='Valid Product Attribute Lines' args: 'product.template.attribute.line'
  • variant_seller_ids One2many → product.supplierinfo
    args: 'product.supplierinfo', 'product_tmpl_id'
  • volume Float
    compute='_compute_volume' digits='Volume' inverse='_set_volume' store=True args: 'Volume'
  • volume_uom_name Char
    compute='_compute_volume_uom_name' string='Volume unit of measure label'
  • weight Float
    compute='_compute_weight' digits='Stock Weight' inverse='_set_weight' store=True args: 'Weight'
  • weight_uom_name Char
    compute='_compute_weight_uom_name' string='Weight unit of measure label'
Public methods (14)
  • action_open_documents(self)
  • action_open_label_layout(self)
  • copy(self, default=None)
  • copy_data(self, default=None)
  • create(self, vals_list)
    @api.model_create_multi
    Store the initial standard price in order to be able to retrieve the cost of a product template for a given date
  • default_get(self, fields_list)
  • get_contextual_price(self, product=None)
  • get_empty_list_help(self, help_message)
    @api.model
  • get_import_templates(self)
    @api.model
  • get_single_product_variant(self)
    Method used by the product configurator to check if the product is configurable or not. We need to open the product configurator if the product: - is configurable (see has_configurable_attributes) - has optional products (method is extended in sale to return optional products info) Note: self.ensure_one()
  • has_dynamic_attributes(self)
    Return whether this `product.template` has at least one dynamic attribute. :return: True if at least one dynamic attribute, False otherwise :rtype: bool
  • name_search(self, name='', args=None, operator='ilike', limit=100)
    @api.model
  • open_pricelist_rules(self)
  • write(self, vals)

New fields (3)
  • product_template_attribute_value_id Many2one → product.template.attribute.value
    comodel_name='product.template.attribute.value' index=True ondelete='cascade' string='Attribute Value'
  • product_tmpl_id Many2one → product.template
    comodel_name='product.template' index=True ondelete='cascade' required=True string='Product Template'
  • value_ids Many2many → product.template.attribute.value
    comodel_name='product.template.attribute.value' domain="[('product_tmpl_id', '=', product_tmpl_id), ('ptav_active', '=', True)]" relation='product_attr_exclusion_value_ids_rel' string='Attribute Values'
Public methods (3)
  • create(self, vals_list)
    @api.model_create_multi
  • unlink(self)
  • write(self, values)

New fields (7)
  • active Boolean
    default=True
  • attribute_id Many2one → product.attribute
    comodel_name='product.attribute' index=True ondelete='restrict' required=True string='Attribute'
  • product_template_value_ids One2many → product.template.attribute.value
    comodel_name='product.template.attribute.value' inverse_name='attribute_line_id' string='Product Attribute Values'
  • product_tmpl_id Many2one → product.template
    comodel_name='product.template' index=True ondelete='cascade' required=True string='Product Template'
  • sequence Integer
    default=10 args: 'Sequence'
  • value_count Integer
    compute='_compute_value_count' store=True
  • value_ids Many2many → product.attribute.value
    comodel_name='product.attribute.value' domain="[('attribute_id', '=', attribute_id)]" ondelete='restrict' relation='product_attribute_value_product_template_attribute_line_rel' string='Values'
Public methods (4)
  • action_open_attribute_values(self)
  • create(self, vals_list)
    @api.model_create_multi
    Override to: - Activate archived lines having the same configuration (if they exist) instead of creating new lines. - Set up related values and related variants. Reactivating existing lines allows to re-use existing variants when possible, keeping their configuration and avoiding duplication.
  • unlink(self)
    Override to: - Archive the line if unlink is not possible. - Clean up related values and related variants. Archiving is typically needed when the line has values that can't be deleted because they are referenced elsewhere (on a variant that can't be deleted, on a sales order line, ...).
  • write(self, values)
    Override to: - Add constraints to prevent doing changes that are not supported such as modifying the template or the attribute of existing lines. - Clean up related values and related variants when archiving or when updating `value_ids`.

New fields (15)
  • attribute_id Many2one
    index=True related='attribute_line_id.attribute_id' store=True
  • attribute_line_id Many2one → product.template.attribute.line
    comodel_name='product.template.attribute.line' index=True ondelete='cascade' required=True
  • color Integer
    default=_get_default_color string='Color'
  • currency_id Many2one
    related='attribute_line_id.product_tmpl_id.currency_id'
  • display_type Selection
    related='product_attribute_value_id.display_type'
  • exclude_for One2many → product.template.attribute.exclusion
    comodel_name='product.template.attribute.exclusion' help='Make this attribute value not compatible with other values of the product or some attribute values of optional and accessory products.' inverse_name='product_template_attribute_value_id' string='Exclude for'
  • html_color Char
    related='product_attribute_value_id.html_color' string='HTML Color Index'
  • image Image
    related='product_attribute_value_id.image'
  • is_custom Boolean
    related='product_attribute_value_id.is_custom'
  • name Char
    related='product_attribute_value_id.name' string='Value'
  • price_extra Float
    default=0.0 help='Extra price for the variant with this attribute value on sale price. eg. 200 price extra, 1000 + 200 = 1200.' min_display_digits='Product Price' string='Extra Price'
  • product_attribute_value_id Many2one → product.attribute.value
    comodel_name='product.attribute.value' index=True ondelete='cascade' required=True string='Attribute Value'
  • product_tmpl_id Many2one
    index=True related='attribute_line_id.product_tmpl_id' store=True
  • ptav_active Boolean
    default=True string='Active'
  • ptav_product_variant_ids Many2many → product.product
    comodel_name='product.product' readonly=True relation='product_variant_combination' string='Related Variants'
Public methods (3)
  • create(self, vals_list)
    @api.model_create_multi
  • unlink(self)
    Override to: - Clean up the variants that use any of the values in self: - Remove the value from the variant if the value belonged to an attribute line with only one value. - Unlink or archive all related variants. - Archive the value if unlink is not possible. Archiving is typically needed when the value is referenced elsewhere (on a variant that can't be deleted, on a sales order line, ...).
  • write(self, values)

New fields (0)

No new fields.

Public methods (1)
  • get_html(self, data)
    @api.model

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (2)
  • create(self, vals_list)
    @api.model_create_multi
  • write(self, vals)
    Delay the automatic creation of pricelists post-company update. This makes sure that the pricelist(s) automatically created are created with the right currency.

New fields (7)
  • group_product_pricelist Boolean
    implied_group='product.group_product_pricelist' args: 'Pricelists'
  • group_product_variant Boolean
    implied_group='product.group_product_variant' args: 'Variants'
  • group_stock_packaging Boolean
    implied_group='product.group_stock_packaging' args: 'Product Packagings'
  • group_uom Boolean
    implied_group='uom.group_uom' args: 'Units of Measure'
  • module_loyalty Boolean
    args: 'Promotions, Coupons, Gift Card & Loyalty Program'
  • product_volume_volume_in_cubic_feet Selection
    config_parameter='product.volume_in_cubic_feet' default='0' args: [('0', 'Cubic Meters'), ('1', 'Cubic Feet')], 'Volume unit of measure'
  • product_weight_in_lbs Selection
    config_parameter='product.weight_in_lbs' default='0' args: [('0', 'Kilograms'), ('1', 'Pounds')], 'Weight unit of measure'
Public methods (1)
  • set_values(self)

New fields (1)
  • pricelist_ids Many2many → product.pricelist
    column1='res_country_group_id' column2='pricelist_id' comodel_name='product.pricelist' relation='res_country_group_pricelist_rel' string='Pricelists'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (1)
  • write(self, vals)
    Archive pricelist when the linked currency is archived.

New fields (2)
  • property_product_pricelist Many2one → product.pricelist
    comodel_name='product.pricelist' company_dependent=False compute='_compute_product_pricelist' domain=<expr> help='This pricelist will be used, instead of the default one, for sales to the current partner' inverse='_inverse_product_pricelist' string='Pricelist'
  • specific_property_product_pricelist Many2one → product.pricelist
    comodel_name='product.pricelist' company_dependent=True
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (4)
  • attribute_value_id Many2one → product.attribute.value
    required=True args: 'product.attribute.value'
  • message Char
    compute='_compute_message'
  • mode Selection
    selection=[('add', 'Add to existing products'), ('update_extra_price', 'Update the extra price on existing products')]
  • product_count Integer
    compute='_compute_product_count'
Public methods (1)
  • action_confirm(self)
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/17.0/product
VERSION
VERSION 1.2
CATEGORY
CATEGORYSales/Sales
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Martin Trigaux, Fabien Pinckaers, Thibault Delavallée, Denis Ledoux, Xavier Morel, qdp-odoo, Atul Patel, Aaron Bohy, Damien Bouvy, Yannick Tivisse, Odoo Online, Pierre Masereel, Romain Derie, Jorge Pinna Puissant, Alexandre Kühn, Arnold Moyaux, Xavier-Do, Victor Feyens, Andrea Grazioso (agr-odoo), William Henrotin, Akim Juillerat, Julien Mougenot, svs-odoo, Lois Rilo, Samuel Degueldre, Ivan Yelizariev, Touati Djamel (otd), Prakash Prajapati, Tiffany Chang (tic), Rémy Voet (ryv), Ivàn Todorovich, Gorash, Pierre Paridans, Arnaud Joset, William Braeckman, momegahed, Jigar Vaghela, william-andre, JF Aubert, Bruno Zanotti, Antoine Vandevenne (anv), Demesmaeker, Aurelien van Delft (avd), Mathieu Walravens, Achraf, Valentin Chevalier, niyasraphy, Simone Rubino, mehjabinfarsana, alsh-odoo, Louis Wicket (wil), David, Adrien Widart (awt), Victor Piryns (pivi), Julien (jula), Mahamadasif Ansari, miad-odoo, Pierre-Yves Dufays, clesgow, Valentin Vallaeys (vava), pash-odoo, Levi Siuzdak (sile), Maruan Aguerdouh (magm), Dylan Kiss (dyki), Bruno Boi, Antoine (ande), Julien Alardot (jual), Michael (mcm), Preksha Chouhan, Horacio Tellez, Valeriya(vchu), paso-odoo, Uttam Pragda, Adrien Schoffeniels, Martin Maes, Xavier Bol (xbo), Brieuc-brd, SilvioC2C, Paweł Fertyk, Sarah Bellefroid, Adrien Guilliams (adgu), Paul Stroobant, stefanorigano (SRI), Mattis Megevand, Youssef Bashandy, Ethan Vincent, lase@odoo.com, Benjamin Hanquin (beha), Louis (loti), axtr, Nathaniel (naja), vava-odoo, Julien Carion (juca), kcv-odoo, adsh-odoo, mega, Tanguy Quéguineur, dere-odoo, Alexandre de Pape (alpa), Lina (liew), Louis (wil), Mathieu (mano), Ryan Cen, gteboul, sabr, Christopher Maloney (cmal), Viktors Lipskis (vili), David Van Droogenbroeck (DROD), khsr-odoo, Pierre Pulinckx (pipu), Bastien PIERRE, kasm, TuyenTran, Carmine, Shrey Mehta, Bastien (bvdn), Tejas Modi, Vincent Sevestre, plha-odoo, Danial Sheikhani, Matias Peralta, krip-odoo, mohannedah, rkka-odoo, Samiul Hoque
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 01:02:09
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - uom
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
This is the base module for managing products and pricelists in Odoo.
========================================================================

Products support variants, different pricing methods, vendors information,
make to stock/order, different units of measure, packaging and properties.

Pricelists support:
-------------------
    * Multiple-level of discount (by product, category, quantities)
    * Compute price based on different criteria:
        * Other pricelist
        * Cost price
        * List price
        * Vendor price

Pricelists preferences by product and/or partners.

Print product labels with barcode.
    

Code Analysis

Views touched (67)
XML IDNameModelTypeStatus
attribute_tree_view product.attribute.tree product.attribute tree New
inherits_website_sale_country_group_form res.country.group.form.inherit.product res.country.group group Inherits base.view_country_group_form
product_attribute_value_list product.attribute.value.list product.attribute.value tree New
product_attribute_view_form product.attribute.form product.attribute form New
product_category_form_view product.category.form product.category form New
product_category_list_view product.category.list product.category tree New
product_category_search_view product.category.search product.category search New
product_document_form product.document.form product.document form New
product_document_kanban product.document.kanban product.document kanban New
product_document_list product.document.list product.document tree New
product_document_search product.document.search product.document search New
product_kanban_view Product Kanban product.product kanban New
product_label_layout_form product.label.layout.form product.label.layout form New
product_normal_form_view product.product.form product.product form Inherits product.product_template_form_view
product_packaging_form_view product.packaging.form.view product.packaging form New
product_packaging_form_view2 product.packaging.form.view2 product.packaging xpath Inherits product.product_packaging_form_view
product_packaging_tree_view product.packaging.tree.view product.packaging tree New
product_packaging_tree_view2 product.packaging.tree.view2 product.packaging xpath Inherits product.product_packaging_tree_view
product_pricelist_item_form_view product.pricelist.item.form product.pricelist.item form New
product_pricelist_item_tree_view product.pricelist.item.tree product.pricelist.item tree New
product_pricelist_item_tree_view_from_product product.pricelist.item.tree product.pricelist.item tree New
product_pricelist_item_view_search product.pricelist.item.search product.pricelist.item search New
product_pricelist_view product.pricelist.form product.pricelist form New
product_pricelist_view_kanban product.pricelist.kanban product.pricelist kanban New
product_pricelist_view_search product.pricelist.search product.pricelist search New
product_pricelist_view_tree product.pricelist.tree product.pricelist tree New
product_product_tree_view product.product.tree product.product tree New
product_product_view_activity product.product.activity product.product activity New
product_product_view_tree_tag product.product.view.tree.tag product.product tree New
product_search_form_view product.product.search product.product field Inherits product.product_template_search_view
product_supplierinfo_form_view product.supplierinfo.form.view product.supplierinfo form New
product_supplierinfo_search_view product.supplierinfo.search.view product.supplierinfo search New
product_supplierinfo_tree_view product.supplierinfo.tree.view product.supplierinfo tree New
product_supplierinfo_view_kanban product.supplierinfo.kanban product.supplierinfo kanban New
product_tag_form_view product.tag.form product.tag form New
product_tag_tree_view product.tag.tree product.tag tree New
product_template_attribute_line_form product.template.attribute.line.form product.template.attribute.line form New
product_template_attribute_value_view_form product.template.attribute.value.view.form. product.template.attribute.value form New
product_template_attribute_value_view_search product.template.attribute.value search New
product_template_attribute_value_view_tree product.template.attribute.value.view.tree product.template.attribute.value tree New
product_template_form_view product.template.common.form product.template form New
product_template_kanban_view Product.template.product.kanban product.template kanban New
product_template_only_form_view product.template.product.form product.template xpath Inherits product.product_template_form_view
product_template_search_view product.template.search product.template search New
product_template_tree_view product.template.product.tree product.template tree New
product_template_view_activity product.template.activity product.template activity New
product_template_view_tree_tag product.template.view.tree.tag product.template tree New
product_variant_easy_edit_view product.product.view.form.easy product.product form New
product_view_kanban_catalog product.view.kanban.catalog product.product kanban New
product_view_search_catalog product.view.search.catalog product.product search New
report_packagingbarcode report_packagingbarcode ir.ui.view qweb New
report_pricelist report_pricelist ir.ui.view qweb New
report_pricelist_page report_pricelist_page ir.ui.view qweb New
report_productlabel report_productlabel ir.ui.view qweb New
report_productlabel_dymo report_productlabel_dymo ir.ui.view qweb New
report_producttemplatelabel2x7 report_producttemplatelabel2x7 ir.ui.view qweb New
report_producttemplatelabel4x12 report_producttemplatelabel4x12 ir.ui.view qweb New
report_producttemplatelabel4x12noprice report_producttemplatelabel4x12noprice ir.ui.view qweb New
report_producttemplatelabel4x7 report_producttemplatelabel4x7 ir.ui.view qweb New
report_producttemplatelabel_dymo report_producttemplatelabel_dymo ir.ui.view qweb New
report_simple_label2x7 report_simple_label2x7 ir.ui.view qweb New
report_simple_label4x12 report_simple_label4x12 ir.ui.view qweb New
report_simple_label4x12_no_price report_simple_label4x12_no_price ir.ui.view qweb New
report_simple_label4x7 report_simple_label4x7 ir.ui.view qweb New
report_simple_label_dymo report_simple_label_dymo ir.ui.view qweb New
res_config_settings_view_form res.config.settings.view.form.inherit.product res.config.settings xpath Inherits base_setup.res_config_settings_view_form
view_partner_property_form res.partner.product.property.form.inherit res.partner group Inherits base.view_partner_form
Models touched (41)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (1)
  • create(self, vals_list)
    @api.model_create_multi
    Create product.document for attachments added in products chatters

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (8)
  • attribute_line_ids One2many → product.template.attribute.line
    comodel_name='product.template.attribute.line' inverse_name='attribute_id' string='Lines'
  • create_variant Selection
    default='always' help='- Instantly: All possible variants are created as soon as the attribute and its values are added to a product.\n - Dynamically: Each variant is created only when its corresponding attributes and values are added to a sales order.\n - Never: Variants are never created for the attribute.\n Note: the variants creation mode cannot be changed once the attribute is used on at least one product.' required=True selection=[('always', 'Instantly'), ('dynamic', 'Dynamically'), ('no_variant', 'Never (option)')] string='Variants Creation Mode'
  • display_type Selection
    default='radio' help='The display type used in the Product Configurator.' required=True selection=[('radio', 'Radio'), ('pills', 'Pills'), ('select', 'Select'), ('color', 'Color'), ('multi', 'Multi-checkbox (option)')]
  • name Char
    required=True string='Attribute' translate=True
  • number_related_products Integer
    compute='_compute_number_related_products'
  • product_tmpl_ids Many2many → product.template
    comodel_name='product.template' compute='_compute_products' store=True string='Related Products'
  • sequence Integer
    default=20 help='Determine the display order' index=True string='Sequence'
  • value_ids One2many → product.attribute.value
    comodel_name='product.attribute.value' copy=True inverse_name='attribute_id' string='Values'
Public methods (2)
  • action_open_related_products(self)
  • write(self, vals)
    Override to make sure attribute type can't be changed if it's used on a product template. This is important to prevent because changing the type would make existing combinations invalid without recomputing them, and recomputing them might take too long and we don't want to change products without the user knowing about it.

New fields (3)
  • custom_product_template_attribute_value_id Many2one → product.template.attribute.value
    comodel_name='product.template.attribute.value' ondelete='restrict' required=True string='Attribute Value'
  • custom_value Char
    string='Custom Value'
  • name Char
    compute='_compute_name' string='Name'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (11)
  • attribute_id Many2one → product.attribute
    comodel_name='product.attribute' help='The attribute cannot be changed once the value is used on at least one product.' index=True ondelete='cascade' required=True string='Attribute'
  • color Integer
    default=_get_default_color string='Color Index'
  • default_extra_price Float
  • display_type Selection
    related='attribute_id.display_type'
  • html_color Char
    help="Here you can set a specific HTML color index (e.g. #ff0000) to display the color if the attribute type is 'Color'." string='Color'
  • image Image
    help='You can upload an image that will be used as the color of the attribute value.' max_height=70 max_width=70 string='Image'
  • is_custom Boolean
    help='Allow users to input custom values for this attribute value' string='Is custom value'
  • is_used_on_products Boolean
    compute='_compute_is_used_on_products' string='Used on Products'
  • name Char
    required=True string='Value' translate=True
  • pav_attribute_line_ids Many2many → product.template.attribute.line
    comodel_name='product.template.attribute.line' copy=False relation='product_attribute_value_product_template_attribute_line_rel' string='Lines'
  • sequence Integer
    help='Determine the display order' index=True string='Sequence'
Public methods (1)
  • write(self, values)

New fields (0)

No new fields.

Public methods (1)
  • action_add_from_catalog(self)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (7)
  • child_id One2many → product.category
    args: 'product.category', 'parent_id', 'Child Categories'
  • complete_name Char
    compute='_compute_complete_name' recursive=True store=True args: 'Complete Name'
  • name Char
    index='trigram' required=True args: 'Name'
  • parent_id Many2one → product.category
    index=True ondelete='cascade' args: 'product.category', 'Parent Category'
  • parent_path Char
    index=True unaccent=False
  • product_count Integer
    compute='_compute_product_count' help='The number of products under this category (Does not consider the children categories)' args: '# Products'
  • product_properties_definition PropertiesDefinition
    args: 'Product Properties'
Public methods (1)
  • name_create(self, name)
    @api.model

New fields (2)
  • active Boolean
    default=True
  • ir_attachment_id Many2one → ir.attachment
    ondelete='cascade' required=True string='Related attachment' args: 'ir.attachment'
Public methods (3)
  • copy(self, default=None)
  • create(self, vals_list)
    @api.model_create_multi
  • unlink(self)

New fields (8)
  • columns Integer
    compute='_compute_dimensions'
  • custom_quantity Integer
    default=1 required=True args: 'Quantity'
  • extra_html Html
    default='' args: 'Extra Content'
  • pricelist_id Many2one → product.pricelist
    string='Pricelist' args: 'product.pricelist'
  • print_format Selection
    default='2x7xprice' required=True string='Format' args: [('dymo', 'Dymo'), ('2x7xprice', '2 x 7 with price'), ('4x7xprice', '4 x 7 with price'), ('4x12', '4 x 12'), ('4x12xprice', '4 x 12 with price')]
  • product_ids Many2many → product.product
    args: 'product.product'
  • product_tmpl_ids Many2many → product.template
    args: 'product.template'
  • rows Integer
    compute='_compute_dimensions'
Public methods (1)
  • process(self)

New fields (7)
  • barcode Char
    copy=False help='Barcode used for packaging identification. Scan this packaging barcode from a transfer in the Barcode app to move all the contained units' args: 'Barcode'
  • company_id Many2one → res.company
    index=True args: 'res.company', 'Company'
  • name Char
    required=True args: 'Product Packaging'
  • product_id Many2one → product.product
    check_company=True ondelete='cascade' required=True string='Product' args: 'product.product'
  • product_uom_id Many2one → uom.uom
    readonly=True related='product_id.uom_id' args: 'uom.uom'
  • qty Float
    default=1 digits='Product Unit of Measure' help='Quantity of products contained in the packaging.' args: 'Contained Quantity'
  • sequence Integer
    default=1 help='The first in the sequence is the default one.' args: 'Sequence'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (8)
  • active Boolean
    default=True help='If unchecked, it will allow you to hide the pricelist without removing it.' string='Active'
  • company_id Many2one → res.company
    comodel_name='res.company' default=<expr> tracking=5
  • country_group_ids Many2many → res.country.group
    column1='pricelist_id' column2='res_country_group_id' comodel_name='res.country.group' relation='res_country_group_pricelist_rel' string='Country Groups' tracking=10
  • currency_id Many2one → res.currency
    comodel_name='res.currency' default=_default_currency_id required=True tracking=1
  • discount_policy Selection
    default='with_discount' required=True selection=[('with_discount', 'Discount included in the price'), ('without_discount', 'Show public price & discount to the customer')] tracking=15
  • item_ids One2many → product.pricelist.item
    comodel_name='product.pricelist.item' copy=True domain=['&', '|', ('product_tmpl_id', '=', None), ('product_tmpl_id.active', '=', True), '|', ('product_id', '=', None), ('product_id.active', '=', True)] inverse_name='pricelist_id' string='Pricelist Rules'
  • name Char
    required=True string='Pricelist Name' translate=True
  • sequence Integer
    default=16
Public methods (3)
  • copy_data(self, default=None)
  • get_import_templates(self)
    @api.model
  • write(self, values)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (23)
  • applied_on Selection
    default='3_global' help='Pricelist Item applicable on selected option' required=True selection=[('3_global', 'All Products'), ('2_product_category', 'Product Category'), ('1_product', 'Product'), ('0_product_variant', 'Product Variant')] string='Apply On'
  • base Selection
    default='list_price' help='Base price for computation.\nSales Price: The base price will be the Sales Price.\nCost Price: The base price will be the cost price.\nOther Pricelist: Computation of the base price based on another Pricelist.' required=True selection=[('list_price', 'Sales Price'), ('standard_price', 'Cost'), ('pricelist', 'Other Pricelist')] string='Based on'
  • base_pricelist_id Many2one → product.pricelist
    check_company=True args: 'product.pricelist', 'Other Pricelist'
  • categ_id Many2one → product.category
    comodel_name='product.category' help='Specify a product category if this rule only applies to products belonging to this category or its children categories. Keep empty otherwise.' ondelete='cascade' string='Product Category'
  • company_id Many2one
    related='pricelist_id.company_id' store=True
  • compute_price Selection
    default='fixed' index=True required=True selection=[('fixed', 'Fixed Price'), ('percentage', 'Discount'), ('formula', 'Formula')]
  • currency_id Many2one
    related='pricelist_id.currency_id' store=True
  • date_end Datetime
    help='Ending datetime for the pricelist item validation\nThe displayed value depends on the timezone set in your preferences.' string='End Date'
  • date_start Datetime
    help='Starting datetime for the pricelist item validation\nThe displayed value depends on the timezone set in your preferences.' string='Start Date'
  • fixed_price Float
    digits='Product Price' string='Fixed Price'
  • min_quantity Float
    default=0 digits='Product Unit of Measure' help='For the rule to apply, bought/sold quantity must be greater than or equal to the minimum quantity specified in this field.\nExpressed in the default unit of measure of the product.' string='Min. Quantity'
  • name Char
    compute='_compute_name_and_price' help='Explicit rule name for this pricelist line.' string='Name'
  • percent_price Float
    help='You can apply a mark-up by setting a negative discount.' string='Percentage Price'
  • price Char
    compute='_compute_name_and_price' help='Explicit rule name for this pricelist line.' string='Price'
  • price_discount Float
    default=0 digits=(16, 2) help='You can apply a mark-up by setting a negative discount.' string='Price Discount'
  • price_max_margin Float
    digits='Product Price' help='Specify the maximum amount of margin over the base price.' string='Max. Price Margin'
  • price_min_margin Float
    digits='Product Price' help='Specify the minimum amount of margin over the base price.' string='Min. Price Margin'
  • price_round Float
    digits='Product Price' help='Sets the price so that it is a multiple of this value.\nRounding is applied after the discount and before the surcharge.\nTo have prices that end in 9.99, set rounding 10, surcharge -0.01' string='Price Rounding'
  • price_surcharge Float
    digits='Product Price' help='Specify the fixed amount to add or subtract (if negative) to the amount calculated with the discount.' string='Price Surcharge'
  • pricelist_id Many2one → product.pricelist
    comodel_name='product.pricelist' default=_default_pricelist_id index=True ondelete='cascade' required=True string='Pricelist'
  • product_id Many2one → product.product
    check_company=True comodel_name='product.product' help='Specify a product if this rule only applies to one product. Keep empty otherwise.' ondelete='cascade' string='Product Variant'
  • product_tmpl_id Many2one → product.template
    check_company=True comodel_name='product.template' help='Specify a template if this rule only applies to one product template. Keep empty otherwise.' ondelete='cascade' string='Product'
  • rule_tip Char
    compute='_compute_rule_tip'
Public methods (2)
  • create(self, vals_list)
    @api.model_create_multi
  • write(self, values)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (34)
  • active Boolean
    default=True help='If unchecked, it will allow you to hide the product without removing it.' args: 'Active'
  • additional_product_tag_ids Many2many → product.tag
    comodel_name='product.tag' domain="[('id', 'not in', product_tag_ids)]" relation='product_tag_product_product_rel' string='Additional Product Tags'
  • all_product_tag_ids Many2many → product.tag
    compute='_compute_all_product_tag_ids' search='_search_all_product_tag_ids' args: 'product.tag'
  • barcode Char
    copy=False help='International Article Number used for product identification.' index='btree_not_null' args: 'Barcode'
  • can_image_1024_be_zoomed Boolean
    compute='_compute_can_image_1024_be_zoomed' args: 'Can Image 1024 be zoomed'
  • can_image_variant_1024_be_zoomed Boolean
    compute='_compute_can_image_variant_1024_be_zoomed' store=True args: 'Can Variant Image 1024 be zoomed'
  • code Char
    compute='_compute_product_code' args: 'Reference'
  • combination_indices Char
    compute='_compute_combination_indices' index=True store=True
  • default_code Char
    index=True args: 'Internal Reference'
  • image_1024 Image
    compute='_compute_image_1024' args: 'Image 1024'
  • image_128 Image
    compute='_compute_image_128' args: 'Image 128'
  • image_1920 Image
    compute='_compute_image_1920' inverse='_set_image_1920' args: 'Image'
  • image_256 Image
    compute='_compute_image_256' args: 'Image 256'
  • image_512 Image
    compute='_compute_image_512' args: 'Image 512'
  • image_variant_1024 Image
    max_height=1024 max_width=1024 related='image_variant_1920' store=True args: 'Variant Image 1024'
  • image_variant_128 Image
    max_height=128 max_width=128 related='image_variant_1920' store=True args: 'Variant Image 128'
  • image_variant_1920 Image
    max_height=1920 max_width=1920 args: 'Variant Image'
  • image_variant_256 Image
    max_height=256 max_width=256 related='image_variant_1920' store=True args: 'Variant Image 256'
  • image_variant_512 Image
    max_height=512 max_width=512 related='image_variant_1920' store=True args: 'Variant Image 512'
  • is_product_variant Boolean
    compute='_compute_is_product_variant'
  • lst_price Float
    compute='_compute_product_lst_price' digits='Product Price' help="The sale price is managed from the product template. Click on the 'Configure Variants' button to set the extra attribute prices." inverse='_set_product_lst_price' args: 'Sales\xa0Price'
  • packaging_ids One2many → product.packaging
    help='Gives the different ways to package the same product.' args: 'product.packaging', 'product_id', 'Product Packages'
  • partner_ref Char
    compute='_compute_partner_ref' args: 'Customer Ref'
  • price_extra Float
    compute='_compute_product_price_extra' digits='Product Price' help='This is the sum of the extra price of all attributes' args: 'Variant Price Extra'
  • pricelist_item_count Integer
    compute='_compute_variant_item_count' args: 'Number of price rules'
  • product_document_count Integer
    compute='_compute_product_document_count' string='Documents Count'
  • product_document_ids One2many → product.document
    comodel_name='product.document' domain=<expr> inverse_name='res_id' string='Documents'
  • product_template_attribute_value_ids Many2many → product.template.attribute.value
    ondelete='restrict' relation='product_variant_combination' string='Attribute Values' args: 'product.template.attribute.value'
  • product_template_variant_value_ids Many2many → product.template.attribute.value
    domain=[('attribute_line_id.value_count', '>', 1)] ondelete='restrict' relation='product_variant_combination' string='Variant Values' args: 'product.template.attribute.value'
  • product_tmpl_id Many2one → product.template
    auto_join=True index=True ondelete='cascade' required=True args: 'product.template', 'Product Template'
  • standard_price Float
    company_dependent=True digits='Product Price' groups='base.group_user' help='Value of the product (automatically computed in AVCO).\n Used to value the product when the purchase cost is not known (e.g. inventory adjustment).\n Used to compute margins on sale orders.' args: 'Cost'
  • volume Float
    digits='Volume' args: 'Volume'
  • weight Float
    digits='Stock Weight' args: 'Weight'
  • write_date Datetime
    compute='_compute_write_date' store=True
Public methods (14)
  • action_open_documents(self)
  • action_open_label_layout(self)
  • copy(self, default=None)
    @api.returns('self', <expr>)
    Variants are generated depending on the configuration of attributes and values on the template, so copying them does not make sense. For convenience the template is copied instead and its first variant is returned.
  • create(self, vals_list)
    @api.model_create_multi
  • get_contextual_price(self)
  • get_empty_list_help(self, help_message)
    @api.model
  • get_product_multiline_description_sale(self)
    Compute a multiline description of this product, in the context of sales (do not use for purchases or other display reasons that don't intend to use "description_sale"). It will often be used as the default description of a sale order line referencing this product.
  • init(self)
    Ensure there is at most one active variant for each combination. There could be no variant for a combination if using dynamic attributes.
  • open_pricelist_rules(self)
  • open_product_template(self)
    Utility method used to add an "Open Template" button in product views
  • toggle_active(self)
    Archiving related product.template if there is not any more active product.product (and vice versa, unarchiving the related product template if there is now an active product.product)
  • unlink(self)
  • view_header_get(self, view_id, view_type)
    @api.model
  • write(self, values)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (17)
  • company_id Many2one → res.company
    default=<expr> index=1 args: 'res.company', 'Company'
  • currency_id Many2one → res.currency
    default=<expr> required=True args: 'res.currency', 'Currency'
  • date_end Date
    help='End date for this vendor price' args: 'End Date'
  • date_start Date
    help='Start date for this vendor price' args: 'Start Date'
  • delay Integer
    default=1 help='Lead time in days between the confirmation of the purchase order and the receipt of the products in your warehouse. Used by the scheduler for automatic computation of the purchase order planning.' required=True args: 'Delivery Lead Time'
  • discount Float
    digits='Discount' readonly=False string='Discount (%)'
  • min_qty Float
    default=0.0 digits='Product Unit of Measure' help='The quantity to purchase from this vendor to benefit from the price, expressed in the vendor Product Unit of Measure if not any, in the default unit of measure of the product otherwise.' required=True args: 'Quantity'
  • partner_id Many2one → res.partner
    check_company=True ondelete='cascade' required=True args: 'res.partner', 'Vendor'
  • price Float
    default=0.0 digits='Product Price' help='The price to purchase a product' required=True args: 'Price'
  • price_discounted Float
    compute='_compute_price_discounted' args: 'Discounted Price'
  • product_code Char
    help="This vendor's product code will be used when printing a request for quotation. Keep empty to use the internal one." args: 'Vendor Product Code'
  • product_id Many2one → product.product
    check_company=True default=_default_product_id domain="[('product_tmpl_id', '=', product_tmpl_id)] if product_tmpl_id else []" help='If not set, the vendor price will apply to all variants of this product.' args: 'product.product', 'Product Variant'
  • product_name Char
    help="This vendor's product name will be used when printing a request for quotation. Keep empty to use the internal one." args: 'Vendor Product Name'
  • product_tmpl_id Many2one → product.template
    check_company=True index=True ondelete='cascade' args: 'product.template', 'Product Template'
  • product_uom Many2one → uom.uom
    related='product_tmpl_id.uom_po_id' args: 'uom.uom', 'Unit of Measure'
  • product_variant_count Integer
    related='product_tmpl_id.product_variant_count' args: 'Variant Count'
  • sequence Integer
    default=1 help='Assigns the priority to the list of product vendor.' args: 'Sequence'
Public methods (3)
  • create(self, vals_list)
    @api.model_create_multi
  • get_import_templates(self)
    @api.model
  • write(self, vals)

New fields (5)
  • color Char
    default='#3C3C3C' string='Color'
  • name Char
    required=True string='Name' translate=True
  • product_ids Many2many → product.product
    compute='_compute_product_ids' search='_search_product_ids' string='All Product Variants using this Tag' args: 'product.product'
  • product_product_ids Many2many → product.product
    comodel_name='product.product' default=_get_default_variant_id domain="[('attribute_line_ids', '!=', False), ('product_tmpl_id', 'not in', product_template_ids)]" relation='product_tag_product_product_rel' string='Product Variants'
  • product_template_ids Many2many → product.template
    comodel_name='product.template' default=_get_default_template_id relation='product_tag_product_template_rel' string='Product Templates'
Public methods (1)
  • copy_data(self, default=None)
    @api.returns(None, <expr>)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (44)
  • active Boolean
    default=True help='If unchecked, it will allow you to hide the product without removing it.' args: 'Active'
  • attribute_line_ids One2many → product.template.attribute.line
    copy=True args: 'product.template.attribute.line', 'product_tmpl_id', 'Product Attributes'
  • barcode Char
    compute='_compute_barcode' inverse='_set_barcode' search='_search_barcode' args: 'Barcode'
  • can_image_1024_be_zoomed Boolean
    compute='_compute_can_image_1024_be_zoomed' store=True args: 'Can Image 1024 be zoomed'
  • categ_id Many2one → product.category
    change_default=True default=_get_default_category_id group_expand='_read_group_categ_id' required=True args: 'product.category', 'Product Category'
  • color Integer
    args: 'Color Index'
  • company_id Many2one → res.company
    index=True args: 'res.company', 'Company'
  • cost_currency_id Many2one → res.currency
    compute='_compute_cost_currency_id' args: 'res.currency', 'Cost Currency'
  • currency_id Many2one → res.currency
    compute='_compute_currency_id' args: 'res.currency', 'Currency'
  • default_code Char
    compute='_compute_default_code' inverse='_set_default_code' store=True args: 'Internal Reference'
  • description Html
    translate=True args: 'Description'
  • description_purchase Text
    translate=True args: 'Purchase Description'
  • description_sale Text
    help='A description of the Product that you want to communicate to your customers. This description will be copied to every Sales Order, Delivery Order and Customer Invoice/Credit Note' translate=True args: 'Sales Description'
  • detailed_type Selection
    default='consu' help='A storable product is a product for which you manage stock. The Inventory app has to be installed.\nA consumable product is a product for which stock is not managed.\nA service is a non-material product you provide.' required=True string='Product Type' args: [('consu', 'Consumable'), ('service', 'Service')]
  • has_configurable_attributes Boolean
    compute='_compute_has_configurable_attributes' store=True args: 'Is a configurable product'
  • is_product_variant Boolean
    compute='_compute_is_product_variant' string='Is a product variant'
  • list_price Float
    default=1.0 digits='Product Price' help='Price at which the product is sold to customers.' args: 'Sales Price'
  • name Char
    index='trigram' required=True translate=True args: 'Name'
  • packaging_ids One2many → product.packaging
    compute='_compute_packaging_ids' help='Gives the different ways to package the same product.' inverse='_set_packaging_ids' string='Product Packages' args: 'product.packaging'
  • pricelist_item_count Integer
    compute='_compute_item_count' args: 'Number of price rules'
  • priority Selection
    default='0' string='Favorite' args: [('0', 'Normal'), ('1', 'Favorite')]
  • product_document_count Integer
    compute='_compute_product_document_count' string='Documents Count'
  • product_document_ids One2many → product.document
    comodel_name='product.document' domain=<expr> inverse_name='res_id' string='Documents'
  • product_properties Properties
    copy=True definition='categ_id.product_properties_definition' args: 'Properties'
  • product_tag_ids Many2many → product.tag
    comodel_name='product.tag' relation='product_tag_product_template_rel' string='Product Template Tags'
  • product_tooltip Char
    compute='_compute_product_tooltip'
  • product_variant_count Integer
    compute='_compute_product_variant_count' args: '# Product Variants'
  • product_variant_id Many2one → product.product
    compute='_compute_product_variant_id' args: 'product.product', 'Product'
  • product_variant_ids One2many → product.product
    required=True args: 'product.product', 'product_tmpl_id', 'Products'
  • purchase_ok Boolean
    default=True args: 'Can be Purchased'
  • sale_ok Boolean
    default=True args: 'Can be Sold'
  • seller_ids One2many → product.supplierinfo
    depends_context=('company') args: 'product.supplierinfo', 'product_tmpl_id', 'Vendors'
  • sequence Integer
    default=1 help='Gives the sequence order when displaying a product list' args: 'Sequence'
  • standard_price Float
    compute='_compute_standard_price' digits='Product Price' groups='base.group_user' help='Value of the product (automatically computed in AVCO).\n Used to value the product when the purchase cost is not known (e.g. inventory adjustment).\n Used to compute margins on sale orders.' inverse='_set_standard_price' search='_search_standard_price' args: 'Cost'
  • type Selection
    compute='_compute_type' precompute=True readonly=False store=True args: [('consu', 'Consumable'), ('service', 'Service')]
  • uom_id Many2one → uom.uom
    default=_get_default_uom_id help='Default unit of measure used for all stock operations.' required=True args: 'uom.uom', 'Unit of Measure'
  • uom_name Char
    readonly=True related='uom_id.name' string='Unit of Measure Name'
  • uom_po_id Many2one → uom.uom
    compute='_compute_uom_po_id' help='Default unit of measure used for purchase orders. It must be in the same category as the default unit of measure.' precompute=True readonly=False required=True store=True args: 'uom.uom', 'Purchase UoM'
  • valid_product_template_attribute_line_ids Many2many → product.template.attribute.line
    compute='_compute_valid_product_template_attribute_line_ids' string='Valid Product Attribute Lines' args: 'product.template.attribute.line'
  • variant_seller_ids One2many → product.supplierinfo
    args: 'product.supplierinfo', 'product_tmpl_id'
  • volume Float
    compute='_compute_volume' digits='Volume' inverse='_set_volume' store=True args: 'Volume'
  • volume_uom_name Char
    compute='_compute_volume_uom_name' string='Volume unit of measure label'
  • weight Float
    compute='_compute_weight' digits='Stock Weight' inverse='_set_weight' store=True args: 'Weight'
  • weight_uom_name Char
    compute='_compute_weight_uom_name' string='Weight unit of measure label'
Public methods (11)
  • action_open_documents(self)
  • action_open_label_layout(self)
  • copy(self, default=None)
    @api.returns('self', <expr>)
  • create(self, vals_list)
    @api.model_create_multi
    Store the initial standard price in order to be able to retrieve the cost of a product template for a given date
  • get_contextual_price(self, product=None)
  • get_empty_list_help(self, help_message)
    @api.model
  • get_import_templates(self)
    @api.model
  • get_single_product_variant(self)
    Method used by the product configurator to check if the product is configurable or not. We need to open the product configurator if the product: - is configurable (see has_configurable_attributes) - has optional products (method is extended in sale to return optional products info) Note: self.ensure_one()
  • has_dynamic_attributes(self)
    Return whether this `product.template` has at least one dynamic attribute. :return: True if at least one dynamic attribute, False otherwise :rtype: bool
  • open_pricelist_rules(self)
  • write(self, vals)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (3)
  • product_template_attribute_value_id Many2one → product.template.attribute.value
    comodel_name='product.template.attribute.value' index=True ondelete='cascade' string='Attribute Value'
  • product_tmpl_id Many2one → product.template
    comodel_name='product.template' index=True ondelete='cascade' required=True string='Product Template'
  • value_ids Many2many → product.template.attribute.value
    comodel_name='product.template.attribute.value' domain="[('product_tmpl_id', '=', product_tmpl_id), ('ptav_active', '=', True)]" relation='product_attr_exclusion_value_ids_rel' string='Attribute Values'
Public methods (3)
  • create(self, vals_list)
    @api.model_create_multi
  • unlink(self)
  • write(self, values)

New fields (7)
  • active Boolean
    default=True
  • attribute_id Many2one → product.attribute
    comodel_name='product.attribute' index=True ondelete='restrict' required=True string='Attribute'
  • product_template_value_ids One2many → product.template.attribute.value
    comodel_name='product.template.attribute.value' inverse_name='attribute_line_id' string='Product Attribute Values'
  • product_tmpl_id Many2one → product.template
    comodel_name='product.template' index=True ondelete='cascade' required=True string='Product Template'
  • sequence Integer
    default=10 args: 'Sequence'
  • value_count Integer
    compute='_compute_value_count' store=True
  • value_ids Many2many → product.attribute.value
    comodel_name='product.attribute.value' domain="[('attribute_id', '=', attribute_id)]" ondelete='restrict' relation='product_attribute_value_product_template_attribute_line_rel' string='Values'
Public methods (4)
  • action_open_attribute_values(self)
  • create(self, vals_list)
    @api.model_create_multi
    Override to: - Activate archived lines having the same configuration (if they exist) instead of creating new lines. - Set up related values and related variants. Reactivating existing lines allows to re-use existing variants when possible, keeping their configuration and avoiding duplication.
  • unlink(self)
    Override to: - Archive the line if unlink is not possible. - Clean up related values and related variants. Archiving is typically needed when the line has values that can't be deleted because they are referenced elsewhere (on a variant that can't be deleted, on a sales order line, ...).
  • write(self, values)
    Override to: - Add constraints to prevent doing changes that are not supported such as modifying the template or the attribute of existing lines. - Clean up related values and related variants when archiving or when updating `value_ids`.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (15)
  • attribute_id Many2one
    index=True related='attribute_line_id.attribute_id' store=True
  • attribute_line_id Many2one → product.template.attribute.line
    comodel_name='product.template.attribute.line' index=True ondelete='cascade' required=True
  • color Integer
    default=_get_default_color string='Color'
  • currency_id Many2one
    related='attribute_line_id.product_tmpl_id.currency_id'
  • display_type Selection
    related='product_attribute_value_id.display_type'
  • exclude_for One2many → product.template.attribute.exclusion
    comodel_name='product.template.attribute.exclusion' help='Make this attribute value not compatible with other values of the product or some attribute values of optional and accessory products.' inverse_name='product_template_attribute_value_id' string='Exclude for'
  • html_color Char
    related='product_attribute_value_id.html_color' string='HTML Color Index'
  • image Image
    related='product_attribute_value_id.image'
  • is_custom Boolean
    related='product_attribute_value_id.is_custom'
  • name Char
    related='product_attribute_value_id.name' string='Value'
  • price_extra Float
    default=0.0 digits='Product Price' help='Extra price for the variant with this attribute value on sale price. eg. 200 price extra, 1000 + 200 = 1200.' string='Value Price Extra'
  • product_attribute_value_id Many2one → product.attribute.value
    comodel_name='product.attribute.value' index=True ondelete='cascade' required=True string='Attribute Value'
  • product_tmpl_id Many2one
    index=True related='attribute_line_id.product_tmpl_id' store=True
  • ptav_active Boolean
    default=True string='Active'
  • ptav_product_variant_ids Many2many → product.product
    comodel_name='product.product' readonly=True relation='product_variant_combination' string='Related Variants'
Public methods (3)
  • create(self, vals_list)
    @api.model_create_multi
  • unlink(self)
    Override to: - Clean up the variants that use any of the values in self: - Remove the value from the variant if the value belonged to an attribute line with only one value. - Unlink or archive all related variants. - Archive the value if unlink is not possible. Archiving is typically needed when the value is referenced elsewhere (on a variant that can't be deleted, on a sales order line, ...).
  • write(self, values)

New fields (0)

No new fields.

Public methods (1)
  • get_html(self, data)
    @api.model

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (2)
  • create(self, vals_list)
    @api.model_create_multi
  • write(self, vals)
    Delay the automatic creation of pricelists post-company update. This makes sure that the pricelist(s) automatically created are created with the right currency.

New fields (11)
  • group_discount_per_so_line Boolean
    implied_group='product.group_discount_per_so_line' args: 'Discounts'
  • group_product_pricelist Boolean
    implied_group='product.group_product_pricelist' args: 'Pricelists'
  • group_product_variant Boolean
    implied_group='product.group_product_variant' args: 'Variants'
  • group_sale_pricelist Boolean
    help='Allows to manage different prices based on rules per category of customers.\n Example: 10% for retailers, promotion of 5 EUR on this product, etc.' implied_group='product.group_sale_pricelist' args: 'Advanced Pricelists'
  • group_stock_packaging Boolean
    implied_group='product.group_stock_packaging' args: 'Product Packagings'
  • group_uom Boolean
    implied_group='uom.group_uom' args: 'Units of Measure'
  • module_loyalty Boolean
    args: 'Promotions, Coupons, Gift Card & Loyalty Program'
  • module_sale_product_matrix Boolean
    args: 'Sales Grid Entry'
  • product_pricelist_setting Selection
    config_parameter='product.product_pricelist_setting' default='basic' help='Multiple prices: Pricelists with fixed price rules by product,\nAdvanced rules: enables advanced price rules for pricelists.' string='Pricelists Method' args: [('basic', 'Multiple prices per product'), ('advanced', 'Advanced price rules (discounts, formulas)')]
  • product_volume_volume_in_cubic_feet Selection
    config_parameter='product.volume_in_cubic_feet' default='0' args: [('0', 'Cubic Meters'), ('1', 'Cubic Feet')], 'Volume unit of measure'
  • product_weight_in_lbs Selection
    config_parameter='product.weight_in_lbs' default='0' args: [('0', 'Kilograms'), ('1', 'Pounds')], 'Weight unit of measure'
Public methods (1)
  • set_values(self)

New fields (1)
  • pricelist_ids Many2many → product.pricelist
    column1='res_country_group_id' column2='pricelist_id' comodel_name='product.pricelist' relation='res_country_group_pricelist_rel' string='Pricelists'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (1)
  • write(self, vals)
    Archive pricelist when the linked currency is archived.

New fields (1)
  • property_product_pricelist Many2one → product.pricelist
    comodel_name='product.pricelist' company_dependent=False compute='_compute_product_pricelist' domain=<expr> help='This pricelist will be used, instead of the default one, for sales to the current partner' inverse='_inverse_product_pricelist' string='Pricelist'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/16.0/product
VERSION
VERSION 1.2
CATEGORY
CATEGORYSales/Sales
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Martin Trigaux, Fabien Pinckaers, Thibault Delavallée, Denis Ledoux, Christophe Simonis, Xavier Morel, Goffin Simon, Sylvain LE GAL, GitHub, Damien Bouvy, Yannick Tivisse, qsm-odoo, Pierre Masereel, Romain Derie, Jorge Pinna Puissant, Aurélien Warnon, Xavier-Do, Romeo Fragomeli, Victor Feyens, William Henrotin, Akim Juillerat, Florent de Labarre, svs-odoo, Lois Rilo, Samuel Degueldre, Adrien Widart, Ivan Yelizariev, Touati Djamel (otd), Tiffany Chang (tic), Rémy Voet (ryv), Gorash, Mathieu Duckerts-Antoine, Aurélien (avd), Arnaud Joset, William Braeckman, Romain Estievenart, Stefan-Calin Crainiciuc (stcc), Miquel Raïch, Laurent Desausoi (lade), momegahed, Bruno-brsy, william-andre, Julien Van Roy, Florian Damhaut, JF Aubert, thcl-odoo, Bruno Zanotti, Krzysztof Magusiak, Audric Onockx (auon), Yolann Sabaux, Antoine Vandevenne (anv), Thibault Libioulle, Jinjiu Liu, Demesmaeker, luvi, Achraf, Valentin Chevalier, niyasraphy, Simone Rubino, alsh-odoo, Louis Wicket (wil), Walid, Adrien Widart (awt), Victor Piryns (pivi), Nicolas Pierre, Valentin Vallaeys (vava), Ethan Hildick, Levi Siuzdak (sile), Maruan Aguerdouh (magm), Antoine (ande), Preksha Chouhan, paso-odoo, Uttam Pragda, Ahmed Khalaf (ahkh), adda-odoo, Nidhi Patel, Paul Stroobant, stefanorigano (SRI), boan-odoo, lase@odoo.com, Benjamin Hanquin (beha), Nathaniel (naja), Aktiv Software, mega, dere-odoo, Martin Trigaux (mat), Adesh Jolhe (adjo), Mathieu (mano), luve-odoo, khsr-odoo, kasm, TuyenTran, Carmine, Shrey Mehta
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:40:52
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - uom
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
This is the base module for managing products and pricelists in Odoo.
========================================================================

Products support variants, different pricing methods, vendors information,
make to stock/order, different units of measure, packaging and properties.

Pricelists support:
-------------------
    * Multiple-level of discount (by product, category, quantities)
    * Compute price based on different criteria:
        * Other pricelist
        * Cost price
        * List price
        * Vendor price

Pricelists preferences by product and/or partners.

Print product labels with barcode.
    

Code Analysis

Views touched (54)
XML IDNameModelTypeStatus
attribute_tree_view product.attribute.tree product.attribute tree New
inherits_website_sale_country_group_form res.country.group.form.inherit.product res.country.group group Inherits base.view_country_group_form
product_attribute_view_form product.attribute.form product.attribute form New
product_category_form_view product.category.form product.category form New
product_category_list_view product.category.list product.category tree New
product_category_search_view product.category.search product.category search New
product_kanban_view Product Kanban product.product kanban New
product_label_layout_form product.label.layout.form product.label.layout form New
product_normal_form_view product.product.form product.product form Inherits product.product_template_form_view
product_packaging_form_view product.packaging.form.view product.packaging form New
product_packaging_form_view2 product.packaging.form.view2 product.packaging xpath Inherits product.product_packaging_form_view
product_packaging_tree_view product.packaging.tree.view product.packaging tree New
product_packaging_tree_view2 product.packaging.tree.view2 product.packaging xpath Inherits product.product_packaging_tree_view
product_pricelist_item_form_view product.pricelist.item.form product.pricelist.item form New
product_pricelist_item_tree_view product.pricelist.item.tree product.pricelist.item tree New
product_pricelist_item_tree_view_from_product product.pricelist.item.tree product.pricelist.item tree New
product_pricelist_item_view_search product.pricelist.item.search product.pricelist.item search New
product_pricelist_view product.pricelist.form product.pricelist form New
product_pricelist_view_kanban product.pricelist.kanban product.pricelist kanban New
product_pricelist_view_search product.pricelist.search product.pricelist search New
product_pricelist_view_tree product.pricelist.tree product.pricelist tree New
product_product_tree_view product.product.tree product.product tree New
product_product_view_activity product.product.activity product.product activity New
product_search_form_view product.product.search product.product field Inherits product.product_template_search_view
product_supplierinfo_form_view product.supplierinfo.form.view product.supplierinfo form New
product_supplierinfo_search_view product.supplierinfo.search.view product.supplierinfo search New
product_supplierinfo_tree_view product.supplierinfo.tree.view product.supplierinfo tree New
product_supplierinfo_view_kanban product.supplierinfo.kanban product.supplierinfo kanban New
product_tag_form_view product.tag.form product.tag form New
product_tag_tree_view product.tag.tree product.tag tree New
product_template_attribute_line_form product.template.attribute.line.form product.template.attribute.line form New
product_template_attribute_value_view_form product.template.attribute.value.view.form. product.template.attribute.value form New
product_template_attribute_value_view_search product.template.attribute.value search New
product_template_attribute_value_view_tree product.template.attribute.value.view.tree product.template.attribute.value tree New
product_template_form_view product.template.common.form product.template form New
product_template_kanban_view Product.template.product.kanban product.template kanban New
product_template_only_form_view product.template.product.form product.template xpath Inherits product.product_template_form_view
product_template_search_view product.template.search product.template search New
product_template_tree_view product.template.product.tree product.template tree New
product_template_view_activity product.template.activity product.template activity New
product_variant_easy_edit_view product.product.view.form.easy product.product form New
report_packagingbarcode report_packagingbarcode ir.ui.view qweb New
report_pricelist report_pricelist ir.ui.view qweb New
report_pricelist_page report_pricelist_page ir.ui.view qweb New
report_productlabel report_productlabel ir.ui.view qweb New
report_productlabel_dymo report_productlabel_dymo ir.ui.view qweb New
report_producttemplatelabel report_producttemplatelabel ir.ui.view qweb New
report_producttemplatelabel_dymo report_producttemplatelabel_dymo ir.ui.view qweb New
report_simple_label2x7 report_simple_label2x7 ir.ui.view qweb New
report_simple_label4x12 report_simple_label4x12 ir.ui.view qweb New
report_simple_label4x7 report_simple_label4x7 ir.ui.view qweb New
report_simple_label_dymo report_simple_label_dymo ir.ui.view qweb New
res_config_settings_view_form res.config.settings.view.form.inherit.product res.config.settings xpath Inherits base_setup.res_config_settings_view_form
view_partner_property_form res.partner.product.property.form.inherit res.partner group Inherits base.view_partner_form
Models touched (35)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (8)
  • attribute_line_ids One2many → product.template.attribute.line
    args: 'product.template.attribute.line', 'attribute_id', 'Lines'
  • create_variant Selection
    default='always' help='- Instantly: All possible variants are created as soon as the attribute and its values are added to a product.\n - Dynamically: Each variant is created only when its corresponding attributes and values are added to a sales order.\n - Never: Variants are never created for the attribute.\n Note: the variants creation mode cannot be changed once the attribute is used on at least one product.' required=True string='Variants Creation Mode' args: [('always', 'Instantly'), ('dynamic', 'Dynamically'), ('no_variant', 'Never (option)')]
  • display_type Selection
    default='radio' help='The display type used in the Product Configurator.' required=True args: [('radio', 'Radio'), ('pills', 'Pills'), ('select', 'Select'), ('color', 'Color')]
  • name Char
    required=True translate=True args: 'Attribute'
  • number_related_products Integer
    compute='_compute_number_related_products'
  • product_tmpl_ids Many2many → product.template
    compute='_compute_products' store=True string='Related Products' args: 'product.template'
  • sequence Integer
    default=20 help='Determine the display order' index=True args: 'Sequence'
  • value_ids One2many → product.attribute.value
    copy=True args: 'product.attribute.value', 'attribute_id', 'Values'
Public methods (2)
  • action_open_related_products(self)
  • write(self, vals)
    Override to make sure attribute type can't be changed if it's used on a product template. This is important to prevent because changing the type would make existing combinations invalid without recomputing them, and recomputing them might take too long and we don't want to change products without the user knowing about it.

New fields (3)
  • custom_product_template_attribute_value_id Many2one → product.template.attribute.value
    ondelete='restrict' required=True string='Attribute Value' args: 'product.template.attribute.value'
  • custom_value Char
    args: 'Custom Value'
  • name Char
    compute='_compute_name' args: 'Name'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (9)
  • attribute_id Many2one → product.attribute
    help='The attribute cannot be changed once the value is used on at least one product.' index=True ondelete='cascade' required=True string='Attribute' args: 'product.attribute'
  • color Integer
    default=_get_default_color args: 'Color Index'
  • display_type Selection
    readonly=True related='attribute_id.display_type'
  • html_color Char
    help="Here you can set a specific HTML color index (e.g. #ff0000) to display the color if the attribute type is 'Color'." string='Color'
  • is_custom Boolean
    help='Allow users to input custom values for this attribute value' args: 'Is custom value'
  • is_used_on_products Boolean
    compute='_compute_is_used_on_products' args: 'Used on Products'
  • name Char
    required=True string='Value' translate=True
  • pav_attribute_line_ids Many2many → product.template.attribute.line
    copy=False relation='product_attribute_value_product_template_attribute_line_rel' string='Lines' args: 'product.template.attribute.line'
  • sequence Integer
    help='Determine the display order' index=True string='Sequence'
Public methods (2)
  • name_get(self)
    Override because in general the name of the value is confusing if it is displayed without the name of the corresponding attribute. Eg. on product list & kanban views, on BOM form view However during variant set up (on the product template form) the name of the attribute is already on each line so there is no need to repeat it on every value.
  • write(self, values)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (6)
  • child_id One2many → product.category
    args: 'product.category', 'parent_id', 'Child Categories'
  • complete_name Char
    compute='_compute_complete_name' recursive=True store=True args: 'Complete Name'
  • name Char
    index='trigram' required=True args: 'Name'
  • parent_id Many2one → product.category
    index=True ondelete='cascade' args: 'product.category', 'Parent Category'
  • parent_path Char
    index=True unaccent=False
  • product_count Integer
    compute='_compute_product_count' help='The number of products under this category (Does not consider the children categories)' args: '# Products'
Public methods (2)
  • name_create(self, name)
    @api.model
  • name_get(self)

New fields (7)
  • columns Integer
    compute='_compute_dimensions'
  • custom_quantity Integer
    default=1 required=True args: 'Quantity'
  • extra_html Html
    default='' args: 'Extra Content'
  • print_format Selection
    default='2x7xprice' required=True string='Format' args: [('dymo', 'Dymo'), ('2x7xprice', '2 x 7 with price'), ('4x7xprice', '4 x 7 with price'), ('4x12', '4 x 12'), ('4x12xprice', '4 x 12 with price')]
  • product_ids Many2many → product.product
    args: 'product.product'
  • product_tmpl_ids Many2many → product.template
    args: 'product.template'
  • rows Integer
    compute='_compute_dimensions'
Public methods (1)
  • process(self)

New fields (7)
  • barcode Char
    copy=False help='Barcode used for packaging identification. Scan this packaging barcode from a transfer in the Barcode app to move all the contained units' args: 'Barcode'
  • company_id Many2one → res.company
    index=True args: 'res.company', 'Company'
  • name Char
    required=True args: 'Product Packaging'
  • product_id Many2one → product.product
    check_company=True string='Product' args: 'product.product'
  • product_uom_id Many2one → uom.uom
    readonly=True related='product_id.uom_id' args: 'uom.uom'
  • qty Float
    default=1 digits='Product Unit of Measure' help='Quantity of products contained in the packaging.' args: 'Contained Quantity'
  • sequence Integer
    default=1 help='The first in the sequence is the default one.' args: 'Sequence'
Public methods (1)
  • write(self, vals)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (8)
  • active Boolean
    default=True help='If unchecked, it will allow you to hide the pricelist without removing it.' string='Active'
  • company_id Many2one → res.company
    comodel_name='res.company'
  • country_group_ids Many2many → res.country.group
    column1='pricelist_id' column2='res_country_group_id' comodel_name='res.country.group' relation='res_country_group_pricelist_rel' string='Country Groups'
  • currency_id Many2one → res.currency
    comodel_name='res.currency' default=_default_currency_id required=True
  • discount_policy Selection
    default='with_discount' required=True selection=[('with_discount', 'Discount included in the price'), ('without_discount', 'Show public price & discount to the customer')]
  • item_ids One2many → product.pricelist.item
    comodel_name='product.pricelist.item' copy=True inverse_name='pricelist_id' string='Pricelist Rules'
  • name Char
    required=True string='Pricelist Name' translate=True
  • sequence Integer
    default=16
Public methods (2)
  • get_import_templates(self)
    @api.model
  • name_get(self)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (24)
  • active Boolean
    related='pricelist_id.active' store=True
  • applied_on Selection
    default='3_global' help='Pricelist Item applicable on selected option' required=True selection=[('3_global', 'All Products'), ('2_product_category', 'Product Category'), ('1_product', 'Product'), ('0_product_variant', 'Product Variant')] string='Apply On'
  • base Selection
    default='list_price' help='Base price for computation.\nSales Price: The base price will be the Sales Price.\nCost Price : The base price will be the cost price.\nOther Pricelist : Computation of the base price based on another Pricelist.' required=True selection=[('list_price', 'Sales Price'), ('standard_price', 'Cost'), ('pricelist', 'Other Pricelist')] string='Based on'
  • base_pricelist_id Many2one → product.pricelist
    check_company=True args: 'product.pricelist', 'Other Pricelist'
  • categ_id Many2one → product.category
    comodel_name='product.category' help='Specify a product category if this rule only applies to products belonging to this category or its children categories. Keep empty otherwise.' ondelete='cascade' string='Product Category'
  • company_id Many2one
    related='pricelist_id.company_id' store=True
  • compute_price Selection
    default='fixed' index=True required=True selection=[('fixed', 'Fixed Price'), ('percentage', 'Discount'), ('formula', 'Formula')]
  • currency_id Many2one
    related='pricelist_id.currency_id' store=True
  • date_end Datetime
    help='Ending datetime for the pricelist item validation\nThe displayed value depends on the timezone set in your preferences.' string='End Date'
  • date_start Datetime
    help='Starting datetime for the pricelist item validation\nThe displayed value depends on the timezone set in your preferences.' string='Start Date'
  • fixed_price Float
    digits='Product Price' string='Fixed Price'
  • min_quantity Float
    default=0 digits='Product Unit of Measure' help='For the rule to apply, bought/sold quantity must be greater than or equal to the minimum quantity specified in this field.\nExpressed in the default unit of measure of the product.' string='Min. Quantity'
  • name Char
    compute='_compute_name_and_price' help='Explicit rule name for this pricelist line.' string='Name'
  • percent_price Float
    help='You can apply a mark-up by setting a negative discount.' string='Percentage Price'
  • price Char
    compute='_compute_name_and_price' help='Explicit rule name for this pricelist line.' string='Price'
  • price_discount Float
    default=0 digits=(16, 2) help='You can apply a mark-up by setting a negative discount.' string='Price Discount'
  • price_max_margin Float
    digits='Product Price' help='Specify the maximum amount of margin over the base price.' string='Max. Price Margin'
  • price_min_margin Float
    digits='Product Price' help='Specify the minimum amount of margin over the base price.' string='Min. Price Margin'
  • price_round Float
    digits='Product Price' help='Sets the price so that it is a multiple of this value.\nRounding is applied after the discount and before the surcharge.\nTo have prices that end in 9.99, set rounding 10, surcharge -0.01' string='Price Rounding'
  • price_surcharge Float
    digits='Product Price' help='Specify the fixed amount to add or subtract (if negative) to the amount calculated with the discount.' string='Price Surcharge'
  • pricelist_id Many2one → product.pricelist
    comodel_name='product.pricelist' default=_default_pricelist_id index=True ondelete='cascade' required=True string='Pricelist'
  • product_id Many2one → product.product
    check_company=True comodel_name='product.product' help='Specify a product if this rule only applies to one product. Keep empty otherwise.' ondelete='cascade' string='Product Variant'
  • product_tmpl_id Many2one → product.template
    check_company=True comodel_name='product.template' help='Specify a template if this rule only applies to one product template. Keep empty otherwise.' ondelete='cascade' string='Product'
  • rule_tip Char
    compute='_compute_rule_tip'
Public methods (3)
  • create(self, vals_list)
    @api.model_create_multi
  • toggle_active(self)
  • write(self, values)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (31)
  • active Boolean
    default=True help='If unchecked, it will allow you to hide the product without removing it.' args: 'Active'
  • additional_product_tag_ids Many2many → product.tag
    args: 'product.tag', 'product_tag_product_product_rel'
  • all_product_tag_ids Many2many → product.tag
    compute='_compute_all_product_tag_ids' search='_search_all_product_tag_ids' args: 'product.tag'
  • barcode Char
    copy=False help='International Article Number used for product identification.' index='btree_not_null' args: 'Barcode'
  • can_image_1024_be_zoomed Boolean
    compute='_compute_can_image_1024_be_zoomed' args: 'Can Image 1024 be zoomed'
  • can_image_variant_1024_be_zoomed Boolean
    compute='_compute_can_image_variant_1024_be_zoomed' store=True args: 'Can Variant Image 1024 be zoomed'
  • code Char
    compute='_compute_product_code' args: 'Reference'
  • combination_indices Char
    compute='_compute_combination_indices' index=True store=True
  • default_code Char
    index=True args: 'Internal Reference'
  • image_1024 Image
    compute='_compute_image_1024' args: 'Image 1024'
  • image_128 Image
    compute='_compute_image_128' args: 'Image 128'
  • image_1920 Image
    compute='_compute_image_1920' inverse='_set_image_1920' args: 'Image'
  • image_256 Image
    compute='_compute_image_256' args: 'Image 256'
  • image_512 Image
    compute='_compute_image_512' args: 'Image 512'
  • image_variant_1024 Image
    max_height=1024 max_width=1024 related='image_variant_1920' store=True args: 'Variant Image 1024'
  • image_variant_128 Image
    max_height=128 max_width=128 related='image_variant_1920' store=True args: 'Variant Image 128'
  • image_variant_1920 Image
    max_height=1920 max_width=1920 args: 'Variant Image'
  • image_variant_256 Image
    max_height=256 max_width=256 related='image_variant_1920' store=True args: 'Variant Image 256'
  • image_variant_512 Image
    max_height=512 max_width=512 related='image_variant_1920' store=True args: 'Variant Image 512'
  • is_product_variant Boolean
    compute='_compute_is_product_variant'
  • lst_price Float
    compute='_compute_product_lst_price' digits='Product Price' help="The sale price is managed from the product template. Click on the 'Configure Variants' button to set the extra attribute prices." inverse='_set_product_lst_price' args: 'Sales\xa0Price'
  • packaging_ids One2many → product.packaging
    help='Gives the different ways to package the same product.' args: 'product.packaging', 'product_id', 'Product Packages'
  • partner_ref Char
    compute='_compute_partner_ref' args: 'Customer Ref'
  • price_extra Float
    compute='_compute_product_price_extra' digits='Product Price' help='This is the sum of the extra price of all attributes' args: 'Variant Price Extra'
  • pricelist_item_count Integer
    compute='_compute_variant_item_count' args: 'Number of price rules'
  • product_template_attribute_value_ids Many2many → product.template.attribute.value
    ondelete='restrict' relation='product_variant_combination' string='Attribute Values' args: 'product.template.attribute.value'
  • product_template_variant_value_ids Many2many → product.template.attribute.value
    domain=[('attribute_line_id.value_count', '>', 1)] ondelete='restrict' relation='product_variant_combination' string='Variant Values' args: 'product.template.attribute.value'
  • product_tmpl_id Many2one → product.template
    auto_join=True index=True ondelete='cascade' required=True args: 'product.template', 'Product Template'
  • standard_price Float
    company_dependent=True digits='Product Price' groups='base.group_user' help='In Standard Price & AVCO: value of the product (automatically computed in AVCO).\n In FIFO: value of the next unit that will leave the stock (automatically computed).\n Used to value the product when the purchase cost is not known (e.g. inventory adjustment).\n Used to compute margins on sale orders.' args: 'Cost'
  • volume Float
    digits='Volume' args: 'Volume'
  • weight Float
    digits='Stock Weight' args: 'Weight'
Public methods (15)
  • action_open_label_layout(self)
  • copy(self, default=None)
    @api.returns('self', <expr>)
    Variants are generated depending on the configuration of attributes and values on the template, so copying them does not make sense. For convenience the template is copied instead and its first variant is returned.
  • create(self, vals_list)
    @api.model_create_multi
  • get_contextual_price(self)
  • get_empty_list_help(self, help)
    @api.model
  • get_product_multiline_description_sale(self)
    Compute a multiline description of this product, in the context of sales (do not use for purchases or other display reasons that don't intend to use "description_sale"). It will often be used as the default description of a sale order line referencing this product.
  • init(self)
    Ensure there is at most one active variant for each combination. There could be no variant for a combination if using dynamic attributes.
  • name_get(self)
  • open_pricelist_rules(self)
  • open_product_template(self)
    Utility method used to add an "Open Template" button in product views
  • price_compute(self, price_type, uom=None, currency=None, company=None, date=False)
  • toggle_active(self)
    Archiving related product.template if there is not any more active product.product (and vice versa, unarchiving the related product template if there is now an active product.product)
  • unlink(self)
  • view_header_get(self, view_id, view_type)
    @api.model
  • write(self, values)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (15)
  • company_id Many2one → res.company
    default=<expr> index=1 args: 'res.company', 'Company'
  • currency_id Many2one → res.currency
    default=<expr> required=True args: 'res.currency', 'Currency'
  • date_end Date
    help='End date for this vendor price' args: 'End Date'
  • date_start Date
    help='Start date for this vendor price' args: 'Start Date'
  • delay Integer
    default=1 help='Lead time in days between the confirmation of the purchase order and the receipt of the products in your warehouse. Used by the scheduler for automatic computation of the purchase order planning.' required=True args: 'Delivery Lead Time'
  • min_qty Float
    default=0.0 digits='Product Unit of Measure' help='The quantity to purchase from this vendor to benefit from the price, expressed in the vendor Product Unit of Measure if not any, in the default unit of measure of the product otherwise.' required=True args: 'Quantity'
  • partner_id Many2one → res.partner
    check_company=True ondelete='cascade' required=True args: 'res.partner', 'Vendor'
  • price Float
    default=0.0 digits='Product Price' help='The price to purchase a product' required=True args: 'Price'
  • product_code Char
    help="This vendor's product code will be used when printing a request for quotation. Keep empty to use the internal one." args: 'Vendor Product Code'
  • product_id Many2one → product.product
    check_company=True default=_default_product_id domain=_domain_product_id help='If not set, the vendor price will apply to all variants of this product.' args: 'product.product', 'Product Variant'
  • product_name Char
    help="This vendor's product name will be used when printing a request for quotation. Keep empty to use the internal one." args: 'Vendor Product Name'
  • product_tmpl_id Many2one → product.template
    check_company=True index=True ondelete='cascade' args: 'product.template', 'Product Template'
  • product_uom Many2one → uom.uom
    related='product_tmpl_id.uom_po_id' args: 'uom.uom', 'Unit of Measure'
  • product_variant_count Integer
    related='product_tmpl_id.product_variant_count' args: 'Variant Count'
  • sequence Integer
    default=1 help='Assigns the priority to the list of product vendor.' args: 'Sequence'
Public methods (3)
  • create(self, vals_list)
    @api.model_create_multi
  • get_import_templates(self)
    @api.model
  • write(self, vals)

New fields (5)
  • color Integer
    default=_get_default_color args: 'Color'
  • name Char
    required=True translate=True args: 'Tag Name'
  • product_ids Many2many → product.product
    compute='_compute_product_ids' search='_search_product_ids' string='All Product Variants using this Tag' args: 'product.product'
  • product_product_ids Many2many → product.product
    args: 'product.product', 'product_tag_product_product_rel'
  • product_template_ids Many2many → product.template
    args: 'product.template', 'product_tag_product_template_rel'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (41)
  • active Boolean
    default=True help='If unchecked, it will allow you to hide the product without removing it.' args: 'Active'
  • attribute_line_ids One2many → product.template.attribute.line
    copy=True args: 'product.template.attribute.line', 'product_tmpl_id', 'Product Attributes'
  • barcode Char
    compute='_compute_barcode' inverse='_set_barcode' search='_search_barcode' args: 'Barcode'
  • can_image_1024_be_zoomed Boolean
    compute='_compute_can_image_1024_be_zoomed' store=True args: 'Can Image 1024 be zoomed'
  • categ_id Many2one → product.category
    change_default=True default=_get_default_category_id group_expand='_read_group_categ_id' required=True args: 'product.category', 'Product Category'
  • color Integer
    args: 'Color Index'
  • company_id Many2one → res.company
    index=True args: 'res.company', 'Company'
  • cost_currency_id Many2one → res.currency
    compute='_compute_cost_currency_id' args: 'res.currency', 'Cost Currency'
  • currency_id Many2one → res.currency
    compute='_compute_currency_id' args: 'res.currency', 'Currency'
  • default_code Char
    compute='_compute_default_code' inverse='_set_default_code' store=True args: 'Internal Reference'
  • description Html
    translate=True args: 'Description'
  • description_purchase Text
    translate=True args: 'Purchase Description'
  • description_sale Text
    help='A description of the Product that you want to communicate to your customers. This description will be copied to every Sales Order, Delivery Order and Customer Invoice/Credit Note' translate=True args: 'Sales Description'
  • detailed_type Selection
    default='consu' help='A storable product is a product for which you manage stock. The Inventory app has to be installed.\nA consumable product is a product for which stock is not managed.\nA service is a non-material product you provide.' required=True string='Product Type' args: [('consu', 'Consumable'), ('service', 'Service')]
  • has_configurable_attributes Boolean
    compute='_compute_has_configurable_attributes' store=True args: 'Is a configurable product'
  • is_product_variant Boolean
    compute='_compute_is_product_variant' string='Is a product variant'
  • list_price Float
    default=1.0 digits='Product Price' help='Price at which the product is sold to customers.' args: 'Sales Price'
  • name Char
    index='trigram' required=True translate=True args: 'Name'
  • packaging_ids One2many → product.packaging
    compute='_compute_packaging_ids' help='Gives the different ways to package the same product.' inverse='_set_packaging_ids' string='Product Packages' args: 'product.packaging'
  • pricelist_item_count Integer
    compute='_compute_item_count' args: 'Number of price rules'
  • priority Selection
    default='0' string='Favorite' args: [('0', 'Normal'), ('1', 'Favorite')]
  • product_tag_ids Many2many → product.tag
    string='Product Tags' args: 'product.tag', 'product_tag_product_template_rel'
  • product_tooltip Char
    compute='_compute_product_tooltip'
  • product_variant_count Integer
    compute='_compute_product_variant_count' args: '# Product Variants'
  • product_variant_id Many2one → product.product
    compute='_compute_product_variant_id' args: 'product.product', 'Product'
  • product_variant_ids One2many → product.product
    required=True args: 'product.product', 'product_tmpl_id', 'Products'
  • purchase_ok Boolean
    default=True args: 'Can be Purchased'
  • sale_ok Boolean
    default=True args: 'Can be Sold'
  • seller_ids One2many → product.supplierinfo
    depends_context=('company') args: 'product.supplierinfo', 'product_tmpl_id', 'Vendors'
  • sequence Integer
    default=1 help='Gives the sequence order when displaying a product list' args: 'Sequence'
  • standard_price Float
    compute='_compute_standard_price' digits='Product Price' groups='base.group_user' help='In Standard Price & AVCO: value of the product (automatically computed in AVCO).\n In FIFO: value of the next unit that will leave the stock (automatically computed).\n Used to value the product when the purchase cost is not known (e.g. inventory adjustment).\n Used to compute margins on sale orders.' inverse='_set_standard_price' search='_search_standard_price' args: 'Cost'
  • type Selection
    compute='_compute_type' precompute=True readonly=False store=True args: [('consu', 'Consumable'), ('service', 'Service')]
  • uom_id Many2one → uom.uom
    default=_get_default_uom_id help='Default unit of measure used for all stock operations.' required=True args: 'uom.uom', 'Unit of Measure'
  • uom_name Char
    readonly=True related='uom_id.name' string='Unit of Measure Name'
  • uom_po_id Many2one → uom.uom
    default=_get_default_uom_po_id help='Default unit of measure used for purchase orders. It must be in the same category as the default unit of measure.' required=True args: 'uom.uom', 'Purchase UoM'
  • valid_product_template_attribute_line_ids Many2many → product.template.attribute.line
    compute='_compute_valid_product_template_attribute_line_ids' string='Valid Product Attribute Lines' args: 'product.template.attribute.line'
  • variant_seller_ids One2many → product.supplierinfo
    args: 'product.supplierinfo', 'product_tmpl_id'
  • volume Float
    compute='_compute_volume' digits='Volume' inverse='_set_volume' store=True args: 'Volume'
  • volume_uom_name Char
    compute='_compute_volume_uom_name' string='Volume unit of measure label'
  • weight Float
    compute='_compute_weight' digits='Stock Weight' inverse='_set_weight' store=True args: 'Weight'
  • weight_uom_name Char
    compute='_compute_weight_uom_name' string='Weight unit of measure label'
Public methods (12)
  • action_open_label_layout(self)
  • copy(self, default=None)
    @api.returns('self', <expr>)
  • create(self, vals_list)
    @api.model_create_multi
    Store the initial standard price in order to be able to retrieve the cost of a product template for a given date
  • get_contextual_price(self, product=None)
  • get_empty_list_help(self, help)
    @api.model
  • get_import_templates(self)
    @api.model
  • get_single_product_variant(self)
    Method used by the product configurator to check if the product is configurable or not. We need to open the product configurator if the product: - is configurable (see has_configurable_attributes) - has optional products (method is extended in sale to return optional products info)
  • has_dynamic_attributes(self)
    Return whether this `product.template` has at least one dynamic attribute. :return: True if at least one dynamic attribute, False otherwise :rtype: bool
  • name_get(self)
  • open_pricelist_rules(self)
  • price_compute(self, price_type, uom=None, currency=None, company=None, date=False)
  • write(self, vals)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (3)
  • product_template_attribute_value_id Many2one → product.template.attribute.value
    index=True ondelete='cascade' string='Attribute Value' args: 'product.template.attribute.value'
  • product_tmpl_id Many2one → product.template
    index=True ondelete='cascade' required=True string='Product Template' args: 'product.template'
  • value_ids Many2many → product.template.attribute.value
    domain="[('product_tmpl_id', '=', product_tmpl_id), ('ptav_active', '=', True)]" relation='product_attr_exclusion_value_ids_rel' string='Attribute Values' args: 'product.template.attribute.value'
Public methods (3)
  • create(self, vals_list)
    @api.model_create_multi
  • unlink(self)
  • write(self, values)

New fields (6)
  • active Boolean
    default=True
  • attribute_id Many2one → product.attribute
    index=True ondelete='restrict' required=True string='Attribute' args: 'product.attribute'
  • product_template_value_ids One2many → product.template.attribute.value
    string='Product Attribute Values' args: 'product.template.attribute.value', 'attribute_line_id'
  • product_tmpl_id Many2one → product.template
    index=True ondelete='cascade' required=True string='Product Template' args: 'product.template'
  • value_count Integer
    compute='_compute_value_count' readonly=True store=True
  • value_ids Many2many → product.attribute.value
    domain="[('attribute_id', '=', attribute_id)]" ondelete='restrict' relation='product_attribute_value_product_template_attribute_line_rel' string='Values' args: 'product.attribute.value'
Public methods (4)
  • action_open_attribute_values(self)
  • create(self, vals_list)
    @api.model_create_multi
    Override to: - Activate archived lines having the same configuration (if they exist) instead of creating new lines. - Set up related values and related variants. Reactivating existing lines allows to re-use existing variants when possible, keeping their configuration and avoiding duplication.
  • unlink(self)
    Override to: - Archive the line if unlink is not possible. - Clean up related values and related variants. Archiving is typically needed when the line has values that can't be deleted because they are referenced elsewhere (on a variant that can't be deleted, on a sales order line, ...).
  • write(self, values)
    Override to: - Add constraints to prevent doing changes that are not supported such as modifying the template or the attribute of existing lines. - Clean up related values and related variants when archiving or when updating `value_ids`.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (14)
  • attribute_id Many2one → product.attribute
    index=True related='attribute_line_id.attribute_id' store=True string='Attribute' args: 'product.attribute'
  • attribute_line_id Many2one → product.template.attribute.line
    index=True ondelete='cascade' required=True args: 'product.template.attribute.line'
  • color Integer
    default=_get_default_color args: 'Color'
  • currency_id Many2one
    related='attribute_line_id.product_tmpl_id.currency_id'
  • display_type Selection
    readonly=True related='product_attribute_value_id.display_type'
  • exclude_for One2many → product.template.attribute.exclusion
    help='Make this attribute value not compatible with other values of the product or some attribute values of optional and accessory products.' string='Exclude for' args: 'product.template.attribute.exclusion', 'product_template_attribute_value_id'
  • html_color Char
    related='product_attribute_value_id.html_color' args: 'HTML Color Index'
  • is_custom Boolean
    related='product_attribute_value_id.is_custom' args: 'Is custom value'
  • name Char
    related='product_attribute_value_id.name' args: 'Value'
  • price_extra Float
    default=0.0 digits='Product Price' help='Extra price for the variant with this attribute value on sale price. eg. 200 price extra, 1000 + 200 = 1200.' string='Value Price Extra'
  • product_attribute_value_id Many2one → product.attribute.value
    index=True ondelete='cascade' required=True string='Attribute Value' args: 'product.attribute.value'
  • product_tmpl_id Many2one → product.template
    index=True related='attribute_line_id.product_tmpl_id' store=True string='Product Template' args: 'product.template'
  • ptav_active Boolean
    default=True args: 'Active'
  • ptav_product_variant_ids Many2many → product.product
    readonly=True relation='product_variant_combination' string='Related Variants' args: 'product.product'
Public methods (4)
  • create(self, vals_list)
    @api.model_create_multi
  • name_get(self)
    Override because in general the name of the value is confusing if it is displayed without the name of the corresponding attribute. Eg. on exclusion rules form
  • unlink(self)
    Override to: - Clean up the variants that use any of the values in self: - Remove the value from the variant if the value belonged to an attribute line with only one value. - Unlink or archive all related variants. - Archive the value if unlink is not possible. Archiving is typically needed when the value is referenced elsewhere (on a variant that can't be deleted, on a sales order line, ...).
  • write(self, values)

New fields (0)

No new fields.

Public methods (1)
  • get_html(self, data)
    @api.model

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (2)
  • create(self, vals_list)
    @api.model_create_multi
  • write(self, values)

New fields (11)
  • group_discount_per_so_line Boolean
    implied_group='product.group_discount_per_so_line' args: 'Discounts'
  • group_product_pricelist Boolean
    implied_group='product.group_product_pricelist' args: 'Pricelists'
  • group_product_variant Boolean
    implied_group='product.group_product_variant' args: 'Variants'
  • group_sale_pricelist Boolean
    help='Allows to manage different prices based on rules per category of customers.\n Example: 10% for retailers, promotion of 5 EUR on this product, etc.' implied_group='product.group_sale_pricelist' args: 'Advanced Pricelists'
  • group_stock_packaging Boolean
    implied_group='product.group_stock_packaging' args: 'Product Packagings'
  • group_uom Boolean
    implied_group='uom.group_uom' args: 'Units of Measure'
  • module_loyalty Boolean
    args: 'Promotions, Coupons, Gift Card & Loyalty Program'
  • module_sale_product_matrix Boolean
    args: 'Sales Grid Entry'
  • product_pricelist_setting Selection
    config_parameter='product.product_pricelist_setting' default='basic' help='Multiple prices: Pricelists with fixed price rules by product,\nAdvanced rules: enables advanced price rules for pricelists.' string='Pricelists Method' args: [('basic', 'Multiple prices per product'), ('advanced', 'Advanced price rules (discounts, formulas)')]
  • product_volume_volume_in_cubic_feet Selection
    config_parameter='product.volume_in_cubic_feet' default='0' args: [('0', 'Cubic Meters'), ('1', 'Cubic Feet')], 'Volume unit of measure'
  • product_weight_in_lbs Selection
    config_parameter='product.weight_in_lbs' default='0' args: [('0', 'Kilograms'), ('1', 'Pounds')], 'Weight unit of measure'
Public methods (1)
  • set_values(self)

New fields (1)
  • pricelist_ids Many2many → product.pricelist
    column1='res_country_group_id' column2='pricelist_id' comodel_name='product.pricelist' relation='res_country_group_pricelist_rel' string='Pricelists'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (1)
  • property_product_pricelist Many2one → product.pricelist
    comodel_name='product.pricelist' company_dependent=False compute='_compute_product_pricelist' domain=<expr> help='This pricelist will be used, instead of the default one, for sales to the current partner' inverse='_inverse_product_pricelist' string='Pricelist'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/15.0/product
VERSION
VERSION 1.2
CATEGORY
CATEGORYSales/Sales
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Martin Trigaux, Thibault Delavallée, Christophe Simonis, Aaron Bohy, Jeremy Kersten, GitHub, Barad Mahendra, Wolfgang Taferner, Yannick Tivisse, qsm-odoo, Romain Derie, Christophe Monniez, Arnold Moyaux, wan, Priyanka Kakadiya, Xavier-Do, Victor Feyens, Andrea Grazioso (agr-odoo), Fanny He, William Henrotin, Sébastien Theys, Julien Mougenot, Adrien Horgnies, Achraf (abz), Carlos Lopez, Adrien Widart, Ivan Yelizariev, Nasreddin Boulif (bon), Touati Djamel (otd), Nicolas Galler, Tiffany Chang (tic), Rémy Voet (ryv), Ivàn Todorovich, Aurélien (avd), nans, Pratima Gupta, Stefan-Calin Crainiciuc (stcc), roen-odoo, Benoit Socias, Miquel Raïch, Laurent Desausoi (lade), momegahed, Bruno-brsy, Nicolas (vin), william-andre, Julien Van Roy, Florian Damhaut, JF Aubert, yhu-odoo, thcl-odoo, Audric Onockx (auon), Yolann Sabaux, Jinjiu Liu, Laurent Stukkens (LTU), Demesmaeker, Michael Mattiello (mcm), Achraf, Valentin Chevalier, niyasraphy, Habib (ayh), Adrien Widart (awt), Victor Piryns (pivi), Valentin Vallaeys (vava), Levi Siuzdak (sile), Nam Dao, paso-odoo, Uttam Pragda, Stephan Keller, Paul Stroobant, MAHAMADASIF ANSARI, lase@odoo.com, Benjamin Hanquin (beha), Aktiv Software, mega, pilarvargas-tecnativa, dere-odoo
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:25:29
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - uom
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
This is the base module for managing products and pricelists in Odoo.
========================================================================

Products support variants, different pricing methods, vendors information,
make to stock/order, different units of measure, packaging and properties.

Pricelists support:
-------------------
    * Multiple-level of discount (by product, category, quantities)
    * Compute price based on different criteria:
        * Other pricelist
        * Cost price
        * List price
        * Vendor price

Pricelists preferences by product and/or partners.

Print product labels with barcode.
    

Code Analysis

Views touched (53)
XML IDNameModelTypeStatus
attribute_tree_view product.attribute.tree product.attribute tree New
inherits_website_sale_country_group_form website_sale.country_group.form res.country.group group Inherits base.view_country_group_form
product_attribute_view_form product.attribute.form product.attribute form New
product_category_form_view product.category.form product.category form New
product_category_list_view product.category.list product.category tree New
product_category_search_view product.category.search product.category search New
product_kanban_view Product Kanban product.product kanban New
product_label_layout_form product.label.layout.form product.label.layout form New
product_normal_form_view product.product.form product.product form Inherits product.product_template_form_view
product_packaging_form_view product.packaging.form.view product.packaging form New
product_packaging_form_view2 product.packaging.form.view2 product.packaging xpath Inherits product.product_packaging_form_view
product_packaging_tree_view product.packaging.tree.view product.packaging tree New
product_packaging_tree_view2 product.packaging.tree.view2 product.packaging xpath Inherits product.product_packaging_tree_view
product_pricelist_item_form_view product.pricelist.item.form product.pricelist.item form New
product_pricelist_item_tree_view product.pricelist.item.tree product.pricelist.item tree New
product_pricelist_item_tree_view_from_product product.pricelist.item.tree product.pricelist.item tree New
product_pricelist_item_view_search product.pricelist.item.search product.pricelist.item search New
product_pricelist_view product.pricelist.form product.pricelist form New
product_pricelist_view_inherit product.pricelist.form.inherit product.pricelist field Inherits product.product_pricelist_view
product_pricelist_view_kanban product.pricelist.kanban product.pricelist kanban New
product_pricelist_view_search product.pricelist.search product.pricelist search New
product_pricelist_view_tree product.pricelist.tree product.pricelist tree New
product_product_tree_view product.product.tree product.product tree New
product_product_view_activity product.product.activity product.product activity New
product_search_form_view product.product.search product.product field Inherits product.product_template_search_view
product_supplierinfo_form_view product.supplierinfo.form.view product.supplierinfo form New
product_supplierinfo_search_view product.supplierinfo.search.view product.supplierinfo search New
product_supplierinfo_tree_view product.supplierinfo.tree.view product.supplierinfo tree New
product_supplierinfo_view_kanban product.supplierinfo.kanban product.supplierinfo kanban New
product_template_attribute_line_form product.template.attribute.line.form product.template.attribute.line form New
product_template_attribute_value_view_form product.template.attribute.value.view.form. product.template.attribute.value form New
product_template_attribute_value_view_search product.template.attribute.value search New
product_template_attribute_value_view_tree product.template.attribute.value.view.tree product.template.attribute.value tree New
product_template_form_view product.template.common.form product.template form New
product_template_kanban_view Product.template.product.kanban product.template kanban New
product_template_only_form_view product.template.product.form product.template xpath Inherits product.product_template_form_view
product_template_search_view product.template.search product.template search New
product_template_tree_view product.template.product.tree product.template tree New
product_template_view_activity product.template.activity product.template activity New
product_variant_easy_edit_view product.product.view.form.easy product.product form New
report_packagingbarcode report_packagingbarcode ir.ui.view qweb New
report_pricelist report_pricelist ir.ui.view qweb New
report_pricelist_page report_pricelist_page ir.ui.view qweb New
report_productlabel report_productlabel ir.ui.view qweb New
report_productlabel_dymo report_productlabel_dymo ir.ui.view qweb New
report_producttemplatelabel report_producttemplatelabel ir.ui.view qweb New
report_producttemplatelabel_dymo report_producttemplatelabel_dymo ir.ui.view qweb New
report_simple_label2x7 report_simple_label2x7 ir.ui.view qweb New
report_simple_label4x12 report_simple_label4x12 ir.ui.view qweb New
report_simple_label4x7 report_simple_label4x7 ir.ui.view qweb New
report_simple_label_dymo report_simple_label_dymo ir.ui.view qweb New
res_config_settings_view_form res.config.settings.view.form.inherit.product res.config.settings xpath Inherits base_setup.res_config_settings_view_form
view_partner_property_form res.partner.product.property.form.inherit res.partner group Inherits base.view_partner_form
Models touched (34)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (8)
  • attribute_line_ids One2many → product.template.attribute.line
    args: 'product.template.attribute.line', 'attribute_id', 'Lines'
  • create_variant Selection
    default='always' help='- Instantly: All possible variants are created as soon as the attribute and its values are added to a product.\n - Dynamically: Each variant is created only when its corresponding attributes and values are added to a sales order.\n - Never: Variants are never created for the attribute.\n Note: the variants creation mode cannot be changed once the attribute is used on at least one product.' required=True string='Variants Creation Mode' args: [('always', 'Instantly'), ('dynamic', 'Dynamically'), ('no_variant', 'Never (option)')]
  • display_type Selection
    default='radio' help='The display type used in the Product Configurator.' required=True args: [('radio', 'Radio'), ('pills', 'Pills'), ('select', 'Select'), ('color', 'Color')]
  • name Char
    required=True translate=True args: 'Attribute'
  • number_related_products Integer
    compute='_compute_number_related_products'
  • product_tmpl_ids Many2many → product.template
    compute='_compute_products' store=True string='Related Products' args: 'product.template'
  • sequence Integer
    help='Determine the display order' index=True args: 'Sequence'
  • value_ids One2many → product.attribute.value
    copy=True args: 'product.attribute.value', 'attribute_id', 'Values'
Public methods (2)
  • action_open_related_products(self)
  • write(self, vals)
    Override to make sure attribute type can't be changed if it's used on a product template. This is important to prevent because changing the type would make existing combinations invalid without recomputing them, and recomputing them might take too long and we don't want to change products without the user knowing about it.

New fields (3)
  • custom_product_template_attribute_value_id Many2one → product.template.attribute.value
    ondelete='restrict' required=True string='Attribute Value' args: 'product.template.attribute.value'
  • custom_value Char
    args: 'Custom Value'
  • name Char
    compute='_compute_name' args: 'Name'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (9)
  • attribute_id Many2one → product.attribute
    help='The attribute cannot be changed once the value is used on at least one product.' index=True ondelete='cascade' required=True string='Attribute' args: 'product.attribute'
  • color Integer
    default=_get_default_color args: 'Color Index'
  • display_type Selection
    readonly=True related='attribute_id.display_type'
  • html_color Char
    help="Here you can set a specific HTML color index (e.g. #ff0000) to display the color if the attribute type is 'Color'." string='Color'
  • is_custom Boolean
    help='Allow users to input custom values for this attribute value' args: 'Is custom value'
  • is_used_on_products Boolean
    compute='_compute_is_used_on_products' args: 'Used on Products'
  • name Char
    required=True string='Value' translate=True
  • pav_attribute_line_ids Many2many → product.template.attribute.line
    copy=False relation='product_attribute_value_product_template_attribute_line_rel' string='Lines' args: 'product.template.attribute.line'
  • sequence Integer
    help='Determine the display order' index=True string='Sequence'
Public methods (2)
  • name_get(self)
    Override because in general the name of the value is confusing if it is displayed without the name of the corresponding attribute. Eg. on product list & kanban views, on BOM form view However during variant set up (on the product template form) the name of the attribute is already on each line so there is no need to repeat it on every value.
  • write(self, values)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (6)
  • child_id One2many → product.category
    args: 'product.category', 'parent_id', 'Child Categories'
  • complete_name Char
    compute='_compute_complete_name' recursive=True store=True args: 'Complete Name'
  • name Char
    index=True required=True args: 'Name'
  • parent_id Many2one → product.category
    index=True ondelete='cascade' args: 'product.category', 'Parent Category'
  • parent_path Char
    index=True
  • product_count Integer
    compute='_compute_product_count' help='The number of products under this category (Does not consider the children categories)' args: '# Products'
Public methods (2)
  • name_create(self, name)
    @api.model
  • name_get(self)

New fields (7)
  • columns Integer
    compute='_compute_dimensions'
  • custom_quantity Integer
    default=1 required=True args: 'Quantity'
  • extra_html Html
    default='' args: 'Extra Content'
  • print_format Selection
    default='2x7xprice' required=True string='Format' args: [('dymo', 'Dymo'), ('2x7xprice', '2 x 7 with price'), ('4x7xprice', '4 x 7 with price'), ('4x12', '4 x 12'), ('4x12xprice', '4 x 12 with price')]
  • product_ids Many2many → product.product
    args: 'product.product'
  • product_tmpl_ids Many2many → product.template
    args: 'product.template'
  • rows Integer
    compute='_compute_dimensions'
Public methods (1)
  • process(self)

New fields (7)
  • barcode Char
    copy=False help='Barcode used for packaging identification. Scan this packaging barcode from a transfer in the Barcode app to move all the contained units' args: 'Barcode'
  • company_id Many2one → res.company
    index=True args: 'res.company', 'Company'
  • name Char
    required=True args: 'Product Packaging'
  • product_id Many2one → product.product
    check_company=True string='Product' args: 'product.product'
  • product_uom_id Many2one → uom.uom
    readonly=True related='product_id.uom_id' args: 'uom.uom'
  • qty Float
    default=1 digits='Product Unit of Measure' help='Quantity of products contained in the packaging.' args: 'Contained Quantity'
  • sequence Integer
    default=1 help='The first in the sequence is the default one.' args: 'Sequence'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (8)
  • active Boolean
    default=True help='If unchecked, it will allow you to hide the pricelist without removing it.' args: 'Active'
  • company_id Many2one → res.company
    args: 'res.company', 'Company'
  • country_group_ids Many2many → res.country.group
    string='Country Groups' args: 'res.country.group', 'res_country_group_pricelist_rel', 'pricelist_id', 'res_country_group_id'
  • currency_id Many2one → res.currency
    default=_get_default_currency_id required=True args: 'res.currency', 'Currency'
  • discount_policy Selection
    default='with_discount' required=True args: [('with_discount', 'Discount included in the price'), ('without_discount', 'Show public price & discount to the customer')]
  • item_ids One2many → product.pricelist.item
    copy=True args: 'product.pricelist.item', 'pricelist_id', 'Pricelist Rules'
  • name Char
    required=True translate=True args: 'Pricelist Name'
  • sequence Integer
    default=16
Public methods (8)
  • get_import_templates(self)
    @api.model
  • get_product_price(self, product, quantity, partner, date=False, uom_id=False)
    For a given pricelist, return price for a given product
  • get_product_price_rule(self, product, quantity, partner, date=False, uom_id=False)
    For a given pricelist, return price and rule for a given product
  • get_products_price(self, products, quantities, partners, date=False, uom_id=False)
    For a given pricelist, return price for products Returns: dict{product_id: product price}, in the given pricelist
  • name_get(self)
  • price_get(self, prod_id, qty, partner=None)
    Multi pricelist, mono product - returns price per pricelist
  • price_rule_get(self, prod_id, qty, partner=None)
    Multi pricelist, mono product - return tuple
  • price_rule_get_multi(self, products_by_qty_by_partner)
    Multi pricelist, multi product - return tuple

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (24)
  • active Boolean
    readonly=True related='pricelist_id.active' store=True
  • applied_on Selection
    default='3_global' help='Pricelist Item applicable on selected option' required=True args: [('3_global', 'All Products'), ('2_product_category', 'Product Category'), ('1_product', 'Product'), ('0_product_variant', 'Product Variant')], 'Apply On'
  • base Selection
    default='list_price' help='Base price for computation.\nSales Price: The base price will be the Sales Price.\nCost Price : The base price will be the cost price.\nOther Pricelist : Computation of the base price based on another Pricelist.' required=True args: [('list_price', 'Sales Price'), ('standard_price', 'Cost'), ('pricelist', 'Other Pricelist')], 'Based on'
  • base_pricelist_id Many2one → product.pricelist
    check_company=True args: 'product.pricelist', 'Other Pricelist'
  • categ_id Many2one → product.category
    help='Specify a product category if this rule only applies to products belonging to this category or its children categories. Keep empty otherwise.' ondelete='cascade' args: 'product.category', 'Product Category'
  • company_id Many2one → res.company
    readonly=True related='pricelist_id.company_id' store=True args: 'res.company', 'Company'
  • compute_price Selection
    default='fixed' index=True required=True args: [('fixed', 'Fixed Price'), ('percentage', 'Discount'), ('formula', 'Formula')]
  • currency_id Many2one → res.currency
    readonly=True related='pricelist_id.currency_id' store=True args: 'res.currency', 'Currency'
  • date_end Datetime
    help='Ending datetime for the pricelist item validation\nThe displayed value depends on the timezone set in your preferences.' args: 'End Date'
  • date_start Datetime
    help='Starting datetime for the pricelist item validation\nThe displayed value depends on the timezone set in your preferences.' args: 'Start Date'
  • fixed_price Float
    digits='Product Price' args: 'Fixed Price'
  • min_quantity Float
    default=0 digits='Product Unit Of Measure' help='For the rule to apply, bought/sold quantity must be greater than or equal to the minimum quantity specified in this field.\nExpressed in the default unit of measure of the product.' args: 'Min. Quantity'
  • name Char
    compute='_get_pricelist_item_name_price' help='Explicit rule name for this pricelist line.' args: 'Name'
  • percent_price Float
    help='You can apply a mark-up by setting a negative discount.' args: 'Percentage Price'
  • price Char
    compute='_get_pricelist_item_name_price' help='Explicit rule name for this pricelist line.' args: 'Price'
  • price_discount Float
    default=0 digits=(16, 2) help='You can apply a mark-up by setting a negative discount.' args: 'Price Discount'
  • price_max_margin Float
    digits='Product Price' help='Specify the maximum amount of margin over the base price.' args: 'Max. Price Margin'
  • price_min_margin Float
    digits='Product Price' help='Specify the minimum amount of margin over the base price.' args: 'Min. Price Margin'
  • price_round Float
    digits='Product Price' help='Sets the price so that it is a multiple of this value.\nRounding is applied after the discount and before the surcharge.\nTo have prices that end in 9.99, set rounding 10, surcharge -0.01' args: 'Price Rounding'
  • price_surcharge Float
    digits='Product Price' help='Specify the fixed amount to add or subtract(if negative) to the amount calculated with the discount.' args: 'Price Surcharge'
  • pricelist_id Many2one → product.pricelist
    default=_default_pricelist_id index=True ondelete='cascade' required=True args: 'product.pricelist', 'Pricelist'
  • product_id Many2one → product.product
    check_company=True help='Specify a product if this rule only applies to one product. Keep empty otherwise.' ondelete='cascade' args: 'product.product', 'Product Variant'
  • product_tmpl_id Many2one → product.template
    check_company=True help='Specify a template if this rule only applies to one product template. Keep empty otherwise.' ondelete='cascade' args: 'product.template', 'Product'
  • rule_tip Char
    compute='_compute_rule_tip'
Public methods (3)
  • create(self, vals_list)
    @api.model_create_multi
  • toggle_active(self)
  • write(self, values)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (30)
  • active Boolean
    default=True help='If unchecked, it will allow you to hide the product without removing it.' args: 'Active'
  • barcode Char
    copy=False help='International Article Number used for product identification.' args: 'Barcode'
  • can_image_1024_be_zoomed Boolean
    compute='_compute_can_image_1024_be_zoomed' args: 'Can Image 1024 be zoomed'
  • can_image_variant_1024_be_zoomed Boolean
    compute='_compute_can_image_variant_1024_be_zoomed' store=True args: 'Can Variant Image 1024 be zoomed'
  • code Char
    compute='_compute_product_code' args: 'Reference'
  • combination_indices Char
    compute='_compute_combination_indices' index=True store=True
  • default_code Char
    index=True args: 'Internal Reference'
  • image_1024 Image
    compute='_compute_image_1024' args: 'Image 1024'
  • image_128 Image
    compute='_compute_image_128' args: 'Image 128'
  • image_1920 Image
    compute='_compute_image_1920' inverse='_set_image_1920' args: 'Image'
  • image_256 Image
    compute='_compute_image_256' args: 'Image 256'
  • image_512 Image
    compute='_compute_image_512' args: 'Image 512'
  • image_variant_1024 Image
    max_height=1024 max_width=1024 related='image_variant_1920' store=True args: 'Variant Image 1024'
  • image_variant_128 Image
    max_height=128 max_width=128 related='image_variant_1920' store=True args: 'Variant Image 128'
  • image_variant_1920 Image
    max_height=1920 max_width=1920 args: 'Variant Image'
  • image_variant_256 Image
    max_height=256 max_width=256 related='image_variant_1920' store=True args: 'Variant Image 256'
  • image_variant_512 Image
    max_height=512 max_width=512 related='image_variant_1920' store=True args: 'Variant Image 512'
  • is_product_variant Boolean
    compute='_compute_is_product_variant'
  • lst_price Float
    compute='_compute_product_lst_price' digits='Product Price' help="The sale price is managed from the product template. Click on the 'Configure Variants' button to set the extra attribute prices." inverse='_set_product_lst_price' args: 'Sales\xa0Price'
  • packaging_ids One2many → product.packaging
    help='Gives the different ways to package the same product.' args: 'product.packaging', 'product_id', 'Product Packages'
  • partner_ref Char
    compute='_compute_partner_ref' args: 'Customer Ref'
  • price Float
    compute='_compute_product_price' digits='Product Price' inverse='_set_product_price' args: 'Price'
  • price_extra Float
    compute='_compute_product_price_extra' digits='Product Price' help='This is the sum of the extra price of all attributes' args: 'Variant Price Extra'
  • pricelist_item_count Integer
    compute='_compute_variant_item_count' args: 'Number of price rules'
  • product_template_attribute_value_ids Many2many → product.template.attribute.value
    ondelete='restrict' relation='product_variant_combination' string='Attribute Values' args: 'product.template.attribute.value'
  • product_template_variant_value_ids Many2many → product.template.attribute.value
    domain=[('attribute_line_id.value_count', '>', 1)] ondelete='restrict' relation='product_variant_combination' string='Variant Values' args: 'product.template.attribute.value'
  • product_tmpl_id Many2one → product.template
    auto_join=True index=True ondelete='cascade' required=True args: 'product.template', 'Product Template'
  • standard_price Float
    company_dependent=True digits='Product Price' groups='base.group_user' help='In Standard Price & AVCO: value of the product (automatically computed in AVCO).\n In FIFO: value of the next unit that will leave the stock (automatically computed).\n Used to value the product when the purchase cost is not known (e.g. inventory adjustment).\n Used to compute margins on sale orders.' args: 'Cost'
  • volume Float
    digits='Volume' args: 'Volume'
  • weight Float
    digits='Stock Weight' args: 'Weight'
Public methods (15)
  • action_open_label_layout(self)
  • compute_concurrency_field_with_access(self)
    @api.depends('create_date', 'write_date', 'product_tmpl_id.create_date', 'product_tmpl_id.write_date')
  • copy(self, default=None)
    @api.returns('self', <expr>)
    Variants are generated depending on the configuration of attributes and values on the template, so copying them does not make sense. For convenience the template is copied instead and its first variant is returned.
  • create(self, vals_list)
    @api.model_create_multi
  • get_empty_list_help(self, help)
    @api.model
  • get_product_multiline_description_sale(self)
    Compute a multiline description of this product, in the context of sales (do not use for purchases or other display reasons that don't intend to use "description_sale"). It will often be used as the default description of a sale order line referencing this product.
  • init(self)
    Ensure there is at most one active variant for each combination. There could be no variant for a combination if using dynamic attributes.
  • name_get(self)
  • open_pricelist_rules(self)
  • open_product_template(self)
    Utility method used to add an "Open Template" button in product views
  • price_compute(self, price_type, uom=False, currency=False, company=None)
  • toggle_active(self)
    Archiving related product.template if there is not any more active product.product (and vice versa, unarchiving the related product template if there is now an active product.product)
  • unlink(self)
  • view_header_get(self, view_id, view_type)
    @api.model
  • write(self, values)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (15)
  • company_id Many2one → res.company
    default=<expr> index=1 args: 'res.company', 'Company'
  • currency_id Many2one → res.currency
    default=<expr> required=True args: 'res.currency', 'Currency'
  • date_end Date
    help='End date for this vendor price' args: 'End Date'
  • date_start Date
    help='Start date for this vendor price' args: 'Start Date'
  • delay Integer
    default=1 help='Lead time in days between the confirmation of the purchase order and the receipt of the products in your warehouse. Used by the scheduler for automatic computation of the purchase order planning.' required=True args: 'Delivery Lead Time'
  • min_qty Float
    default=0.0 digits='Product Unit Of Measure' help='The quantity to purchase from this vendor to benefit from the price, expressed in the vendor Product Unit of Measure if not any, in the default unit of measure of the product otherwise.' required=True args: 'Quantity'
  • name Many2one → res.partner
    check_company=True help='Vendor of this product' ondelete='cascade' required=True args: 'res.partner', 'Vendor'
  • price Float
    default=0.0 digits='Product Price' help='The price to purchase a product' required=True args: 'Price'
  • product_code Char
    help="This vendor's product code will be used when printing a request for quotation. Keep empty to use the internal one." args: 'Vendor Product Code'
  • product_id Many2one → product.product
    check_company=True help='If not set, the vendor price will apply to all variants of this product.' args: 'product.product', 'Product Variant'
  • product_name Char
    help="This vendor's product name will be used when printing a request for quotation. Keep empty to use the internal one." args: 'Vendor Product Name'
  • product_tmpl_id Many2one → product.template
    check_company=True index=True ondelete='cascade' args: 'product.template', 'Product Template'
  • product_uom Many2one → uom.uom
    help='This comes from the product form.' related='product_tmpl_id.uom_po_id' args: 'uom.uom', 'Unit of Measure'
  • product_variant_count Integer
    related='product_tmpl_id.product_variant_count' args: 'Variant Count'
  • sequence Integer
    default=1 help='Assigns the priority to the list of product vendor.' args: 'Sequence'
Public methods (3)
  • create(self, vals_list)
    @api.model_create_multi
  • get_import_templates(self)
    @api.model
  • write(self, vals)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (42)
  • active Boolean
    default=True help='If unchecked, it will allow you to hide the product without removing it.' args: 'Active'
  • attribute_line_ids One2many → product.template.attribute.line
    copy=True args: 'product.template.attribute.line', 'product_tmpl_id', 'Product Attributes'
  • barcode Char
    compute='_compute_barcode' inverse='_set_barcode' search='_search_barcode' args: 'Barcode'
  • can_image_1024_be_zoomed Boolean
    compute='_compute_can_image_1024_be_zoomed' store=True args: 'Can Image 1024 be zoomed'
  • categ_id Many2one → product.category
    change_default=True default=_get_default_category_id group_expand='_read_group_categ_id' help='Select category for the current product' required=True args: 'product.category', 'Product Category'
  • color Integer
    args: 'Color Index'
  • company_id Many2one → res.company
    index=1 args: 'res.company', 'Company'
  • cost_currency_id Many2one → res.currency
    compute='_compute_cost_currency_id' args: 'res.currency', 'Cost Currency'
  • currency_id Many2one → res.currency
    compute='_compute_currency_id' args: 'res.currency', 'Currency'
  • default_code Char
    compute='_compute_default_code' inverse='_set_default_code' store=True args: 'Internal Reference'
  • description Html
    translate=True args: 'Description'
  • description_purchase Text
    translate=True args: 'Purchase Description'
  • description_sale Text
    help='A description of the Product that you want to communicate to your customers. This description will be copied to every Sales Order, Delivery Order and Customer Invoice/Credit Note' translate=True args: 'Sales Description'
  • detailed_type Selection
    default='consu' help='A storable product is a product for which you manage stock. The Inventory app has to be installed.\nA consumable product is a product for which stock is not managed.\nA service is a non-material product you provide.' required=True string='Product Type' args: [('consu', 'Consumable'), ('service', 'Service')]
  • has_configurable_attributes Boolean
    compute='_compute_has_configurable_attributes' store=True args: 'Is a configurable product'
  • is_product_variant Boolean
    compute='_compute_is_product_variant' string='Is a product variant'
  • list_price Float
    default=1.0 digits='Product Price' help='Price at which the product is sold to customers.' args: 'Sales Price'
  • name Char
    index=True required=True translate=True args: 'Name'
  • packaging_ids One2many → product.packaging
    compute='_compute_packaging_ids' help='Gives the different ways to package the same product.' inverse='_set_packaging_ids' string='Product Packages' args: 'product.packaging'
  • price Float
    compute='_compute_template_price' digits='Product Price' inverse='_set_template_price' args: 'Price'
  • pricelist_id Many2one → product.pricelist
    help='Technical field. Used for searching on pricelists, not stored in database.' store=False args: 'product.pricelist', 'Pricelist'
  • pricelist_item_count Integer
    compute='_compute_item_count' args: 'Number of price rules'
  • priority Selection
    default='0' string='Favorite' args: [('0', 'Normal'), ('1', 'Favorite')]
  • product_tooltip Char
    compute='_compute_product_tooltip'
  • product_variant_count Integer
    compute='_compute_product_variant_count' args: '# Product Variants'
  • product_variant_id Many2one → product.product
    compute='_compute_product_variant_id' args: 'product.product', 'Product'
  • product_variant_ids One2many → product.product
    required=True args: 'product.product', 'product_tmpl_id', 'Products'
  • purchase_ok Boolean
    default=True args: 'Can be Purchased'
  • sale_ok Boolean
    default=True args: 'Can be Sold'
  • seller_ids One2many → product.supplierinfo
    depends_context=('company') help='Define vendor pricelists.' args: 'product.supplierinfo', 'product_tmpl_id', 'Vendors'
  • sequence Integer
    default=1 help='Gives the sequence order when displaying a product list' args: 'Sequence'
  • standard_price Float
    compute='_compute_standard_price' digits='Product Price' groups='base.group_user' help='In Standard Price & AVCO: value of the product (automatically computed in AVCO).\n In FIFO: value of the next unit that will leave the stock (automatically computed).\n Used to value the product when the purchase cost is not known (e.g. inventory adjustment).\n Used to compute margins on sale orders.' inverse='_set_standard_price' search='_search_standard_price' args: 'Cost'
  • type Selection
    compute='_compute_type' readonly=False selection=[('consu', 'Consumable'), ('service', 'Service')] store=True
  • uom_id Many2one → uom.uom
    default=_get_default_uom_id help='Default unit of measure used for all stock operations.' required=True args: 'uom.uom', 'Unit of Measure'
  • uom_name Char
    readonly=True related='uom_id.name' string='Unit of Measure Name'
  • uom_po_id Many2one → uom.uom
    default=_get_default_uom_po_id help='Default unit of measure used for purchase orders. It must be in the same category as the default unit of measure.' required=True args: 'uom.uom', 'Purchase UoM'
  • valid_product_template_attribute_line_ids Many2many → product.template.attribute.line
    compute='_compute_valid_product_template_attribute_line_ids' help='Technical compute' string='Valid Product Attribute Lines' args: 'product.template.attribute.line'
  • variant_seller_ids One2many → product.supplierinfo
    args: 'product.supplierinfo', 'product_tmpl_id'
  • volume Float
    compute='_compute_volume' digits='Volume' inverse='_set_volume' store=True args: 'Volume'
  • volume_uom_name Char
    compute='_compute_volume_uom_name' string='Volume unit of measure label'
  • weight Float
    compute='_compute_weight' digits='Stock Weight' inverse='_set_weight' store=True args: 'Weight'
  • weight_uom_name Char
    compute='_compute_weight_uom_name' string='Weight unit of measure label'
Public methods (11)
  • action_open_label_layout(self)
  • copy(self, default=None)
    @api.returns('self', <expr>)
  • create(self, vals_list)
    @api.model_create_multi
    Store the initial standard price in order to be able to retrieve the cost of a product template for a given date
  • get_empty_list_help(self, help)
    @api.model
  • get_import_templates(self)
    @api.model
  • get_single_product_variant(self)
    Method used by the product configurator to check if the product is configurable or not. We need to open the product configurator if the product: - is configurable (see has_configurable_attributes) - has optional products (method is extended in sale to return optional products info)
  • has_dynamic_attributes(self)
    Return whether this `product.template` has at least one dynamic attribute. :return: True if at least one dynamic attribute, False otherwise :rtype: bool
  • name_get(self)
  • open_pricelist_rules(self)
  • price_compute(self, price_type, uom=False, currency=False, company=None)
  • write(self, vals)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (3)
  • product_template_attribute_value_id Many2one → product.template.attribute.value
    index=True ondelete='cascade' string='Attribute Value' args: 'product.template.attribute.value'
  • product_tmpl_id Many2one → product.template
    index=True ondelete='cascade' required=True string='Product Template' args: 'product.template'
  • value_ids Many2many → product.template.attribute.value
    domain="[('product_tmpl_id', '=', product_tmpl_id), ('ptav_active', '=', True)]" relation='product_attr_exclusion_value_ids_rel' string='Attribute Values' args: 'product.template.attribute.value'
Public methods (0)

No public methods.

New fields (6)
  • active Boolean
    default=True
  • attribute_id Many2one → product.attribute
    index=True ondelete='restrict' required=True string='Attribute' args: 'product.attribute'
  • product_template_value_ids One2many → product.template.attribute.value
    string='Product Attribute Values' args: 'product.template.attribute.value', 'attribute_line_id'
  • product_tmpl_id Many2one → product.template
    index=True ondelete='cascade' required=True string='Product Template' args: 'product.template'
  • value_count Integer
    compute='_compute_value_count' readonly=True store=True
  • value_ids Many2many → product.attribute.value
    domain="[('attribute_id', '=', attribute_id)]" ondelete='restrict' relation='product_attribute_value_product_template_attribute_line_rel' string='Values' args: 'product.attribute.value'
Public methods (4)
  • action_open_attribute_values(self)
  • create(self, vals_list)
    @api.model_create_multi
    Override to: - Activate archived lines having the same configuration (if they exist) instead of creating new lines. - Set up related values and related variants. Reactivating existing lines allows to re-use existing variants when possible, keeping their configuration and avoiding duplication.
  • unlink(self)
    Override to: - Archive the line if unlink is not possible. - Clean up related values and related variants. Archiving is typically needed when the line has values that can't be deleted because they are referenced elsewhere (on a variant that can't be deleted, on a sales order line, ...).
  • write(self, values)
    Override to: - Add constraints to prevent doing changes that are not supported such as modifying the template or the attribute of existing lines. - Clean up related values and related variants when archiving or when updating `value_ids`.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (14)
  • attribute_id Many2one → product.attribute
    index=True related='attribute_line_id.attribute_id' store=True string='Attribute' args: 'product.attribute'
  • attribute_line_id Many2one → product.template.attribute.line
    index=True ondelete='cascade' required=True args: 'product.template.attribute.line'
  • color Integer
    default=_get_default_color args: 'Color'
  • currency_id Many2one
    related='attribute_line_id.product_tmpl_id.currency_id'
  • display_type Selection
    readonly=True related='product_attribute_value_id.display_type'
  • exclude_for One2many → product.template.attribute.exclusion
    help='Make this attribute value not compatible with other values of the product or some attribute values of optional and accessory products.' string='Exclude for' args: 'product.template.attribute.exclusion', 'product_template_attribute_value_id'
  • html_color Char
    related='product_attribute_value_id.html_color' args: 'HTML Color Index'
  • is_custom Boolean
    related='product_attribute_value_id.is_custom' args: 'Is custom value'
  • name Char
    related='product_attribute_value_id.name' args: 'Value'
  • price_extra Float
    default=0.0 digits='Product Price' help='Extra price for the variant with this attribute value on sale price. eg. 200 price extra, 1000 + 200 = 1200.' string='Value Price Extra'
  • product_attribute_value_id Many2one → product.attribute.value
    index=True ondelete='cascade' required=True string='Attribute Value' args: 'product.attribute.value'
  • product_tmpl_id Many2one → product.template
    index=True related='attribute_line_id.product_tmpl_id' store=True string='Product Template' args: 'product.template'
  • ptav_active Boolean
    default=True args: 'Active'
  • ptav_product_variant_ids Many2many → product.product
    readonly=True relation='product_variant_combination' string='Related Variants' args: 'product.product'
Public methods (4)
  • create(self, vals_list)
    @api.model_create_multi
  • name_get(self)
    Override because in general the name of the value is confusing if it is displayed without the name of the corresponding attribute. Eg. on exclusion rules form
  • unlink(self)
    Override to: - Clean up the variants that use any of the values in self: - Remove the value from the variant if the value belonged to an attribute line with only one value. - Unlink or archive all related variants. - Archive the value if unlink is not possible. Archiving is typically needed when the value is referenced elsewhere (on a variant that can't be deleted, on a sales order line, ...).
  • write(self, values)

New fields (0)

No new fields.

Public methods (1)
  • get_html(self, data)
    @api.model

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (2)
  • create(self, vals_list)
    @api.model_create_multi
  • write(self, values)

New fields (11)
  • group_discount_per_so_line Boolean
    implied_group='product.group_discount_per_so_line' args: 'Discounts'
  • group_product_pricelist Boolean
    implied_group='product.group_product_pricelist' args: 'Pricelists'
  • group_product_variant Boolean
    implied_group='product.group_product_variant' args: 'Variants'
  • group_sale_pricelist Boolean
    help='Allows to manage different prices based on rules per category of customers.\n Example: 10% for retailers, promotion of 5 EUR on this product, etc.' implied_group='product.group_sale_pricelist' args: 'Advanced Pricelists'
  • group_stock_packaging Boolean
    implied_group='product.group_stock_packaging' args: 'Product Packagings'
  • group_uom Boolean
    implied_group='uom.group_uom' args: 'Units of Measure'
  • module_sale_product_configurator Boolean
    args: 'Product Configurator'
  • module_sale_product_matrix Boolean
    args: 'Sales Grid Entry'
  • product_pricelist_setting Selection
    config_parameter='product.product_pricelist_setting' default='basic' help='Multiple prices: Pricelists with fixed price rules by product,\nAdvanced rules: enables advanced price rules for pricelists.' string='Pricelists Method' args: [('basic', 'Multiple prices per product'), ('advanced', 'Advanced price rules (discounts, formulas)')]
  • product_volume_volume_in_cubic_feet Selection
    config_parameter='product.volume_in_cubic_feet' default='0' args: [('0', 'Cubic Meters'), ('1', 'Cubic Feet')], 'Volume unit of measure'
  • product_weight_in_lbs Selection
    config_parameter='product.weight_in_lbs' default='0' args: [('0', 'Kilograms'), ('1', 'Pounds')], 'Weight unit of measure'
Public methods (1)
  • set_values(self)

New fields (1)
  • pricelist_ids Many2many → product.pricelist
    string='Pricelists' args: 'product.pricelist', 'res_country_group_pricelist_rel', 'res_country_group_id', 'pricelist_id'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (1)
  • property_product_pricelist Many2one → product.pricelist
    company_dependent=False compute='_compute_product_pricelist' domain=<expr> help='This pricelist will be used, instead of the default one, for sales to the current partner' inverse='_inverse_product_pricelist' args: 'product.pricelist', 'Pricelist'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/14.0/product
VERSION
VERSION 1.2
CATEGORY
CATEGORYSales/Sales
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Martin Trigaux, Olivier Dony, Thibault Delavallée, Christophe Simonis, Xavier Morel, Goffin Simon, Simon Lejeune, Nicolas Martinelli, Nicolas Lempereur, Aaron Bohy, GitHub, Damien Bouvy, Barad Mahendra, Yannick Tivisse, Pierre Masereel, Romain Derie, Jorge Pinna Puissant, Arnold Moyaux, Adrian Torres, Antoine Prieels, Xavier-Do, jvm-odoo, jerome hanke (jhk), Victor Feyens, Andrea Grazioso (agr-odoo), Fanny He, William Henrotin, Sébastien Theys, Florent de Labarre, Julien Mougenot, Jason Van Malder, fw-bot, Adrien Horgnies, Debauche Stéphane, svs-odoo, Achraf (abz), Adrien Widart, Ivan Yelizariev, jev, Nasreddin Boulif (bon), Touati Djamel (otd), Prakash Prajapati, Nicolas Galler, Tiffany Chang (tic), Aurélien (avd), Arnaud Joset, Jordi Ballester Alomar, nans, Kevin Baptiste, Arnaud Baes, Xavier BOL (xbo), roen-odoo, Benoit Socias, Miquel Raïch, Laurent Desausoi (lade), Bruno-brsy, Julien Van Roy, Florian Damhaut, Ankita Raval, yhu-odoo, Florian Vranckx, Yolann Sabaux, Hemali Bhimani, Jinjiu Liu, mightyjol (jhk), nje-odoo, niyasraphy, Adrien Widart (awt), Victor Piryns (pivi), Uttam Pragda
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:14:30
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - uom
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
This is the base module for managing products and pricelists in Odoo.
========================================================================

Products support variants, different pricing methods, vendors information,
make to stock/order, different units of measure, packaging and properties.

Pricelists support:
-------------------
    * Multiple-level of discount (by product, category, quantities)
    * Compute price based on different criteria:
        * Other pricelist
        * Cost price
        * List price
        * Vendor price

Pricelists preferences by product and/or partners.

Print product labels with barcode.
    

Code Analysis

Views touched (52)
XML IDNameModelTypeStatus
assets_backend Product assets backend ir.ui.view qweb Inherits web.assets_backend
attribute_tree_view product.attribute.tree product.attribute tree New
inherits_website_sale_country_group_form website_sale.country_group.form res.country.group group Inherits base.view_country_group_form
product_attribute_view_form product.attribute.form product.attribute form New
product_category_form_view product.category.form product.category form New
product_category_list_view product.category.list product.category tree New
product_category_search_view product.category.search product.category search New
product_kanban_view Product Kanban product.product kanban New
product_normal_form_view product.product.form product.product form Inherits product.product_template_form_view
product_packaging_form_view product.packaging.form.view product.packaging form New
product_packaging_form_view2 product.packaging.form.view2 product.packaging xpath Inherits product.product_packaging_form_view
product_packaging_tree_view product.packaging.tree.view product.packaging tree New
product_packaging_tree_view2 product.packaging.tree.view2 product.packaging xpath Inherits product.product_packaging_tree_view
product_pricelist_item_form_view product.pricelist.item.form product.pricelist.item form New
product_pricelist_item_tree_view product.pricelist.item.tree product.pricelist.item tree New
product_pricelist_item_tree_view_from_product product.pricelist.item.tree product.pricelist.item tree New
product_pricelist_item_view_search product.pricelist.item.search product.pricelist.item search New
product_pricelist_view product.pricelist.form product.pricelist form New
product_pricelist_view_inherit product.pricelist.form.inherit product.pricelist field Inherits product.product_pricelist_view
product_pricelist_view_kanban product.pricelist.kanban product.pricelist kanban New
product_pricelist_view_search product.pricelist.search product.pricelist search New
product_pricelist_view_tree product.pricelist.tree product.pricelist tree New
product_product_tree_view product.product.tree product.product tree New
product_product_view_activity product.product.activity product.product activity New
product_search_form_view product.product.search product.product field Inherits product.product_template_search_view
product_supplierinfo_form_view product.supplierinfo.form.view product.supplierinfo form New
product_supplierinfo_search_view product.supplierinfo.search.view product.supplierinfo search New
product_supplierinfo_tree_view product.supplierinfo.tree.view product.supplierinfo tree New
product_supplierinfo_view_kanban product.supplierinfo.kanban product.supplierinfo kanban New
product_template_attribute_line_form product.template.attribute.line.form product.template.attribute.line form New
product_template_attribute_value_view_form product.template.attribute.value.view.form. product.template.attribute.value form New
product_template_attribute_value_view_search product.template.attribute.value search New
product_template_attribute_value_view_tree product.template.attribute.value.view.tree product.template.attribute.value tree New
product_template_form_view product.template.common.form product.template form New
product_template_kanban_view Product.template.product.kanban product.template kanban New
product_template_only_form_view product.template.product.form product.template xpath Inherits product.product_template_form_view
product_template_search_view product.template.search product.template search New
product_template_tree_view product.template.product.tree product.template tree New
product_template_view_activity product.template.activity product.template activity New
product_variant_easy_edit_view product.product.view.form.easy product.product form New
qunit_suite Product pricelist report tests ir.ui.view qweb Inherits web.qunit_suite_tests
report_packagingbarcode report_packagingbarcode ir.ui.view qweb New
report_pricelist report_pricelist ir.ui.view qweb New
report_pricelist_page report_pricelist_page ir.ui.view qweb New
report_productbarcode report_productbarcode ir.ui.view qweb New
report_productlabel report_productlabel ir.ui.view qweb New
report_producttemplatebarcode report_producttemplatebarcode ir.ui.view qweb New
report_producttemplatelabel report_producttemplatelabel ir.ui.view qweb New
report_simple_barcode report_simple_barcode ir.ui.view qweb New
report_simple_label report_simple_label ir.ui.view qweb New
res_config_settings_view_form res.config.settings.view.form.inherit.product res.config.settings xpath Inherits base_setup.res_config_settings_view_form
view_partner_property_form res.partner.product.property.form.inherit res.partner group Inherits base.view_partner_form
Models touched (22)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (8)
  • attribute_line_ids One2many → product.template.attribute.line
    args: 'product.template.attribute.line', 'attribute_id', 'Lines'
  • create_variant Selection
    default='always' help='- Instantly: All possible variants are created as soon as the attribute and its values are added to a product.\n - Dynamically: Each variant is created only when its corresponding attributes and values are added to a sales order.\n - Never: Variants are never created for the attribute.\n Note: the variants creation mode cannot be changed once the attribute is used on at least one product.' required=True string='Variants Creation Mode' args: [('always', 'Instantly'), ('dynamic', 'Dynamically'), ('no_variant', 'Never')]
  • display_type Selection
    default='radio' help='The display type used in the Product Configurator.' required=True args: [('radio', 'Radio'), ('select', 'Select'), ('color', 'Color')]
  • is_used_on_products Boolean
    compute='_compute_is_used_on_products' args: 'Used on Products'
  • name Char
    required=True translate=True args: 'Attribute'
  • product_tmpl_ids Many2many → product.template
    compute='_compute_products' store=True string='Related Products' args: 'product.template'
  • sequence Integer
    help='Determine the display order' index=True args: 'Sequence'
  • value_ids One2many → product.attribute.value
    copy=True args: 'product.attribute.value', 'attribute_id', 'Values'
Public methods (2)
  • unlink(self)
  • write(self, vals)
    Override to make sure attribute type can't be changed if it's used on a product template. This is important to prevent because changing the type would make existing combinations invalid without recomputing them, and recomputing them might take too long and we don't want to change products without the user knowing about it.

New fields (3)
  • custom_product_template_attribute_value_id Many2one → product.template.attribute.value
    ondelete='restrict' required=True string='Attribute Value' args: 'product.template.attribute.value'
  • custom_value Char
    args: 'Custom Value'
  • name Char
    compute='_compute_name' args: 'Name'
Public methods (0)

No public methods.

New fields (8)
  • attribute_id Many2one → product.attribute
    help='The attribute cannot be changed once the value is used on at least one product.' index=True ondelete='cascade' required=True string='Attribute' args: 'product.attribute'
  • display_type Selection
    readonly=True related='attribute_id.display_type'
  • html_color Char
    help="Here you can set a specific HTML color index (e.g. #ff0000) to display the color if the attribute type is 'Color'." string='Color'
  • is_custom Boolean
    help='Allow users to input custom values for this attribute value' args: 'Is custom value'
  • is_used_on_products Boolean
    compute='_compute_is_used_on_products' args: 'Used on Products'
  • name Char
    required=True string='Value' translate=True
  • pav_attribute_line_ids Many2many → product.template.attribute.line
    copy=False relation='product_attribute_value_product_template_attribute_line_rel' string='Lines' args: 'product.template.attribute.line'
  • sequence Integer
    help='Determine the display order' index=True string='Sequence'
Public methods (3)
  • name_get(self)
    Override because in general the name of the value is confusing if it is displayed without the name of the corresponding attribute. Eg. on product list & kanban views, on BOM form view However during variant set up (on the product template form) the name of the attribute is already on each line so there is no need to repeat it on every value.
  • unlink(self)
  • write(self, values)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (6)
  • child_id One2many → product.category
    args: 'product.category', 'parent_id', 'Child Categories'
  • complete_name Char
    compute='_compute_complete_name' store=True args: 'Complete Name'
  • name Char
    index=True required=True args: 'Name'
  • parent_id Many2one → product.category
    index=True ondelete='cascade' args: 'product.category', 'Parent Category'
  • parent_path Char
    index=True
  • product_count Integer
    compute='_compute_product_count' help='The number of products under this category (Does not consider the children categories)' args: '# Products'
Public methods (2)
  • name_create(self, name)
    @api.model
  • unlink(self)

New fields (7)
  • barcode Char
    copy=False help='Barcode used for packaging identification. Scan this packaging barcode from a transfer in the Barcode app to move all the contained units' args: 'Barcode'
  • company_id Many2one → res.company
    index=True args: 'res.company', 'Company'
  • name Char
    required=True args: 'Package Type'
  • product_id Many2one → product.product
    check_company=True string='Product' args: 'product.product'
  • product_uom_id Many2one → uom.uom
    readonly=True related='product_id.uom_id' args: 'uom.uom'
  • qty Float
    digits='Product Unit of Measure' help='Quantity of products contained in the packaging.' args: 'Contained Quantity'
  • sequence Integer
    default=1 help='The first in the sequence is the default one.' args: 'Sequence'
Public methods (0)

No public methods.

New fields (8)
  • active Boolean
    default=True help='If unchecked, it will allow you to hide the pricelist without removing it.' args: 'Active'
  • company_id Many2one → res.company
    args: 'res.company', 'Company'
  • country_group_ids Many2many → res.country.group
    string='Country Groups' args: 'res.country.group', 'res_country_group_pricelist_rel', 'pricelist_id', 'res_country_group_id'
  • currency_id Many2one → res.currency
    default=_get_default_currency_id required=True args: 'res.currency', 'Currency'
  • discount_policy Selection
    default='with_discount' required=True args: [('with_discount', 'Discount included in the price'), ('without_discount', 'Show public price & discount to the customer')]
  • item_ids One2many → product.pricelist.item
    copy=True args: 'product.pricelist.item', 'pricelist_id', 'Pricelist Items'
  • name Char
    required=True translate=True args: 'Pricelist Name'
  • sequence Integer
    default=16
Public methods (9)
  • get_import_templates(self)
    @api.model
  • get_product_price(self, product, quantity, partner, date=False, uom_id=False)
    For a given pricelist, return price for a given product
  • get_product_price_rule(self, product, quantity, partner, date=False, uom_id=False)
    For a given pricelist, return price and rule for a given product
  • get_products_price(self, products, quantities, partners, date=False, uom_id=False)
    For a given pricelist, return price for products Returns: dict{product_id: product price}, in the given pricelist
  • name_get(self)
  • price_get(self, prod_id, qty, partner=None)
    Multi pricelist, mono product - returns price per pricelist
  • price_rule_get(self, prod_id, qty, partner=None)
    Multi pricelist, mono product - return tuple
  • price_rule_get_multi(self, products_by_qty_by_partner)
    Multi pricelist, multi product - return tuple
  • unlink(self)

New fields (23)
  • active Boolean
    readonly=True related='pricelist_id.active' store=True
  • applied_on Selection
    default='3_global' help='Pricelist Item applicable on selected option' required=True args: [('3_global', 'All Products'), ('2_product_category', 'Product Category'), ('1_product', 'Product'), ('0_product_variant', 'Product Variant')], 'Apply On'
  • base Selection
    default='list_price' help='Base price for computation.\nSales Price: The base price will be the Sales Price.\nCost Price : The base price will be the cost price.\nOther Pricelist : Computation of the base price based on another Pricelist.' required=True args: [('list_price', 'Sales Price'), ('standard_price', 'Cost'), ('pricelist', 'Other Pricelist')], 'Based on'
  • base_pricelist_id Many2one → product.pricelist
    check_company=True args: 'product.pricelist', 'Other Pricelist'
  • categ_id Many2one → product.category
    help='Specify a product category if this rule only applies to products belonging to this category or its children categories. Keep empty otherwise.' ondelete='cascade' args: 'product.category', 'Product Category'
  • company_id Many2one → res.company
    readonly=True related='pricelist_id.company_id' store=True args: 'res.company', 'Company'
  • compute_price Selection
    default='fixed' index=True required=True args: [('fixed', 'Fixed Price'), ('percentage', 'Percentage (discount)'), ('formula', 'Formula')]
  • currency_id Many2one → res.currency
    readonly=True related='pricelist_id.currency_id' store=True args: 'res.currency', 'Currency'
  • date_end Datetime
    help='Ending datetime for the pricelist item validation\nThe displayed value depends on the timezone set in your preferences.' args: 'End Date'
  • date_start Datetime
    help='Starting datetime for the pricelist item validation\nThe displayed value depends on the timezone set in your preferences.' args: 'Start Date'
  • fixed_price Float
    digits='Product Price' args: 'Fixed Price'
  • min_quantity Float
    default=0 digits='Product Unit Of Measure' help='For the rule to apply, bought/sold quantity must be greater than or equal to the minimum quantity specified in this field.\nExpressed in the default unit of measure of the product.' args: 'Min. Quantity'
  • name Char
    compute='_get_pricelist_item_name_price' help='Explicit rule name for this pricelist line.' args: 'Name'
  • percent_price Float
    args: 'Percentage Price'
  • price Char
    compute='_get_pricelist_item_name_price' help='Explicit rule name for this pricelist line.' args: 'Price'
  • price_discount Float
    default=0 digits=(16, 2) args: 'Price Discount'
  • price_max_margin Float
    digits='Product Price' help='Specify the maximum amount of margin over the base price.' args: 'Max. Price Margin'
  • price_min_margin Float
    digits='Product Price' help='Specify the minimum amount of margin over the base price.' args: 'Min. Price Margin'
  • price_round Float
    digits='Product Price' help='Sets the price so that it is a multiple of this value.\nRounding is applied after the discount and before the surcharge.\nTo have prices that end in 9.99, set rounding 10, surcharge -0.01' args: 'Price Rounding'
  • price_surcharge Float
    digits='Product Price' help='Specify the fixed amount to add or subtract(if negative) to the amount calculated with the discount.' args: 'Price Surcharge'
  • pricelist_id Many2one → product.pricelist
    default=_default_pricelist_id index=True ondelete='cascade' required=True args: 'product.pricelist', 'Pricelist'
  • product_id Many2one → product.product
    check_company=True help='Specify a product if this rule only applies to one product. Keep empty otherwise.' ondelete='cascade' args: 'product.product', 'Product Variant'
  • product_tmpl_id Many2one → product.template
    check_company=True help='Specify a template if this rule only applies to one product template. Keep empty otherwise.' ondelete='cascade' args: 'product.template', 'Product'
Public methods (3)
  • create(self, vals_list)
    @api.model_create_multi
  • toggle_active(self)
  • write(self, values)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (29)
  • active Boolean
    default=True help='If unchecked, it will allow you to hide the product without removing it.' args: 'Active'
  • barcode Char
    copy=False help='International Article Number used for product identification.' args: 'Barcode'
  • can_image_1024_be_zoomed Boolean
    compute='_compute_can_image_1024_be_zoomed' args: 'Can Image 1024 be zoomed'
  • can_image_variant_1024_be_zoomed Boolean
    compute='_compute_can_image_variant_1024_be_zoomed' store=True args: 'Can Variant Image 1024 be zoomed'
  • code Char
    compute='_compute_product_code' args: 'Reference'
  • combination_indices Char
    compute='_compute_combination_indices' index=True store=True
  • default_code Char
    index=True args: 'Internal Reference'
  • image_1024 Image
    compute='_compute_image_1024' args: 'Image 1024'
  • image_128 Image
    compute='_compute_image_128' args: 'Image 128'
  • image_1920 Image
    compute='_compute_image_1920' inverse='_set_image_1920' args: 'Image'
  • image_256 Image
    compute='_compute_image_256' args: 'Image 256'
  • image_512 Image
    compute='_compute_image_512' args: 'Image 512'
  • image_variant_1024 Image
    max_height=1024 max_width=1024 related='image_variant_1920' store=True args: 'Variant Image 1024'
  • image_variant_128 Image
    max_height=128 max_width=128 related='image_variant_1920' store=True args: 'Variant Image 128'
  • image_variant_1920 Image
    max_height=1920 max_width=1920 args: 'Variant Image'
  • image_variant_256 Image
    max_height=256 max_width=256 related='image_variant_1920' store=True args: 'Variant Image 256'
  • image_variant_512 Image
    max_height=512 max_width=512 related='image_variant_1920' store=True args: 'Variant Image 512'
  • is_product_variant Boolean
    compute='_compute_is_product_variant'
  • lst_price Float
    compute='_compute_product_lst_price' digits='Product Price' help="The sale price is managed from the product template. Click on the 'Configure Variants' button to set the extra attribute prices." inverse='_set_product_lst_price' args: 'Public Price'
  • packaging_ids One2many → product.packaging
    help='Gives the different ways to package the same product.' args: 'product.packaging', 'product_id', 'Product Packages'
  • partner_ref Char
    compute='_compute_partner_ref' args: 'Customer Ref'
  • price Float
    compute='_compute_product_price' digits='Product Price' inverse='_set_product_price' args: 'Price'
  • price_extra Float
    compute='_compute_product_price_extra' digits='Product Price' help='This is the sum of the extra price of all attributes' args: 'Variant Price Extra'
  • pricelist_item_count Integer
    compute='_compute_variant_item_count' args: 'Number of price rules'
  • product_template_attribute_value_ids Many2many → product.template.attribute.value
    ondelete='restrict' relation='product_variant_combination' string='Attribute Values' args: 'product.template.attribute.value'
  • product_tmpl_id Many2one → product.template
    auto_join=True index=True ondelete='cascade' required=True args: 'product.template', 'Product Template'
  • standard_price Float
    company_dependent=True digits='Product Price' groups='base.group_user' help='In Standard Price & AVCO: value of the product (automatically computed in AVCO).\n In FIFO: value of the next unit that will leave the stock (automatically computed).\n Used to value the product when the purchase cost is not known (e.g. inventory adjustment).\n Used to compute margins on sale orders.' args: 'Cost'
  • volume Float
    digits='Volume' args: 'Volume'
  • weight Float
    digits='Stock Weight' args: 'Weight'
Public methods (14)
  • compute_concurrency_field_with_access(self)
    @api.depends('create_date', 'write_date', 'product_tmpl_id.create_date', 'product_tmpl_id.write_date')
  • copy(self, default=None)
    @api.returns('self', <expr>)
    Variants are generated depending on the configuration of attributes and values on the template, so copying them does not make sense. For convenience the template is copied instead and its first variant is returned.
  • create(self, vals_list)
    @api.model_create_multi
  • get_empty_list_help(self, help)
    @api.model
  • get_product_multiline_description_sale(self)
    Compute a multiline description of this product, in the context of sales (do not use for purchases or other display reasons that don't intend to use "description_sale"). It will often be used as the default description of a sale order line referencing this product.
  • init(self)
    Ensure there is at most one active variant for each combination. There could be no variant for a combination if using dynamic attributes.
  • name_get(self)
  • open_pricelist_rules(self)
  • open_product_template(self)
    Utility method used to add an "Open Template" button in product views
  • price_compute(self, price_type, uom=False, currency=False, company=None)
  • toggle_active(self)
    Archiving related product.template if there is not any more active product.product (and vice versa, unarchiving the related product template if there is now an active product.product)
  • unlink(self)
  • view_header_get(self, view_id, view_type)
    @api.model
  • write(self, values)

New fields (15)
  • company_id Many2one → res.company
    default=<expr> index=1 args: 'res.company', 'Company'
  • currency_id Many2one → res.currency
    default=<expr> required=True args: 'res.currency', 'Currency'
  • date_end Date
    help='End date for this vendor price' args: 'End Date'
  • date_start Date
    help='Start date for this vendor price' args: 'Start Date'
  • delay Integer
    default=1 help='Lead time in days between the confirmation of the purchase order and the receipt of the products in your warehouse. Used by the scheduler for automatic computation of the purchase order planning.' required=True args: 'Delivery Lead Time'
  • min_qty Float
    default=0.0 digits='Product Unit Of Measure' help='The quantity to purchase from this vendor to benefit from the price, expressed in the vendor Product Unit of Measure if not any, in the default unit of measure of the product otherwise.' required=True args: 'Quantity'
  • name Many2one → res.partner
    check_company=True help='Vendor of this product' ondelete='cascade' required=True args: 'res.partner', 'Vendor'
  • price Float
    default=0.0 digits='Product Price' help='The price to purchase a product' required=True args: 'Price'
  • product_code Char
    help="This vendor's product code will be used when printing a request for quotation. Keep empty to use the internal one." args: 'Vendor Product Code'
  • product_id Many2one → product.product
    check_company=True help='If not set, the vendor price will apply to all variants of this product.' args: 'product.product', 'Product Variant'
  • product_name Char
    help="This vendor's product name will be used when printing a request for quotation. Keep empty to use the internal one." args: 'Vendor Product Name'
  • product_tmpl_id Many2one → product.template
    check_company=True index=True ondelete='cascade' args: 'product.template', 'Product Template'
  • product_uom Many2one → uom.uom
    help='This comes from the product form.' related='product_tmpl_id.uom_po_id' args: 'uom.uom', 'Unit of Measure'
  • product_variant_count Integer
    related='product_tmpl_id.product_variant_count' args: 'Variant Count'
  • sequence Integer
    default=1 help='Assigns the priority to the list of product vendor.' args: 'Sequence'
Public methods (1)
  • get_import_templates(self)
    @api.model

New fields (40)
  • active Boolean
    default=True help='If unchecked, it will allow you to hide the product without removing it.' args: 'Active'
  • attribute_line_ids One2many → product.template.attribute.line
    copy=True args: 'product.template.attribute.line', 'product_tmpl_id', 'Product Attributes'
  • barcode Char
    compute='_compute_barcode' inverse='_set_barcode' search='_search_barcode' args: 'Barcode'
  • can_image_1024_be_zoomed Boolean
    compute='_compute_can_image_1024_be_zoomed' store=True args: 'Can Image 1024 be zoomed'
  • categ_id Many2one → product.category
    change_default=True default=_get_default_category_id group_expand='_read_group_categ_id' help='Select category for the current product' required=True args: 'product.category', 'Product Category'
  • color Integer
    args: 'Color Index'
  • company_id Many2one → res.company
    index=1 args: 'res.company', 'Company'
  • cost_currency_id Many2one → res.currency
    compute='_compute_cost_currency_id' args: 'res.currency', 'Cost Currency'
  • currency_id Many2one → res.currency
    compute='_compute_currency_id' args: 'res.currency', 'Currency'
  • default_code Char
    compute='_compute_default_code' inverse='_set_default_code' store=True args: 'Internal Reference'
  • description Text
    translate=True args: 'Description'
  • description_purchase Text
    translate=True args: 'Purchase Description'
  • description_sale Text
    help='A description of the Product that you want to communicate to your customers. This description will be copied to every Sales Order, Delivery Order and Customer Invoice/Credit Note' translate=True args: 'Sales Description'
  • has_configurable_attributes Boolean
    compute='_compute_has_configurable_attributes' store=True args: 'Is a configurable product'
  • is_product_variant Boolean
    compute='_compute_is_product_variant' string='Is a product variant'
  • list_price Float
    default=1.0 digits='Product Price' help='Price at which the product is sold to customers.' args: 'Sales Price'
  • lst_price Float
    digits='Product Price' readonly=False related='list_price' args: 'Public Price'
  • name Char
    index=True required=True translate=True args: 'Name'
  • packaging_ids One2many → product.packaging
    compute='_compute_packaging_ids' help='Gives the different ways to package the same product.' inverse='_set_packaging_ids' string='Product Packages' args: 'product.packaging'
  • price Float
    compute='_compute_template_price' digits='Product Price' inverse='_set_template_price' args: 'Price'
  • pricelist_id Many2one → product.pricelist
    help='Technical field. Used for searching on pricelists, not stored in database.' store=False args: 'product.pricelist', 'Pricelist'
  • pricelist_item_count Integer
    compute='_compute_item_count' args: 'Number of price rules'
  • product_variant_count Integer
    compute='_compute_product_variant_count' args: '# Product Variants'
  • product_variant_id Many2one → product.product
    compute='_compute_product_variant_id' args: 'product.product', 'Product'
  • product_variant_ids One2many → product.product
    required=True args: 'product.product', 'product_tmpl_id', 'Products'
  • purchase_ok Boolean
    default=True args: 'Can be Purchased'
  • sale_ok Boolean
    default=True args: 'Can be Sold'
  • seller_ids One2many → product.supplierinfo
    depends_context=('company') help='Define vendor pricelists.' args: 'product.supplierinfo', 'product_tmpl_id', 'Vendors'
  • sequence Integer
    default=1 help='Gives the sequence order when displaying a product list' args: 'Sequence'
  • standard_price Float
    compute='_compute_standard_price' digits='Product Price' groups='base.group_user' help='In Standard Price & AVCO: value of the product (automatically computed in AVCO).\n In FIFO: value of the next unit that will leave the stock (automatically computed).\n Used to value the product when the purchase cost is not known (e.g. inventory adjustment).\n Used to compute margins on sale orders.' inverse='_set_standard_price' search='_search_standard_price' args: 'Cost'
  • type Selection
    default='consu' help='A storable product is a product for which you manage stock. The Inventory app has to be installed.\nA consumable product is a product for which stock is not managed.\nA service is a non-material product you provide.' required=True string='Product Type' args: [('consu', 'Consumable'), ('service', 'Service')]
  • uom_id Many2one → uom.uom
    default=_get_default_uom_id help='Default unit of measure used for all stock operations.' required=True args: 'uom.uom', 'Unit of Measure'
  • uom_name Char
    readonly=True related='uom_id.name' string='Unit of Measure Name'
  • uom_po_id Many2one → uom.uom
    default=_get_default_uom_po_id help='Default unit of measure used for purchase orders. It must be in the same category as the default unit of measure.' required=True args: 'uom.uom', 'Purchase Unit of Measure'
  • valid_product_template_attribute_line_ids Many2many → product.template.attribute.line
    compute='_compute_valid_product_template_attribute_line_ids' help='Technical compute' string='Valid Product Attribute Lines' args: 'product.template.attribute.line'
  • variant_seller_ids One2many → product.supplierinfo
    args: 'product.supplierinfo', 'product_tmpl_id'
  • volume Float
    compute='_compute_volume' digits='Volume' inverse='_set_volume' store=True args: 'Volume'
  • volume_uom_name Char
    compute='_compute_volume_uom_name' string='Volume unit of measure label'
  • weight Float
    compute='_compute_weight' digits='Stock Weight' inverse='_set_weight' store=True args: 'Weight'
  • weight_uom_name Char
    compute='_compute_weight_uom_name' string='Weight unit of measure label'
Public methods (10)
  • copy(self, default=None)
    @api.returns('self', <expr>)
  • create(self, vals_list)
    @api.model_create_multi
    Store the initial standard price in order to be able to retrieve the cost of a product template for a given date
  • get_empty_list_help(self, help)
    @api.model
  • get_import_templates(self)
    @api.model
  • get_single_product_variant(self)
    Method used by the product configurator to check if the product is configurable or not. We need to open the product configurator if the product: - is configurable (see has_configurable_attributes) - has optional products (method is extended in sale to return optional products info)
  • has_dynamic_attributes(self)
    Return whether this `product.template` has at least one dynamic attribute. :return: True if at least one dynamic attribute, False otherwise :rtype: bool
  • name_get(self)
  • open_pricelist_rules(self)
  • price_compute(self, price_type, uom=False, currency=False, company=None)
  • write(self, vals)

New fields (3)
  • product_template_attribute_value_id Many2one → product.template.attribute.value
    index=True ondelete='cascade' string='Attribute Value' args: 'product.template.attribute.value'
  • product_tmpl_id Many2one → product.template
    index=True ondelete='cascade' required=True string='Product Template' args: 'product.template'
  • value_ids Many2many → product.template.attribute.value
    domain="[('product_tmpl_id', '=', product_tmpl_id), ('ptav_active', '=', True)]" relation='product_attr_exclusion_value_ids_rel' string='Attribute Values' args: 'product.template.attribute.value'
Public methods (0)

No public methods.

New fields (5)
  • active Boolean
    default=True
  • attribute_id Many2one → product.attribute
    index=True ondelete='restrict' required=True string='Attribute' args: 'product.attribute'
  • product_template_value_ids One2many → product.template.attribute.value
    string='Product Attribute Values' args: 'product.template.attribute.value', 'attribute_line_id'
  • product_tmpl_id Many2one → product.template
    index=True ondelete='cascade' required=True string='Product Template' args: 'product.template'
  • value_ids Many2many → product.attribute.value
    domain="[('attribute_id', '=', attribute_id)]" ondelete='restrict' relation='product_attribute_value_product_template_attribute_line_rel' string='Values' args: 'product.attribute.value'
Public methods (3)
  • create(self, vals_list)
    @api.model_create_multi
    Override to: - Activate archived lines having the same configuration (if they exist) instead of creating new lines. - Set up related values and related variants. Reactivating existing lines allows to re-use existing variants when possible, keeping their configuration and avoiding duplication.
  • unlink(self)
    Override to: - Archive the line if unlink is not possible. - Clean up related values and related variants. Archiving is typically needed when the line has values that can't be deleted because they are referenced elsewhere (on a variant that can't be deleted, on a sales order line, ...).
  • write(self, values)
    Override to: - Add constraints to prevent doing changes that are not supported such as modifying the template or the attribute of existing lines. - Clean up related values and related variants when archiving or when updating `value_ids`.

New fields (13)
  • attribute_id Many2one → product.attribute
    index=True related='attribute_line_id.attribute_id' store=True string='Attribute' args: 'product.attribute'
  • attribute_line_id Many2one → product.template.attribute.line
    index=True ondelete='cascade' required=True args: 'product.template.attribute.line'
  • currency_id Many2one
    related='attribute_line_id.product_tmpl_id.currency_id'
  • display_type Selection
    readonly=True related='product_attribute_value_id.display_type'
  • exclude_for One2many → product.template.attribute.exclusion
    help='Make this attribute value not compatible with other values of the product or some attribute values of optional and accessory products.' string='Exclude for' args: 'product.template.attribute.exclusion', 'product_template_attribute_value_id'
  • html_color Char
    related='product_attribute_value_id.html_color' args: 'HTML Color Index'
  • is_custom Boolean
    related='product_attribute_value_id.is_custom' args: 'Is custom value'
  • name Char
    related='product_attribute_value_id.name' args: 'Value'
  • price_extra Float
    default=0.0 digits='Product Price' help='Extra price for the variant with this attribute value on sale price. eg. 200 price extra, 1000 + 200 = 1200.' string='Value Price Extra'
  • product_attribute_value_id Many2one → product.attribute.value
    index=True ondelete='cascade' required=True string='Attribute Value' args: 'product.attribute.value'
  • product_tmpl_id Many2one → product.template
    index=True related='attribute_line_id.product_tmpl_id' store=True string='Product Template' args: 'product.template'
  • ptav_active Boolean
    default=True args: 'Active'
  • ptav_product_variant_ids Many2many → product.product
    readonly=True relation='product_variant_combination' string='Related Variants' args: 'product.product'
Public methods (4)
  • create(self, vals_list)
    @api.model_create_multi
  • name_get(self)
    Override because in general the name of the value is confusing if it is displayed without the name of the corresponding attribute. Eg. on exclusion rules form
  • unlink(self)
    Override to: - Clean up the variants that use any of the values in self: - Remove the value from the variant if the value belonged to an attribute line with only one value. - Unlink or archive all related variants. - Archive the value if unlink is not possible. Archiving is typically needed when the value is referenced elsewhere (on a variant that can't be deleted, on a sales order line, ...).
  • write(self, values)

New fields (0)

No new fields.

Public methods (1)
  • get_html(self)
    @api.model

New fields (0)

No new fields.

Public methods (2)
  • create(self, vals)
    @api.model
  • write(self, values)

New fields (11)
  • group_discount_per_so_line Boolean
    implied_group='product.group_discount_per_so_line' args: 'Discounts'
  • group_product_pricelist Boolean
    implied_group='product.group_product_pricelist' args: 'Pricelists'
  • group_product_variant Boolean
    implied_group='product.group_product_variant' args: 'Variants'
  • group_sale_pricelist Boolean
    help='Allows to manage different prices based on rules per category of customers.\n Example: 10% for retailers, promotion of 5 EUR on this product, etc.' implied_group='product.group_sale_pricelist' args: 'Advanced Pricelists'
  • group_stock_packaging Boolean
    implied_group='product.group_stock_packaging' args: 'Product Packagings'
  • group_uom Boolean
    implied_group='uom.group_uom' args: 'Units of Measure'
  • module_sale_product_configurator Boolean
    args: 'Product Configurator'
  • module_sale_product_matrix Boolean
    args: 'Sales Grid Entry'
  • product_pricelist_setting Selection
    config_parameter='product.product_pricelist_setting' default='basic' help='Multiple prices: Pricelists with fixed price rules by product,\nAdvanced rules: enables advanced price rules for pricelists.' string='Pricelists Method' args: [('basic', 'Multiple prices per product'), ('advanced', 'Advanced price rules (discounts, formulas)')]
  • product_volume_volume_in_cubic_feet Selection
    config_parameter='product.volume_in_cubic_feet' default='0' args: [('0', 'Cubic Meters'), ('1', 'Cubic Feet')], 'Volume unit of measure'
  • product_weight_in_lbs Selection
    config_parameter='product.weight_in_lbs' default='0' args: [('0', 'Kilograms'), ('1', 'Pounds')], 'Weight unit of measure'
Public methods (1)
  • set_values(self)

New fields (1)
  • pricelist_ids Many2many → product.pricelist
    string='Pricelists' args: 'product.pricelist', 'res_country_group_pricelist_rel', 'res_country_group_id', 'pricelist_id'
Public methods (0)

No public methods.

New fields (1)
  • property_product_pricelist Many2one → product.pricelist
    company_dependent=False compute='_compute_product_pricelist' domain=<expr> help='This pricelist will be used, instead of the default one, for sales to the current partner' inverse='_inverse_product_pricelist' args: 'product.pricelist', 'Pricelist'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/13.0/product
VERSION
VERSION 1.2
CATEGORY
CATEGORYSales/Sales
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Martin Trigaux, Thibault Delavallée, Josse Colpaert, Denis Ledoux, Xavier ALT, Christophe Simonis, Xavier Morel, Goffin Simon, Mohammed Shekha, Simon Lejeune, Nicolas Martinelli, Nicolas Lempereur, Aaron Bohy, Lucas Perais (lpe), Damien Bouvy, Barad Mahendra, Yannick Tivisse, Martin Geubelle, Odoo Online, Pierre Masereel, Romain Derie, jem-odoo, Jorge Pinna Puissant, Gert Pellin, Alexandre Kühn, Arnold Moyaux, Adrian Torres, Aurélien Warnon, Xavier-Do, jvm-odoo, mgh-odoo, jerome hanke (jhk), Victor Feyens, Andrea Grazioso (agr-odoo), William Henrotin, Sébastien Theys, Shreya Modi, Florent de Labarre, Jason Van Malder, fw-bot, Adrien Horgnies, svs-odoo, Achraf (abz), Adrien Widart, Ivan Yelizariev, jev, Nasreddin Boulif (bon), Touati Djamel (otd), Prakash Prajapati, Nicolas Galler, Nathan Marotte (nama), Mathieu Duckerts-Antoine, Djamel (otd), Arnaud Joset, Hetashree Chauhan, root, Jordi Ballester Alomar, nans, Arnaud Baes, Miquel Raïch, Mitali Patel, Julien Van Roy, Florian Vranckx, Yolann Sabaux, Antoine Vandevenne (anv), Hemali Bhimani, Jinjiu Liu, mightyjol (jhk)
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:06:43
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - uom
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
This is the base module for managing products and pricelists in Odoo.
========================================================================

Products support variants, different pricing methods, vendors information,
make to stock/order, different units of measure, packaging and properties.

Pricelists support:
-------------------
    * Multiple-level of discount (by product, category, quantities)
    * Compute price based on different criteria:
        * Other pricelist
        * Cost price
        * List price
        * Vendor price

Pricelists preferences by product and/or partners.

Print product labels with barcode.
    

Code Analysis

Views touched (50)
XML IDNameModelTypeStatus
attribute_tree_view product.attribute.tree product.attribute tree New
inherits_website_sale_country_group_form website_sale.country_group.form res.country.group group Inherits base.view_country_group_form
product_attribute_view_form product.attribute.form product.attribute form New
product_category_form_view product.category.form product.category form New
product_category_list_view product.category.list product.category tree New
product_category_search_view product.category.search product.category search New
product_kanban_view Product Kanban product.product kanban New
product_normal_form_view product.product.form product.product form Inherits product.product_template_form_view
product_packaging_form_view product.packaging.form.view product.packaging form New
product_packaging_form_view2 product.packaging.form.view2 product.packaging xpath Inherits product.product_packaging_form_view
product_packaging_tree_view product.packaging.tree.view product.packaging tree New
product_packaging_tree_view2 product.packaging.tree.view2 product.packaging xpath Inherits product.product_packaging_tree_view
product_pricelist_item_form_view product.pricelist.item.form product.pricelist.item form New
product_pricelist_item_tree_view product.pricelist.item.tree product.pricelist.item tree New
product_pricelist_item_tree_view_from_product product.pricelist.item.tree product.pricelist.item tree New
product_pricelist_item_view_search product.pricelist.item.search product.pricelist.item search New
product_pricelist_view product.pricelist.form product.pricelist form New
product_pricelist_view_inherit product.pricelist.form.inherit product.pricelist field Inherits product.product_pricelist_view
product_pricelist_view_kanban product.pricelist.kanban product.pricelist kanban New
product_pricelist_view_search product.pricelist.search product.pricelist search New
product_pricelist_view_tree product.pricelist.tree product.pricelist tree New
product_product_tree_view product.product.tree product.product tree New
product_product_view_activity product.product.activity product.product activity New
product_search_form_view product.product.search product.product field Inherits product.product_template_search_view
product_supplierinfo_form_view product.supplierinfo.form.view product.supplierinfo form New
product_supplierinfo_search_view product.supplierinfo.search.view product.supplierinfo search New
product_supplierinfo_tree_view product.supplierinfo.tree.view product.supplierinfo tree New
product_supplierinfo_view_kanban product.supplierinfo.kanban product.supplierinfo kanban New
product_template_attribute_line_form product.template.attribute.line.form product.template.attribute.line form New
product_template_attribute_value_view_form product.template.attribute.value.view.form. product.template.attribute.value form New
product_template_attribute_value_view_search product.template.attribute.value search New
product_template_attribute_value_view_tree product.template.attribute.value.view.tree product.template.attribute.value tree New
product_template_form_view product.template.common.form product.template form New
product_template_kanban_view Product.template.product.kanban product.template kanban New
product_template_only_form_view product.template.product.form product.template xpath Inherits product.product_template_form_view
product_template_search_view product.template.search product.template search New
product_template_tree_view product.template.product.tree product.template tree New
product_template_view_activity product.template.activity product.template activity New
product_variant_easy_edit_view product.product.view.form.easy product.product form New
report_packagingbarcode report_packagingbarcode ir.ui.view qweb New
report_pricelist report_pricelist ir.ui.view qweb New
report_productbarcode report_productbarcode ir.ui.view qweb New
report_productlabel report_productlabel ir.ui.view qweb New
report_producttemplatebarcode report_producttemplatebarcode ir.ui.view qweb New
report_producttemplatelabel report_producttemplatelabel ir.ui.view qweb New
report_simple_barcode report_simple_barcode ir.ui.view qweb New
report_simple_label report_simple_label ir.ui.view qweb New
res_config_settings_view_form res.config.settings.view.form.inherit.product res.config.settings xpath Inherits base_setup.res_config_settings_view_form
view_partner_property_form res.partner.product.property.form.inherit res.partner group Inherits base.view_partner_form
view_product_price_list Price per unit product.price_list form New
Models touched (20)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (7)
  • attribute_line_ids One2many → product.template.attribute.line
    args: 'product.template.attribute.line', 'attribute_id', 'Lines'
  • create_variant Selection
    default='always' help='- Instantly: All possible variants are created as soon as the attribute and its values are added to a product.\n - Dynamically: Each variant is created only when its corresponding attributes and values are added to a sales order.\n - Never: Variants are never created for the attribute.\n Note: the variants creation mode cannot be changed once the attribute is used on at least one product.' required=True string='Variants Creation Mode' args: [('always', 'Instantly'), ('dynamic', 'Dynamically'), ('no_variant', 'Never')]
  • is_used_on_products Boolean
    compute='_compute_is_used_on_products' args: 'Used on Products'
  • name Char
    required=True translate=True args: 'Attribute'
  • product_tmpl_ids Many2many → product.template
    compute='_compute_products' store=True string='Related Products' args: 'product.template'
  • sequence Integer
    help='Determine the display order' index=True args: 'Sequence'
  • value_ids One2many → product.attribute.value
    copy=True args: 'product.attribute.value', 'attribute_id', 'Values'
Public methods (2)
  • unlink(self)
  • write(self, vals)
    Override to make sure attribute type can't be changed if it's used on a product template. This is important to prevent because changing the type would make existing combinations invalid without recomputing them, and recomputing them might take too long and we don't want to change products without the user knowing about it.

New fields (5)
  • attribute_id Many2one → product.attribute
    help='The attribute cannot be changed once the value is used on at least one product.' index=True ondelete='cascade' required=True string='Attribute' args: 'product.attribute'
  • is_used_on_products Boolean
    compute='_compute_is_used_on_products' args: 'Used on Products'
  • name Char
    required=True string='Value' translate=True
  • pav_attribute_line_ids Many2many → product.template.attribute.line
    copy=False relation='product_attribute_value_product_template_attribute_line_rel' string='Lines' args: 'product.template.attribute.line'
  • sequence Integer
    help='Determine the display order' index=True string='Sequence'
Public methods (3)
  • name_get(self)
    Override because in general the name of the value is confusing if it is displayed without the name of the corresponding attribute. Eg. on product list & kanban views, on BOM form view However during variant set up (on the product template form) the name of the attribute is already on each line so there is no need to repeat it on every value.
  • unlink(self)
  • write(self, values)

New fields (6)
  • child_id One2many → product.category
    args: 'product.category', 'parent_id', 'Child Categories'
  • complete_name Char
    compute='_compute_complete_name' store=True args: 'Complete Name'
  • name Char
    index=True required=True args: 'Name'
  • parent_id Many2one → product.category
    index=True ondelete='cascade' args: 'product.category', 'Parent Category'
  • parent_path Char
    index=True
  • product_count Integer
    compute='_compute_product_count' help='The number of products under this category (Does not consider the children categories)' args: '# Products'
Public methods (1)
  • name_create(self, name)
    @api.model

New fields (7)
  • barcode Char
    copy=False help='Barcode used for packaging identification. Scan this packaging barcode from a transfer in the Barcode app to move all the contained units' args: 'Barcode'
  • company_id Many2one → res.company
    index=True args: 'res.company', 'Company'
  • name Char
    required=True args: 'Package Type'
  • product_id Many2one → product.product
    check_company=True string='Product' args: 'product.product'
  • product_uom_id Many2one → uom.uom
    readonly=True related='product_id.uom_id' args: 'uom.uom'
  • qty Float
    digits='Product Unit of Measure' help='Quantity of products contained in the packaging.' args: 'Contained Quantity'
  • sequence Integer
    default=1 help='The first in the sequence is the default one.' args: 'Sequence'
Public methods (0)

No public methods.

New fields (6)
  • price_list Many2one → product.pricelist
    required=True args: 'product.pricelist', 'PriceList'
  • qty1 Integer
    default=1 args: 'Quantity-1'
  • qty2 Integer
    default=5 args: 'Quantity-2'
  • qty3 Integer
    default=10 args: 'Quantity-3'
  • qty4 Integer
    default=0 args: 'Quantity-4'
  • qty5 Integer
    default=0 args: 'Quantity-5'
Public methods (1)
  • print_report(self)
    To get the date and print the report @return : return report

New fields (8)
  • active Boolean
    default=True help='If unchecked, it will allow you to hide the pricelist without removing it.' args: 'Active'
  • company_id Many2one → res.company
    args: 'res.company', 'Company'
  • country_group_ids Many2many → res.country.group
    string='Country Groups' args: 'res.country.group', 'res_country_group_pricelist_rel', 'pricelist_id', 'res_country_group_id'
  • currency_id Many2one → res.currency
    default=_get_default_currency_id required=True args: 'res.currency', 'Currency'
  • discount_policy Selection
    default='with_discount' args: [('with_discount', 'Discount included in the price'), ('without_discount', 'Show public price & discount to the customer')]
  • item_ids One2many → product.pricelist.item
    copy=True args: 'product.pricelist.item', 'pricelist_id', 'Pricelist Items'
  • name Char
    required=True translate=True args: 'Pricelist Name'
  • sequence Integer
    default=16
Public methods (8)
  • get_import_templates(self)
    @api.model
  • get_product_price(self, product, quantity, partner, date=False, uom_id=False)
    For a given pricelist, return price for a given product
  • get_product_price_rule(self, product, quantity, partner, date=False, uom_id=False)
    For a given pricelist, return price and rule for a given product
  • get_products_price(self, products, quantities, partners, date=False, uom_id=False)
    For a given pricelist, return price for products Returns: dict{product_id: product price}, in the given pricelist
  • name_get(self)
  • price_get(self, prod_id, qty, partner=None)
    Multi pricelist, mono product - returns price per pricelist
  • price_rule_get(self, prod_id, qty, partner=None)
    Multi pricelist, mono product - return tuple
  • price_rule_get_multi(self, products_by_qty_by_partner)
    Multi pricelist, multi product - return tuple

New fields (23)
  • active Boolean
    readonly=True related='pricelist_id.active' store=True
  • applied_on Selection
    default='3_global' help='Pricelist Item applicable on selected option' required=True args: [('3_global', 'All Products'), ('2_product_category', 'Product Category'), ('1_product', 'Product'), ('0_product_variant', 'Product Variant')], 'Apply On'
  • base Selection
    default='list_price' help='Base price for computation.\nSales Price: The base price will be the Sales Price.\nCost Price : The base price will be the cost price.\nOther Pricelist : Computation of the base price based on another Pricelist.' required=True args: [('list_price', 'Sales Price'), ('standard_price', 'Cost'), ('pricelist', 'Other Pricelist')], 'Based on'
  • base_pricelist_id Many2one → product.pricelist
    check_company=True args: 'product.pricelist', 'Other Pricelist'
  • categ_id Many2one → product.category
    help='Specify a product category if this rule only applies to products belonging to this category or its children categories. Keep empty otherwise.' ondelete='cascade' args: 'product.category', 'Product Category'
  • company_id Many2one → res.company
    readonly=True related='pricelist_id.company_id' store=True args: 'res.company', 'Company'
  • compute_price Selection
    default='fixed' index=True required=True args: [('fixed', 'Fixed Price'), ('percentage', 'Percentage (discount)'), ('formula', 'Formula')]
  • currency_id Many2one → res.currency
    readonly=True related='pricelist_id.currency_id' store=True args: 'res.currency', 'Currency'
  • date_end Date
    help='Ending valid for the pricelist item validation' args: 'End Date'
  • date_start Date
    help='Starting date for the pricelist item validation' args: 'Start Date'
  • fixed_price Float
    digits='Product Price' args: 'Fixed Price'
  • min_quantity Integer
    default=0 help='For the rule to apply, bought/sold quantity must be greater than or equal to the minimum quantity specified in this field.\nExpressed in the default unit of measure of the product.' args: 'Min. Quantity'
  • name Char
    compute='_get_pricelist_item_name_price' help='Explicit rule name for this pricelist line.' args: 'Name'
  • percent_price Float
    args: 'Percentage Price'
  • price Char
    compute='_get_pricelist_item_name_price' help='Explicit rule name for this pricelist line.' args: 'Price'
  • price_discount Float
    default=0 digits=(16, 2) args: 'Price Discount'
  • price_max_margin Float
    digits='Product Price' help='Specify the maximum amount of margin over the base price.' args: 'Max. Price Margin'
  • price_min_margin Float
    digits='Product Price' help='Specify the minimum amount of margin over the base price.' args: 'Min. Price Margin'
  • price_round Float
    digits='Product Price' help='Sets the price so that it is a multiple of this value.\nRounding is applied after the discount and before the surcharge.\nTo have prices that end in 9.99, set rounding 10, surcharge -0.01' args: 'Price Rounding'
  • price_surcharge Float
    digits='Product Price' help='Specify the fixed amount to add or substract(if negative) to the amount calculated with the discount.' args: 'Price Surcharge'
  • pricelist_id Many2one → product.pricelist
    default=_default_pricelist_id index=True ondelete='cascade' required=True args: 'product.pricelist', 'Pricelist'
  • product_id Many2one → product.product
    check_company=True help='Specify a product if this rule only applies to one product. Keep empty otherwise.' ondelete='cascade' args: 'product.product', 'Product Variant'
  • product_tmpl_id Many2one → product.template
    check_company=True help='Specify a template if this rule only applies to one product template. Keep empty otherwise.' ondelete='cascade' args: 'product.template', 'Product'
Public methods (3)
  • create(self, vals_list)
    @api.model_create_multi
  • toggle_active(self)
  • write(self, values)

New fields (29)
  • active Boolean
    default=True help='If unchecked, it will allow you to hide the product without removing it.' args: 'Active'
  • barcode Char
    copy=False help='International Article Number used for product identification.' args: 'Barcode'
  • can_image_1024_be_zoomed Boolean
    compute='_compute_can_image_1024_be_zoomed' args: 'Can Image 1024 be zoomed'
  • can_image_variant_1024_be_zoomed Boolean
    compute='_compute_can_image_variant_1024_be_zoomed' store=True args: 'Can Variant Image 1024 be zoomed'
  • code Char
    compute='_compute_product_code' args: 'Reference'
  • combination_indices Char
    compute='_compute_combination_indices' index=True store=True
  • default_code Char
    index=True args: 'Internal Reference'
  • image_1024 Image
    compute='_compute_image_1024' args: 'Image 1024'
  • image_128 Image
    compute='_compute_image_128' args: 'Image 128'
  • image_1920 Image
    compute='_compute_image_1920' inverse='_set_image_1920' args: 'Image'
  • image_256 Image
    compute='_compute_image_256' args: 'Image 256'
  • image_512 Image
    compute='_compute_image_512' args: 'Image 512'
  • image_variant_1024 Image
    max_height=1024 max_width=1024 related='image_variant_1920' store=True args: 'Variant Image 1024'
  • image_variant_128 Image
    max_height=128 max_width=128 related='image_variant_1920' store=True args: 'Variant Image 128'
  • image_variant_1920 Image
    max_height=1920 max_width=1920 args: 'Variant Image'
  • image_variant_256 Image
    max_height=256 max_width=256 related='image_variant_1920' store=True args: 'Variant Image 256'
  • image_variant_512 Image
    max_height=512 max_width=512 related='image_variant_1920' store=True args: 'Variant Image 512'
  • is_product_variant Boolean
    compute='_compute_is_product_variant'
  • lst_price Float
    compute='_compute_product_lst_price' digits='Product Price' help="The sale price is managed from the product template. Click on the 'Configure Variants' button to set the extra attribute prices." inverse='_set_product_lst_price' args: 'Public Price'
  • packaging_ids One2many → product.packaging
    help='Gives the different ways to package the same product.' args: 'product.packaging', 'product_id', 'Product Packages'
  • partner_ref Char
    compute='_compute_partner_ref' args: 'Customer Ref'
  • price Float
    compute='_compute_product_price' digits='Product Price' inverse='_set_product_price' args: 'Price'
  • price_extra Float
    compute='_compute_product_price_extra' digits='Product Price' help='This is the sum of the extra price of all attributes' args: 'Variant Price Extra'
  • pricelist_item_count Integer
    compute='_compute_variant_item_count' args: 'Number of price rules'
  • product_template_attribute_value_ids Many2many → product.template.attribute.value
    ondelete='restrict' relation='product_variant_combination' string='Attribute Values' args: 'product.template.attribute.value'
  • product_tmpl_id Many2one → product.template
    auto_join=True index=True ondelete='cascade' required=True args: 'product.template', 'Product Template'
  • standard_price Float
    company_dependent=True digits='Product Price' groups='base.group_user' help='In Standard Price & AVCO: value of the product (automatically computed in AVCO).\n In FIFO: value of the last unit that left the stock (automatically computed).\n Used to value the product when the purchase cost is not known (e.g. inventory adjustment).\n Used to compute margins on sale orders.' args: 'Cost'
  • volume Float
    digits='Volume' args: 'Volume'
  • weight Float
    digits='Stock Weight' args: 'Weight'
Public methods (13)
  • copy(self, default=None)
    @api.returns('self', <expr>)
    Variants are generated depending on the configuration of attributes and values on the template, so copying them does not make sense. For convenience the template is copied instead and its first variant is returned.
  • create(self, vals_list)
    @api.model_create_multi
  • get_empty_list_help(self, help)
    @api.model
  • get_product_multiline_description_sale(self)
    Compute a multiline description of this product, in the context of sales (do not use for purchases or other display reasons that don't intend to use "description_sale"). It will often be used as the default description of a sale order line referencing this product.
  • init(self)
    Ensure there is at most one active variant for each combination. There could be no variant for a combination if using dynamic attributes.
  • name_get(self)
  • open_pricelist_rules(self)
  • open_product_template(self)
    Utility method used to add an "Open Template" button in product views
  • price_compute(self, price_type, uom=False, currency=False, company=False)
  • toggle_active(self)
    Archiving related product.template if there is not any more active product.product (and vice versa, unarchiving the related product template if there is now an active product.product)
  • unlink(self)
  • view_header_get(self, view_id, view_type)
    @api.model
  • write(self, values)

New fields (15)
  • company_id Many2one → res.company
    default=<expr> index=1 args: 'res.company', 'Company'
  • currency_id Many2one → res.currency
    default=<expr> required=True args: 'res.currency', 'Currency'
  • date_end Date
    help='End date for this vendor price' args: 'End Date'
  • date_start Date
    help='Start date for this vendor price' args: 'Start Date'
  • delay Integer
    default=1 help='Lead time in days between the confirmation of the purchase order and the receipt of the products in your warehouse. Used by the scheduler for automatic computation of the purchase order planning.' required=True args: 'Delivery Lead Time'
  • min_qty Float
    default=0.0 help='The quantity to purchase from this vendor to benefit from the price, expressed in the vendor Product Unit of Measure if not any, in the default unit of measure of the product otherwise.' required=True args: 'Quantity'
  • name Many2one → res.partner
    check_company=True help='Vendor of this product' ondelete='cascade' required=True args: 'res.partner', 'Vendor'
  • price Float
    default=0.0 digits='Product Price' help='The price to purchase a product' required=True args: 'Price'
  • product_code Char
    help="This vendor's product code will be used when printing a request for quotation. Keep empty to use the internal one." args: 'Vendor Product Code'
  • product_id Many2one → product.product
    check_company=True help='If not set, the vendor price will apply to all variants of this product.' args: 'product.product', 'Product Variant'
  • product_name Char
    help="This vendor's product name will be used when printing a request for quotation. Keep empty to use the internal one." args: 'Vendor Product Name'
  • product_tmpl_id Many2one → product.template
    check_company=True index=True ondelete='cascade' args: 'product.template', 'Product Template'
  • product_uom Many2one → uom.uom
    help='This comes from the product form.' related='product_tmpl_id.uom_po_id' args: 'uom.uom', 'Unit of Measure'
  • product_variant_count Integer
    readonly=False related='product_tmpl_id.product_variant_count' args: 'Variant Count'
  • sequence Integer
    default=1 help='Assigns the priority to the list of product vendor.' args: 'Sequence'
Public methods (1)
  • get_import_templates(self)
    @api.model

New fields (41)
  • active Boolean
    default=True help='If unchecked, it will allow you to hide the product without removing it.' args: 'Active'
  • attribute_line_ids One2many → product.template.attribute.line
    copy=True args: 'product.template.attribute.line', 'product_tmpl_id', 'Product Attributes'
  • barcode Char
    readonly=False related='product_variant_ids.barcode' args: 'Barcode'
  • can_image_1024_be_zoomed Boolean
    compute='_compute_can_image_1024_be_zoomed' store=True args: 'Can Image 1024 be zoomed'
  • categ_id Many2one → product.category
    change_default=True default=_get_default_category_id group_expand='_read_group_categ_id' help='Select category for the current product' required=True args: 'product.category', 'Product Category'
  • color Integer
    args: 'Color Index'
  • company_id Many2one → res.company
    index=1 args: 'res.company', 'Company'
  • cost_currency_id Many2one → res.currency
    compute='_compute_cost_currency_id' args: 'res.currency', 'Cost Currency'
  • currency_id Many2one → res.currency
    compute='_compute_currency_id' args: 'res.currency', 'Currency'
  • default_code Char
    compute='_compute_default_code' inverse='_set_default_code' store=True args: 'Internal Reference'
  • description Text
    translate=True args: 'Description'
  • description_purchase Text
    translate=True args: 'Purchase Description'
  • description_sale Text
    help='A description of the Product that you want to communicate to your customers. This description will be copied to every Sales Order, Delivery Order and Customer Invoice/Credit Note' translate=True args: 'Sales Description'
  • has_configurable_attributes Boolean
    compute='_compute_has_configurable_attributes' store=True args: 'Is a configurable product'
  • is_product_variant Boolean
    compute='_compute_is_product_variant' string='Is a product variant'
  • list_price Float
    default=1.0 digits='Product Price' help='Price at which the product is sold to customers.' args: 'Sales Price'
  • lst_price Float
    digits='Product Price' readonly=False related='list_price' args: 'Public Price'
  • name Char
    index=True required=True translate=True args: 'Name'
  • packaging_ids One2many → product.packaging
    compute='_compute_packaging_ids' help='Gives the different ways to package the same product.' inverse='_set_packaging_ids' string='Product Packages' args: 'product.packaging'
  • price Float
    compute='_compute_template_price' digits='Product Price' inverse='_set_template_price' args: 'Price'
  • pricelist_id Many2one → product.pricelist
    help='Technical field. Used for searching on pricelists, not stored in database.' store=False args: 'product.pricelist', 'Pricelist'
  • pricelist_item_count Integer
    compute='_compute_item_count' args: 'Number of price rules'
  • product_variant_count Integer
    compute='_compute_product_variant_count' args: '# Product Variants'
  • product_variant_id Many2one → product.product
    compute='_compute_product_variant_id' args: 'product.product', 'Product'
  • product_variant_ids One2many → product.product
    required=True args: 'product.product', 'product_tmpl_id', 'Products'
  • purchase_ok Boolean
    default=True args: 'Can be Purchased'
  • rental Boolean
    args: 'Can be Rent'
  • sale_ok Boolean
    default=True args: 'Can be Sold'
  • seller_ids One2many → product.supplierinfo
    help='Define vendor pricelists.' args: 'product.supplierinfo', 'product_tmpl_id', 'Vendors'
  • sequence Integer
    default=1 help='Gives the sequence order when displaying a product list' args: 'Sequence'
  • standard_price Float
    compute='_compute_standard_price' digits='Product Price' groups='base.group_user' help='In Standard Price & AVCO: value of the product (automatically computed in AVCO).\n In FIFO: value of the last unit that left the stock (automatically computed).\n Used to value the product when the purchase cost is not known (e.g. inventory adjustment).\n Used to compute margins on sale orders.' inverse='_set_standard_price' search='_search_standard_price' args: 'Cost'
  • type Selection
    default='consu' help='A storable product is a product for which you manage stock. The Inventory app has to be installed.\nA consumable product is a product for which stock is not managed.\nA service is a non-material product you provide.' required=True string='Product Type' args: [('consu', 'Consumable'), ('service', 'Service')]
  • uom_id Many2one → uom.uom
    default=_get_default_uom_id help='Default unit of measure used for all stock operations.' required=True args: 'uom.uom', 'Unit of Measure'
  • uom_name Char
    readonly=True related='uom_id.name' string='Unit of Measure Name'
  • uom_po_id Many2one → uom.uom
    default=_get_default_uom_id help='Default unit of measure used for purchase orders. It must be in the same category as the default unit of measure.' required=True args: 'uom.uom', 'Purchase Unit of Measure'
  • valid_product_template_attribute_line_ids Many2many → product.template.attribute.line
    compute='_compute_valid_product_template_attribute_line_ids' help='Technical compute' string='Valid Product Attribute Lines' args: 'product.template.attribute.line'
  • variant_seller_ids One2many → product.supplierinfo
    args: 'product.supplierinfo', 'product_tmpl_id'
  • volume Float
    compute='_compute_volume' digits='Volume' inverse='_set_volume' store=True args: 'Volume'
  • volume_uom_name Char
    compute='_compute_volume_uom_name' default=_get_default_volume_uom string='Volume unit of measure label'
  • weight Float
    compute='_compute_weight' digits='Stock Weight' inverse='_set_weight' store=True args: 'Weight'
  • weight_uom_name Char
    compute='_compute_weight_uom_name' default=_get_default_weight_uom readonly=True string='Weight unit of measure label'
Public methods (10)
  • copy(self, default=None)
    @api.returns('self', <expr>)
  • create(self, vals_list)
    @api.model_create_multi
    Store the initial standard price in order to be able to retrieve the cost of a product template for a given date
  • get_empty_list_help(self, help)
    @api.model
  • get_import_templates(self)
    @api.model
  • get_single_product_variant(self)
    Method used by the product configurator to check if the product is configurable or not. We need to open the product configurator if the product: - is configurable (see has_configurable_attributes) - has optional products (method is extended in sale to return optional products info)
  • has_dynamic_attributes(self)
    Return whether this `product.template` has at least one dynamic attribute. :return: True if at least one dynamic attribute, False otherwise :rtype: bool
  • name_get(self)
  • open_pricelist_rules(self)
  • price_compute(self, price_type, uom=False, currency=False, company=False)
  • write(self, vals)

New fields (3)
  • product_template_attribute_value_id Many2one → product.template.attribute.value
    index=True ondelete='cascade' string='Attribute Value' args: 'product.template.attribute.value'
  • product_tmpl_id Many2one → product.template
    index=True ondelete='cascade' required=True string='Product Template' args: 'product.template'
  • value_ids Many2many → product.template.attribute.value
    domain="[('product_tmpl_id', '=', product_tmpl_id), ('ptav_active', '=', True)]" relation='product_attr_exclusion_value_ids_rel' string='Attribute Values' args: 'product.template.attribute.value'
Public methods (0)

No public methods.

New fields (5)
  • active Boolean
    default=True
  • attribute_id Many2one → product.attribute
    index=True ondelete='restrict' required=True string='Attribute' args: 'product.attribute'
  • product_template_value_ids One2many → product.template.attribute.value
    string='Product Attribute Values' args: 'product.template.attribute.value', 'attribute_line_id'
  • product_tmpl_id Many2one → product.template
    index=True ondelete='cascade' required=True string='Product Template' args: 'product.template'
  • value_ids Many2many → product.attribute.value
    domain="[('attribute_id', '=', attribute_id)]" ondelete='restrict' relation='product_attribute_value_product_template_attribute_line_rel' string='Values' args: 'product.attribute.value'
Public methods (3)
  • create(self, vals_list)
    @api.model_create_multi
    Override to: - Activate archived lines having the same configuration (if they exist) instead of creating new lines. - Set up related values and related variants. Reactivating existing lines allows to re-use existing variants when possible, keeping their configuration and avoiding duplication.
  • unlink(self)
    Override to: - Archive the line if unlink is not possible. - Clean up related values and related variants. Archiving is typically needed when the line has values that can't be deleted because they are referenced elsewhere (on a variant that can't be deleted, on a sales order line, ...).
  • write(self, values)
    Override to: - Add constraints to prevent doing changes that are not supported such as modifying the template or the attribute of existing lines. - Clean up related values and related variants when archiving or when updating `value_ids`.

New fields (9)
  • attribute_id Many2one → product.attribute
    index=True related='attribute_line_id.attribute_id' store=True string='Attribute' args: 'product.attribute'
  • attribute_line_id Many2one → product.template.attribute.line
    index=True ondelete='cascade' required=True args: 'product.template.attribute.line'
  • exclude_for One2many → product.template.attribute.exclusion
    help='Make this attribute value not compatible with other values of the product or some attribute values of optional and accessory products.' relation='product_template_attribute_exclusion' string='Exclude for' args: 'product.template.attribute.exclusion', 'product_template_attribute_value_id'
  • name Char
    related='product_attribute_value_id.name' args: 'Value'
  • price_extra Float
    default=0.0 digits='Product Price' help='Extra price for the variant with this attribute value on sale price. eg. 200 price extra, 1000 + 200 = 1200.' string='Value Price Extra'
  • product_attribute_value_id Many2one → product.attribute.value
    index=True ondelete='cascade' required=True string='Attribute Value' args: 'product.attribute.value'
  • product_tmpl_id Many2one → product.template
    index=True related='attribute_line_id.product_tmpl_id' store=True string='Product Template' args: 'product.template'
  • ptav_active Boolean
    default=True args: 'Active'
  • ptav_product_variant_ids Many2many → product.product
    readonly=True relation='product_variant_combination' string='Related Variants' args: 'product.product'
Public methods (4)
  • create(self, vals_list)
    @api.model_create_multi
  • name_get(self)
    Override because in general the name of the value is confusing if it is displayed without the name of the corresponding attribute. Eg. on exclusion rules form
  • unlink(self)
    Override to: - Clean up the variants that use any of the values in self: - Remove the value from the variant if the value belonged to an attribute line with only one value. - Unlink or archive all related variants. - Archive the value if unlink is not possible. Archiving is typically needed when the value is referenced elsewhere (on a variant that can't be deleted, on a sales order line, ...).
  • write(self, values)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (2)
  • create(self, vals)
    @api.model
  • write(self, values)

New fields (11)
  • group_discount_per_so_line Boolean
    implied_group='product.group_discount_per_so_line' args: 'Discounts'
  • group_product_pricelist Boolean
    implied_group='product.group_product_pricelist' args: 'Pricelists'
  • group_product_variant Boolean
    implied_group='product.group_product_variant' args: 'Variants'
  • group_sale_pricelist Boolean
    help='Allows to manage different prices based on rules per category of customers.\n Example: 10% for retailers, promotion of 5 EUR on this product, etc.' implied_group='product.group_sale_pricelist' args: 'Advanced Pricelists'
  • group_stock_packaging Boolean
    implied_group='product.group_stock_packaging' args: 'Product Packagings'
  • group_uom Boolean
    implied_group='uom.group_uom' args: 'Units of Measure'
  • module_sale_product_configurator Boolean
    args: 'Product Configurator'
  • module_sale_product_matrix Boolean
    args: 'Sales Grid Entry'
  • product_pricelist_setting Selection
    config_parameter='product.product_pricelist_setting' default='basic' help='Multiple prices: Pricelists with fixed price rules by product,\nAdvanced rules: enables advanced price rules for pricelists.' string='Pricelists Method' args: [('basic', 'Multiple prices per product'), ('advanced', 'Advanced price rules (discounts, formulas)')]
  • product_volume_volume_in_cubic_feet Selection
    config_parameter='product.volume_in_cubic_feet' default='0' args: [('0', 'Cubic Meters'), ('1', 'Cubic Feet')], 'Volume unit of measure'
  • product_weight_in_lbs Selection
    config_parameter='product.weight_in_lbs' default='0' args: [('0', 'Kilogram'), ('1', 'Pound')], 'Weight unit of measure'
Public methods (1)
  • set_values(self)

New fields (1)
  • pricelist_ids Many2many → product.pricelist
    string='Pricelists' args: 'product.pricelist', 'res_country_group_pricelist_rel', 'res_country_group_id', 'pricelist_id'
Public methods (0)

No public methods.

New fields (1)
  • property_product_pricelist Many2one → product.pricelist
    company_dependent=False compute='_compute_product_pricelist' domain=<expr> help='This pricelist will be used, instead of the default one, for sales to the current partner' inverse='_inverse_product_pricelist' args: 'product.pricelist', 'Pricelist'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/12.0/product
VERSION
VERSION 1.2
CATEGORY
CATEGORYSales
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Christophe Matthieu, Martin Trigaux, Fabien Pinckaers, Thibault Delavallée, Denis Ledoux, Christophe Simonis, Goffin Simon, Simon Lejeune, Nicolas Martinelli, Nicolas Lempereur, xmo-odoo, qdp-odoo, GitHub, Lucas Perais (lpe), Yannick Tivisse, Alexandre Kühn, qsm-odoo, Pierre Masereel, Romain Derie, jem-odoo, RomainLibert, len-odoo, Jorge Pinna Puissant, Gert Pellin - GPE, Nans Lefebvre, Arnold Moyaux, Adrian Torres, XavierDo, Aurélien Warnon, Xavier-Do, jerome hanke (jhk), Victor Feyens, Andrea Grazioso (agr-odoo), Moisés López, Fanny He, William Henrotin, Sébastien Theys, Adrien Horgnies, Kinjal Mehta, Achraf (abz), Adrien Widart, sri-odoo, Nasreddin Boulif (bon), snd, Quentin Nicolay, Jordi Ballester Alomar, nans, Francisco Fernández @PlanetaTIC
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-05 23:57:01
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - base
    - decimal_precision
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - uom
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
This is the base module for managing products and pricelists in Odoo.
========================================================================

Products support variants, different pricing methods, vendors information,
make to stock/order, different units of measure, packaging and properties.

Pricelists support:
-------------------
    * Multiple-level of discount (by product, category, quantities)
    * Compute price based on different criteria:
        * Other pricelist
        * Cost price
        * List price
        * Vendor price

Pricelists preferences by product and/or partners.

Print product labels with barcode.
    

Code Analysis

Views touched (45)
XML IDNameModelTypeStatus
attribute_tree_view product.attribute.tree product.attribute tree New
inherits_website_sale_country_group_form website_sale.country_group.form res.country.group group Inherits base.view_country_group_form
product_attribute_view_form product.attribute.form product.attribute form New
product_category_form_view product.category.form product.category form New
product_category_list_view product.category.list product.category tree New
product_category_search_view product.category.search product.category search New
product_kanban_view Product Kanban product.product kanban New
product_normal_form_view product.product.form product.product form Inherits product.product_template_form_view
product_packaging_form_view product.packaging.form.view product.packaging form New
product_packaging_form_view2 product.packaging.form.view2 product.packaging xpath Inherits product.product_packaging_form_view
product_packaging_tree_view product.packaging.tree.view product.packaging tree New
product_packaging_tree_view2 product.packaging.tree.view2 product.packaging xpath Inherits product.product_packaging_tree_view
product_pricelist_item_form_view product.pricelist.item.form product.pricelist.item form New
product_pricelist_item_tree_view product.pricelist.item.tree product.pricelist.item tree New
product_pricelist_view product.pricelist.form product.pricelist form New
product_pricelist_view_kanban product.pricelist.kanban product.pricelist kanban New
product_pricelist_view_search product.pricelist.search product.pricelist search New
product_pricelist_view_tree product.pricelist.tree product.pricelist tree New
product_product_tree_view product.product.tree product.product tree New
product_search_form_view product.product.search product.product field Inherits product.product_template_search_view
product_supplierinfo_form_view product.supplierinfo.form.view product.supplierinfo form New
product_supplierinfo_search_view product.supplierinfo.search.view product.supplierinfo search New
product_supplierinfo_tree_view product.supplierinfo.tree.view product.supplierinfo tree New
product_supplierinfo_view_kanban product.supplierinfo.kanban product.supplierinfo kanban New
product_template_attribute_line_form product.template.attribute.line.form product.template.attribute.line form New
product_template_attribute_value_view_form product.template.attribute.value.view.form. product.template.attribute.value form New
product_template_attribute_value_view_tree product.template.attribute.value.view.tree product.template.attribute.value tree New
product_template_form_view product.template.common.form product.template form New
product_template_kanban_view Product.template.product.kanban product.template kanban New
product_template_only_form_view product.template.product.form product.template xpath Inherits product.product_template_form_view
product_template_search_view product.template.search product.template search New
product_template_tree_view product.template.product.tree product.template tree New
product_variant_easy_edit_view product.product.view.form.easy product.product form New
report_packagingbarcode report_packagingbarcode ir.ui.view qweb New
report_pricelist report_pricelist ir.ui.view qweb New
report_productbarcode report_productbarcode ir.ui.view qweb New
report_productlabel report_productlabel ir.ui.view qweb New
report_producttemplatebarcode report_producttemplatebarcode ir.ui.view qweb New
report_producttemplatelabel report_producttemplatelabel ir.ui.view qweb New
report_simple_barcode report_simple_barcode ir.ui.view qweb New
report_simple_label report_simple_label ir.ui.view qweb New
res_config_settings_view_form res.config.settings.view.form.inherit.product res.config.settings xpath Inherits base_setup.res_config_settings_view_form
variants_tree_view product.attribute.value.tree product.attribute.value tree New
view_partner_property_form res.partner.product.property.form.inherit res.partner group Inherits base.view_partner_form
view_product_price_list Price per unit product.price_list form New
Models touched (21)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (5)
  • attribute_line_ids One2many → product.template.attribute.line
    args: 'product.template.attribute.line', 'attribute_id', 'Lines'
  • create_variant Selection
    default='always' help='Check this if you want to create multiple variants for this attribute.' required=True string='Create Variants' args: [('no_variant', 'Never'), ('always', 'Always'), ('dynamic', 'Only when the product is added to a sales order')]
  • name Char
    required=True translate=True args: 'Attribute'
  • sequence Integer
    help='Determine the display order' index=True args: 'Sequence'
  • value_ids One2many → product.attribute.value
    copy=True args: 'product.attribute.value', 'attribute_id', 'Values'
Public methods (1)
  • write(self, vals)
    @api.multi
    Override to make sure attribute type can't be changed if it's used on a product template. This is important to prevent because changing the type would make existing combinations invalid without recomputing them, and recomputing them might take too long and we don't want to change products without the user knowing about it.

New fields (3)
  • attribute_id Many2one → product.attribute
    index=True ondelete='cascade' required=True string='Attribute' args: 'product.attribute'
  • name Char
    required=True string='Value' translate=True
  • sequence Integer
    help='Determine the display order' index=True string='Sequence'
Public methods (3)
  • name_get(self)
    @api.multi
  • unlink(self)
    @api.multi
  • write(self, values)
    @api.multi

New fields (6)
  • child_id One2many → product.category
    args: 'product.category', 'parent_id', 'Child Categories'
  • complete_name Char
    compute='_compute_complete_name' store=True args: 'Complete Name'
  • name Char
    index=True required=True translate=True args: 'Name'
  • parent_id Many2one → product.category
    index=True ondelete='cascade' args: 'product.category', 'Parent Category'
  • parent_path Char
    index=True
  • product_count Integer
    compute='_compute_product_count' help='The number of products under this category (Does not consider the children categories)' args: '# Products'
Public methods (1)
  • name_create(self, name)
    @api.model

New fields (6)
  • barcode Char
    copy=False help='Barcode used for packaging identification.' args: 'Barcode'
  • name Char
    required=True args: 'Package Type'
  • product_id Many2one → product.product
    string='Product' args: 'product.product'
  • product_uom_id Many2one → uom.uom
    readonly=True related='product_id.uom_id' args: 'uom.uom'
  • qty Float
    help='The total number of products you can have per pallet or box.' args: 'Contained Quantity'
  • sequence Integer
    default=1 help='The first in the sequence is the default one.' args: 'Sequence'
Public methods (0)

No public methods.

New fields (4)
  • company_id Many2one → res.company
    default=_get_default_company_id required=True string='Company' args: 'res.company'
  • cost Float
    digits=dp.get_precision('Product Price') args: 'Cost'
  • datetime Datetime
    default=fields.Datetime.now args: 'Date'
  • product_id Many2one → product.product
    ondelete='cascade' required=True args: 'product.product', 'Product'
Public methods (0)

No public methods.

New fields (6)
  • price_list Many2one → product.pricelist
    required=True args: 'product.pricelist', 'PriceList'
  • qty1 Integer
    default=1 args: 'Quantity-1'
  • qty2 Integer
    default=5 args: 'Quantity-2'
  • qty3 Integer
    default=10 args: 'Quantity-3'
  • qty4 Integer
    default=0 args: 'Quantity-4'
  • qty5 Integer
    default=0 args: 'Quantity-5'
Public methods (1)
  • print_report(self)
    @api.multi
    To get the date and print the report @return : return report

New fields (7)
  • active Boolean
    default=True help='If unchecked, it will allow you to hide the pricelist without removing it.' args: 'Active'
  • company_id Many2one → res.company
    args: 'res.company', 'Company'
  • country_group_ids Many2many → res.country.group
    string='Country Groups' args: 'res.country.group', 'res_country_group_pricelist_rel', 'pricelist_id', 'res_country_group_id'
  • currency_id Many2one → res.currency
    default=_get_default_currency_id required=True args: 'res.currency', 'Currency'
  • item_ids One2many → product.pricelist.item
    copy=True default=_get_default_item_ids args: 'product.pricelist.item', 'pricelist_id', 'Pricelist Items'
  • name Char
    required=True translate=True args: 'Pricelist Name'
  • sequence Integer
    default=16
Public methods (8)
  • get_import_templates(self)
    @api.model
  • get_product_price(self, product, quantity, partner, date=False, uom_id=False)
    For a given pricelist, return price for a given product
  • get_product_price_rule(self, product, quantity, partner, date=False, uom_id=False)
    For a given pricelist, return price and rule for a given product
  • get_products_price(self, products, quantities, partners, date=False, uom_id=False)
    For a given pricelist, return price for products Returns: dict{product_id: product price}, in the given pricelist
  • name_get(self)
    @api.multi
  • price_get(self, prod_id, qty, partner=None)
    @api.multi
    Multi pricelist, mono product - returns price per pricelist
  • price_rule_get(self, prod_id, qty, partner=None)
    @api.multi
    Multi pricelist, mono product - return tuple
  • price_rule_get_multi(self, products_by_qty_by_partner)
    @api.multi
    Multi pricelist, multi product - return tuple

New fields (22)
  • applied_on Selection
    default='3_global' help='Pricelist Item applicable on selected option' required=True args: [('3_global', 'Global'), ('2_product_category', ' Product Category'), ('1_product', 'Product'), ('0_product_variant', 'Product Variant')], 'Apply On'
  • base Selection
    default='list_price' help='Base price for computation.\nPublic Price: The base price will be the Sale/public Price.\nCost Price : The base price will be the cost price.\nOther Pricelist : Computation of the base price based on another Pricelist.' required=True args: [('list_price', 'Public Price'), ('standard_price', 'Cost'), ('pricelist', 'Other Pricelist')], 'Based on'
  • base_pricelist_id Many2one → product.pricelist
    args: 'product.pricelist', 'Other Pricelist'
  • categ_id Many2one → product.category
    help='Specify a product category if this rule only applies to products belonging to this category or its children categories. Keep empty otherwise.' ondelete='cascade' args: 'product.category', 'Product Category'
  • company_id Many2one → res.company
    readonly=True related='pricelist_id.company_id' store=True args: 'res.company', 'Company'
  • compute_price Selection
    default='fixed' index=True args: [('fixed', 'Fix Price'), ('percentage', 'Percentage (discount)'), ('formula', 'Formula')]
  • currency_id Many2one → res.currency
    readonly=True related='pricelist_id.currency_id' store=True args: 'res.currency', 'Currency'
  • date_end Date
    help='Ending valid for the pricelist item validation' args: 'End Date'
  • date_start Date
    help='Starting date for the pricelist item validation' args: 'Start Date'
  • fixed_price Float
    digits=dp.get_precision('Product Price') args: 'Fixed Price'
  • min_quantity Integer
    default=0 help='For the rule to apply, bought/sold quantity must be greater than or equal to the minimum quantity specified in this field.\nExpressed in the default unit of measure of the product.' args: 'Min. Quantity'
  • name Char
    compute='_get_pricelist_item_name_price' help='Explicit rule name for this pricelist line.' args: 'Name'
  • percent_price Float
    args: 'Percentage Price'
  • price Char
    compute='_get_pricelist_item_name_price' help='Explicit rule name for this pricelist line.' args: 'Price'
  • price_discount Float
    default=0 digits=(16, 2) args: 'Price Discount'
  • price_max_margin Float
    digits=dp.get_precision('Product Price') help='Specify the maximum amount of margin over the base price.' args: 'Max. Price Margin'
  • price_min_margin Float
    digits=dp.get_precision('Product Price') help='Specify the minimum amount of margin over the base price.' args: 'Min. Price Margin'
  • price_round Float
    digits=dp.get_precision('Product Price') help='Sets the price so that it is a multiple of this value.\nRounding is applied after the discount and before the surcharge.\nTo have prices that end in 9.99, set rounding 10, surcharge -0.01' args: 'Price Rounding'
  • price_surcharge Float
    digits=dp.get_precision('Product Price') help='Specify the fixed amount to add or substract(if negative) to the amount calculated with the discount.' args: 'Price Surcharge'
  • pricelist_id Many2one → product.pricelist
    index=True ondelete='cascade' args: 'product.pricelist', 'Pricelist'
  • product_id Many2one → product.product
    help='Specify a product if this rule only applies to one product. Keep empty otherwise.' ondelete='cascade' args: 'product.product', 'Product'
  • product_tmpl_id Many2one → product.template
    help='Specify a template if this rule only applies to one product template. Keep empty otherwise.' ondelete='cascade' args: 'product.template', 'Product Template'
Public methods (1)
  • write(self, values)
    @api.multi

New fields (21)
  • active Boolean
    default=True help='If unchecked, it will allow you to hide the product without removing it.' args: 'Active'
  • attribute_value_ids Many2many → product.attribute.value
    ondelete='restrict' string='Attribute Values' args: 'product.attribute.value'
  • barcode Char
    copy=False help='International Article Number used for product identification.' oldname='ean13' args: 'Barcode'
  • code Char
    compute='_compute_product_code' args: 'Reference'
  • default_code Char
    index=True args: 'Internal Reference'
  • image Binary
    compute='_compute_images' help='Image of the product variant (Big-sized image of product template if false). It is automatically resized as a 1024x1024px image, with aspect ratio preserved.' inverse='_set_image' args: 'Big-sized image'
  • image_medium Binary
    compute='_compute_images' help='Image of the product variant (Medium-sized image of product template if false).' inverse='_set_image_medium' args: 'Medium-sized image'
  • image_small Binary
    compute='_compute_images' help='Image of the product variant (Small-sized image of product template if false).' inverse='_set_image_small' args: 'Small-sized image'
  • image_variant Binary
    attachment=True help='This field holds the image used as image for the product variant, limited to 1024x1024px.' args: 'Variant Image'
  • is_product_variant Boolean
    compute='_compute_is_product_variant'
  • lst_price Float
    compute='_compute_product_lst_price' digits=dp.get_precision('Product Price') help="The sale price is managed from the product template. Click on the 'Configure Variants' button to set the extra attribute prices." inverse='_set_product_lst_price' args: 'Sale Price'
  • packaging_ids One2many → product.packaging
    help='Gives the different ways to package the same product.' args: 'product.packaging', 'product_id', 'Product Packages'
  • partner_ref Char
    compute='_compute_partner_ref' args: 'Customer Ref'
  • price Float
    compute='_compute_product_price' digits=dp.get_precision('Product Price') inverse='_set_product_price' args: 'Price'
  • price_extra Float
    compute='_compute_product_price_extra' digits=dp.get_precision('Product Price') help='This is the sum of the extra price of all attributes' args: 'Variant Price Extra'
  • pricelist_item_ids Many2many → product.pricelist.item
    compute='_get_pricelist_items' args: 'product.pricelist.item', 'Pricelist Items'
  • product_template_attribute_value_ids Many2many → product.template.attribute.value
    compute='_compute_product_template_attribute_value_ids' string='Template Attribute Values' args: 'product.template.attribute.value'
  • product_tmpl_id Many2one → product.template
    auto_join=True index=True ondelete='cascade' required=True args: 'product.template', 'Product Template'
  • standard_price Float
    company_dependent=True digits=dp.get_precision('Product Price') groups='base.group_user' help='Cost used for stock valuation in standard price and as a first price to set in average/fifo. Also used as a base price for pricelists. Expressed in the default unit of measure of the product.' args: 'Cost'
  • volume Float
    help='The volume in m3.' args: 'Volume'
  • weight Float
    digits=dp.get_precision('Stock Weight') help='Weight of the product, packaging not included. The unit of measure can be changed in the general settings' args: 'Weight'
Public methods (12)
  • copy(self, default=None)
    @api.multi@api.returns('self', <expr>)
  • create(self, vals_list)
    @api.model_create_multi
  • get_empty_list_help(self, help)
    @api.model
  • get_history_price(self, company_id, date=None)
    @api.multi
  • get_product_multiline_description_sale(self)
    Compute a multiline description of this product, in the context of sales (do not use for purchases or other display reasons that don't intend to use "description_sale"). It will often be used as the default description of a sale order line referencing this product.
  • name_get(self)
    @api.multi
  • open_product_template(self)
    @api.multi
    Utility method used to add an "Open Template" button in product views
  • price_compute(self, price_type, uom=False, currency=False, company=False)
    @api.multi
  • price_get(self, ptype='list_price')
    @api.multi
  • unlink(self)
    @api.multi
  • view_header_get(self, view_id, view_type)
    @api.model
  • write(self, values)
    @api.multi
    Store the standard price change in order to be able to retrieve the cost of a product for a given date

New fields (15)
  • company_id Many2one → res.company
    default=<expr> index=1 args: 'res.company', 'Company'
  • currency_id Many2one → res.currency
    default=<expr> required=True args: 'res.currency', 'Currency'
  • date_end Date
    help='End date for this vendor price' args: 'End Date'
  • date_start Date
    help='Start date for this vendor price' args: 'Start Date'
  • delay Integer
    default=1 help='Lead time in days between the confirmation of the purchase order and the receipt of the products in your warehouse. Used by the scheduler for automatic computation of the purchase order planning.' required=True args: 'Delivery Lead Time'
  • min_qty Float
    default=0.0 help='The minimal quantity to purchase from this vendor, expressed in the vendor Product Unit of Measure if not any, in the default unit of measure of the product otherwise.' required=True args: 'Minimal Quantity'
  • name Many2one → res.partner
    domain=[('supplier', '=', True)] help='Vendor of this product' ondelete='cascade' required=True args: 'res.partner', 'Vendor'
  • price Float
    default=0.0 digits=dp.get_precision('Product Price') help='The price to purchase a product' required=True args: 'Price'
  • product_code Char
    help="This vendor's product code will be used when printing a request for quotation. Keep empty to use the internal one." args: 'Vendor Product Code'
  • product_id Many2one → product.product
    help='If not set, the vendor price will apply to all variants of this product.' args: 'product.product', 'Product Variant'
  • product_name Char
    help="This vendor's product name will be used when printing a request for quotation. Keep empty to use the internal one." args: 'Vendor Product Name'
  • product_tmpl_id Many2one → product.template
    index=True oldname='product_id' ondelete='cascade' args: 'product.template', 'Product Template'
  • product_uom Many2one → uom.uom
    help='This comes from the product form.' related='product_tmpl_id.uom_po_id' args: 'uom.uom', 'Unit of Measure'
  • product_variant_count Integer
    readonly=False related='product_tmpl_id.product_variant_count' args: 'Variant Count'
  • sequence Integer
    default=1 help='Assigns the priority to the list of product vendor.' args: 'Sequence'
Public methods (1)
  • get_import_templates(self)
    @api.model

New fields (49)
  • active Boolean
    default=True help='If unchecked, it will allow you to hide the product without removing it.' args: 'Active'
  • attribute_line_ids One2many → product.template.attribute.line
    args: 'product.template.attribute.line', 'product_tmpl_id', 'Product Attributes'
  • barcode Char
    oldname='ean13' readonly=False related='product_variant_ids.barcode' args: 'Barcode'
  • categ_id Many2one → product.category
    change_default=True default=_get_default_category_id help='Select category for the current product' required=True args: 'product.category', 'Product Category'
  • color Integer
    args: 'Color Index'
  • company_id Many2one → res.company
    default=<expr> index=1 args: 'res.company', 'Company'
  • cost_currency_id Many2one → res.currency
    compute='_compute_cost_currency_id' args: 'res.currency', 'Cost Currency'
  • currency_id Many2one → res.currency
    compute='_compute_currency_id' args: 'res.currency', 'Currency'
  • default_code Char
    compute='_compute_default_code' inverse='_set_default_code' store=True args: 'Internal Reference'
  • description Text
    translate=True args: 'Description'
  • description_purchase Text
    translate=True args: 'Purchase Description'
  • description_sale Text
    help='A description of the Product that you want to communicate to your customers. This description will be copied to every Sales Order, Delivery Order and Customer Invoice/Credit Note' translate=True args: 'Sale Description'
  • image Binary
    attachment=True help='This field holds the image used as image for the product, limited to 1024x1024px.' args: 'Image'
  • image_medium Binary
    attachment=True help='Medium-sized image of the product. It is automatically resized as a 128x128px image, with aspect ratio preserved, only when the image exceeds one of those sizes. Use this field in form views or some kanban views.' args: 'Medium-sized image'
  • image_small Binary
    attachment=True help='Small-sized image of the product. It is automatically resized as a 64x64px image, with aspect ratio preserved. Use this field anywhere a small image is required.' args: 'Small-sized image'
  • is_product_variant Boolean
    compute='_compute_is_product_variant' string='Is a product variant'
  • item_ids One2many → product.pricelist.item
    args: 'product.pricelist.item', 'product_tmpl_id', 'Pricelist Items'
  • list_price Float
    default=1.0 digits=dp.get_precision('Product Price') help='Price at which the product is sold to customers.' args: 'Sales Price'
  • lst_price Float
    digits=dp.get_precision('Product Price') readonly=False related='list_price' args: 'Public Price'
  • name Char
    index=True required=True translate=True args: 'Name'
  • packaging_ids One2many → product.packaging
    compute='_compute_packaging_ids' help='Gives the different ways to package the same product.' inverse='_set_packaging_ids' string='Product Packages' args: 'product.packaging'
  • price Float
    compute='_compute_template_price' digits=dp.get_precision('Product Price') inverse='_set_template_price' args: 'Price'
  • pricelist_id Many2one → product.pricelist
    help='Technical field. Used for searching on pricelists, not stored in database.' store=False args: 'product.pricelist', 'Pricelist'
  • product_variant_count Integer
    compute='_compute_product_variant_count' args: '# Product Variants'
  • product_variant_id Many2one → product.product
    compute='_compute_product_variant_id' args: 'product.product', 'Product'
  • product_variant_ids One2many → product.product
    required=True args: 'product.product', 'product_tmpl_id', 'Products'
  • purchase_ok Boolean
    default=True args: 'Can be Purchased'
  • rental Boolean
    args: 'Can be Rent'
  • sale_ok Boolean
    default=True args: 'Can be Sold'
  • seller_ids One2many → product.supplierinfo
    help='Define vendor pricelists.' args: 'product.supplierinfo', 'product_tmpl_id', 'Vendors'
  • sequence Integer
    default=1 help='Gives the sequence order when displaying a product list' args: 'Sequence'
  • standard_price Float
    compute='_compute_standard_price' digits=dp.get_precision('Product Price') groups='base.group_user' help='Cost used for stock valuation in standard price and as a first price to set in average/FIFO.' inverse='_set_standard_price' search='_search_standard_price' args: 'Cost'
  • type Selection
    default='consu' help='A storable product is a product for which you manage stock. The Inventory app has to be installed.\nA consumable product is a product for which stock is not managed.\nA service is a non-material product you provide.' required=True string='Product Type' args: [('consu', 'Consumable'), ('service', 'Service')]
  • uom_id Many2one → uom.uom
    default=_get_default_uom_id help='Default unit of measure used for all stock operations.' required=True args: 'uom.uom', 'Unit of Measure'
  • uom_name Char
    readonly=True related='uom_id.name' string='Unit of Measure Name'
  • uom_po_id Many2one → uom.uom
    default=_get_default_uom_id help='Default unit of measure used for purchase orders. It must be in the same category as the default unit of measure.' required=True args: 'uom.uom', 'Purchase Unit of Measure'
  • valid_archived_variant_ids Many2many → product.product
    compute='_compute_valid_archived_variant_ids' help='Technical compute' string='Valid Archived Variants' args: 'product.product'
  • valid_existing_variant_ids Many2many → product.product
    compute='_compute_valid_existing_variant_ids' help='Technical compute' string='Valid Existing Variants' args: 'product.product'
  • valid_product_attribute_ids Many2many → product.attribute
    compute='_compute_valid_attributes' help='Technical compute' string='Valid Product Attributes' args: 'product.attribute'
  • valid_product_attribute_value_ids Many2many → product.attribute.value
    compute='_compute_valid_attributes' help='Technical compute' string='Valid Product Attribute Values' args: 'product.attribute.value'
  • valid_product_attribute_value_wnva_ids Many2many → product.attribute.value
    compute='_compute_valid_attributes' help='Technical compute' string='Valid Product Attribute Values Without No Variant Attributes' args: 'product.attribute.value'
  • valid_product_attribute_wnva_ids Many2many → product.attribute
    compute='_compute_valid_attributes' help='Technical compute' string='Valid Product Attributes Without No Variant Attributes' args: 'product.attribute'
  • valid_product_template_attribute_line_ids Many2many → product.template.attribute.line
    compute='_compute_valid_attributes' help='Technical compute' string='Valid Product Attribute Lines' args: 'product.template.attribute.line'
  • valid_product_template_attribute_line_wnva_ids Many2many → product.template.attribute.line
    compute='_compute_valid_attributes' help='Technical compute' string='Valid Product Attribute Lines Without No Variant Attributes' args: 'product.template.attribute.line'
  • variant_seller_ids One2many → product.supplierinfo
    args: 'product.supplierinfo', 'product_tmpl_id'
  • volume Float
    compute='_compute_volume' help='The volume in m3.' inverse='_set_volume' store=True args: 'Volume'
  • weight Float
    compute='_compute_weight' digits=dp.get_precision('Stock Weight') help='The weight of the contents in Kg, not including any packaging, etc.' inverse='_set_weight' store=True args: 'Weight'
  • weight_uom_id Many2one → uom.uom
    compute='_compute_weight_uom_id' string='Weight Unit of Measure' args: 'uom.uom'
  • weight_uom_name Char
    readonly=True related='weight_uom_id.name' string='Weight unit of measure label'
Public methods (10)
  • copy(self, default=None)
    @api.multi@api.returns('self', <expr>)
  • create(self, vals_list)
    @api.model_create_multi
    Store the initial standard price in order to be able to retrieve the cost of a product template for a given date
  • create_variant_ids(self)
    @api.multi
  • get_empty_list_help(self, help)
    @api.model
  • get_filtered_variants(self, reference_product=None)
    @api.multi
    deprecated, use _get_possible_variants instead
  • get_import_templates(self)
    @api.model
  • has_dynamic_attributes(self)
    Return whether this `product.template` has at least one dynamic attribute. :return: True if at least one dynamic attribute, False otherwise :rtype: bool
  • name_get(self)
    @api.multi
  • price_compute(self, price_type, uom=False, currency=False, company=False)
    @api.multi
  • write(self, vals)
    @api.multi

New fields (3)
  • product_template_attribute_value_id Many2one → product.template.attribute.value
    index=True ondelete='cascade' string='Attribute Value' args: 'product.template.attribute.value'
  • product_tmpl_id Many2one → product.template
    index=True ondelete='cascade' required=True string='Product Template' args: 'product.template'
  • value_ids Many2many → product.template.attribute.value
    domain="[('product_tmpl_id', '=', product_tmpl_id)]" relation='product_attr_exclusion_value_ids_rel' string='Attribute Values' args: 'product.template.attribute.value'
Public methods (0)

No public methods.

New fields (4)
  • attribute_id Many2one → product.attribute
    index=True ondelete='restrict' required=True string='Attribute' args: 'product.attribute'
  • product_template_value_ids Many2many → product.template.attribute.value
    compute='_set_product_template_value_ids' store=False string='Product Attribute Values' args: 'product.template.attribute.value'
  • product_tmpl_id Many2one → product.template
    index=True ondelete='cascade' required=True string='Product Template' args: 'product.template'
  • value_ids Many2many → product.attribute.value
    string='Attribute Values' args: 'product.attribute.value'
Public methods (3)
  • create(self, values)
    @api.model
  • unlink(self)
    @api.multi
  • write(self, values)

New fields (7)
  • attribute_id Many2one → product.attribute
    related='product_attribute_value_id.attribute_id' string='Attribute' args: 'product.attribute'
  • exclude_for One2many → product.template.attribute.exclusion
    help='Make this attribute value not compatible with\n other values of the product or some attribute values of optional and accessory products.' relation='product_template_attribute_exclusion' string='Exclude for' args: 'product.template.attribute.exclusion', 'product_template_attribute_value_id'
  • name Char
    related='product_attribute_value_id.name' args: 'Value'
  • price_extra Float
    default=0.0 digits=dp.get_precision('Product Price') help='Price Extra: Extra price for the variant with\n this attribute value on sale price. eg. 200 price extra, 1000 + 200 = 1200.' string='Attribute Price Extra'
  • product_attribute_value_id Many2one → product.attribute.value
    index=True ondelete='cascade' required=True string='Attribute Value' args: 'product.attribute.value'
  • product_tmpl_id Many2one → product.template
    index=True ondelete='cascade' required=True string='Product Template' args: 'product.template'
  • sequence Integer
    related='product_attribute_value_id.sequence' args: 'Sequence'
Public methods (1)
  • name_get(self)
    @api.multi

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (2)
  • create(self, vals)
    @api.model
  • write(self, values)
    @api.multi

New fields (8)
  • company_share_product Boolean
    help='Share your product to all companies defined in your instance.\n * Checked : Product are visible for every company, even if a company is defined on the partner.\n * Unchecked : Each company can see only its product (product where company is defined). Product not related to a company are visible for all companies.' args: 'Share product to all companies'
  • group_pricelist_item Boolean
    implied_group='product.group_pricelist_item' args: 'Show pricelists to customers'
  • group_product_pricelist Boolean
    implied_group='product.group_product_pricelist' args: 'Show pricelists On Products'
  • group_product_variant Boolean
    implied_group='product.group_product_variant' args: 'Variants and Options'
  • group_sale_pricelist Boolean
    help='Allows to manage different prices based on rules per category of customers.\n Example: 10% for retailers, promotion of 5 EUR on this product, etc.' implied_group='product.group_sale_pricelist' args: 'Use pricelists to adapt your price per customers'
  • group_stock_packaging Boolean
    implied_group='product.group_stock_packaging' args: 'Product Packagings'
  • group_uom Boolean
    implied_group='uom.group_uom' args: 'Units of Measure'
  • product_weight_in_lbs Selection
    config_parameter='product.weight_in_lbs' default='0' args: [('0', 'Kilogram'), ('1', 'Pound')], 'Weight unit of measure'
Public methods (4)
  • get_values(self)
    @api.model
  • pos_pricelist_setting_sync(self, sale_pricelist_setting)
  • sale_pricelist_setting_sync(self, pos_pricelist_setting)
  • set_values(self)

New fields (1)
  • pricelist_ids Many2many → product.pricelist
    string='Pricelists' args: 'product.pricelist', 'res_country_group_pricelist_rel', 'res_country_group_id', 'pricelist_id'
Public methods (0)

No public methods.

New fields (1)
  • property_product_pricelist Many2one → product.pricelist
    company_dependent=False compute='_compute_product_pricelist' help='This pricelist will be used, instead of the default one, for sales to the current partner' inverse='_inverse_product_pricelist' args: 'product.pricelist', 'Pricelist'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/11.0/product
VERSION
VERSION 1.2
CATEGORY
CATEGORYSales
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Christophe Matthieu, Martin Trigaux, Fabien Pinckaers, Olivier Dony, Thibault Delavallée, Christophe Simonis, Xavier Morel, Goffin Simon, Cedric Snauwaert, Simon Lejeune, Nicolas Martinelli, Nicolas Lempereur, Jérome Maes, Richard Mathot, qdp-odoo, Aaron Bohy, Jeremy Kersten, GitHub, Lucas Perais (lpe), Wolfgang Taferner, Yannick Tivisse, qsm-odoo, Odoo Online, Pierre Masereel, Laurent Smet, Denis Vermylen (dve), Adrien Dieudonne, Julien (juc) Castiaux, Jorge Pinna Puissant, amoyaux, jerome hanke (jhk), rar-odoo, Victor Feyens, Fanny He
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-05 23:53:43
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - base
    - decimal_precision
    - mail
    - base_setup
    - web
    - bus
    - web_tour
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
This is the base module for managing products and pricelists in Odoo.
========================================================================

Products support variants, different pricing methods, vendors information,
make to stock/order, different units of measure, packaging and properties.

Pricelists support:
-------------------
    * Multiple-level of discount (by product, category, quantities)
    * Compute price based on different criteria:
        * Other pricelist
        * Cost price
        * List price
        * Vendor price

Pricelists preferences by product and/or partners.

Print product labels with barcode.
    

Code Analysis

Views touched (41)
XML IDNameModelTypeStatus
attribute_tree_view product.attribute.tree product.attribute tree New
inherits_website_sale_country_group_form website_sale.country_group.form res.country.group group Inherits base.view_country_group_form
product_attribute_line_form product.attribute.line.form product.attribute.line form New
product_attribute_value_view_tree product.attribute.value.view.tree product.attribute.value tree New
product_attribute_view_form product.attribute.form product.attribute form New
product_category_form_view product.category.form product.category form New
product_category_list_view product.category.list product.category tree New
product_category_search_view product.category.search product.category search New
product_kanban_view Product Kanban product.product kanban New
product_normal_form_view product.product.form product.product form Inherits product.product_template_form_view
product_packaging_form_view product.packaging.form.view product.packaging form New
product_packaging_form_view2 product.packaging.form.view2 product.packaging xpath Inherits product.product_packaging_form_view
product_packaging_tree_view product.packaging.tree.view product.packaging tree New
product_pricelist_item_form_view product.pricelist.item.form product.pricelist.item form New
product_pricelist_item_tree_view product.pricelist.item.tree product.pricelist.item tree New
product_pricelist_view product.pricelist.form product.pricelist form New
product_pricelist_view_kanban product.pricelist.kanban product.pricelist kanban New
product_pricelist_view_search product.pricelist.search product.pricelist search New
product_pricelist_view_tree product.pricelist.tree product.pricelist tree New
product_product_tree_view product.product.tree product.product tree New
product_search_form_view product.product.search product.product field Inherits product.product_template_search_view
product_supplierinfo_form_view product.supplierinfo.form.view product.supplierinfo form New
product_supplierinfo_search_view product.supplierinfo.search.view product.supplierinfo search New
product_supplierinfo_tree_view product.supplierinfo.tree.view product.supplierinfo tree New
product_template_form_view product.template.common.form product.template form New
product_template_kanban_view Product.template.product.kanban product.template kanban New
product_template_only_form_view product.template.product.form product.template xpath Inherits product.product_template_form_view
product_template_search_view product.template.search product.template search New
product_template_tree_view product.template.product.tree product.template tree New
product_uom_categ_form_view product.uom.categ.form product.uom.categ form New
product_uom_form_view product.uom.form product.uom form New
product_uom_tree_view product.uom.tree product.uom tree New
product_variant_easy_edit_view product.product.view.form.easy product.product form New
report_pricelist report_pricelist ir.ui.view qweb New
report_productlabel report_productlabel ir.ui.view qweb New
report_producttemplatelabel report_producttemplatelabel ir.ui.view qweb New
report_simple_label report_simple_label ir.ui.view qweb New
res_config_settings_view_form res.config.settings.view.form.inherit.product res.config.settings xpath Inherits base_setup.res_config_settings_view_form
variants_tree_view product.attribute.value.tree product.attribute.value tree New
view_partner_property_form res.partner.product.property.form.inherit res.partner group Inherits base.view_partner_form
view_product_price_list Price per unit product.price_list form New
Models touched (21)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (5)
  • attribute_line_ids One2many → product.attribute.line
    args: 'product.attribute.line', 'attribute_id', 'Lines'
  • create_variant Boolean
    default=True help='Check this if you want to create multiple variants for this attribute.'
  • name Char
    required=True translate=True args: 'Name'
  • sequence Integer
    help='Determine the display order' args: 'Sequence'
  • value_ids One2many → product.attribute.value
    copy=True args: 'product.attribute.value', 'attribute_id', 'Values'
Public methods (0)

No public methods.

New fields (3)
  • attribute_id Many2one → product.attribute
    ondelete='restrict' required=True args: 'product.attribute', 'Attribute'
  • product_tmpl_id Many2one → product.template
    ondelete='cascade' required=True args: 'product.template', 'Product Template'
  • value_ids Many2many → product.attribute.value
    string='Attribute Values' args: 'product.attribute.value'
Public methods (1)
  • name_search(self, name='', args=None, operator='ilike', limit=100)
    @api.model

New fields (3)
  • price_extra Float
    digits=dp.get_precision('Product Price') args: 'Price Extra'
  • product_tmpl_id Many2one → product.template
    ondelete='cascade' required=True args: 'product.template', 'Product Template'
  • value_id Many2one → product.attribute.value
    ondelete='cascade' required=True args: 'product.attribute.value', 'Product Attribute Value'
Public methods (0)

No public methods.

New fields (6)
  • attribute_id Many2one → product.attribute
    ondelete='cascade' required=True args: 'product.attribute', 'Attribute'
  • name Char
    required=True translate=True args: 'Value'
  • price_extra Float
    compute='_compute_price_extra' default=0.0 digits=dp.get_precision('Product Price') help='Price Extra: Extra price for the variant with this attribute value on sale price. eg. 200 price extra, 1000 + 200 = 1200.' inverse='_set_price_extra' args: 'Attribute Price Extra'
  • price_ids One2many → product.attribute.price
    readonly=True args: 'product.attribute.price', 'value_id', 'Attribute Prices'
  • product_ids Many2many → product.product
    readonly=True string='Variants' args: 'product.product'
  • sequence Integer
    help='Determine the display order' args: 'Sequence'
Public methods (2)
  • name_get(self)
    @api.multi
  • unlink(self)
    @api.multi

New fields (7)
  • child_id One2many → product.category
    args: 'product.category', 'parent_id', 'Child Categories'
  • complete_name Char
    compute='_compute_complete_name' store=True args: 'Complete Name'
  • name Char
    index=True required=True translate=True args: 'Name'
  • parent_id Many2one → product.category
    index=True ondelete='cascade' args: 'product.category', 'Parent Category'
  • parent_left Integer
    index=1 args: 'Left Parent'
  • parent_right Integer
    index=1 args: 'Right Parent'
  • product_count Integer
    compute='_compute_product_count' help='The number of products under this category (Does not consider the children categories)' args: '# Products'
Public methods (1)
  • name_create(self, name)
    @api.model

New fields (5)
  • barcode Char
    copy=False help='Barcode used for packaging identification.' args: 'Barcode'
  • name Char
    required=True args: 'Package Type'
  • product_id Many2one → product.product
    string='Product' args: 'product.product'
  • qty Float
    help='The total number of products you can have per pallet or box.' args: 'Quantity per Package'
  • sequence Integer
    default=1 help='The first in the sequence is the default one.' args: 'Sequence'
Public methods (0)

No public methods.

New fields (4)
  • company_id Many2one → res.company
    default=_get_default_company_id required=True string='Company' args: 'res.company'
  • cost Float
    digits=dp.get_precision('Product Price') args: 'Cost'
  • datetime Datetime
    default=fields.Datetime.now args: 'Date'
  • product_id Many2one → product.product
    ondelete='cascade' required=True args: 'product.product', 'Product'
Public methods (0)

No public methods.

New fields (6)
  • price_list Many2one → product.pricelist
    required=True args: 'product.pricelist', 'PriceList'
  • qty1 Integer
    default=1 args: 'Quantity-1'
  • qty2 Integer
    default=5 args: 'Quantity-2'
  • qty3 Integer
    default=10 args: 'Quantity-3'
  • qty4 Integer
    default=0 args: 'Quantity-4'
  • qty5 Integer
    default=0 args: 'Quantity-5'
Public methods (1)
  • print_report(self)
    @api.multi
    To get the date and print the report @return : return report

New fields (7)
  • active Boolean
    default=True help='If unchecked, it will allow you to hide the pricelist without removing it.' args: 'Active'
  • company_id Many2one → res.company
    args: 'res.company', 'Company'
  • country_group_ids Many2many → res.country.group
    string='Country Groups' args: 'res.country.group', 'res_country_group_pricelist_rel', 'pricelist_id', 'res_country_group_id'
  • currency_id Many2one → res.currency
    default=_get_default_currency_id required=True args: 'res.currency', 'Currency'
  • item_ids One2many → product.pricelist.item
    copy=True default=_get_default_item_ids args: 'product.pricelist.item', 'pricelist_id', 'Pricelist Items'
  • name Char
    required=True translate=True args: 'Pricelist Name'
  • sequence Integer
    default=16
Public methods (8)
  • get_product_price(self, product, quantity, partner, date=False, uom_id=False)
    For a given pricelist, return price for a given product
  • get_product_price_rule(self, product, quantity, partner, date=False, uom_id=False)
    For a given pricelist, return price and rule for a given product
  • get_products_price(self, products, quantities, partners, date=False, uom_id=False)
    For a given pricelist, return price for products Returns: dict{product_id: product price}, in the given pricelist
  • name_get(self)
    @api.multi
  • name_search(self, name, args=None, operator='ilike', limit=100)
    @api.model
  • price_get(self, prod_id, qty, partner=None)
    @api.multi
    Multi pricelist, mono product - returns price per pricelist
  • price_rule_get(self, prod_id, qty, partner=None)
    @api.multi
    Multi pricelist, mono product - return tuple
  • price_rule_get_multi(self, products_by_qty_by_partner)
    @api.multi
    Multi pricelist, multi product - return tuple

New fields (22)
  • applied_on Selection
    default='3_global' help='Pricelist Item applicable on selected option' required=True args: [('3_global', 'Global'), ('2_product_category', ' Product Category'), ('1_product', 'Product'), ('0_product_variant', 'Product Variant')], 'Apply On'
  • base Selection
    default='list_price' help='Base price for computation.\nPublic Price: The base price will be the Sale/public Price.\nCost Price : The base price will be the cost price.\nOther Pricelist : Computation of the base price based on another Pricelist.' required=True args: [('list_price', 'Public Price'), ('standard_price', 'Cost'), ('pricelist', 'Other Pricelist')], 'Based on'
  • base_pricelist_id Many2one → product.pricelist
    args: 'product.pricelist', 'Other Pricelist'
  • categ_id Many2one → product.category
    help='Specify a product category if this rule only applies to products belonging to this category or its children categories. Keep empty otherwise.' ondelete='cascade' args: 'product.category', 'Product Category'
  • company_id Many2one → res.company
    readonly=True related='pricelist_id.company_id' store=True args: 'res.company', 'Company'
  • compute_price Selection
    default='fixed' index=True args: [('fixed', 'Fix Price'), ('percentage', 'Percentage (discount)'), ('formula', 'Formula')]
  • currency_id Many2one → res.currency
    readonly=True related='pricelist_id.currency_id' store=True args: 'res.currency', 'Currency'
  • date_end Date
    help='Ending valid for the pricelist item validation' args: 'End Date'
  • date_start Date
    help='Starting date for the pricelist item validation' args: 'Start Date'
  • fixed_price Float
    digits=dp.get_precision('Product Price') args: 'Fixed Price'
  • min_quantity Integer
    default=0 help='For the rule to apply, bought/sold quantity must be greater than or equal to the minimum quantity specified in this field.\nExpressed in the default unit of measure of the product.' args: 'Min. Quantity'
  • name Char
    compute='_get_pricelist_item_name_price' help='Explicit rule name for this pricelist line.' args: 'Name'
  • percent_price Float
    args: 'Percentage Price'
  • price Char
    compute='_get_pricelist_item_name_price' help='Explicit rule name for this pricelist line.' args: 'Price'
  • price_discount Float
    default=0 digits=(16, 2) args: 'Price Discount'
  • price_max_margin Float
    digits=dp.get_precision('Product Price') help='Specify the maximum amount of margin over the base price.' args: 'Max. Price Margin'
  • price_min_margin Float
    digits=dp.get_precision('Product Price') help='Specify the minimum amount of margin over the base price.' args: 'Min. Price Margin'
  • price_round Float
    digits=dp.get_precision('Product Price') help='Sets the price so that it is a multiple of this value.\nRounding is applied after the discount and before the surcharge.\nTo have prices that end in 9.99, set rounding 10, surcharge -0.01' args: 'Price Rounding'
  • price_surcharge Float
    digits=dp.get_precision('Product Price') help='Specify the fixed amount to add or substract(if negative) to the amount calculated with the discount.' args: 'Price Surcharge'
  • pricelist_id Many2one → product.pricelist
    index=True ondelete='cascade' args: 'product.pricelist', 'Pricelist'
  • product_id Many2one → product.product
    help='Specify a product if this rule only applies to one product. Keep empty otherwise.' ondelete='cascade' args: 'product.product', 'Product'
  • product_tmpl_id Many2one → product.template
    help='Specify a template if this rule only applies to one product template. Keep empty otherwise.' ondelete='cascade' args: 'product.template', 'Product Template'
Public methods (0)

No public methods.

New fields (20)
  • active Boolean
    default=True help='If unchecked, it will allow you to hide the product without removing it.' args: 'Active'
  • attribute_value_ids Many2many → product.attribute.value
    ondelete='restrict' string='Attributes' args: 'product.attribute.value'
  • barcode Char
    copy=False help='International Article Number used for product identification.' oldname='ean13' args: 'Barcode'
  • code Char
    compute='_compute_product_code' args: 'Reference'
  • default_code Char
    index=True args: 'Internal Reference'
  • image Binary
    compute='_compute_images' help='Image of the product variant (Big-sized image of product template if false). It is automatically resized as a 1024x1024px image, with aspect ratio preserved.' inverse='_set_image' args: 'Big-sized image'
  • image_medium Binary
    compute='_compute_images' help='Image of the product variant (Medium-sized image of product template if false).' inverse='_set_image_medium' args: 'Medium-sized image'
  • image_small Binary
    compute='_compute_images' help='Image of the product variant (Small-sized image of product template if false).' inverse='_set_image_small' args: 'Small-sized image'
  • image_variant Binary
    attachment=True help='This field holds the image used as image for the product variant, limited to 1024x1024px.' args: 'Variant Image'
  • is_product_variant Boolean
    compute='_compute_is_product_variant'
  • lst_price Float
    compute='_compute_product_lst_price' digits=dp.get_precision('Product Price') help="The sale price is managed from the product template. Click on the 'Variant Prices' button to set the extra attribute prices." inverse='_set_product_lst_price' args: 'Sale Price'
  • packaging_ids One2many → product.packaging
    help='Gives the different ways to package the same product.' args: 'product.packaging', 'product_id', 'Product Packages'
  • partner_ref Char
    compute='_compute_partner_ref' args: 'Customer Ref'
  • price Float
    compute='_compute_product_price' digits=dp.get_precision('Product Price') inverse='_set_product_price' args: 'Price'
  • price_extra Float
    compute='_compute_product_price_extra' digits=dp.get_precision('Product Price') help='This is the sum of the extra price of all attributes' args: 'Variant Price Extra'
  • pricelist_item_ids Many2many → product.pricelist.item
    compute='_get_pricelist_items' args: 'product.pricelist.item', 'Pricelist Items'
  • product_tmpl_id Many2one → product.template
    auto_join=True index=True ondelete='cascade' required=True args: 'product.template', 'Product Template'
  • standard_price Float
    company_dependent=True digits=dp.get_precision('Product Price') groups='base.group_user' help='Cost used for stock valuation in standard price and as a first price to set in average/fifo. Also used as a base price for pricelists. Expressed in the default unit of measure of the product.' args: 'Cost'
  • volume Float
    help='The volume in m3.' args: 'Volume'
  • weight Float
    digits=dp.get_precision('Stock Weight') help='The weight of the contents in Kg, not including any packaging, etc.' args: 'Weight'
Public methods (12)
  • copy(self, default=None)
    @api.multi
  • create(self, vals)
    @api.model
  • get_history_price(self, company_id, date=None)
    @api.multi
  • name_get(self)
    @api.multi
  • name_search(self, name='', args=None, operator='ilike', limit=100)
    @api.model
  • open_product_template(self)
    @api.multi
    Utility method used to add an "Open Template" button in product views
  • price_compute(self, price_type, uom=False, currency=False, company=False)
    @api.multi
  • price_get(self, ptype='list_price')
    @api.multi
  • search(self, args, offset=0, limit=None, order=None, count=False)
    @api.model
  • unlink(self)
    @api.multi
  • view_header_get(self, view_id, view_type)
    @api.model
  • write(self, values)
    @api.multi
    Store the standard price change in order to be able to retrieve the cost of a product for a given date

New fields (15)
  • company_id Many2one → res.company
    default=<expr> index=1 args: 'res.company', 'Company'
  • currency_id Many2one → res.currency
    default=<expr> required=True args: 'res.currency', 'Currency'
  • date_end Date
    help='End date for this vendor price' args: 'End Date'
  • date_start Date
    help='Start date for this vendor price' args: 'Start Date'
  • delay Integer
    default=1 help='Lead time in days between the confirmation of the purchase order and the receipt of the products in your warehouse. Used by the scheduler for automatic computation of the purchase order planning.' required=True args: 'Delivery Lead Time'
  • min_qty Float
    default=0.0 help='The minimal quantity to purchase from this vendor, expressed in the vendor Product Unit of Measure if not any, in the default unit of measure of the product otherwise.' required=True args: 'Minimal Quantity'
  • name Many2one → res.partner
    domain=[('supplier', '=', True)] help='Vendor of this product' ondelete='cascade' required=True args: 'res.partner', 'Vendor'
  • price Float
    default=0.0 digits=dp.get_precision('Product Price') help='The price to purchase a product' required=True args: 'Price'
  • product_code Char
    help="This vendor's product code will be used when printing a request for quotation. Keep empty to use the internal one." args: 'Vendor Product Code'
  • product_id Many2one → product.product
    help='If not set, the vendor price will apply to all variants of this products.' args: 'product.product', 'Product Variant'
  • product_name Char
    help="This vendor's product name will be used when printing a request for quotation. Keep empty to use the internal one." args: 'Vendor Product Name'
  • product_tmpl_id Many2one → product.template
    index=True oldname='product_id' ondelete='cascade' args: 'product.template', 'Product Template'
  • product_uom Many2one → product.uom
    help='This comes from the product form.' readonly='1' related='product_tmpl_id.uom_po_id' args: 'product.uom', 'Vendor Unit of Measure'
  • product_variant_count Integer
    related='product_tmpl_id.product_variant_count' args: 'Variant Count'
  • sequence Integer
    default=1 help='Assigns the priority to the list of product vendor.' args: 'Sequence'
Public methods (0)

No public methods.

New fields (38)
  • active Boolean
    default=True help='If unchecked, it will allow you to hide the product without removing it.' args: 'Active'
  • attribute_line_ids One2many → product.attribute.line
    args: 'product.attribute.line', 'product_tmpl_id', 'Product Attributes'
  • barcode Char
    oldname='ean13' related='product_variant_ids.barcode' args: 'Barcode'
  • categ_id Many2one → product.category
    change_default=True default=_get_default_category_id help='Select category for the current product' required=True args: 'product.category', 'Internal Category'
  • color Integer
    args: 'Color Index'
  • company_id Many2one → res.company
    default=<expr> index=1 args: 'res.company', 'Company'
  • cost_currency_id Many2one → res.currency
    compute='_compute_cost_currency_id' args: 'res.currency', 'Cost Currency'
  • currency_id Many2one → res.currency
    compute='_compute_currency_id' args: 'res.currency', 'Currency'
  • default_code Char
    compute='_compute_default_code' inverse='_set_default_code' store=True args: 'Internal Reference'
  • description Text
    help='A precise description of the Product, used only for internal information purposes.' translate=True args: 'Description'
  • description_purchase Text
    help='A description of the Product that you want to communicate to your vendors. This description will be copied to every Purchase Order, Receipt and Vendor Bill/Credit Note.' translate=True args: 'Purchase Description'
  • description_sale Text
    help='A description of the Product that you want to communicate to your customers. This description will be copied to every Sales Order, Delivery Order and Customer Invoice/Credit Note' translate=True args: 'Sale Description'
  • image Binary
    attachment=True help='This field holds the image used as image for the product, limited to 1024x1024px.' args: 'Image'
  • image_medium Binary
    attachment=True help='Medium-sized image of the product. It is automatically resized as a 128x128px image, with aspect ratio preserved, only when the image exceeds one of those sizes. Use this field in form views or some kanban views.' args: 'Medium-sized image'
  • image_small Binary
    attachment=True help='Small-sized image of the product. It is automatically resized as a 64x64px image, with aspect ratio preserved. Use this field anywhere a small image is required.' args: 'Small-sized image'
  • is_product_variant Boolean
    compute='_compute_is_product_variant' string='Is a product variant'
  • item_ids One2many → product.pricelist.item
    args: 'product.pricelist.item', 'product_tmpl_id', 'Pricelist Items'
  • list_price Float
    default=1.0 digits=dp.get_precision('Product Price') help='Base price to compute the customer price. Sometimes called the catalog price.' args: 'Sales Price'
  • lst_price Float
    digits=dp.get_precision('Product Price') related='list_price' args: 'Public Price'
  • name Char
    index=True required=True translate=True args: 'Name'
  • packaging_ids One2many → product.packaging
    compute='_compute_packaging_ids' help='Gives the different ways to package the same product.' inverse='_set_packaging_ids' string='Product Packages' args: 'product.packaging'
  • price Float
    compute='_compute_template_price' digits=dp.get_precision('Product Price') inverse='_set_template_price' args: 'Price'
  • pricelist_id Many2one → product.pricelist
    help='Technical field. Used for searching on pricelists, not stored in database.' store=False args: 'product.pricelist', 'Pricelist'
  • product_variant_count Integer
    compute='_compute_product_variant_count' args: '# Product Variants'
  • product_variant_id Many2one → product.product
    compute='_compute_product_variant_id' args: 'product.product', 'Product'
  • product_variant_ids One2many → product.product
    required=True args: 'product.product', 'product_tmpl_id', 'Products'
  • purchase_ok Boolean
    default=True args: 'Can be Purchased'
  • rental Boolean
    args: 'Can be Rent'
  • sale_ok Boolean
    default=True help='Specify if the product can be selected in a sales order line.' args: 'Can be Sold'
  • seller_ids One2many → product.supplierinfo
    args: 'product.supplierinfo', 'product_tmpl_id', 'Vendors'
  • sequence Integer
    default=1 help='Gives the sequence order when displaying a product list' args: 'Sequence'
  • standard_price Float
    compute='_compute_standard_price' digits=dp.get_precision('Product Price') groups='base.group_user' help='Cost used for stock valuation in standard price and as a first price to set in average/fifo. Also used as a base price for pricelists. Expressed in the default unit of measure of the product. ' inverse='_set_standard_price' search='_search_standard_price' args: 'Cost'
  • type Selection
    default='consu' help='A stockable product is a product for which you manage stock. The "Inventory" app has to be installed.\nA consumable product, on the other hand, is a product for which stock is not managed.\nA service is a non-material product you provide.\nA digital content is a non-material product you sell online. The files attached to the products are the one that are sold on the e-commerce such as e-books, music, pictures,... The "Digital Product" module has to be installed.' required=True string='Product Type' args: [('consu', 'Consumable'), ('service', 'Service')]
  • uom_id Many2one → product.uom
    default=_get_default_uom_id help='Default Unit of Measure used for all stock operation.' required=True args: 'product.uom', 'Unit of Measure'
  • uom_po_id Many2one → product.uom
    default=_get_default_uom_id help='Default Unit of Measure used for purchase orders. It must be in the same category than the default unit of measure.' required=True args: 'product.uom', 'Purchase Unit of Measure'
  • variant_seller_ids One2many → product.supplierinfo
    args: 'product.supplierinfo', 'product_tmpl_id'
  • volume Float
    compute='_compute_volume' help='The volume in m3.' inverse='_set_volume' store=True args: 'Volume'
  • weight Float
    compute='_compute_weight' digits=dp.get_precision('Stock Weight') help='The weight of the contents in Kg, not including any packaging, etc.' inverse='_set_weight' store=True args: 'Weight'
Public methods (7)
  • copy(self, default=None)
    @api.multi
  • create(self, vals)
    @api.model
    Store the initial standard price in order to be able to retrieve the cost of a product template for a given date
  • create_variant_ids(self)
    @api.multi
  • name_get(self)
    @api.multi
  • name_search(self, name='', args=None, operator='ilike', limit=100)
    @api.model
  • price_compute(self, price_type, uom=False, currency=False, company=False)
    @api.multi
  • write(self, vals)
    @api.multi

New fields (7)
  • active Boolean
    default=True help='Uncheck the active field to disable a unit of measure without deleting it.' args: 'Active'
  • category_id Many2one → product.uom.categ
    help='Conversion between Units of Measure can only occur if they belong to the same category. The conversion will be made based on the ratios.' ondelete='cascade' required=True args: 'product.uom.categ', 'Category'
  • factor Float
    default=1.0 digits=0 help='How much bigger or smaller this unit is compared to the reference Unit of Measure for this category: 1 * (reference unit) = ratio * (this unit)' required=True args: 'Ratio'
  • factor_inv Float
    compute='_compute_factor_inv' digits=0 help='How many times this Unit of Measure is bigger than the reference Unit of Measure in this category: 1 * (this unit) = ratio * (reference unit)' readonly=True required=True args: 'Bigger Ratio'
  • name Char
    required=True translate=True args: 'Unit of Measure'
  • rounding Float
    default=0.01 digits=0 help='The computed quantity will be a multiple of this value. Use 1.0 for a Unit of Measure that cannot be further split, such as a piece.' required=True args: 'Rounding Precision'
  • uom_type Selection
    default='reference' required=1 args: [('bigger', 'Bigger than the reference Unit of Measure'), ('reference', 'Reference Unit of Measure for this category'), ('smaller', 'Smaller than the reference Unit of Measure')], 'Type'
Public methods (3)
  • create(self, values)
    @api.model
  • name_create(self, name)
    @api.model
    The UoM category and factor are required, so we'll have to add temporary values for imported UoMs
  • write(self, values)
    @api.multi

New fields (1)
  • name Char
    required=True translate=True args: 'Name'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (1)
  • get_report_values(self, docids, data=None)
    @api.model

New fields (0)

No new fields.

Public methods (2)
  • create(self, vals)
    @api.model
  • write(self, values)
    @api.multi

New fields (7)
  • company_share_product Boolean
    help='Share your product to all companies defined in your instance.\n * Checked : Product are visible for every company, even if a company is defined on the partner.\n * Unchecked : Each company can see only its product (product where company is defined). Product not related to a company are visible for all companies.' args: 'Share product to all companies'
  • group_pricelist_item Boolean
    implied_group='product.group_pricelist_item' args: 'Show pricelists to customers'
  • group_product_pricelist Boolean
    implied_group='product.group_product_pricelist' args: 'Show pricelists On Products'
  • group_product_variant Boolean
    implied_group='product.group_product_variant' args: 'Attributes and Variants'
  • group_sale_pricelist Boolean
    help='Allows to manage different prices based on rules per category of customers.\n Example: 10% for retailers, promotion of 5 EUR on this product, etc.' implied_group='product.group_sale_pricelist' args: 'Use pricelists to adapt your price per customers'
  • group_stock_packaging Boolean
    implied_group='product.group_stock_packaging' args: 'Product Packages'
  • group_uom Boolean
    implied_group='product.group_uom' args: 'Units of Measure'
Public methods (2)
  • get_values(self)
    @api.model
  • set_values(self)

New fields (1)
  • pricelist_ids Many2many → product.pricelist
    string='Pricelists' args: 'product.pricelist', 'res_country_group_pricelist_rel', 'res_country_group_id', 'pricelist_id'
Public methods (0)

No public methods.

New fields (1)
  • property_product_pricelist Many2one → product.pricelist
    company_dependent=False compute='_compute_product_pricelist' help='This pricelist will be used, instead of the default one, for sales to the current partner' inverse='_inverse_product_pricelist' args: 'product.pricelist', 'Sale Pricelist'
Public methods (0)

No public methods.

REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/10.0/product
VERSION
VERSION 1.2
CATEGORY
CATEGORYSales
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Christophe Matthieu, Martin Trigaux, Fabien Pinckaers, Olivier Dony, Thibault Delavallée, Josse Colpaert, Denis Ledoux, Christophe Simonis, David Monjoie, Goffin Simon, Nicolas Martinelli, Julien Legros, Richard Mathot, qdp-odoo, Aaron Bohy, Jeremy Kersten, Lucas Perais (lpe), Damien Bouvy, Yannick Tivisse, Pierre Masereel, Denis Vermylen (dve), Tanguy Charlier, fwi-odoo, RomainLibert, Denis Vermylen, amoyaux, Moens Alexandre, This Is Banana
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-05 23:50:48
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - base
    - decimal_precision
    - mail
    - base_setup
    - web_kanban
    - web
    - bus
    - web_tour
    - report
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
This is the base module for managing products and pricelists in Odoo.
========================================================================

Products support variants, different pricing methods, vendors information,
make to stock/order, different units of measure, packaging and properties.

Pricelists support:
-------------------
    * Multiple-level of discount (by product, category, quantities)
    * Compute price based on different criteria:
        * Other pricelist
        * Cost price
        * List price
        * Vendor price

Pricelists preferences by product and/or partners.

Print product labels with barcode.
    

Code Analysis

Views touched (39)
XML IDNameModelTypeStatus
attribute_tree_view product.attribute.tree product.attribute tree New
inherit_view_general_configuration General Settings base.config.settings xpath Inherits base_setup.view_general_configuration
inherits_website_sale_country_group_form website_sale.country_group.form res.country.group group Inherits base.view_country_group_form
product_attribute_line_form product.attribute.line.form product.attribute.line form New
product_attribute_value_view_tree product.attribute.value.view.tree product.attribute.value tree New
product_attribute_view_form product.attribute.form product.attribute form New
product_category_form_view product.category.form product.category form New
product_category_list_view product.category.list product.category tree New
product_category_search_view product.category.search product.category search New
product_kanban_view Product Kanban product.product kanban New
product_normal_form_view product.product.form product.product form Inherits product.product_template_form_view
product_packaging_form_view product.packaging.form.view product.packaging form New
product_packaging_tree_view product.packaging.tree.view product.packaging tree New
product_pricelist_item_form_view product.pricelist.item.form product.pricelist.item form New
product_pricelist_item_tree_view product.pricelist.item.tree product.pricelist.item tree New
product_pricelist_view product.pricelist.form product.pricelist form New
product_pricelist_view_search product.pricelist.search product.pricelist search New
product_pricelist_view_tree product.pricelist.tree product.pricelist tree New
product_product_tree_view product.product.tree product.product tree New
product_search_form_view product.product.search product.product field Inherits product.product_template_search_view
product_supplierinfo_form_view product.supplierinfo.form.view product.supplierinfo form New
product_supplierinfo_search_view product.supplierinfo.search.view product.supplierinfo search New
product_supplierinfo_tree_view product.supplierinfo.tree.view product.supplierinfo tree New
product_template_form_view product.template.common.form product.template form New
product_template_kanban_view Product.template.product.kanban product.template kanban New
product_template_only_form_view product.template.product.form product.template xpath Inherits product.product_template_form_view
product_template_search_view product.template.search product.template search New
product_template_tree_view product.template.product.tree product.template tree New
product_uom_categ_form_view product.uom.categ.form product.uom.categ form New
product_uom_form_view product.uom.form product.uom form New
product_uom_tree_view product.uom.tree product.uom tree New
product_variant_easy_edit_view product.product.view.form.easy product.product form New
report_pricelist report_pricelist ir.ui.view qweb New
report_productlabel report_productlabel ir.ui.view qweb New
report_producttemplatelabel report_producttemplatelabel ir.ui.view qweb New
report_simple_label report_simple_label ir.ui.view qweb New
variants_tree_view product.attribute.value.tree product.attribute.value tree New
view_partner_property_form res.partner.product.property.form.inherit res.partner group Inherits base.view_partner_form
view_product_price_list Price per unit product.price_list form New
Models touched (21)

New fields (2)
  • company_share_product Boolean
    help='Share your product to all companies defined in your instance.\n * Checked : Product are visible for every company, even if a company is defined on the partner.\n * Unchecked : Each company can see only its product (product where company is defined). Product not related to a company are visible for all companies.' args: 'Share product to all companies'
  • group_product_variant Selection
    help='Work with product variant allows you to define some variant of the same products, an ease the product management in the ecommerce for example' implied_group='product.group_product_variant' args: [(0, 'No variants on products'), (1, 'Products can have several attributes, defining variants (Example: size, color,...)')], 'Product Variants'
Public methods (2)
  • get_default_company_share_product(self, fields)
    @api.model
  • set_auth_company_share_product(self)
    @api.multi

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (5)
  • attribute_line_ids One2many → product.attribute.line
    args: 'product.attribute.line', 'attribute_id', 'Lines'
  • create_variant Boolean
    default=True help='Check this if you want to create multiple variants for this attribute.'
  • name Char
    required=True translate=True args: 'Name'
  • sequence Integer
    help='Determine the display order' args: 'Sequence'
  • value_ids One2many → product.attribute.value
    copy=True args: 'product.attribute.value', 'attribute_id', 'Values'
Public methods (0)

No public methods.

New fields (3)
  • attribute_id Many2one → product.attribute
    ondelete='restrict' required=True args: 'product.attribute', 'Attribute'
  • product_tmpl_id Many2one → product.template
    ondelete='cascade' required=True args: 'product.template', 'Product Template'
  • value_ids Many2many → product.attribute.value
    string='Attribute Values' args: 'product.attribute.value'
Public methods (1)
  • name_search(self, name='', args=None, operator='ilike', limit=100)
    @api.model

New fields (3)
  • price_extra Float
    digits=dp.get_precision('Product Price') args: 'Price Extra'
  • product_tmpl_id Many2one → product.template
    ondelete='cascade' required=True args: 'product.template', 'Product Template'
  • value_id Many2one → product.attribute.value
    ondelete='cascade' required=True args: 'product.attribute.value', 'Product Attribute Value'
Public methods (0)

No public methods.

New fields (6)
  • attribute_id Many2one → product.attribute
    ondelete='cascade' required=True args: 'product.attribute', 'Attribute'
  • name Char
    required=True translate=True args: 'Value'
  • price_extra Float
    compute='_compute_price_extra' default=0.0 digits=dp.get_precision('Product Price') help='Price Extra: Extra price for the variant with this attribute value on sale price. eg. 200 price extra, 1000 + 200 = 1200.' inverse='_set_price_extra' args: 'Attribute Price Extra'
  • price_ids One2many → product.attribute.price
    readonly=True args: 'product.attribute.price', 'value_id', 'Attribute Prices'
  • product_ids Many2many → product.product
    readonly=True string='Variants' args: 'product.product'
  • sequence Integer
    help='Determine the display order' args: 'Sequence'
Public methods (2)
  • name_get(self)
    @api.multi
  • unlink(self)
    @api.multi

New fields (7)
  • child_id One2many → product.category
    args: 'product.category', 'parent_id', 'Child Categories'
  • name Char
    index=True required=True translate=True args: 'Name'
  • parent_id Many2one → product.category
    index=True ondelete='cascade' args: 'product.category', 'Parent Category'
  • parent_left Integer
    index=1 args: 'Left Parent'
  • parent_right Integer
    index=1 args: 'Right Parent'
  • product_count Integer
    compute='_compute_product_count' help='The number of products under this category (Does not consider the children categories)' args: '# Products'
  • type Selection
    default='normal' help='A category of the view type is a virtual category that can be used as the parent of another category to create a hierarchical structure.' args: [('view', 'View'), ('normal', 'Normal')], 'Category Type'
Public methods (2)
  • name_get(self)
    @api.multi
  • name_search(self, name, args=None, operator='ilike', limit=100)
    @api.model

New fields (4)
  • name Char
    required=True args: 'Packaging Type'
  • product_tmpl_id Many2one → product.template
    string='Product' args: 'product.template'
  • qty Float
    help='The total number of products you can have per pallet or box.' args: 'Quantity per Package'
  • sequence Integer
    default=1 help='The first in the sequence is the default one.' args: 'Sequence'
Public methods (0)

No public methods.

New fields (4)
  • company_id Many2one → res.company
    default=_get_default_company_id required=True string='Company' args: 'res.company'
  • cost Float
    digits=dp.get_precision('Product Price') args: 'Cost'
  • datetime Datetime
    default=fields.Datetime.now args: 'Date'
  • product_id Many2one → product.product
    ondelete='cascade' required=True args: 'product.product', 'Product'
Public methods (0)

No public methods.

New fields (6)
  • price_list Many2one → product.pricelist
    required=True args: 'product.pricelist', 'PriceList'
  • qty1 Integer
    default=1 args: 'Quantity-1'
  • qty2 Integer
    default=5 args: 'Quantity-2'
  • qty3 Integer
    default=10 args: 'Quantity-3'
  • qty4 Integer
    default=0 args: 'Quantity-4'
  • qty5 Integer
    default=0 args: 'Quantity-5'
Public methods (1)
  • print_report(self)
    @api.multi
    To get the date and print the report @return : return report

New fields (7)
  • active Boolean
    default=True help='If unchecked, it will allow you to hide the pricelist without removing it.' args: 'Active'
  • company_id Many2one → res.company
    args: 'res.company', 'Company'
  • country_group_ids Many2many → res.country.group
    string='Country Groups' args: 'res.country.group', 'res_country_group_pricelist_rel', 'pricelist_id', 'res_country_group_id'
  • currency_id Many2one → res.currency
    default=_get_default_currency_id required=True args: 'res.currency', 'Currency'
  • item_ids One2many → product.pricelist.item
    copy=True default=_get_default_item_ids args: 'product.pricelist.item', 'pricelist_id', 'Pricelist Items'
  • name Char
    required=True translate=True args: 'Pricelist Name'
  • sequence Integer
    default=16
Public methods (8)
  • get_product_price(self, product, quantity, partner, date=False, uom_id=False)
    For a given pricelist, return price for a given product
  • get_product_price_rule(self, product, quantity, partner, date=False, uom_id=False)
    For a given pricelist, return price and rule for a given product
  • get_products_price(self, products, quantities, partners, date=False, uom_id=False)
    For a given pricelist, return price for products Returns: dict{product_id: product price}, in the given pricelist
  • name_get(self)
    @api.multi
  • name_search(self, name, args=None, operator='ilike', limit=100)
    @api.model
  • price_get(self, prod_id, qty, partner=None)
    @api.multi
    Multi pricelist, mono product - returns price per pricelist
  • price_rule_get(self, prod_id, qty, partner=None)
    @api.multi
    Multi pricelist, mono product - return tuple
  • price_rule_get_multi(self, products_by_qty_by_partner)
    @api.multi
    Multi pricelist, multi product - return tuple

New fields (23)
  • applied_on Selection
    default='3_global' help='Pricelist Item applicable on selected option' required=True args: [('3_global', 'Global'), ('2_product_category', ' Product Category'), ('1_product', 'Product'), ('0_product_variant', 'Product Variant')], 'Apply On'
  • base Selection
    default='list_price' help='Base price for computation.\nPublic Price: The base price will be the Sale/public Price.\nCost Price : The base price will be the cost price.\nOther Pricelist : Computation of the base price based on another Pricelist.' required=True args: [('list_price', 'Public Price'), ('standard_price', 'Cost'), ('pricelist', 'Other Pricelist')], 'Based on'
  • base_pricelist_id Many2one → product.pricelist
    args: 'product.pricelist', 'Other Pricelist'
  • categ_id Many2one → product.category
    help='Specify a product category if this rule only applies to products belonging to this category or its children categories. Keep empty otherwise.' ondelete='cascade' args: 'product.category', 'Product Category'
  • company_id Many2one → res.company
    readonly=True related='pricelist_id.company_id' store=True args: 'res.company', 'Company'
  • compute_price Selection
    default='fixed' index=True args: [('fixed', 'Fix Price'), ('percentage', 'Percentage (discount)'), ('formula', 'Formula')]
  • currency_id Many2one → res.currency
    readonly=True related='pricelist_id.currency_id' store=True args: 'res.currency', 'Currency'
  • date_end Date
    help='Ending valid for the pricelist item validation' args: 'End Date'
  • date_start Date
    help='Starting date for the pricelist item validation' args: 'Start Date'
  • fixed_price Float
    digits=dp.get_precision('Product Price') args: 'Fixed Price'
  • min_quantity Integer
    default=0 help='For the rule to apply, bought/sold quantity must be greater than or equal to the minimum quantity specified in this field.\nExpressed in the default unit of measure of the product.' args: 'Min. Quantity'
  • name Char
    compute='_get_pricelist_item_name_price' help='Explicit rule name for this pricelist line.' args: 'Name'
  • percent_price Float
    args: 'Percentage Price'
  • price Char
    compute='_get_pricelist_item_name_price' help='Explicit rule name for this pricelist line.' args: 'Price'
  • price_discount Float
    default=0 digits=(16, 2) args: 'Price Discount'
  • price_max_margin Float
    digits=dp.get_precision('Product Price') help='Specify the maximum amount of margin over the base price.' args: 'Max. Price Margin'
  • price_min_margin Float
    digits=dp.get_precision('Product Price') help='Specify the minimum amount of margin over the base price.' args: 'Min. Price Margin'
  • price_round Float
    digits=dp.get_precision('Product Price') help='Sets the price so that it is a multiple of this value.\nRounding is applied after the discount and before the surcharge.\nTo have prices that end in 9.99, set rounding 10, surcharge -0.01' args: 'Price Rounding'
  • price_surcharge Float
    digits=dp.get_precision('Product Price') help='Specify the fixed amount to add or substract(if negative) to the amount calculated with the discount.' args: 'Price Surcharge'
  • pricelist_id Many2one → product.pricelist
    index=True ondelete='cascade' args: 'product.pricelist', 'Pricelist'
  • product_id Many2one → product.product
    help='Specify a product if this rule only applies to one product. Keep empty otherwise.' ondelete='cascade' args: 'product.product', 'Product'
  • product_tmpl_id Many2one → product.template
    help='Specify a template if this rule only applies to one product template. Keep empty otherwise.' ondelete='cascade' args: 'product.template', 'Product Template'
  • sequence Integer
    default=5 help='Gives the order in which the pricelist items will be checked. The evaluation gives highest priority to lowest sequence and stops as soon as a matching item is found.' required=True args: 'Sequence'
Public methods (0)

No public methods.

New fields (18)
  • active Boolean
    default=True help='If unchecked, it will allow you to hide the product without removing it.' args: 'Active'
  • attribute_value_ids Many2many → product.attribute.value
    ondelete='restrict' string='Attributes' args: 'product.attribute.value'
  • barcode Char
    copy=False help='International Article Number used for product identification.' oldname='ean13' args: 'Barcode'
  • code Char
    compute='_compute_product_code' args: 'Internal Reference'
  • default_code Char
    index=True args: 'Internal Reference'
  • image Binary
    compute='_compute_images' help='Image of the product variant (Big-sized image of product template if false). It is automatically resized as a 1024x1024px image, with aspect ratio preserved.' inverse='_set_image' args: 'Big-sized image'
  • image_medium Binary
    compute='_compute_images' help='Image of the product variant (Medium-sized image of product template if false).' inverse='_set_image_medium' args: 'Medium-sized image'
  • image_small Binary
    compute='_compute_images' help='Image of the product variant (Small-sized image of product template if false).' inverse='_set_image_small' args: 'Small-sized image'
  • image_variant Binary
    attachment=True help='This field holds the image used as image for the product variant, limited to 1024x1024px.' args: 'Variant Image'
  • lst_price Float
    compute='_compute_product_lst_price' digits=dp.get_precision('Product Price') help="The sale price is managed from the product template. Click on the 'Variant Prices' button to set the extra attribute prices." inverse='_set_product_lst_price' args: 'Sale Price'
  • partner_ref Char
    compute='_compute_partner_ref' args: 'Customer Ref'
  • price Float
    compute='_compute_product_price' digits=dp.get_precision('Product Price') inverse='_set_product_price' args: 'Price'
  • price_extra Float
    compute='_compute_product_price_extra' digits=dp.get_precision('Product Price') help='This is the sum of the extra price of all attributes' args: 'Variant Price Extra'
  • pricelist_item_ids Many2many → product.pricelist.item
    compute='_get_pricelist_items' args: 'product.pricelist.item', 'Pricelist Items'
  • product_tmpl_id Many2one → product.template
    auto_join=True index=True ondelete='cascade' required=True args: 'product.template', 'Product Template'
  • standard_price Float
    company_dependent=True digits=dp.get_precision('Product Price') groups='base.group_user' help='Cost of the product template used for standard stock valuation in accounting and used as a base price on purchase orders. Expressed in the default unit of measure of the product.' args: 'Cost'
  • volume Float
    help='The volume in m3.' args: 'Volume'
  • weight Float
    digits=dp.get_precision('Stock Weight') help='The weight of the contents in Kg, not including any packaging, etc.' args: 'Weight'
Public methods (12)
  • copy(self, default=None)
    @api.multi
  • create(self, vals)
    @api.model
  • get_history_price(self, company_id, date=None)
    @api.multi
  • name_get(self)
    @api.multi
  • name_search(self, name='', args=None, operator='ilike', limit=100)
    @api.model
  • open_product_template(self)
    @api.multi
    Utility method used to add an "Open Template" button in product views
  • price_compute(self, price_type, uom=False, currency=False, company=False)
    @api.multi
  • price_get(self, ptype='list_price')
    @api.multi
  • search(self, args, offset=0, limit=None, order=None, count=False)
    @api.model
  • unlink(self)
    @api.multi
  • view_header_get(self, view_id, view_type)
    @api.model
  • write(self, values)
    @api.multi
    Store the standard price change in order to be able to retrieve the cost of a product for a given date

New fields (14)
  • company_id Many2one → res.company
    default=<expr> index=1 args: 'res.company', 'Company'
  • currency_id Many2one → res.currency
    default=<expr> required=True args: 'res.currency', 'Currency'
  • date_end Date
    help='End date for this vendor price' args: 'End Date'
  • date_start Date
    help='Start date for this vendor price' args: 'Start Date'
  • delay Integer
    default=1 help='Lead time in days between the confirmation of the purchase order and the receipt of the products in your warehouse. Used by the scheduler for automatic computation of the purchase order planning.' required=True args: 'Delivery Lead Time'
  • min_qty Float
    default=0.0 help='The minimal quantity to purchase from this vendor, expressed in the vendor Product Unit of Measure if not any, in the default unit of measure of the product otherwise.' required=True args: 'Minimal Quantity'
  • name Many2one → res.partner
    domain=[('supplier', '=', True)] help='Vendor of this product' ondelete='cascade' required=True args: 'res.partner', 'Vendor'
  • price Float
    default=0.0 digits=dp.get_precision('Product Price') help='The price to purchase a product' required=True args: 'Price'
  • product_code Char
    help="This vendor's product code will be used when printing a request for quotation. Keep empty to use the internal one." args: 'Vendor Product Code'
  • product_id Many2one → product.product
    help='When this field is filled in, the vendor data will only apply to the variant.' args: 'product.product', 'Product Variant'
  • product_name Char
    help="This vendor's product name will be used when printing a request for quotation. Keep empty to use the internal one." args: 'Vendor Product Name'
  • product_tmpl_id Many2one → product.template
    index=True oldname='product_id' ondelete='cascade' args: 'product.template', 'Product Template'
  • product_uom Many2one → product.uom
    help='This comes from the product form.' readonly='1' related='product_tmpl_id.uom_po_id' args: 'product.uom', 'Vendor Unit of Measure'
  • sequence Integer
    default=1 help='Assigns the priority to the list of product vendor.' args: 'Sequence'
Public methods (0)

No public methods.

New fields (36)
  • active Boolean
    default=True help='If unchecked, it will allow you to hide the product without removing it.' args: 'Active'
  • attribute_line_ids One2many → product.attribute.line
    args: 'product.attribute.line', 'product_tmpl_id', 'Product Attributes'
  • barcode Char
    oldname='ean13' related='product_variant_ids.barcode' args: 'Barcode'
  • categ_id Many2one → product.category
    change_default=True default=_get_default_category_id domain="[('type','=','normal')]" help='Select category for the current product' required=True args: 'product.category', 'Internal Category'
  • color Integer
    args: 'Color Index'
  • company_id Many2one → res.company
    default=<expr> index=1 args: 'res.company', 'Company'
  • currency_id Many2one → res.currency
    compute='_compute_currency_id' args: 'res.currency', 'Currency'
  • default_code Char
    compute='_compute_default_code' inverse='_set_default_code' store=True args: 'Internal Reference'
  • description Text
    help='A precise description of the Product, used only for internal information purposes.' translate=True args: 'Description'
  • description_purchase Text
    help='A description of the Product that you want to communicate to your vendors. This description will be copied to every Purchase Order, Receipt and Vendor Bill/Refund.' translate=True args: 'Purchase Description'
  • description_sale Text
    help='A description of the Product that you want to communicate to your customers. This description will be copied to every Sale Order, Delivery Order and Customer Invoice/Refund' translate=True args: 'Sale Description'
  • image Binary
    attachment=True help='This field holds the image used as image for the product, limited to 1024x1024px.' args: 'Image'
  • image_medium Binary
    attachment=True help='Medium-sized image of the product. It is automatically resized as a 128x128px image, with aspect ratio preserved, only when the image exceeds one of those sizes. Use this field in form views or some kanban views.' args: 'Medium-sized image'
  • image_small Binary
    attachment=True help='Small-sized image of the product. It is automatically resized as a 64x64px image, with aspect ratio preserved. Use this field anywhere a small image is required.' args: 'Small-sized image'
  • item_ids One2many → product.pricelist.item
    args: 'product.pricelist.item', 'product_tmpl_id', 'Pricelist Items'
  • list_price Float
    default=1.0 digits=dp.get_precision('Product Price') help='Base price to compute the customer price. Sometimes called the catalog price.' args: 'Sale Price'
  • lst_price Float
    digits=dp.get_precision('Product Price') related='list_price' args: 'Public Price'
  • name Char
    index=True required=True translate=True args: 'Name'
  • packaging_ids One2many → product.packaging
    help='Gives the different ways to package the same product. This has no impact on the picking order and is mainly used if you use the EDI module.' args: 'product.packaging', 'product_tmpl_id', 'Logistical Units'
  • price Float
    compute='_compute_template_price' digits=dp.get_precision('Product Price') inverse='_set_template_price' args: 'Price'
  • pricelist_id Many2one → product.pricelist
    help='Technical field. Used for searching on pricelists, not stored in database.' store=False args: 'product.pricelist', 'Pricelist'
  • product_variant_count Integer
    compute='_compute_product_variant_count' args: '# Product Variants'
  • product_variant_id Many2one → product.product
    compute='_compute_product_variant_id' args: 'product.product', 'Product'
  • product_variant_ids One2many → product.product
    required=True args: 'product.product', 'product_tmpl_id', 'Products'
  • purchase_ok Boolean
    default=True args: 'Can be Purchased'
  • rental Boolean
    args: 'Can be Rent'
  • sale_ok Boolean
    default=True help='Specify if the product can be selected in a sales order line.' args: 'Can be Sold'
  • seller_ids One2many → product.supplierinfo
    args: 'product.supplierinfo', 'product_tmpl_id', 'Vendors'
  • sequence Integer
    default=1 help='Gives the sequence order when displaying a product list' args: 'Sequence'
  • standard_price Float
    compute='_compute_standard_price' digits=dp.get_precision('Product Price') groups='base.group_user' help='Cost of the product, in the default unit of measure of the product.' inverse='_set_standard_price' search='_search_standard_price' args: 'Cost'
  • type Selection
    default='consu' help='A stockable product is a product for which you manage stock. The "Inventory" app has to be installed.\nA consumable product, on the other hand, is a product for which stock is not managed.\nA service is a non-material product you provide.\nA digital content is a non-material product you sell online. The files attached to the products are the one that are sold on the e-commerce such as e-books, music, pictures,... The "Digital Product" module has to be installed.' required=True string='Product Type' args: [('consu', _('Consumable')), ('service', _('Service'))]
  • uom_id Many2one → product.uom
    default=_get_default_uom_id help='Default Unit of Measure used for all stock operation.' required=True args: 'product.uom', 'Unit of Measure'
  • uom_po_id Many2one → product.uom
    default=_get_default_uom_id help='Default Unit of Measure used for purchase orders. It must be in the same category than the default unit of measure.' required=True args: 'product.uom', 'Purchase Unit of Measure'
  • volume Float
    compute='_compute_volume' help='The volume in m3.' inverse='_set_volume' store=True args: 'Volume'
  • warranty Float
    args: 'Warranty'
  • weight Float
    compute='_compute_weight' digits=dp.get_precision('Stock Weight') help='The weight of the contents in Kg, not including any packaging, etc.' inverse='_set_weight' store=True args: 'Weight'
Public methods (7)
  • copy(self, default=None)
    @api.multi
  • create(self, vals)
    @api.model
    Store the initial standard price in order to be able to retrieve the cost of a product template for a given date
  • create_variant_ids(self)
    @api.multi
  • name_get(self)
    @api.multi
  • name_search(self, name='', args=None, operator='ilike', limit=100)
    @api.model
  • price_compute(self, price_type, uom=False, currency=False, company=False)
    @api.multi
  • write(self, vals)
    @api.multi

New fields (7)
  • active Boolean
    default=True help='Uncheck the active field to disable a unit of measure without deleting it.' args: 'Active'
  • category_id Many2one → product.uom.categ
    help='Conversion between Units of Measure can only occur if they belong to the same category. The conversion will be made based on the ratios.' ondelete='cascade' required=True args: 'product.uom.categ', 'Category'
  • factor Float
    default=1.0 digits=0 help='How much bigger or smaller this unit is compared to the reference Unit of Measure for this category: 1 * (reference unit) = ratio * (this unit)' required=True args: 'Ratio'
  • factor_inv Float
    compute='_compute_factor_inv' digits=0 help='How many times this Unit of Measure is bigger than the reference Unit of Measure in this category: 1 * (this unit) = ratio * (reference unit)' readonly=True required=True args: 'Bigger Ratio'
  • name Char
    required=True translate=True args: 'Unit of Measure'
  • rounding Float
    default=0.01 digits=0 help='The computed quantity will be a multiple of this value. Use 1.0 for a Unit of Measure that cannot be further split, such as a piece.' required=True args: 'Rounding Precision'
  • uom_type Selection
    default='reference' required=1 args: [('bigger', 'Bigger than the reference Unit of Measure'), ('reference', 'Reference Unit of Measure for this category'), ('smaller', 'Smaller than the reference Unit of Measure')], 'Type'
Public methods (3)
  • create(self, values)
    @api.model
  • name_create(self, name)
    @api.model
    The UoM category and factor are required, so we'll have to add temporary values for imported UoMs
  • write(self, values)
    @api.multi

New fields (1)
  • name Char
    required=True translate=True args: 'Name'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (1)
  • render_html(self, docids, data=None)
    @api.model

New fields (0)

No new fields.

Public methods (2)
  • create(self, vals)
    @api.model
  • write(self, values)
    @api.multi

New fields (1)
  • pricelist_ids Many2many → product.pricelist
    string='Pricelists' args: 'product.pricelist', 'res_country_group_pricelist_rel', 'res_country_group_id', 'pricelist_id'
Public methods (0)

No public methods.

New fields (1)
  • property_product_pricelist Many2one → product.pricelist
    company_dependent=False compute='_compute_product_pricelist' help='This pricelist will be used, instead of the default one, for sales to the current partner' inverse='_inverse_product_pricelist' args: 'product.pricelist', 'Sale Pricelist'
Public methods (0)

No public methods.

REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/9.0/product
VERSION
VERSION 1.2
CATEGORY
CATEGORYSales
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Christophe Matthieu, Martin Trigaux, Fabien Pinckaers, Antony Lesuisse, Olivier Dony, Thibault Delavallée, Josse Colpaert, Denis Ledoux, Christophe Simonis, Goffin Simon, Simon Lejeune, Frédéric van der Essen, Nicolas Martinelli, Nicolas Lempereur, Jérome Maes, Richard Mathot, qdp-odoo, Géry Debongnie, Aaron Bohy, Jeremy Kersten, Damien Bouvy, Yannick Tivisse, qsm-odoo, Martin Geubelle, Olivier Laurent
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-05 23:48:31
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - base
    - decimal_precision
    - mail
    - base_setup
    - web_kanban
    - web
    - bus
    - report
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
This is the base module for managing products and pricelists in OpenERP.
========================================================================

Products support variants, different pricing methods, vendors information,
make to stock/order, different unit of measures, packaging and properties.

Pricelists support:
-------------------
    * Multiple-level of discount (by product, category, quantities)
    * Compute price based on different criteria:
        * Other pricelist
        * Cost price
        * List price
        * Vendor price

Pricelists preferences by product and/or partners.

Print product labels with barcode.
    

Code Analysis

Views touched (33)
XML IDNameModelTypeStatus
attribute_tree_view product.attribute.tree product.attribute tree New
inherit_view_general_configuration General Settings base.config.settings xpath Inherits base_setup.view_general_configuration
product_attribute_value_view_tree product.attribute.value.view.tree product.attribute.value tree New
product_category_form_view product.category.form product.category form New
product_category_list_view product.category.list product.category tree New
product_category_search_view product.category.search product.category search New
product_kanban_view Product Kanban product.product kanban New
product_normal_form_view product.product.form product.product form Inherits product.product_template_form_view
product_packaging_form_view product.packaging.form.view product.packaging form New
product_packaging_tree_view product.packaging.tree.view product.packaging tree New
product_pricelist_item_form_view product.pricelist.item.form product.pricelist.item form New
product_pricelist_item_tree_view product.pricelist.item.tree product.pricelist.item tree New
product_pricelist_view product.pricelist.form product.pricelist form New
product_pricelist_view_search product.pricelist.search product.pricelist search New
product_pricelist_view_tree product.pricelist.tree product.pricelist tree New
product_product_tree_view product.product.tree product.product tree New
product_search_form_view product.product.search product.product field Inherits product.product_template_search_view
product_supplierinfo_form_view product.supplierinfo.form.view product.supplierinfo form New
product_supplierinfo_tree_view product.supplierinfo.tree.view product.supplierinfo tree New
product_template_form_view product.template.common.form product.template form New
product_template_kanban_view Product.template.product.kanban product.template kanban New
product_template_only_form_view product.template.product.form product.template xpath Inherits product.product_template_form_view
product_template_search_view product.template.search product.template search New
product_template_tree_view product.template.product.tree product.template tree New
product_uom_categ_form_view product.uom.categ.form product.uom.categ form New
product_uom_form_view product.uom.form product.uom form New
product_uom_tree_view product.uom.tree product.uom tree New
product_variant_easy_edit_view product.product.view.form.easy product.product form New
report_pricelist report_pricelist ir.ui.view qweb New
report_productlabel report_productlabel ir.ui.view qweb New
variants_tree_view product.attribute.value.tree product.attribute.value tree New
view_partner_property_form res.partner.product.property.form.inherit res.partner group Inherits base.view_partner_form
view_product_price_list Price per unit product.price_list form New
Models touched (3)

New fields (0)

No new fields.

Public methods (2)
  • get_default_company_share_product(self, cr, uid, fields, context=None)
  • set_auth_company_share_product(self, cr, uid, ids, context=None)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/8.0/product
VERSION
VERSION 1.1
CATEGORY
CATEGORYSales Management
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOpenERP SA
MAINTAINERS
MAINTAINERSOpenERP SA
COMMITTERS
COMMITTERSRaphael Collet, Stephane Wirtel, Odoo Translation Bot, Numerigraphe - Lionel Sausin, Christophe Matthieu, DBR (OpenERP), Martin Trigaux, Ajay Chauhan (OpenERP), Foram Katharotiya (OpenERP), Fabien Pinckaers, Antony Lesuisse, Olivier Dony, Thibault Delavallée, Vo Minh Thu, Josse Colpaert, Launchpad Translations on behalf of openerp, Quentin (OpenERP), Denis Ledoux, Fabien Meghazi, niv-openerp, Christophe Simonis, David Monjoie, Xavier Morel, Frederic van der Essen, Goffin Simon, Cedric Snauwaert, Simon Lejeune, Frédéric van der Essen, Vishmita, Nicolas Martinelli, Guewen Baconnier, Amit Bhavsar (Open ERP), Paramjit Singh Sahota, Nicolas Lempereur, xmo-odoo, Richard Mathot, qdp-odoo, Atul Patel, jke-openerp, Aaron Bohy, Vishmita Jadeja (openerp), Richard Mathot (OpenERP), Jeremy Kersten, Darshan Kalola (OpenERP), Darshan Kalola, Rakesh Sindhav (OpenERP), sve-odoo
WEBSITE
WEBSITEhttps://www.odoo.com
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-05 23:45:40
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - base
    - decimal_precision
    - mail
    - base_setup
    - web_kanban
    - web
    - report
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
This is the base module for managing products and pricelists in OpenERP.
========================================================================

Products support variants, different pricing methods, suppliers information,
make to stock/order, different unit of measures, packaging and properties.

Pricelists support:
-------------------
    * Multiple-level of discount (by product, category, quantities)
    * Compute price based on different criteria:
        * Other pricelist
        * Cost price
        * List price
        * Supplier price

Pricelists preferences by product and/or partners.

Print product labels with barcode.
    

Code Analysis

Views touched (38)
XML IDNameModelTypeStatus
attribute_tree_view product.attribute.tree product.attribute tree New
product_category_form_view product.category.form product.category form New
product_category_list_view product.category.list product.category tree New
product_category_search_view product.category.search product.category search New
product_category_tree_view product.category.tree product.category tree New
product_kanban_view Product Kanban product.product kanban New
product_normal_form_view product.product.form product.product form Inherits product.product_template_form_view
product_packaging_form_view product.packaging.form.view product.packaging form New
product_packaging_form_view_without_product product.packaging.form.view.without.product product.packaging form New
product_packaging_tree_view product.packaging.tree.view product.packaging tree New
product_packaging_tree_view_product product.packaging.tree.view.product product.packaging tree New
product_price_type_view product.price.type.form product.price.type form New
product_pricelist_item_form_view product.pricelist.item.form product.pricelist.item form New
product_pricelist_item_tree_view product.pricelist.item.tree product.pricelist.item tree New
product_pricelist_version_form_view product.pricelist.version.form product.pricelist.version form New
product_pricelist_version_tree_view product.pricelist.version.tree product.pricelist.version tree New
product_pricelist_view product.pricelist.form product.pricelist form New
product_pricelist_view_search product.pricelist.search product.pricelist search New
product_pricelist_view_tree product.pricelist.tree product.pricelist tree New
product_product_tree_view product.product.tree product.product tree New
product_search_form_view product.product.search product.product field Inherits product.product_template_search_view
product_supplierinfo_form_view product.supplierinfo.form.view product.supplierinfo form New
product_supplierinfo_tree_view product.supplierinfo.tree.view product.supplierinfo tree New
product_template_form_view product.template.common.form product.template form New
product_template_kanban_view Product.template.product.kanban product.template kanban New
product_template_only_form_view product.template.product.form product.template xpath Inherits product.product_template_form_view
product_template_search_view product.template.search product.template search New
product_template_tree_view product.template.product.tree product.template tree New
product_ul_form_view product.ul.form.view product.ul form New
product_ul_tree product.ul.tree product.ul tree New
product_uom_categ_form_view product.uom.categ.form product.uom.categ form New
product_uom_form_view product.uom.form product.uom form New
product_uom_tree_view product.uom.tree product.uom tree New
report_pricelist report_pricelist ir.ui.view qweb New
variants_template_tree_view variants.template.tree product.attribute.value tree New
variants_tree_view product.attribute.value.tree product.attribute.value tree New
view_partner_property_form res.partner.product.property.form.inherit res.partner page Inherits base.view_partner_form
view_product_price_list Price per unit product.price_list form New
Models touched (1)

New fields (0)

No new fields.

Public methods (0)

No public methods.

REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/7.0/product
VERSION
VERSION 1.1
CATEGORY
CATEGORYSales Management
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOpenERP SA
MAINTAINERS
MAINTAINERSOpenERP SA
COMMITTERS
COMMITTERSRaphael Collet, Jagdish Panchal (Open ERP), Twinkle Christian (OpenERP), Cecile Tonglet, Rucha (Open ERP), Atul Patel (OpenERP), Randhir Mayatra (OpenERP), Stephane Wirtel, Odoo Translation Bot, Turkesh Patel (Open ERP), Numerigraphe - Lionel Sausin, Christophe Matthieu, Pinakin Nayi (OpenERP), Benoit Guillot, DBR (OpenERP), Harry (OpenERP), Antonin Bourguignon, pankita shah (Open ERP), ajay javiya (OpenERP), Martin Trigaux, Ajay Chauhan (OpenERP), Foram Katharotiya (OpenERP), Purnendu Singh (OpenERP), Saurang Suthar (OpenERP), Fabien Pinckaers, Antony Lesuisse, Bharat Devnani (OpenERP), Meera Trambadia (OpenERP), Saurang Suthar, Olivier Dony, Rajesh Prajapati (OpenERP), Twinkle (OpenERP), Divyesh Makwana (Open ERP), Tejas Tank, Thibault Delavallée, Vo Minh Thu, Hardik, Josse Colpaert, Arnaud Pineux, pso (OpenERP), Sbh (Openerp), Amit Patel (OpenERP), Launchpad Translations on behalf of openerp, vta vta@openerp.com, Quentin (OpenERP), Kuldeep Joshi (OpenERP), Denis Ledoux, Mayur Maheshwari (OpenERP), Jigar Amin - OpenERP, Sanjay Gohel (Open ERP), Alexis de Lattre, help, Fabien Meghazi, niv-openerp, ggh-openerp, Xavier ALT, Ujjvala Collins (OpenERP), David Monjoie, Ravi Gohil (OpenERP), Dharti Ratani (OpenERP), Khushboo Bhatt (Open ERP), Bhumi Thakkar (Open ERP), Roberto López López (OpenERP), Cedric Snauwaert, Amit Patel, Frédéric van der Essen, Chris Biersbach, Vijaykumar Baladaniya, Jigar Amin, Yannick Vaucher, Amit (OpenERP), Amit Bhavsar (Open ERP), kirti savalia (OpenERP), sebastien beau
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-05 23:43:10
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - base
    - process
    - web
    - decimal_precision
    - mail
    - base_setup
    - web_kanban
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
This is the base module for managing products and pricelists in OpenERP.
========================================================================

Products support variants, different pricing methods, suppliers information,
make to stock/order, different unit of measures, packaging and properties.

Pricelists support:
-------------------
    * Multiple-level of discount (by product, category, quantities)
    * Compute price based on different criteria:
        * Other pricelist
        * Cost price
        * List price
        * Supplier price

Pricelists preferences by product and/or partners.

Print product labels with barcode.
    

Code Analysis

Views touched (31)
XML IDNameModelTypeStatus
product.product_kanban_view Product Kanban product.product kanban New
product_category_form_view product.category.form product.category form New
product_category_list_view product.category.list product.category tree New
product_category_search_view product.category.search product.category search New
product_category_tree_view product.category.tree product.category tree New
product_normal_form_view product.normal.form product.product form New
product_packaging_form_view product.packaging.form.view product.packaging form New
product_packaging_tree_view product.packaging.tree.view product.packaging tree New
product_price_type_view product.price.type.form product.price.type form New
product_pricelist_item_form_view product.pricelist.item.form product.pricelist.item form New
product_pricelist_item_tree_view product.pricelist.item.tree product.pricelist.item tree New
product_pricelist_version_form_view product.pricelist.version.form product.pricelist.version form New
product_pricelist_version_tree_view product.pricelist.version.tree product.pricelist.version tree New
product_pricelist_view product.pricelist.form product.pricelist form New
product_pricelist_view_search product.pricelist.search product.pricelist search New
product_pricelist_view_tree product.pricelist.tree product.pricelist tree New
product_product_tree_view product.product.tree product.product tree New
product_search_form_view product.search.form product.product search New
product_supplierinfo_form_view product.supplierinfo.form.view product.supplierinfo form New
product_supplierinfo_tree_view product.supplierinfo.tree.view product.supplierinfo tree New
product_template_form_view product.template.product.form product.template form New
product_template_tree_view product.template.product.tree product.template tree New
product_ul_form_view product.ul.form.view product.ul form New
product_ul_tree product.ul.tree product.ul tree New
product_uom_categ_form_view product.uom.categ.form product.uom.categ form New
product_uom_form_view product.uom.form product.uom form New
product_uom_tree_view product.uom.tree product.uom tree New
product_variant_form_view product.variant.form product.product form New
product_variant_tree_view product.variant.tree product.product tree New
view_partner_property_form res.partner.product.property.form.inherit res.partner page Inherits base.view_partner_form
view_product_price_list Price per unit product.price_list form New
Models touched (0)

No models found for this module.

REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/6.1/product
VERSION
VERSION 1.1
CATEGORY
CATEGORYSales Management
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOpenERP SA
MAINTAINERS
MAINTAINERSOpenERP SA
COMMITTERS
COMMITTERSRaphael Collet, Rucha (Open ERP), Stephane Wirtel, Numerigraphe - Lionel Sausin, Benoit Guillot, DBR (OpenERP), Harry (OpenERP), Martin Trigaux, Fabien Pinckaers, Antony Lesuisse, Olivier Dony, Vo Minh Thu, Launchpad Translations on behalf of openerp, Quentin (OpenERP), Mayur Maheshwari (OpenERP), vro, Fabien Meghazi, niv-openerp, Xavier ALT, Ujjvala Collins (OpenERP), Xavier Morel, Chris Biersbach, Amit (OpenERP), Amit Dodiya, Amit Bhavsar (Open ERP), Quentin THEURET, Carlos Vásquez, ksa (Open ERP), Els Van Vossel, Israel Fermin Montilla, Rifakat Haradwala (Open ERP), mayur maheshwari (Open ERP), Hardik Ansodariy (OpenERP), ARA (OpenERP), aag (OpenERP), ron@tinyerp.com, fp, Tejas (OpenERP), Kirti Savalia (OpenERP), Atik Agewan (OpenERP), philubert@gmail.com, rpa (Open ERP), rha@tinyerp.com
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-05 23:41:35
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - base
    - process
    - decimal_precision
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
This is the base module for managing products and pricelists in OpenERP.
========================================================================

Products support variants, different pricing methods, suppliers
information, make to stock/order, different unit of measures,
packaging and properties.

Pricelists support:
    * Multiple-level of discount (by product, category, quantities)
    * Compute price based on different criteria:
        * Other pricelist,
        * Cost price,
        * List price,
        * Supplier price, ...

Pricelists preferences by product and/or partners.

Print product labels with barcode.
    

Code Analysis

Views touched (31)
XML IDNameModelTypeStatus
product_category_form_view product.category.form product.category form New
product_category_list_view product.category.list product.category tree New
product_category_search_view product.category.search product.category search New
product_category_tree_view product.category.tree product.category tree New
product_kanban_view Product Kanban product.product kanban New
product_normal_form_view product.normal.form product.product form New
product_packaging_form_view product.packaging.form.view product.packaging form New
product_packaging_tree_view product.packaging.tree.view product.packaging tree New
product_price_type_view product.price.type.form product.price.type form New
product_pricelist_item_form_view product.pricelist.item.form product.pricelist.item form New
product_pricelist_item_tree_view product.pricelist.item.tree product.pricelist.item tree New
product_pricelist_version_form_view product.pricelist.version.form product.pricelist.version form New
product_pricelist_version_tree_view product.pricelist.version.tree product.pricelist.version tree New
product_pricelist_view product.pricelist.form product.pricelist form New
product_pricelist_view_search product.pricelist.search product.pricelist search New
product_pricelist_view_tree product.pricelist.tree product.pricelist tree New
product_product_tree_view product.product.tree product.product tree New
product_search_form_view product.search.form product.product search New
product_supplierinfo_form_view product.supplierinfo.form.view product.supplierinfo form New
product_supplierinfo_tree_view product.supplierinfo.tree.view product.supplierinfo tree New
product_template_form_view product.template.product.form product.template form New
product_template_tree_view product.template.product.tree product.template tree New
product_ul_form_view product.ul.form.view product.ul form New
product_ul_tree product.ul.tree product.ul tree New
product_uom_categ_form_view product.uom.categ.form product.uom.categ form New
product_uom_form_view product.uom.form product.uom form New
product_uom_tree_view product.uom.tree product.uom tree New
product_variant_form_view product.variant.form product.product form New
product_variant_tree_view product.variant.tree product.product tree New
view_partner_property_form res.partner.product.property.form.inherit res.partner page Inherits base.view_partner_form
view_product_price_list Price per unit product.price_list form New
Models touched (0)

No models found for this module.