changeset 5c3fb7da73f1 in modules/product:default
details: https://hg.tryton.org/modules/product?cmd=changeset;node=5c3fb7da73f1
description:
Allow the product code to be set by a sequence
issue8545
review261921004
diffstat:
CHANGELOG | 1 +
configuration.py | 5 ++++
doc/index.rst | 10 +++++---
product.py | 46 +++++++++++++++++++++++++++++++++++++++++++-
product.xml | 14 +++++++++++++
view/configuration_form.xml | 2 +
6 files changed, 72 insertions(+), 6 deletions(-)
diffs (146 lines):
diff -r 2e637cabeb94 -r 5c3fb7da73f1 CHANGELOG
--- a/CHANGELOG Fri Aug 09 16:36:07 2019 +0200
+++ b/CHANGELOG Mon Aug 19 11:43:26 2019 +0200
@@ -1,3 +1,4 @@
+* Allow the product code to be set by a sequence
* Allow UoM conversion between different categories
* Add product identifiers
diff -r 2e637cabeb94 -r 5c3fb7da73f1 configuration.py
--- a/configuration.py Fri Aug 09 16:36:07 2019 +0200
+++ b/configuration.py Mon Aug 19 11:43:26 2019 +0200
@@ -26,6 +26,11 @@
default_cost_price_method = fields.MultiValue(default_cost_price_method)
get_cost_price_methods = get_cost_price_methods
+ product_sequence = fields.Many2One('ir.sequence', 'Product Sequence',
+ domain=[
+ ('code', '=', 'product.product'),
+ ],
+ help="Used to generate the product code.")
@classmethod
def default_default_cost_price_method(cls, **pattern):
diff -r 2e637cabeb94 -r 5c3fb7da73f1 doc/index.rst
--- a/doc/index.rst Fri Aug 09 16:36:07 2019 +0200
+++ b/doc/index.rst Mon Aug 19 11:43:26 2019 +0200
@@ -53,16 +53,18 @@
- Cost Price Method, which can be *Fixed* or *Average*. Defines how
the cost price should be updated. *Fixed* means that the cost price
stay unchanged. *Average* means that the cost price is the average
- cost of all the items that are in stock.
+ cost of all the items that are in stock. It's default value can be defined
+ on product configuration.
- Default UOM. The default UOM for this product. Used for example to
express stock levels.
- Active, allow to disable a product.
The Product model extend the Product Template with two fields: Code
-and Description. It's also possible to define a list of identifiers on product.
-An identifier is composed by a type and a code. The following types are
-available:
+and Description. If a sequence is set on product configuration the code will
+be readonly and will be filled in using the sequence. It's also possible to
+define a list of identifiers on product. An identifier is composed by a type
+and a code. The following types are available:
* International Article Number (EAN)
* International Standard Audiovisual Number (ISAN)
diff -r 2e637cabeb94 -r 5c3fb7da73f1 product.py
--- a/product.py Fri Aug 09 16:36:07 2019 +0200
+++ b/product.py Mon Aug 19 11:43:26 2019 +0200
@@ -205,8 +205,13 @@
template = fields.Many2One('product.template', 'Product Template',
required=True, ondelete='CASCADE', select=True, states=STATES,
depends=DEPENDS)
- code = fields.Char("Code", size=None, select=True, states=STATES,
- depends=DEPENDS)
+ code_readonly = fields.Function(fields.Boolean('Code Readonly'),
+ 'get_code_readonly')
+ code = fields.Char("Code", size=None, select=True,
+ states={
+ 'readonly': STATES['readonly'] | Eval('code_readonly', False),
+ },
+ depends=DEPENDS + ['code_readonly'])
identifiers = fields.One2Many('product.identifier', 'product',
"Identifiers", states=STATES, depends=DEPENDS,
help="Add other identifiers to the variant.")
@@ -353,6 +358,43 @@
icon = icon or 'tryton-product'
yield id_, rec_name, icon
+ @classmethod
+ def default_code_readonly(cls):
+ pool = Pool()
+ Configuration = pool.get('product.configuration')
+ config = Configuration(1)
+ return bool(config.product_sequence)
+
+ def get_code_readonly(self, name):
+ return self.default_code_readonly()
+
+ @classmethod
+ def _new_code(cls):
+ pool = Pool()
+ Sequence = pool.get('ir.sequence')
+ Configuration = pool.get('product.configuration')
+ config = Configuration(1)
+ sequence = config.product_sequence
+ if sequence:
+ return Sequence.get_id(sequence.id)
+
+ @classmethod
+ def create(cls, vlist):
+ vlist = [x.copy() for x in vlist]
+ for values in vlist:
+ if not values.get('code'):
+ values['code'] = cls._new_code()
+ return super().create(vlist)
+
+ @classmethod
+ def copy(cls, products, default=None):
+ if default is None:
+ default = {}
+ else:
+ default = default.copy()
+ default.setdefault('code', None)
+ return super().copy(products, default=default)
+
class ProductListPrice(ModelSQL, CompanyValueMixin):
"Product List Price"
diff -r 2e637cabeb94 -r 5c3fb7da73f1 product.xml
--- a/product.xml Fri Aug 09 16:36:07 2019 +0200
+++ b/product.xml Mon Aug 19 11:43:26 2019 +0200
@@ -220,6 +220,20 @@
<field name="perm_delete" eval="True"/>
</record>
+ <record model="ir.sequence.type" id="sequence_type_product">
+ <field name="name">Product</field>
+ <field name="code">product.product</field>
+ </record>
+ <record model="ir.sequence.type-res.group"
+ id="sequence_type_product_group_admin">
+ <field name="sequence_type" ref="sequence_type_product"/>
+ <field name="group" ref="res.group_admin"/>
+ </record>
+ <record model="ir.sequence.type-res.group"
+ id="sequence_type_product_group_product_admin">
+ <field name="sequence_type" ref="sequence_type_product"/>
+ <field name="group" ref="group_product_admin"/>
+ </record>
</data>
</tryton>
diff -r 2e637cabeb94 -r 5c3fb7da73f1 view/configuration_form.xml
--- a/view/configuration_form.xml Fri Aug 09 16:36:07 2019 +0200
+++ b/view/configuration_form.xml Mon Aug 19 11:43:26 2019 +0200
@@ -4,4 +4,6 @@
<form>
<label name="default_cost_price_method"/>
<field name="default_cost_price_method"/>
+ <label name="product_sequence"/>
+ <field name="product_sequence"/>
</form>