diff --git a/__init__.py b/__init__.py
index 1f76ece..d81c53a 100644
--- a/__init__.py
+++ b/__init__.py
@@ -5,6 +5,7 @@ from trytond.pool import Pool
from . import party
from . import plot
from . import product
+from . import quality
def register():
@@ -28,6 +29,9 @@ def register():
product.ProductEcological,
product.ProductVariety,
product.Template,
+ quality.QualityTest,
+ quality.QuantitativeTestLine,
+ quality.QualitativeTestLine,
module='agronomics', type_='model')
Pool.register(
module='agronomics', type_='wizard')
diff --git a/locale/ca.po b/locale/ca.po
index 3cfa297..b882c58 100644
--- a/locale/ca.po
+++ b/locale/ca.po
@@ -139,8 +139,8 @@ msgid "Irrigation"
msgstr "Irrigació"
msgctxt "field:agronomics.parcel,max_production:"
-msgid "Max Production"
-msgstr "Producció Màxima"
+msgid "Max. Production"
+msgstr "Max. producció"
msgctxt "field:agronomics.parcel,plant_number:"
msgid "Plant number"
@@ -348,7 +348,7 @@ msgstr "Parcel·la"
msgctxt "model:agronomics.parcel-agronomics.do,name:"
msgid "Parcel - Denomination Origin"
-msgstr ""
+msgstr "Parcel·la - Denominació d'origen"
msgctxt "model:agronomics.plantation,name:"
msgid "Plantation"
@@ -492,12 +492,20 @@ msgstr "Administració Agronomics"
msgctxt "selection:product.product,agronomic_type:"
msgid "Bottled Wine"
-msgstr "Vi Embotellat"
+msgstr "Vi embotellat"
+
+msgctxt "selection:product.product,agronomic_type:"
+msgid "Clarified Wine"
+msgstr "Vi clarificat"
msgctxt "selection:product.product,agronomic_type:"
msgid "DO Wort"
msgstr "Most DO"
+msgctxt "selection:product.product,agronomic_type:"
+msgid "Filtered Wine"
+msgstr "Vi filtrat"
+
msgctxt "selection:product.product,agronomic_type:"
msgid "Grape"
msgstr "Raïm"
@@ -506,18 +514,30 @@ msgctxt "selection:product.product,agronomic_type:"
msgid "Not DO Wort"
msgstr "Most no DO"
+msgctxt "selection:product.product,agronomic_type:"
+msgid "Unfiltered Wine"
+msgstr "Vi en rama"
+
msgctxt "selection:product.product,agronomic_type:"
msgid "Wine"
msgstr "Vi"
msgctxt "selection:product.template,agronomic_type:"
msgid "Bottled Wine"
-msgstr "Vi Embotellat"
+msgstr "Vi embotellat"
+
+msgctxt "selection:product.template,agronomic_type:"
+msgid "Clarified Wine"
+msgstr "Vi clarificat"
msgctxt "selection:product.template,agronomic_type:"
msgid "DO Wort"
msgstr "Most DO"
+msgctxt "selection:product.template,agronomic_type:"
+msgid "Filtered Wine"
+msgstr "Vi filtrat"
+
msgctxt "selection:product.template,agronomic_type:"
msgid "Grape"
msgstr "Raïm"
@@ -526,6 +546,10 @@ msgctxt "selection:product.template,agronomic_type:"
msgid "Not DO Wort"
msgstr "Most no DO"
+msgctxt "selection:product.template,agronomic_type:"
+msgid "Unfiltered Wine"
+msgstr "Vi en rama"
+
msgctxt "selection:product.template,agronomic_type:"
msgid "Wine"
msgstr "Vi"
diff --git a/locale/es.po b/locale/es.po
index f8e2a46..8fd749d 100644
--- a/locale/es.po
+++ b/locale/es.po
@@ -139,8 +139,8 @@ msgid "Irrigation"
msgstr "Irrigación"
msgctxt "field:agronomics.parcel,max_production:"
-msgid "Max Production"
-msgstr "Producción Máxima"
+msgid "Max. Production"
+msgstr "Max. producción"
msgctxt "field:agronomics.parcel,plant_number:"
msgid "Plant number"
@@ -348,7 +348,7 @@ msgstr "Parcela"
msgctxt "model:agronomics.parcel-agronomics.do,name:"
msgid "Parcel - Denomination Origin"
-msgstr ""
+msgstr "Parecela - Denominación de origen"
msgctxt "model:agronomics.plantation,name:"
msgid "Plantation"
@@ -492,12 +492,20 @@ msgstr "Agronomics Administración"
msgctxt "selection:product.product,agronomic_type:"
msgid "Bottled Wine"
-msgstr "Vino Embotellado"
+msgstr "Vino embotellado"
+
+msgctxt "selection:product.product,agronomic_type:"
+msgid "Clarified Wine"
+msgstr "Vino clarificado"
msgctxt "selection:product.product,agronomic_type:"
msgid "DO Wort"
msgstr "Mosto DO"
+msgctxt "selection:product.product,agronomic_type:"
+msgid "Filtered Wine"
+msgstr "Vino filtrado"
+
msgctxt "selection:product.product,agronomic_type:"
msgid "Grape"
msgstr "Uva"
@@ -506,18 +514,30 @@ msgctxt "selection:product.product,agronomic_type:"
msgid "Not DO Wort"
msgstr "Mosto no DO"
+msgctxt "selection:product.product,agronomic_type:"
+msgid "Unfiltered Wine"
+msgstr "Vino en rama"
+
msgctxt "selection:product.product,agronomic_type:"
msgid "Wine"
msgstr "Vino"
msgctxt "selection:product.template,agronomic_type:"
msgid "Bottled Wine"
-msgstr "Vino Embotellado"
+msgstr "Vino embotellado"
+
+msgctxt "selection:product.template,agronomic_type:"
+msgid "Clarified Wine"
+msgstr "Vino clarificado"
msgctxt "selection:product.template,agronomic_type:"
msgid "DO Wort"
msgstr "Mosto DO"
+msgctxt "selection:product.template,agronomic_type:"
+msgid "Filtered Wine"
+msgstr "Vino filtrado"
+
msgctxt "selection:product.template,agronomic_type:"
msgid "Grape"
msgstr "Uva"
@@ -526,6 +546,10 @@ msgctxt "selection:product.template,agronomic_type:"
msgid "Not DO Wort"
msgstr "Mosto no DO"
+msgctxt "selection:product.template,agronomic_type:"
+msgid "Unfiltered Wine"
+msgstr "Vino en rama"
+
msgctxt "selection:product.template,agronomic_type:"
msgid "Wine"
msgstr "Vino"
diff --git a/product.py b/product.py
index 0b4474a..97107d8 100644
--- a/product.py
+++ b/product.py
@@ -1,10 +1,12 @@
# 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 decimal import Decimal
from trytond.model import ModelSQL, ModelView, fields
-from trytond.pool import PoolMeta, Pool
+from trytond.pool import PoolMeta
from trytond.pyson import Eval
from trytond.exceptions import UserError
from trytond.i18n import gettext
+from trytond.modules.agronomics.wine import WineMixin
class Certification(ModelSQL, ModelView):
@@ -35,6 +37,9 @@ class Template(metaclass=PoolMeta):
('grape', "Grape"),
('do-wort', "DO Wort"),
('not-do-wort', "Not DO Wort"),
+ ('unfiltered-wine', 'Unfiltered Wine'),
+ ('filtered-wine', 'Filtered Wine'),
+ ('clarified-wine', 'Clarified Wine'),
('wine', "Wine"),
('bottled-wine', "Bottled Wine"),
], "Agronomic Type", select=True)
@@ -57,7 +62,7 @@ class Template(metaclass=PoolMeta):
return [('container.capacity',) + tuple(clause[1:])]
-class Product(metaclass=PoolMeta):
+class Product(WineMixin, metaclass=PoolMeta):
__name__ = 'product.product'
vintages = fields.Many2Many('product.product-agronomics.crop', 'product',
@@ -77,19 +82,22 @@ class Product(metaclass=PoolMeta):
quality_sample = fields.Many2One('quality.sample', 'Quality Sample',
states={
'invisible': ~ Eval('agronomic_type').in_(
- ['wine', 'bottled-wine']
+ ['wine', 'unfiltered-wine', 'filtered-wine', 'clarified-wine',
+ 'bottled-wine']
)
}, depends=['agronomic_type'])
certification = fields.Many2One('agronomics.certification',
'Certification', states={
'invisible': ~ Eval('agronomic_type').in_(
- ['wine', 'bottled-wine']
+ ['wine', 'unfiltered-wine', 'filtered-wine', 'clarified-wine',
+ 'bottled-wine']
)
}, depends=['agronomic_type'])
- alcohol_volume = fields.Numeric('Alcohol Volume', digits=(16, 2), states={
+ alcohol_volume = fields.Function(fields.Numeric('Alcohol Volume', digits=(16, 2), states={
'invisible': ~ Eval('agronomic_type').in_(
- ['wine', 'bottled-wine']
- )}, depends=['agronomic_type'])
+ ['wine', 'unfiltered-wine', 'filtered-wine', 'clarified-wine',
+ 'bottled-wine']
+ )}, depends=['agronomic_type']), 'get_alcohol_volume')
@classmethod
def validate(cls, products):
@@ -104,6 +112,13 @@ class Product(metaclass=PoolMeta):
raise UserError(gettext('agronomics.msg_variety_limit',
product=product.rec_name))
+ def get_alcohol_volume(self, name):
+ if self.template.capacity and self.wine_alcohol_content:
+ return Decimal(
+ (float(self.template.capacity) * float(self.wine_alcohol_content))
+ / 100).quantize(
+ Decimal(str(10 ** -self.__class__.alcohol_volume.digits[1])))
+
class ProductCrop(ModelSQL):
"Product - Crop"
diff --git a/product.xml b/product.xml
index 3150f14..e396cff 100644
--- a/product.xml
+++ b/product.xml
@@ -11,6 +11,7 @@
template_list
+
product.product
@@ -22,6 +23,49 @@
product_list
+
+
+ Quality Test
+ quality.test
+
+
+
+ form_relate
+ product.product,-1
+
+
+
+
+ Quantitative Lines
+ quality.quantitative.test.line
+
+
+
+ form_relate
+ product.product,-1
+
+
+
+
+ Qualitative Lines
+ quality.qualitative.test.line
+
+
+
+ form_relate
+ product.product,-1
+
+
+
agronomics.certification
@@ -130,15 +174,14 @@
-
-
+
-
+
@@ -146,7 +189,7 @@
-
+
@@ -154,6 +197,5 @@
-
-
\ No newline at end of file
+
diff --git a/quality.py b/quality.py
new file mode 100644
index 0000000..9b5823d
--- /dev/null
+++ b/quality.py
@@ -0,0 +1,92 @@
+# 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.pool import PoolMeta, Pool
+from trytond.model import fields, Model
+from trytond.modules.agronomics.wine import _WINE_DIGITS
+
+
+class QualityTest(metaclass=PoolMeta):
+ __name__ = 'quality.test'
+
+ @classmethod
+ def confirmed(cls, tests):
+ pool = Pool()
+ Product = pool.get('product.product')
+ ModelData = pool.get('ir.model.data')
+ Date = pool.get('ir.date')
+
+ super(QualityTest, cls).confirmed(tests)
+
+ today = Date.today()
+
+ # get all key from ir.model.data
+ to_write = []
+ proof_ids = []
+ for test in tests:
+ if not test.document or not isinstance(test.document, Product):
+ continue
+
+ proof_ids += [line.proof for line in test.quantitative_lines
+ if line.proof]
+ if not proof_ids:
+ return
+
+ datas = ModelData.search([
+ ('module', '=', 'agronomics'),
+ ('db_id', 'in', proof_ids),
+ ('model', '=', 'quality.proof')
+ ])
+ data_key = dict((x.db_id, x.fs_id) for x in datas)
+
+ # check all quantitative lines has key and update the product
+ for test in tests:
+ if not test.document or not isinstance(test.document, Product):
+ continue
+
+ values = {}
+ for line in test.quantitative_lines:
+ key = data_key.get(line.proof.id)
+ if not key:
+ continue
+
+ values[key] = round(line.value, _WINE_DIGITS)
+ values[key + '_comment'] = line.internal_description
+ values[key + '_confirm'] = today
+ values[key + '_success'] = line.success
+
+ if values:
+ to_write.extend(([test.document], values))
+
+ if to_write:
+ Product.write(*to_write)
+
+
+class TestLineMixin(Model):
+ product = fields.Function(fields.Many2One('product.product', 'Product', select=True),
+ 'get_product', searcher='search_product')
+
+ def get_product(self, name):
+ Product = Pool().get('product.product')
+ if isinstance(self.test.document, Product):
+ return self.test.document.id
+
+ @classmethod
+ def search_product(cls, name, clause):
+ Product = Pool().get('product.product')
+
+ _, operator, value = clause[0:3]
+ if isinstance(value, list):
+ values = [('%s,%s' % ('product.product',
+ v.id if isinstance(v, Product) else v)) for v in value]
+ else:
+ values = '%s,%s' % ('product.product',
+ value.id if isinstance(value, Product) else value)
+ return [('test.document', operator, values)]
+
+
+class QuantitativeTestLine(TestLineMixin, metaclass=PoolMeta):
+ __name__ = 'quality.quantitative.test.line'
+
+
+class QualitativeTestLine(TestLineMixin, metaclass=PoolMeta):
+ __name__ = 'quality.qualitative.test.line'
diff --git a/tryton.cfg b/tryton.cfg
index d67166e..48565ed 100644
--- a/tryton.cfg
+++ b/tryton.cfg
@@ -1,6 +1,8 @@
[tryton]
version=6.0.0
depends:
+ ir
+ res
party
product_classification
product_classification_taxonomic
@@ -8,5 +10,6 @@ depends:
xml:
plot.xml
party.xml
- message.xml
product.xml
+ wine.xml
+ message.xml
diff --git a/view/product_form.xml b/view/product_form.xml
index 1e772ea..e65f6aa 100644
--- a/view/product_form.xml
+++ b/view/product_form.xml
@@ -1,6 +1,6 @@
-
+
@@ -17,4 +17,171 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/view/product_list.xml b/view/product_list.xml
index f73f676..aa4f948 100644
--- a/view/product_list.xml
+++ b/view/product_list.xml
@@ -9,5 +9,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/wine.py b/wine.py
new file mode 100644
index 0000000..719dc9c
--- /dev/null
+++ b/wine.py
@@ -0,0 +1,478 @@
+# The COPYRIGHT file at the top level of this repository contains
+# the full copyright notices and license terms.
+from trytond.model import fields, Model
+from trytond.pool import Pool
+from trytond.pyson import Bool, Eval
+from trytond.transaction import Transaction
+
+__all__ = ['WineMixin']
+
+
+_DEPENDS = ['agronomic_type']
+_WINE_DIGITS = 4
+
+
+class WineMixin(Model):
+ wine_quality_comment = fields.Function(fields.Text('Wine Quality Comments'),
+ 'get_wine_quality_comment')
+
+ wine_likely_alcohol_content = fields.Float('Likely Alcohol Content',
+ digits=(16, _WINE_DIGITS), readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['grape', 'do-wort', 'not-do-wort']
+ )}, depends=_DEPENDS)
+ wine_likely_alcohol_content_comment = fields.Text('Likely Alcohol Content Comment',
+ states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['grape', 'do-wort', 'not-do-wort']
+ )}, depends=_DEPENDS)
+ wine_likely_alcohol_content_confirm = fields.Date('Likely Alcohol Content Confirm', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['grape', 'do-wort', 'not-do-wort']
+ )}, depends=_DEPENDS)
+ wine_likely_alcohol_content_success = fields.Boolean('Likely Alcohol Content Success', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['grape', 'do-wort', 'not-do-wort']
+ )}, depends=_DEPENDS)
+
+
+ wine_botrytis = fields.Float('Botrytis',
+ digits=(16, _WINE_DIGITS), readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['grape', 'do-wort', 'not-do-wort', 'unfiltered-wine']
+ )}, depends=_DEPENDS)
+ wine_botrytis_comment = fields.Text('Botrytis Comment',
+ states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['grape', 'do-wort', 'not-do-wort', 'unfiltered-wine']
+ )}, depends=_DEPENDS)
+ wine_botrytis_confirm = fields.Date('Botrytis Confirm', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['grape', 'do-wort', 'not-do-wort', 'unfiltered-wine']
+ )}, depends=_DEPENDS)
+ wine_botrytis_success = fields.Boolean('Botrytis Success', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['grape', 'do-wort', 'not-do-wort', 'unfiltered-wine']
+ )}, depends=_DEPENDS)
+
+ wine_alcohol_content = fields.Float('Alcohol Content',
+ digits=(16, _WINE_DIGITS), readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_alcohol_content_comment = fields.Text('Alcohol Content Comment',
+ states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_alcohol_content_confirm = fields.Date('Alcohol Content Confirm', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_alcohol_content_success = fields.Boolean('Alcohol Content Success', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+
+ wine_density = fields.Float('Density',
+ digits=(16, _WINE_DIGITS), readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine']
+ )}, depends=_DEPENDS)
+ wine_density_comment = fields.Text('Density Comment',
+ states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine']
+ )}, depends=_DEPENDS)
+ wine_density_confirm = fields.Date('Density Comment Confirm', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine']
+ )}, depends=_DEPENDS)
+ wine_density_success = fields.Boolean('Density Comment Success', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine']
+ )}, depends=_DEPENDS)
+
+ wine_temperature = fields.Float('Temperature',
+ digits=(16, _WINE_DIGITS), readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['do-wort', 'not-do-wort', 'filtered-wine']
+ )}, depends=_DEPENDS)
+ wine_temperature_comment = fields.Text('Temperature Comment',
+ states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['do-wort', 'not-do-wort', 'filtered-wine']
+ )}, depends=_DEPENDS)
+ wine_temperature_confirm = fields.Date('Temperature Confirm', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['do-wort', 'not-do-wort', 'filtered-wine']
+ )}, depends=_DEPENDS)
+ wine_temperature_success = fields.Boolean('Temperature Success', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['do-wort', 'not-do-wort', 'filtered-wine']
+ )}, depends=_DEPENDS)
+
+ wine_ph = fields.Float('PH',
+ digits=(16, _WINE_DIGITS), readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['grape', 'do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_ph_comment = fields.Text('PH Comment',
+ states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['grape', 'do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_ph_confirm = fields.Date('PH Confirm', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['grape', 'do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_ph_success= fields.Boolean('PH Success', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['grape', 'do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+
+ wine_free_sulphur = fields.Float('Free Sulphur',
+ digits=(16, _WINE_DIGITS), readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_free_sulphur_comment = fields.Text('Free Sulphur Comment',
+ states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_free_sulphur_confirm = fields.Date('Free Sulphur Confirm', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_free_sulphur_success = fields.Boolean('Free Sulphur Success', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+
+ wine_total_sulphur = fields.Float('Total Sulphur',
+ digits=(16, _WINE_DIGITS), readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_total_sulphur_comment = fields.Text('Total Sulphur Comment',
+ states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_total_sulphur_confirm = fields.Date('Total Sulphur Confirm', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_total_sulphur_success = fields.Boolean('Total Sulphur Success', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+
+ wine_tartaric_acidity = fields.Float('Tartaric Acidity',
+ digits=(16, _WINE_DIGITS), readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['grape', 'do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_tartaric_acidity_comment = fields.Text('Tartaric Acidity Comment',
+ states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['grape', 'do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_tartaric_acidity_confirm = fields.Date('Tartaric Acidity Confirm', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['grape', 'do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_tartaric_acidity_success = fields.Boolean('Tartaric Acidity Success', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['grape', 'do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+
+ wine_volatility = fields.Float('Volatility',
+ digits=(16, _WINE_DIGITS), readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_volatility_comment = fields.Text('Volatility Comment',
+ states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_volatility_confirm = fields.Date('Volatility Confirm', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_volatility_success = fields.Boolean('Volatility Success', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+
+ wine_malic_acid = fields.Float('Malic Acid',
+ digits=(16, _WINE_DIGITS), readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['unfiltered-wine', 'clarified-wine']
+ )}, depends=_DEPENDS)
+ wine_malic_acid_comment = fields.Text('Malic Acid Comment',
+ states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['unfiltered-wine', 'clarified-wine']
+ )}, depends=_DEPENDS)
+ wine_malic_acid_confirm = fields.Date('Malic Acid Confirm', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['unfiltered-wine', 'clarified-wine']
+ )}, depends=_DEPENDS)
+ wine_malic_acid_success = fields.Boolean('Malic Acid Success', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['unfiltered-wine', 'clarified-wine']
+ )}, depends=_DEPENDS)
+
+ wine_lactic_acid = fields.Float('Lactic Acid',
+ digits=(16, _WINE_DIGITS), readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['unfiltered-wine', 'clarified-wine']
+ )}, depends=_DEPENDS)
+ wine_lactic_acid_comment = fields.Text('Lactic Acid Comment',
+ states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['unfiltered-wine', 'clarified-wine']
+ )}, depends=_DEPENDS)
+ wine_lactic_acid_confirm = fields.Date('Lactic Acid Confirm', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['unfiltered-wine', 'clarified-wine']
+ )}, depends=_DEPENDS)
+ wine_lactic_acid_success = fields.Boolean('Lactic Acid Success', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['unfiltered-wine', 'clarified-wine']
+ )}, depends=_DEPENDS)
+
+ wine_protein_stability = fields.Float('Protein Stability',
+ digits=(16, _WINE_DIGITS), readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_protein_stability_comment = fields.Text('Protein Stability Comment',
+ states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_protein_stability_confirm = fields.Date('Protein Stability Confirm', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_protein_stability_success = fields.Boolean('Protein Stability Success', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+
+ wine_tartaric_stability = fields.Float('Tartaric Stability',
+ digits=(16, _WINE_DIGITS), readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_tartaric_stability_comment = fields.Text('Tartaric Stability Comment',
+ states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_tartaric_stability_confirm = fields.Date('Tartaric Stability Confirm', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_tartaric_stability_success = fields.Boolean('Tartaric Stability Success', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+
+ wine_turbidity = fields.Float('Turbidity',
+ digits=(16, _WINE_DIGITS), readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['filtered-wine']
+ )}, depends=_DEPENDS)
+ wine_turbidity_comment = fields.Text('Turbidity Comment',
+ states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['filtered-wine']
+ )}, depends=_DEPENDS)
+ wine_turbidity_confirm = fields.Date('Turbidity Confirm', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['filtered-wine']
+ )}, depends=_DEPENDS)
+ wine_turbidity_success = fields.Boolean('Turbidity Success', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['filtered-wine']
+ )}, depends=_DEPENDS)
+
+ wine_glucose_fructose = fields.Float('Glucose/Fructose',
+ digits=(16, _WINE_DIGITS), readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['grape', 'do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_glucose_fructose_comment = fields.Text('Glucose/Fructose Comment',
+ states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['grape', 'do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_glucose_fructose_confirm = fields.Date('Glucose/Fructose Confirm', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['grape', 'do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_glucose_fructose_success = fields.Boolean('Glucose/Fructose Success', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['grape', 'do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+
+ wine_color_intensity = fields.Float('Color Intensity',
+ digits=(16, _WINE_DIGITS), readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_color_intensity_comment = fields.Text('Color Intensity Comment',
+ states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_color_intensity_confirm = fields.Date('Color Intensity Confirm', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_color_intensity_success = fields.Boolean('Color Intensity Success', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+
+ wine_tone = fields.Float('Tone',
+ digits=(16, _WINE_DIGITS), readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_tone_comment = fields.Text('Tone Comment',
+ states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_tone_confirm = fields.Date('Tone Confirm', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_tone_success = fields.Boolean('Tone Success', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+
+ wine_clogging = fields.Float('Clogging',
+ digits=(16, _WINE_DIGITS), readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['filtered-wine']
+ )}, depends=_DEPENDS)
+ wine_clogging_comment = fields.Text('Clogging Comment',
+ states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['filtered-wine']
+ )}, depends=_DEPENDS)
+ wine_clogging_confirm = fields.Date('Clogging Confirm', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['filtered-wine']
+ )}, depends=_DEPENDS)
+ wine_clogging_success = fields.Boolean('Clogging Success', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['filtered-wine']
+ )}, depends=_DEPENDS)
+
+ wine_overall_impression = fields.Float('Overall Impression',
+ digits=(16, _WINE_DIGITS), readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['grape', 'do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_overall_impression_comment = fields.Text('Overall Impression Comment',
+ states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['grape', 'do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_overall_impression_confirm = fields.Date('Overall Impression Confirm', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['grape', 'do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_overall_impression_success = fields.Boolean('Overall Impression Success', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['grape', 'do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+
+ wine_observing_phase = fields.Float('Observing Phase',
+ digits=(16, _WINE_DIGITS), readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_observing_phase_comment = fields.Text('Observing Phase Comment',
+ states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_observing_phase_confirm = fields.Date('Observing Phase Confirm', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_observing_phase_success = fields.Boolean('Observing Phase Success', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+
+ wine_smelling_phase = fields.Float('Smelling Phase',
+ digits=(16, _WINE_DIGITS), readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_smelling_phase_comment = fields.Text('Smelling Phase Comment',
+ states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_smelling_phase_confirm = fields.Date('Smelling Phase Confirm', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_smelling_phase_success = fields.Boolean('Smelling Phase Success', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+
+ wine_tasting_phase = fields.Float('Tasting Phase',
+ digits=(16, _WINE_DIGITS), readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_tasting_phase_comment = fields.Text('Tasting Phase Comment',
+ states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_tasting_phase_confirm = fields.Date('Tasting Phase Confirm', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+ wine_tasting_phase_success = fields.Boolean('Tasting Phase Success', readonly=True, states={
+ 'invisible': ~Eval('agronomic_type').in_(
+ ['do-wort', 'not-do-wort', 'unfiltered-wine', 'clarified-wine', 'filtered-wine', 'bottled-wine']
+ )}, depends=_DEPENDS)
+
+ @classmethod
+ def get_wine_quality_comment(cls, records, name):
+ pool = Pool()
+ Translation = pool.get('ir.translation')
+
+ res = dict((x.id, None) for x in records)
+ language = Transaction().language
+
+ for record in records:
+ data = ''
+ for key in cls._fields.keys():
+ if (key.startswith('wine_') and key.endswith('_comment')
+ and key != 'wine_quality_comment'):
+ if not getattr(record, key):
+ continue
+ field_name = '%s,%s' % (cls.__name__, key)
+ label = (Translation.get_source(field_name, 'field', language)
+ or getattr(cls, key).string)
+ data += '%s
%s
' % (label, getattr(record, key))
+ res[record.id] = data
+
+ return res
diff --git a/wine.xml b/wine.xml
new file mode 100644
index 0000000..0dc4975
--- /dev/null
+++ b/wine.xml
@@ -0,0 +1,199 @@
+
+
+
+
+ Grau esperat
+ quantitative
+
+
+ Botrytis
+ quantitative
+
+
+ Grau alcohol
+ quantitative
+
+
+ Densitat
+ quantitative
+
+
+ Temperatura
+ quantitative
+
+
+ PH
+ quantitative
+
+
+ Sulfuros lliure
+ quantitative
+
+
+ Sulfurós Total
+ quantitative
+
+
+ Acidesa tartàric
+ quantitative
+
+
+ Volatil
+ quantitative
+
+
+ Àcid màlic
+ quantitative
+
+
+ Àcil lactica
+ quantitative
+
+
+ Estabilitat proteica
+ quantitative
+
+
+ Estabilitat tartarica
+ quantitative
+
+
+ Terbolesa
+ quantitative
+
+
+ Glucosa/fructosa
+ quantitative
+
+
+ Intensitat colorant
+ quantitative
+
+
+ Tonalitat
+ quantitative
+
+
+ Colmatacio
+ quantitative
+
+
+ Impresió general
+ quantitative
+
+
+ Fase visual
+ quantitative
+
+
+ Fase olfactiva
+ quantitative
+
+
+ Fase gustativa
+ quantitative
+
+
+ Observacions
+ quantitative
+
+
+
+
+ Grau esperat
+
+
+
+ Botrytis
+
+
+
+ Grau alcohol
+
+
+
+ Densitat
+
+
+
+ Temperatura
+
+
+
+ PH
+
+
+
+ Sulfuros lliure
+
+
+
+ Sulfurós Total
+
+
+
+ Acidesa tartàric
+
+
+
+ Volatil
+
+
+
+ Àcid màlic
+
+
+
+ Àcil lactica
+
+
+
+ Estabilitat proteica
+
+
+
+ Estabilitat tartarica
+
+
+
+ Terbolesa
+
+
+
+ Glucosa/fructosa
+
+
+
+ Intensitat colorant
+
+
+
+ Tonalitat
+
+
+
+ Colmatacio
+
+
+
+ Impresió general
+
+
+
+ Fase visual
+
+
+
+ Fase olfactiva
+
+
+
+ Fase gustativa
+
+
+
+ Observacions
+
+
+
+