From f2f3f297683ba958b1ce4bd37d205dd420825789 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=80ngel=20=C3=80lvarez?= Date: Tue, 4 Jan 2022 20:36:18 +0100 Subject: [PATCH] add new model quality sample --- __init__.py | 3 + product.py | 19 ++-- production.py | 12 +-- quality.py | 148 +++++++++++++++++++++++++--- quality.xml | 116 +++++++++++++++++++++- tryton.cfg | 2 +- view/product_form.xml | 2 - view/product_list.xml | 1 - view/quality_configuration_form.xml | 9 ++ view/quality_sample_form.xml | 24 +++-- view/quality_sample_list.xml | 9 ++ 11 files changed, 300 insertions(+), 45 deletions(-) create mode 100644 view/quality_configuration_form.xml create mode 100644 view/quality_sample_list.xml diff --git a/__init__.py b/__init__.py index 05ea16d..83518be 100644 --- a/__init__.py +++ b/__init__.py @@ -34,6 +34,9 @@ def register(): weighing.Weighing, weighing.WeighingPlantation, weighing.WeighingDo, + quality.Configuration, + quality.ConfigurationCompany, + quality.ProductQualitySample, quality.QualitySample, quality.QualityTest, quality.QuantitativeTestLine, diff --git a/product.py b/product.py index 5dfb352..f8b7f68 100644 --- a/product.py +++ b/product.py @@ -32,6 +32,7 @@ class Container(ModelSQL, ModelView): class Template(metaclass=PoolMeta): __name__ = 'product.template' + needs_sample = fields.Boolean('Needs Samples') agronomic_type = fields.Selection([ (None, ''), ('grape', "Grape"), @@ -89,13 +90,13 @@ class Product(WineMixin, metaclass=PoolMeta): }, depends=['agronomic_type']) ecologicals = fields.Many2Many('product.product-agronomics.ecological', 'product', 'ecological', 'Ecologicals') - quality_sample = fields.Many2One('quality.sample', 'Quality Sample', - states={ - 'invisible': ~ Eval('agronomic_type').in_( - ['wine', 'unfiltered-wine', 'filtered-wine', 'clarified-wine', - 'bottled-wine'] - ) - }, depends=['agronomic_type']) + # quality_sample = fields.Many2One('quality.sample', 'Quality Sample', + # states={ + # 'invisible': ~ Eval('agronomic_type').in_( + # ['wine', 'unfiltered-wine', 'filtered-wine', 'clarified-wine', + # 'bottled-wine'] + # ) + # }, depends=['agronomic_type']) certification = fields.Many2One('agronomics.certification', 'Certification', states={ 'invisible': ~ Eval('agronomic_type').in_( @@ -109,8 +110,8 @@ class Product(WineMixin, metaclass=PoolMeta): 'bottled-wine'] )}, depends=['agronomic_type']), 'get_alcohol_volume') quality_tests = fields.One2Many('quality.test', 'document', 'Quality Tests') - quality_samples = fields.One2Many('quality.sample', 'product', - 'Quality Samples') + quality_samples = fields.Many2Many('product.product-quality.sample', + 'product', 'sample', 'Quality Samples') @classmethod def validate(cls, products): diff --git a/production.py b/production.py index ac4af13..5c96f53 100644 --- a/production.py +++ b/production.py @@ -366,18 +366,18 @@ class Production(metaclass=PoolMeta): return new_product def copy_quality_samples(self, new_product): - QualitySample = Pool().get('quality.sample') + ProductSample = Pool().get('product.product-quality.sample') products = [x.product for x in self.inputs if x.product.quality_samples] if not self.pass_quality_sample or len(products) != 1: return new_product samples = products[0].quality_samples new_samples =[] for sample in samples: - new_sample, = QualitySample.copy([sample], {'product':new_product}) - new_sample.origin = sample - new_samples.append(new_sample) - QualitySample.save(new_samples) - QualitySample.done(new_samples) + product_sample = ProductSample() + product_sample.product = new_product + product_sample.sample = sample + new_samples.append(product_sample) + ProductSample.save(new_samples) return new_product def copy_quality(self, new_product): diff --git a/quality.py b/quality.py index 318ff12..fe9c483 100644 --- a/quality.py +++ b/quality.py @@ -1,31 +1,149 @@ # This file is part of Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. +import datetime from trytond.pool import PoolMeta, Pool -from trytond.model import fields, Model -from trytond.pyson import Eval +from trytond.model import fields, Model, ModelSQL, ModelView, Workflow +from trytond.pyson import Eval, Id from trytond.modules.agronomics.wine import _WINE_DIGITS +from trytond.transaction import Transaction -class QualitySample(metaclass=PoolMeta): +STATES = { + 'readonly': Eval('state') == 'done', +} +DEPENDS = ['state'] + +class ConfigurationCompany(ModelSQL): + 'Company Quality configuration' + __name__ = 'quality.configuration.company' + + company = fields.Many2One('company.company', 'Company') + sample_sequence = fields.Many2One('ir.sequence', + 'Sample Sequence', domain=[ + ('company', 'in', + [Eval('context', {}).get('company', -1), None]), + ('sequence_type', '=', Id('agronomics', + 'sequence_type_sample')), + ]) + + @staticmethod + def default_company(): + return Transaction().context.get('company') + + +class Configuration(metaclass=PoolMeta): + __name__ = 'quality.configuration' + + sample_sequence = fields.Function(fields.Many2One('ir.sequence', + 'Sample Sequence', domain=[ + ('company', 'in', + [Eval('context', {}).get('company', -1), None]), + ('sequence_type', '=', Id('agronomics', + 'sequence_type_sample')), + ]), + 'get_company_config', setter='set_company_config') + + @classmethod + def get_company_config(cls, configs, names): + pool = Pool() + CompanyConfig = pool.get('quality.configuration.company') + res = dict.fromkeys(names, {configs[0].id: None}) + company_configs = CompanyConfig.search([], limit=1) + if len(company_configs) == 1: + company_config, = company_configs + for field_name in set(names): + value = getattr(company_config, field_name, None) + if value: + res[field_name] = {configs[0].id: value.id} + return res + + @classmethod + def set_company_config(cls, configs, name, value): + pool = Pool() + CompanyConfig = pool.get('quality.configuration.company') + company_configs = CompanyConfig.search([], limit=1) + if len(company_configs) == 1: + company_config, = company_configs + else: + company_config = CompanyConfig() + setattr(company_config, name, value) + company_config.save() + + +class QualitySample(Workflow, ModelSQL, ModelView): + 'Quality Sample' __name__ = 'quality.sample' + code = fields.Char('Code', select=True, readonly=True) + state = fields.Selection([ + ('draft', 'Draft'), + ('done', 'Done')], + 'State', required=True, readonly=True) reference = fields.Char('Reference') - origin = fields.Reference('Origin', selection='get_origin', select=True, - states={ - 'readonly': Eval('state') != 'draft', + products = fields.Many2Many('product.product-quality.sample', 'sample', + 'product', 'Products') + collection_date = fields.DateTime('Collection Date', required=True, + states=STATES, depends=DEPENDS) + company = fields.Many2One('company.company', 'Company', required=True, + select=True, states=STATES, depends=DEPENDS) + + @classmethod + def __setup__(cls): + super(QualitySample, cls).__setup__() + cls._transitions |= set((('draft', 'done'),)) + cls._buttons.update({ + 'done': { + 'invisible': Eval('state') != 'draft', + 'icon': 'tryton-forward', }, - depends=['state']) + }) @classmethod - def _get_origin(cls): - 'Return list of Model names for origin Reference' - return [cls.__name__, 'quality.sample'] + @ModelView.button + @Workflow.transition('done') + def done(cls, samples): + pass + + @staticmethod + def default_state(): + return 'draft' + + @staticmethod + def default_company(): + return Transaction().context.get('company') + + @staticmethod + def default_collection_date(): + return datetime.datetime.now() @classmethod - def get_origin(cls): - IrModel = Pool().get('ir.model') - get_name = IrModel.get_name - models = cls._get_origin() - return [(None, '')] + [(m, get_name(m)) for m in models] + def create(cls, vlist): + pool = Pool() + Config = pool.get('quality.configuration') + + sequence = Config(1).sample_sequence + for value in vlist: + if not value.get('code'): + value['code'] = sequence.get() + return super(QualitySample, cls).create(vlist) + + @classmethod + def copy(cls, samples, default=None): + if default is None: + default = {} + else: + default = default.copy() + default['code'] = None + return super(QualitySample, cls).copy(samples, default=default) + +class ProductQualitySample(ModelSQL): + 'Product - Quality Sample' + __name__ = 'product.product-quality.sample' + + product = fields.Many2One('product.product', 'Product', required=True, + ondelete='CASCADE', select=True) + sample = fields.Many2One('quality.sample', 'Sample', ondelete='CASCADE', + required=True, select=True) + class QualityTest(metaclass=PoolMeta): __name__ = 'quality.test' diff --git a/quality.xml b/quality.xml index 0ce319e..fe92688 100644 --- a/quality.xml +++ b/quality.xml @@ -1,10 +1,122 @@ - + + quality.configuration + + quality_configuration_form + + + + Quality Configuration Company + + + + + + + + + + Quality Sample + + + + + + + + + + + + Sample + + + + + Quality Samples + + + + + + + quality.sample + form quality_sample_form - + + + quality.sample + tree + quality_sample_list + + + + Samples + quality.sample + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Quality Sample + + + + + + + + + + + + done + Done + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tryton.cfg b/tryton.cfg index 0135adf..0492564 100644 --- a/tryton.cfg +++ b/tryton.cfg @@ -7,7 +7,7 @@ depends: product_classification product_classification_taxonomic product_template_form_quantity - quality_control_sample + quality_control purchase_contract production xml: diff --git a/view/product_form.xml b/view/product_form.xml index e65f6aa..978a57b 100644 --- a/view/product_form.xml +++ b/view/product_form.xml @@ -5,8 +5,6 @@ -