Add code on product category
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
* Add code on product category
|
||||
* Add product deactivable mixins
|
||||
|
||||
Version 7.0.0 - 2023-10-30
|
||||
|
||||
@@ -1,13 +1,27 @@
|
||||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
from trytond.model import ModelSQL, ModelView, fields, tree
|
||||
from trytond.pyson import PYSONEncoder
|
||||
|
||||
from sql.conditionals import NullIf
|
||||
from sql.functions import CharLength
|
||||
from sql.operators import Equal
|
||||
|
||||
from trytond.model import Exclude, ModelSQL, ModelView, fields, tree
|
||||
from trytond.pool import Pool
|
||||
from trytond.pyson import Eval, PYSONEncoder
|
||||
from trytond.tools import is_full_text, lstrip_wildcard
|
||||
|
||||
|
||||
class Category(tree(separator=' / '), ModelSQL, ModelView):
|
||||
"Product Category"
|
||||
__name__ = "product.category"
|
||||
name = fields.Char('Name', required=True, translate=True)
|
||||
code = fields.Char(
|
||||
"Code",
|
||||
states={
|
||||
'readonly': Eval('code_readonly', False),
|
||||
})
|
||||
code_readonly = fields.Function(
|
||||
fields.Boolean("Code Readonly"), 'get_code_readonly')
|
||||
parent = fields.Many2One(
|
||||
'product.category', "Parent",
|
||||
help="Used to add structure above the category.")
|
||||
@@ -20,7 +34,13 @@ class Category(tree(separator=' / '), ModelSQL, ModelView):
|
||||
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
cls.code.search_unaccented = False
|
||||
super(Category, cls).__setup__()
|
||||
t = cls.__table__()
|
||||
cls._sql_constraints += [
|
||||
('code_unique', Exclude(t, (NullIf(t.code, ''), Equal)),
|
||||
'product.msg_category_code_unique'),
|
||||
]
|
||||
cls._order.insert(0, ('name', 'ASC'))
|
||||
cls._buttons.update({
|
||||
'add_products': {
|
||||
@@ -28,6 +48,39 @@ class Category(tree(separator=' / '), ModelSQL, ModelView):
|
||||
},
|
||||
})
|
||||
|
||||
@classmethod
|
||||
def default_code_readonly(cls):
|
||||
pool = Pool()
|
||||
Configuration = pool.get('product.configuration')
|
||||
config = Configuration(1)
|
||||
return bool(config.category_sequence)
|
||||
|
||||
def get_code_readonly(self, name):
|
||||
return self.default_code_readonly()
|
||||
|
||||
@classmethod
|
||||
def order_code(cls, tables):
|
||||
table, _ = tables[None]
|
||||
if cls.default_code_readonly():
|
||||
return [CharLength(table.code), table.code]
|
||||
else:
|
||||
return [table.code]
|
||||
|
||||
@classmethod
|
||||
def search_rec_name(cls, name, clause):
|
||||
_, operator, operand, *extra = clause
|
||||
if operator.startswith('!') or operator.startswith('not '):
|
||||
bool_op = 'AND'
|
||||
else:
|
||||
bool_op = 'OR'
|
||||
code_value = operand
|
||||
if operator.endswith('like') and is_full_text(operand):
|
||||
code_value = lstrip_wildcard(operand)
|
||||
return [bool_op,
|
||||
('name', operator, operand, *extra),
|
||||
('code', operator, code_value, *extra),
|
||||
]
|
||||
|
||||
@classmethod
|
||||
@ModelView.button_action('product.act_category_product')
|
||||
def add_products(cls, categories):
|
||||
@@ -37,8 +90,26 @@ class Category(tree(separator=' / '), ModelSQL, ModelView):
|
||||
[('id', '=', categories[0].id)]),
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def _new_code(cls):
|
||||
pool = Pool()
|
||||
Configuration = pool.get('product.configuration')
|
||||
config = Configuration(1)
|
||||
sequence = config.category_sequence
|
||||
if sequence:
|
||||
return sequence.get()
|
||||
|
||||
@classmethod
|
||||
def create(cls, vlist):
|
||||
vlist = [v.copy() for v in vlist]
|
||||
for values in vlist:
|
||||
if not values.get('code'):
|
||||
values['code'] = cls._new_code()
|
||||
return super().create(vlist)
|
||||
|
||||
@classmethod
|
||||
def copy(cls, categories, default=None):
|
||||
default = default.copy() if default is not None else {}
|
||||
default.setdefault('templates')
|
||||
default.setdefault('code', None)
|
||||
return super().copy(categories, default=default)
|
||||
|
||||
@@ -102,5 +102,17 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<field name="perm_create" eval="True"/>
|
||||
<field name="perm_delete" eval="True"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.sequence.type" id="sequence_type_category">
|
||||
<field name="name">Category</field>
|
||||
</record>
|
||||
<record model="ir.sequence.type-res.group" id="sequence_type_category_group_admin">
|
||||
<field name="sequence_type" ref="sequence_type_category"/>
|
||||
<field name="group" ref="res.group_admin"/>
|
||||
</record>
|
||||
<record model="ir.sequence.type-res.group" id="sequence_type_category_group_product_admin">
|
||||
<field name="sequence_type" ref="sequence_type_category"/>
|
||||
<field name="group" ref="group_product_admin"/>
|
||||
</record>
|
||||
</data>
|
||||
</tryton>
|
||||
|
||||
@@ -35,6 +35,12 @@ class Configuration(ModelSingleton, ModelSQL, ModelView, MultiValueMixin):
|
||||
('sequence_type', '=', Id('product', 'sequence_type_template')),
|
||||
],
|
||||
help="Used to generate the first part of the product code.")
|
||||
category_sequence = fields.Many2One(
|
||||
'ir.sequence', "Category Sequence",
|
||||
domain=[
|
||||
('sequence_type', '=', Id('product', 'sequence_type_category')),
|
||||
],
|
||||
help="Used to generate the category code.")
|
||||
|
||||
@classmethod
|
||||
def default_default_cost_price_method(cls, **pattern):
|
||||
|
||||
@@ -30,5 +30,8 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<record model="ir.message" id="msg_product_code_unique">
|
||||
<field name="text">Code of active product must be unique.</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_category_code_unique">
|
||||
<field name="text">The code on product category must be unique.</field>
|
||||
</record>
|
||||
</data>
|
||||
</tryton>
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<form>
|
||||
<form col="6">
|
||||
<label name="name"/>
|
||||
<field name="name"/>
|
||||
<label name="parent"/>
|
||||
<field name="parent"/>
|
||||
<label name="code"/>
|
||||
<field name="code"/>
|
||||
<group colspan="2" col="-1" id="checkboxes">
|
||||
<!-- Add here some checkboxes ! -->
|
||||
</group>
|
||||
<button name="add_products" colspan="2"/>
|
||||
<notebook colspan="4">
|
||||
|
||||
<label name="parent"/>
|
||||
<field name="parent" colspan="3"/>
|
||||
|
||||
<button name="add_products" colspan="6"/>
|
||||
<notebook colspan="6">
|
||||
<page string="Children" col="1" id="childs">
|
||||
<field name="childs"/>
|
||||
</page>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<tree>
|
||||
<field name="rec_name" expand="1"/>
|
||||
<field name="code" expand="1" optional="1"/>
|
||||
<field name="rec_name" expand="2"/>
|
||||
<field name="name" tree_invisible="1"/>
|
||||
</tree>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<form col="2">
|
||||
<label name="name"/>
|
||||
<field name="name" readonly="1"/>
|
||||
<label name="rec_name"/>
|
||||
<field name="rec_name" readonly="1"/>
|
||||
<field name="templates" colspan="2"/>
|
||||
</form>
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<tree keyword_open="1">
|
||||
<field name="name" expand="1"/>
|
||||
<field name="code" expand="1" optional="1"/>
|
||||
<field name="name" expand="2"/>
|
||||
<field name="parent" tree_invisible="1"/>
|
||||
<field name="childs" tree_invisible="1"/>
|
||||
</tree>
|
||||
|
||||
@@ -9,4 +9,7 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<field name="template_sequence"/>
|
||||
<label name="product_sequence"/>
|
||||
<field name="product_sequence"/>
|
||||
|
||||
<label name="category_sequence"/>
|
||||
<field name="category_sequence"/>
|
||||
</form>
|
||||
|
||||
Reference in New Issue
Block a user