Product Abc Classification

product_abc_classification
REPOSITORY
REPOSITORYOCA/product-attribute
GIT
GIThttps://github.com/OCA/product-attribute.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/product-attribute/tree/18.0/product_abc_classification
VERSION
VERSION 2.0.0
CATEGORY
CATEGORYUncategorized
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), ForgeFlow, ACSONE SA/NV
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), ForgeFlow, ACSONE SA/NV
COMMITTERS
COMMITTERSJordiMForgeFlow, Weblate, OCA-git-bot, oca-ci, Hoang Diep
WEBSITE
WEBSITEhttps://github.com/OCA/product-attribute
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 19:30:12
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - product
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - html_editor
    - uom
    - stock
    - barcodes_gs1_nomenclature
    - barcodes
    - digest
    - portal
    - web_editor
    - http_routing
    - auth_signup
    - resource
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
This modules provides the bases to build ABC analysis (or ABC
classification) addons. These classification are used by inventory
management teams to help identify the most important products in their
portfolio and ensure they prioritize managing them above those less
valuable.

Managers will create a profile with several levels (percentages) and
then the profiled products will automatically get a corresponding level
using the ABC classification.

The addon *product_abc_classification_sale_stock* defines a computation
profile based on the number of sale order line delivered by product.

Code Analysis

Views touched (8)
XML IDNameModelTypeStatus
abc_classification_product_level_form_view abc.classification.product.level.form (in product_abc_classification) abc.classification.product.level form New
abc_classification_product_level_search_view abc.classification.product.level.search (in product_abc_classification) abc.classification.product.level search New
abc_classification_product_level_tree_view abc.classification.product.level.tree (in product_abc_classification) abc.classification.product.level list New
abc_classification_profile_form_view abc.classification.profile.form (in product_abc_classification) abc.classification.profile form New
abc_classification_profile_tree_view abc.classification.profile.tree (in product_abc_classification) abc.classification.profile list New
product_product_form_view product.product.form (ABC Classification) product.product field Inherits product.product_normal_form_view
product_template_form_view product.template.form (ABC Classification) product.template xpath Inherits product.product_template_form_view
view_product_category_form product.category.form - product_abc_classification product.category xpath Inherits product.product_category_form_view
Models touched (6)

New fields (4)
  • name Char
    help='Classification A, B or C' required=True
  • percentage Float
    default=0.0 required=True string='% Indicator'
  • percentage_products Float
    default=0.0 required=True string='% Products'
  • profile_id Many2one → abc.classification.profile
    ondelete='cascade' args: 'abc.classification.profile'
Public methods (0)

No public methods.

New fields (9)
  • allowed_profile_ids Many2many → abc.classification.profile
    comodel_name='abc.classification.profile' related='product_id.abc_classification_profile_ids'
  • computed_level_id Many2one → abc.classification.level
    readonly=True string='Computed classification level' args: 'abc.classification.level'
  • flag Boolean
    compute='_compute_flag' default=False index=True store=True string='If True, this means that the manual classification is different from the computed one'
  • level_id Many2one → abc.classification.level
    compute='_compute_level_id' domain="[('profile_id', '=', profile_id)]" store=True string='Classification level' args: 'abc.classification.level'
  • manual_level_id Many2one → abc.classification.level
    domain="[('profile_id', '=', profile_id)]" string='Manual classification level' tracking=True args: 'abc.classification.level'
  • product_id Many2one → product.product
    index=True ondelete='cascade' required=True string='Product' args: 'product.product'
  • product_tmpl_id Many2one → product.template
    index=True readonly=True string='Product template' args: 'product.template'
  • profile_id Many2one → abc.classification.profile
    required=True string='Profile' args: 'abc.classification.profile'
  • profile_type Selection
    readonly=True related='profile_id.profile_type' store=True
Public methods (2)
  • create(self, vals_list)
    @api.model_create_multi
  • write(self, vals)
    We apply the manual level to the product level if computed level is modified and only for profiles with auto_apply_computed_value = =True

