trytond-product_esale/menu.py

182 lines
5.5 KiB
Python

# This file is part product_esale module for Tryton.
# The COPYRIGHT file at the top level of this repository contains
# the full copyright notices and license terms.
from trytond.model import ModelView, ModelSQL, fields
from trytond.pool import Pool
from .tools import slugify
__all__ = ['CatalogMenu']
class CatalogMenu(ModelSQL, ModelView):
"eSale Catalog Menu"
__name__ = 'esale.catalog.menu'
name = fields.Char('Name', required=True, translate=True)
parent = fields.Many2One('esale.catalog.menu', 'Parent', select=True)
childs = fields.One2Many('esale.catalog.menu', 'parent',
string='Children')
active = fields.Boolean('Active')
default_sort_by = fields.Selection([
('', ''),
('position', 'Position'),
('name', 'Name'),
('price', 'Price'),
('date', 'Date'),
], 'Default Product Listing Sort (Sort By)')
slug = fields.Char('Slug', size=None, translate=True, required=True)
full_slug = fields.Function(fields.Char('Full Slug'), 'get_full_slug')
description = fields.Text('Description', translate=True)
metadescription = fields.Char('MetaDescription', size=155, translate=True)
metakeyword = fields.Char('MetaKeyword', size=155, translate=True)
metatitle = fields.Char('MetaTitle', size=155, translate=True)
include_in_menu = fields.Boolean('Included in Menu')
@staticmethod
def default_active():
return True
@staticmethod
def default_default_sort_by():
return 'position'
@staticmethod
def default_include_in_menu():
return True
@fields.depends('name', 'slug')
def on_change_name(self):
if self.name and not self.slug:
self.slug = slugify(self.name)
@classmethod
def __setup__(cls):
super(CatalogMenu, cls).__setup__()
cls._order.insert(0, ('name', 'ASC'))
cls._error_messages.update({
'slug_empty': 'Slug field is empty!',
'slug_exists': 'Slug %s exists. Get another slug!',
'not_copy': 'Copy action is dissabled! Create new menu use New',
})
@classmethod
def validate(cls, menus):
super(CatalogMenu, cls).validate(menus)
cls.check_recursion(menus, rec_name='name')
@classmethod
def copy(cls, menus, default=None):
cls.raise_user_error('not_copy')
def get_full_slug(self, name):
if self.parent:
return self.parent.get_full_slug(name) + '/' + self.slug
else:
return self.slug
def get_rec_name(self, name):
if self.parent:
return self.parent.get_rec_name(name) + ' / ' + self.name
else:
return self.name
@classmethod
def search_rec_name(cls, name, clause):
if isinstance(clause[2], basestring):
values = clause[2].split('/')
values.reverse()
domain = []
field = 'name'
for name in values:
domain.append((field, clause[1], name.strip()))
field = 'parent.' + field
else:
domain = [('name',) + tuple(clause[1:])]
ids = [w.id for w in cls.search(domain, order=[])]
return [('parent', 'child_of', ids)]
@classmethod
def get_topmenu(cls, parent):
"""Get Top Menu
:param id: int
:return id
"""
top_id = False
parent_id = False
if not parent:
return top_id
cat_parent = parent
if parent:
parent_id = cat_parent
while(parent_id):
top_id = parent_id
cat_parent = cls(top_id).parent
parent_id = cat_parent
return top_id
@classmethod
def get_allchild(cls, menu):
"""Get All Childs Menu
:param menu: int
:return list objects
"""
childs = []
for child in cls(menu).childs:
childs.append(child)
childs.extend(cls.get_allchild(child.id))
return childs
@classmethod
def get_slug(cls, id, slug, parent):
"""Get another menu is same slug
Slug is identificator unique
:param id: int
:param slug: str
:return True or False
"""
Config = Pool().get('product.configuration')
config = Config(1)
if not config.check_slug:
return True
topmenu = cls.get_topmenu(parent)
if not topmenu:
return True
childs = cls.get_allchild(topmenu)
records = [c.id for c in childs]
if id and id in records:
records.remove(id)
menus = cls.search([('slug','=',slug),('id','in',records)])
if len(menus)>0:
cls.raise_user_error('slug_exists', slug)
return True
@classmethod
def create(cls, vlist):
for values in vlist:
values = values.copy()
slug = values.get('slug')
parent = values.get('parent')
if not slug:
cls.raise_user_error('slug_empty')
cls.get_slug(None, slug, parent)
return super(CatalogMenu, cls).create(vlist)
@classmethod
def write(cls, *args):
actions = iter(args)
for records, values in zip(actions, actions):
slug = values.get('slug')
parent = values.get('parent')
if slug:
for record in records:
if parent:
parent = cls(record).parent.id
cls.get_slug(record.id, slug, parent)
return super(CatalogMenu, cls).write(*args)