70 lines
3.1 KiB
Python
70 lines
3.1 KiB
Python
|
# -*- coding: utf-8 -*-
|
||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||
|
|
||
|
from odoo import api, fields, models, _
|
||
|
from odoo.exceptions import UserError, ValidationError
|
||
|
|
||
|
|
||
|
class ProductCategory(models.Model):
|
||
|
_name = "product.category"
|
||
|
_description = "Product Category"
|
||
|
_parent_name = "parent_id"
|
||
|
_parent_store = True
|
||
|
_rec_name = 'complete_name'
|
||
|
_order = 'complete_name'
|
||
|
|
||
|
name = fields.Char('Name', index='trigram', required=True)
|
||
|
complete_name = fields.Char(
|
||
|
'Complete Name', compute='_compute_complete_name', recursive=True,
|
||
|
store=True)
|
||
|
parent_id = fields.Many2one('product.category', 'Parent Category', index=True, ondelete='cascade')
|
||
|
parent_path = fields.Char(index=True, unaccent=False)
|
||
|
child_id = fields.One2many('product.category', 'parent_id', 'Child Categories')
|
||
|
product_count = fields.Integer(
|
||
|
'# Products', compute='_compute_product_count',
|
||
|
help="The number of products under this category (Does not consider the children categories)")
|
||
|
product_properties_definition = fields.PropertiesDefinition('Product Properties')
|
||
|
|
||
|
@api.depends('name', 'parent_id.complete_name')
|
||
|
def _compute_complete_name(self):
|
||
|
for category in self:
|
||
|
if category.parent_id:
|
||
|
category.complete_name = '%s / %s' % (category.parent_id.complete_name, category.name)
|
||
|
else:
|
||
|
category.complete_name = category.name
|
||
|
|
||
|
def _compute_product_count(self):
|
||
|
read_group_res = self.env['product.template']._read_group([('categ_id', 'child_of', self.ids)], ['categ_id'], ['__count'])
|
||
|
group_data = {categ.id: count for categ, count in read_group_res}
|
||
|
for categ in self:
|
||
|
product_count = 0
|
||
|
for sub_categ_id in categ.search([('id', 'child_of', categ.ids)]).ids:
|
||
|
product_count += group_data.get(sub_categ_id, 0)
|
||
|
categ.product_count = product_count
|
||
|
|
||
|
@api.constrains('parent_id')
|
||
|
def _check_category_recursion(self):
|
||
|
if not self._check_recursion():
|
||
|
raise ValidationError(_('You cannot create recursive categories.'))
|
||
|
|
||
|
@api.model
|
||
|
def name_create(self, name):
|
||
|
category = self.create({'name': name})
|
||
|
return category.id, category.display_name
|
||
|
|
||
|
@api.depends_context('hierarchical_naming')
|
||
|
def _compute_display_name(self):
|
||
|
if self.env.context.get('hierarchical_naming', True):
|
||
|
return super()._compute_display_name()
|
||
|
for record in self:
|
||
|
record.display_name = record.name
|
||
|
|
||
|
@api.ondelete(at_uninstall=False)
|
||
|
def _unlink_except_default_category(self):
|
||
|
main_category = self.env.ref('product.product_category_all', raise_if_not_found=False)
|
||
|
if main_category and main_category in self:
|
||
|
raise UserError(_("You cannot delete this product category, it is the default generic category."))
|
||
|
expense_category = self.env.ref('product.cat_expense', raise_if_not_found=False)
|
||
|
if expense_category and expense_category in self:
|
||
|
raise UserError(_("You cannot delete the %s product category.", expense_category.name))
|