New fields (7)
  • auto_apply_computed_value Boolean
    default=False help='Check this if you want to apply the computed level on each product that has this profile.'
  • level_ids One2many → abc.classification.level
    comodel_name='abc.classification.level' inverse_name='profile_id'
  • name Char
    required=True
  • period Integer
    default=365 required=True string='Period on which to compute the classification (Days)'
  • product_count Integer
    compute='_compute_product_count' readonly=True
  • product_variant_ids Many2many → product.product
    column1='profile_id' column2='product_id' comodel_name='product.product' index=True relation='abc_classification_profile_product_rel'
  • profile_type Selection
    index=True required=True selection=[('manual', 'Manual')] string='Type of ABC classification'
Public methods (3)
  • action_view_products(self)
  • copy_data(self, default=None)
  • write(self, vals)

New fields (1)
  • abc_classification_profile_ids Many2many → abc.classification.profile
    column1='categ_id' column2='profile_id' comodel_name='abc.classification.profile' index=True relation='abc_classification_profile_product_categ_rel'
Public methods (1)
  • update_product_abc_classification_profile(self)

New fields (3)
  • abc_classification_product_level_ids One2many → abc.classification.product.level
    index=True inverse_name='product_id' args: 'abc.classification.product.level'
  • abc_classification_profile_ids Many2many → abc.classification.profile
    column1='product_id' column2='profile_id' comodel_name='abc.classification.profile' index=True relation='abc_classification_profile_product_rel'
  • abc_classification_profile_updatable_from_category Boolean
    default=True
Public methods (2)
  • create(self, vals_list)
    @api.model_create_multi
  • write(self, vals)

New fields (2)
  • abc_classification_product_level_ids One2many → abc.classification.product.level
    compute='_compute_abc_classification_product_level_ids' inverse='_inverse_abc_classification_product_level_ids' inverse_name='product_tmpl_id' store=True args: 'abc.classification.product.level'
  • abc_classification_profile_ids Many2many → abc.classification.profile
    compute='_compute_abc_classification_profile_ids' inverse='_inverse_abc_classification_profile_ids' store=True args: 'abc.classification.profile'
Public methods (0)

No public methods.

REPOSITORY
REPOSITORYOCA/product-attribute
GIT
GIThttps://github.com/OCA/product-attribute.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/product-attribute/tree/16.0/product_abc_classification
VERSION
VERSION 2.0.0
CATEGORY
CATEGORYUncategorized
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), ForgeFlow, ACSONE SA/NV
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), ForgeFlow, ACSONE SA/NV
COMMITTERS
COMMITTERSDenis Roussel, JordiMForgeFlow, Weblate, OCA-git-bot, Simone Orsi, oca-ci
WEBSITE
WEBSITEhttps://github.com/OCA/product-attribute
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:53:48
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - product
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - uom
    - stock
    - barcodes_gs1_nomenclature
    - barcodes
    - digest
    - portal
    - web_editor
    - http_routing
    - auth_signup
    - resource
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (8)
XML IDNameModelTypeStatus
abc_classification_product_level_form_view abc.classification.product.level.form (in product_abc_classification) abc.classification.product.level form New
abc_classification_product_level_search_view abc.classification.product.level.search (in product_abc_classification) abc.classification.product.level search New
abc_classification_product_level_tree_view abc.classification.product.level.tree (in product_abc_classification) abc.classification.product.level tree New
abc_classification_profile_form_view abc.classification.profile.form (in product_abc_classification) abc.classification.profile form New
abc_classification_profile_tree_view abc.classification.profile.tree (in product_abc_classification) abc.classification.profile tree New
product_product_form_view product.product.form (ABC Classification) product.product field Inherits product.product_normal_form_view
product_template_form_view product.template.form (ABC Classification) product.template xpath Inherits product.product_template_form_view
view_product_category_form product.category.form - product_abc_classification product.category xpath Inherits product.product_category_form_view
Models touched (6)

New fields (4)
  • name Char
    help='Classification A, B or C' required=True
  • percentage Float
    default=0.0 required=True string='% Indicator'
  • percentage_products Float
    default=0.0 required=True string='% Products'
  • profile_id Many2one → abc.classification.profile
    ondelete='cascade' args: 'abc.classification.profile'
Public methods (0)

No public methods.

