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 + + + +