New fields (10)
  • allowed_profile_ids Many2many → abc.classification.profile
    comodel_name='abc.classification.profile' related='product_id.abc_classification_profile_ids'
  • computed_level_id Many2one → abc.classification.level
    readonly=True string='Computed classification level' args: 'abc.classification.level'
  • display_name Char
    compute='_compute_display_name'
  • flag Boolean
    compute='_compute_flag' default=False index=True store=True string='If True, this means that the manual classification is different from the computed one'
  • level_id Many2one → abc.classification.level
    compute='_compute_level_id' domain="[('profile_id', '=', profile_id)]" store=True string='Classification level' args: 'abc.classification.level'
  • manual_level_id Many2one → abc.classification.level
    domain="[('profile_id', '=', profile_id)]" string='Manual classification level' tracking=True args: 'abc.classification.level'
  • product_id Many2one → product.product
    index=True ondelete='cascade' required=True string='Product' args: 'product.product'
  • product_tmpl_id Many2one → product.template
    index=True readonly=True string='Product template' args: 'product.template'
  • profile_id Many2one → abc.classification.profile
    required=True string='Profile' args: 'abc.classification.profile'
  • profile_type Selection
    readonly=True related='profile_id.profile_type' store=True
Public methods (2)
  • create(self, vals_list)
    @api.model_create_multi
  • write(self, vals)
    We apply the manual level to the product level if computed level is modified and only for profiles with auto_apply_computed_value = =True

New fields (7)
  • auto_apply_computed_value Boolean
    default=False help='Check this if you want to apply the computed level on each product that has this profile.'
  • level_ids One2many → abc.classification.level
    comodel_name='abc.classification.level' inverse_name='profile_id'
  • name Char
    required=True
  • period Integer
    default=365 required=True string='Period on which to compute the classification (Days)'
  • product_count Integer
    compute='_compute_product_count' readonly=True
  • product_variant_ids Many2many → product.product
    column1='profile_id' column2='product_id' comodel_name='product.product' index=True relation='abc_classification_profile_product_rel'
  • profile_type Selection
    index=True required=True selection=[('manual', 'Manual')] string='Type of ABC classification'
Public methods (2)
  • action_view_products(self)
  • write(self, vals)

New fields (1)
  • abc_classification_profile_ids Many2many → abc.classification.profile
    column1='categ_id' column2='profile_id' comodel_name='abc.classification.profile' index=True relation='abc_classification_profile_product_categ_rel'
Public methods (1)
  • update_product_abc_classification_profile(self)

New fields (3)
  • abc_classification_product_level_ids One2many → abc.classification.product.level
    index=True inverse_name='product_id' args: 'abc.classification.product.level'
  • abc_classification_profile_ids Many2many → abc.classification.profile
    column1='product_id' column2='profile_id' comodel_name='abc.classification.profile' index=True relation='abc_classification_profile_product_rel'
  • abc_classification_profile_updatable_from_category Boolean
    default=True
Public methods (2)
  • create(self, vals_list)
    @api.model_create_multi
  • write(self, vals)

New fields (2)
  • abc_classification_product_level_ids One2many → abc.classification.product.level
    compute='_compute_abc_classification_product_level_ids' inverse='_inverse_abc_classification_product_level_ids' inverse_name='product_tmpl_id' store=True args: 'abc.classification.product.level'
  • abc_classification_profile_ids Many2many → abc.classification.profile
    compute='_compute_abc_classification_profile_ids' inverse='_inverse_abc_classification_profile_ids' store=True args: 'abc.classification.profile'
Public methods (0)

No public methods.

REPOSITORY
REPOSITORYOCA/product-attribute
GIT
GIThttps://github.com/OCA/product-attribute.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/product-attribute/tree/15.0/product_abc_classification
VERSION
VERSION 1.0.1
CATEGORY
CATEGORYInventory Management
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), ForgeFlow
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), ForgeFlow
COMMITTERS
COMMITTERSWeblate, OCA-git-bot, oca-ci, Stefan, Aude Le
WEBSITE
WEBSITEhttps://github.com/OCA/product-attribute
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:46:35
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - sale_stock
    - sale
    - sales_team
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - payment
    - account
    - product
    - uom
    - analytic
    - portal
    - web_editor
    - http_routing
    - auth_signup
    - digest
    - resource
    - utm
    - stock_account
    - stock
    - barcodes
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (8)
XML IDNameModelTypeStatus
abc_classification_profile_form_view abc.classification.profile.form abc.classification.profile form New
abc_classification_profile_tree_view abc.classification.profile.tree abc.classification.profile tree New
product_category_form_view product.category.form (ABC Classification) product.category group Inherits product.product_category_form_view
product_normal_form_view product.product xpath Inherits product.product_normal_form_view
product_product_tree_view product.product.tree product.product field Inherits product.product_product_tree_view
product_template_only_form_view product.template.form (ABC Classification) product.template xpath Inherits product.product_template_only_form_view
product_template_search_view product.template.search (ABC Classification) product.template xpath Inherits product.product_template_search_view
product_template_tree_view product.template.tree product.template field Inherits product.product_template_tree_view
Models touched (5)

New fields (11)
  • classification_type Selection
    default='percentage' required=True selection=[('percentage', 'Percentage'), ('fixed', 'Fixed')]
  • company_id Many2one → res.company
    comodel_name='res.company' string='Company'
  • data_source Selection
    default='stock_moves' index=True required=True selection=[('stock_moves', 'Stock Moves')]
  • days_to_ignore Integer
    string='Ignore newer than these days'
  • level_ids One2many → abc.classification.profile.level
    comodel_name='abc.classification.profile.level' inverse_name='profile_id'
  • name Char
  • past_period Integer
    default=365 required=True string='Past demand period (Days)'
  • product_count Integer
    compute='_compute_product_count' readonly=True
  • product_variant_ids One2many → product.product
    inverse_name='abc_classification_profile_id' args: 'product.product'
  • representation Char
    compute='_compute_representation'
  • value_criteria Selection
    default='consumption_value' index=True required=True selection=[('consumption_value', 'Consumption Value'), ('sales_revenue', 'Sales Revenue'), ('sales_volume', 'Sales Volume')] string='Value'
Public methods (1)
  • action_view_products(self)

New fields (8)
  • classification_type Selection
    related='profile_id.classification_type' string='Classification Type'
  • company_id Many2one → res.company
    comodel_name='res.company' related='profile_id.company_id' store=True string='Company'
  • currency_id Many2one → res.currency
    related='company_id.currency_id' store=True string='Currency' args: 'res.currency'
  • fixed Monetary
    default=0.0 string='Fixed Value'
  • percentage Float
    default=0.0 string='%'
  • profile_id Many2one → abc.classification.profile
    args: 'abc.classification.profile'
  • sequence Integer
    compute='_compute_sequence' store=True
  • symbol Char
    compute='_compute_symbol' store=True
Public methods (1)
  • name_get(self)

New fields (2)
  • abc_classification_profile_id Many2one → abc.classification.profile
    args: 'abc.classification.profile'
  • product_variant_ids One2many → product.product
    inverse_name='categ_id' args: 'product.product'
Public methods (0)

No public methods.

New fields (2)
  • abc_classification_level_id Many2one → abc.classification.profile.level
    index=True args: 'abc.classification.profile.level'
  • abc_classification_profile_id Many2one → abc.classification.profile
    index=True args: 'abc.classification.profile'
Public methods (0)

No public methods.

New fields (2)
  • abc_classification_level_id Many2one → abc.classification.profile.level
    compute='_compute_abc_classification_level_id' inverse='_inverse_abc_classification_level_id' store=True args: 'abc.classification.profile.level'
  • abc_classification_profile_id Many2one → abc.classification.profile
    compute='_compute_abc_classification_profile_id' inverse='_inverse_abc_classification_profile_id' store=True args: 'abc.classification.profile'
Public methods (0)

No public methods.

REPOSITORY
REPOSITORYOCA/product-attribute
GIT
GIThttps://github.com/OCA/product-attribute.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/product-attribute/tree/13.0/product_abc_classification
VERSION
VERSION 3.0.0
CATEGORY
CATEGORYInventory Management
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), ForgeFlow
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), ForgeFlow
COMMITTERS
COMMITTERSmreficent, Miquel Raïch, oca-travis, Weblate, OCA-git-bot, CarlosRoca13, Alba Riera
WEBSITE
WEBSITEhttps://github.com/OCA/product-attribute
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:34:14
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - sale_stock
    - sale
    - sales_team
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - payment
    - account
    - product
    - uom
    - analytic
    - portal
    - web_editor
    - http_routing
    - auth_signup
    - digest
    - resource
    - utm
    - stock_account
    - stock
    - barcodes
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (8)
XML IDNameModelTypeStatus
abc_classification_profile_form_view abc.classification.profile.form abc.classification.profile form New
abc_classification_profile_tree_view abc.classification.profile.tree abc.classification.profile tree New
product_category_form_view product.category.form (ABC Classification) product.category group Inherits product.product_category_form_view
product_normal_form_view product.product xpath Inherits product.product_normal_form_view
product_product_tree_view product.product.tree product.product field Inherits product.product_product_tree_view
product_template_only_form_view product.template.form (ABC Classification) product.template xpath Inherits product.product_template_only_form_view
product_template_search_view product.template.search (ABC Classification) product.template xpath Inherits product.product_template_search_view
product_template_tree_view product.template.tree product.template field Inherits product.product_template_tree_view
Models touched (5)

New fields (11)
  • classification_type Selection
    default='percentage' required=True selection=[('percentage', 'Percentage'), ('fixed', 'Fixed')] string='Classification Type'
  • company_id Many2one → res.company
    comodel_name='res.company' string='Company'
  • data_source Selection
    default='stock_moves' index=True required=True selection=[('stock_moves', 'Stock Moves')] string='Data Source'
  • days_to_ignore Integer
    string='Ignore newer than these days'
  • level_ids One2many → abc.classification.profile.level
    comodel_name='abc.classification.profile.level' inverse_name='profile_id'
  • name Char
  • past_period Integer
    default=365 required=True string='Past demand period (Days)'
  • product_count Integer
    compute='_compute_product_count' readonly=True string='Product Count'
  • product_variant_ids One2many → product.product
    inverse_name='abc_classification_profile_id' args: 'product.product'
  • representation Char
    compute='_compute_representation'
  • value_criteria Selection
    default='consumption_value' index=True required=True selection=[('consumption_value', 'Consumption Value'), ('sales_revenue', 'Sales Revenue'), ('sales_volume', 'Sales Volume')] string='Value'
Public methods (1)
  • action_view_products(self)

New fields (8)
  • classification_type Selection
    related='profile_id.classification_type' string='Classification Type'
  • company_id Many2one → res.company
    comodel_name='res.company' related='profile_id.company_id' store=True string='Company'
  • currency_id Many2one → res.currency
    related='company_id.currency_id' store=True string='Currency' args: 'res.currency'
  • fixed Monetary
    default=0.0 string='Fixed Value'
  • percentage Float
    default=0.0 string='%'
  • profile_id Many2one → abc.classification.profile
    args: 'abc.classification.profile'
  • sequence Integer
    compute='_compute_sequence' store=True string='Sequence'
  • symbol Char
    compute='_compute_symbol' store=True
Public methods (1)
  • name_get(self)

New fields (2)
  • abc_classification_profile_id Many2one → abc.classification.profile
    args: 'abc.classification.profile'
  • product_variant_ids One2many → product.product
    inverse_name='categ_id' args: 'product.product'
Public methods (0)

No public methods.

New fields (2)
  • abc_classification_level_id Many2one → abc.classification.profile.level
    index=True args: 'abc.classification.profile.level'
  • abc_classification_profile_id Many2one → abc.classification.profile
    index=True args: 'abc.classification.profile'
Public methods (0)

No public methods.

New fields (2)
  • abc_classification_level_id Many2one → abc.classification.profile.level
    compute='_compute_abc_classification_level_id' inverse='_inverse_abc_classification_level_id' store=True args: 'abc.classification.profile.level'
  • abc_classification_profile_id Many2one → abc.classification.profile
    compute='_compute_abc_classification_profile_id' inverse='_inverse_abc_classification_profile_id' store=True args: 'abc.classification.profile'
Public methods (0)

No public methods.