add new model quality sample

This commit is contained in:
Àngel Àlvarez 2022-01-04 20:36:18 +01:00
parent ae01d2813b
commit f2f3f29768
11 changed files with 300 additions and 45 deletions

View file

@ -34,6 +34,9 @@ def register():
weighing.Weighing, weighing.Weighing,
weighing.WeighingPlantation, weighing.WeighingPlantation,
weighing.WeighingDo, weighing.WeighingDo,
quality.Configuration,
quality.ConfigurationCompany,
quality.ProductQualitySample,
quality.QualitySample, quality.QualitySample,
quality.QualityTest, quality.QualityTest,
quality.QuantitativeTestLine, quality.QuantitativeTestLine,

View file

@ -32,6 +32,7 @@ class Container(ModelSQL, ModelView):
class Template(metaclass=PoolMeta): class Template(metaclass=PoolMeta):
__name__ = 'product.template' __name__ = 'product.template'
needs_sample = fields.Boolean('Needs Samples')
agronomic_type = fields.Selection([ agronomic_type = fields.Selection([
(None, ''), (None, ''),
('grape', "Grape"), ('grape', "Grape"),
@ -89,13 +90,13 @@ class Product(WineMixin, metaclass=PoolMeta):
}, depends=['agronomic_type']) }, depends=['agronomic_type'])
ecologicals = fields.Many2Many('product.product-agronomics.ecological', ecologicals = fields.Many2Many('product.product-agronomics.ecological',
'product', 'ecological', 'Ecologicals') 'product', 'ecological', 'Ecologicals')
quality_sample = fields.Many2One('quality.sample', 'Quality Sample', # quality_sample = fields.Many2One('quality.sample', 'Quality Sample',
states={ # states={
'invisible': ~ Eval('agronomic_type').in_( # 'invisible': ~ Eval('agronomic_type').in_(
['wine', 'unfiltered-wine', 'filtered-wine', 'clarified-wine', # ['wine', 'unfiltered-wine', 'filtered-wine', 'clarified-wine',
'bottled-wine'] # 'bottled-wine']
) # )
}, depends=['agronomic_type']) # }, depends=['agronomic_type'])
certification = fields.Many2One('agronomics.certification', certification = fields.Many2One('agronomics.certification',
'Certification', states={ 'Certification', states={
'invisible': ~ Eval('agronomic_type').in_( 'invisible': ~ Eval('agronomic_type').in_(
@ -109,8 +110,8 @@ class Product(WineMixin, metaclass=PoolMeta):
'bottled-wine'] 'bottled-wine']
)}, depends=['agronomic_type']), 'get_alcohol_volume') )}, depends=['agronomic_type']), 'get_alcohol_volume')
quality_tests = fields.One2Many('quality.test', 'document', 'Quality Tests') quality_tests = fields.One2Many('quality.test', 'document', 'Quality Tests')
quality_samples = fields.One2Many('quality.sample', 'product', quality_samples = fields.Many2Many('product.product-quality.sample',
'Quality Samples') 'product', 'sample', 'Quality Samples')
@classmethod @classmethod
def validate(cls, products): def validate(cls, products):

View file

@ -366,18 +366,18 @@ class Production(metaclass=PoolMeta):
return new_product return new_product
def copy_quality_samples(self, 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] products = [x.product for x in self.inputs if x.product.quality_samples]
if not self.pass_quality_sample or len(products) != 1: if not self.pass_quality_sample or len(products) != 1:
return new_product return new_product
samples = products[0].quality_samples samples = products[0].quality_samples
new_samples =[] new_samples =[]
for sample in samples: for sample in samples:
new_sample, = QualitySample.copy([sample], {'product':new_product}) product_sample = ProductSample()
new_sample.origin = sample product_sample.product = new_product
new_samples.append(new_sample) product_sample.sample = sample
QualitySample.save(new_samples) new_samples.append(product_sample)
QualitySample.done(new_samples) ProductSample.save(new_samples)
return new_product return new_product
def copy_quality(self, new_product): def copy_quality(self, new_product):

View file

@ -1,31 +1,149 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of # This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms. # this repository contains the full copyright notices and license terms.
import datetime
from trytond.pool import PoolMeta, Pool from trytond.pool import PoolMeta, Pool
from trytond.model import fields, Model from trytond.model import fields, Model, ModelSQL, ModelView, Workflow
from trytond.pyson import Eval from trytond.pyson import Eval, Id
from trytond.modules.agronomics.wine import _WINE_DIGITS 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' __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') reference = fields.Char('Reference')
origin = fields.Reference('Origin', selection='get_origin', select=True, products = fields.Many2Many('product.product-quality.sample', 'sample',
states={ 'product', 'Products')
'readonly': Eval('state') != 'draft', 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 @classmethod
def _get_origin(cls): @ModelView.button
'Return list of Model names for origin Reference' @Workflow.transition('done')
return [cls.__name__, 'quality.sample'] 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 @classmethod
def get_origin(cls): def create(cls, vlist):
IrModel = Pool().get('ir.model') pool = Pool()
get_name = IrModel.get_name Config = pool.get('quality.configuration')
models = cls._get_origin()
return [(None, '')] + [(m, get_name(m)) for m in models] 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): class QualityTest(metaclass=PoolMeta):
__name__ = 'quality.test' __name__ = 'quality.test'

View file

@ -1,10 +1,122 @@
<tryton> <tryton>
<data> <data>
<!-- Quality Sample--> <record model="ir.ui.view" id="quality_configuration_view_form">
<field name="model">quality.configuration</field>
<field name="inherit" ref="quality_control.quality_configuration_form_view"/>
<field name="name">quality_configuration_form</field>
</record>
<record model="ir.rule.group" id="rule_group_quality_configuration_company">
<field name="name">Quality Configuration Company</field>
<field name="model" search="[('model', '=', 'quality.configuration.company')]"/>
<field name="global_p" eval="True"/>
</record>
<record model="ir.rule" id="rule_quality_configuration_company1">
<field name="rule_group" ref="rule_group_quality_configuration_company"/>
<field name="domain" eval="[('company', '=', Eval('user', {}).get('company', None))]" pyson="1"/>
</record>
<record model="ir.sequence.type" id="sequence_type_sample">
<field name="name">Quality Sample</field>
</record>
<record model="ir.sequence.type-res.group" id="sequence_type_sample_group_admin">
<field name="sequence_type" ref="sequence_type_sample"/>
<field name="group" ref="res.group_admin"/>
</record>
<record model="ir.sequence.type-res.group" id="sequence_type_sample_group_sale_admin">
<field name="sequence_type" ref="sequence_type_sample"/>
<field name="group" ref="quality_control.group_quality_control_admin"/>
</record>
<record model="ir.sequence" id="sequence_sample">
<field name="name">Sample</field>
<field name="sequence_type" ref="sequence_type_sample"/>
</record>
<record model="res.group" id="group_quality_control_sample">
<field name="name">Quality Samples</field>
</record>
<record model="res.user-res.group"
id="user_admin_group_quality_control_sample">
<field name="user" ref="res.user_admin"/>
<field name="group" ref="group_quality_control_sample"/>
</record>
<!-- quality.sample -->
<record model="ir.ui.view" id="quality_sample_view_form"> <record model="ir.ui.view" id="quality_sample_view_form">
<field name="model">quality.sample</field> <field name="model">quality.sample</field>
<field name="type">form</field>
<field name="name">quality_sample_form</field> <field name="name">quality_sample_form</field>
<field name="inherit" ref="quality_control_sample.quality_sample_view_form"/>
</record> </record>
<record model="ir.ui.view" id="quality_sample_view_list">
<field name="model">quality.sample</field>
<field name="type">tree</field>
<field name="name">quality_sample_list</field>
</record>
<record model="ir.action.act_window" id="act_quality_sample">
<field name="name">Samples</field>
<field name="res_model">quality.sample</field>
</record>
<record model="ir.action.act_window.view" id="act_quality_sample_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="quality_sample_view_list"/>
<field name="act_window" ref="act_quality_sample"/>
</record>
<record model="ir.action.act_window.view" id="act_quality_sample_view2">
<field name="sequence" eval="20"/>
<field name="view" ref="quality_sample_view_form"/>
<field name="act_window" ref="act_quality_sample"/>
</record>
<record model="ir.model.access" id="access_quality_sample">
<field name="model" search="[('model', '=', 'quality.sample')]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_quality_sample_group_sample">
<field name="model" search="[('model', '=', 'quality.sample')]"/>
<field name="group" ref="group_quality_control_sample"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="True"/>
</record>
<record model="ir.rule.group" id="rule_group_quality_sample">
<field name="name">Quality Sample</field>
<field name="model" search="[('model', '=', 'quality.sample')]"/>
<field name="global_p" eval="True"/>
</record>
<record model="ir.rule" id="rule_quality_sample1">
<field name="domain" eval="[('company', '=', Eval('user', {}).get('company', None))]" pyson="1"/>
<field name="rule_group" ref="rule_group_quality_sample"/>
</record>
<!-- ir.model.button -->
<record model="ir.model.button" id="sample_done_button">
<field name="name">done</field>
<field name="string">Done</field>
<field name="model" search="[('model', '=', 'quality.sample')]"/>
</record>
<record model="ir.model.button-res.group" id="sample_done_button_group_sample">
<field name="button" ref="sample_done_button"/>
<field name="group" ref="group_quality_control_sample"/>
</record>
<!-- menus -->
<menuitem action="act_quality_sample" id="menu_quality_sample"
parent="quality_control.menu_quality_control" sequence="30"/>
<record model="ir.ui.menu-res.group"
id="menu_quality_control_sample_group_quality_control_sample">
<field name="menu" ref="menu_quality_sample"/>
<field name="group" ref="group_quality_control_sample"/>
</record>
</data> </data>
</tryton> </tryton>

View file

@ -7,7 +7,7 @@ depends:
product_classification product_classification
product_classification_taxonomic product_classification_taxonomic
product_template_form_quantity product_template_form_quantity
quality_control_sample quality_control
purchase_contract purchase_contract
production production
xml: xml:

View file

@ -5,8 +5,6 @@
<field name="varieties" colspan="2"/> <field name="varieties" colspan="2"/>
<field name="denominations_of_origin" colspan="2"/> <field name="denominations_of_origin" colspan="2"/>
<field name="ecologicals" colspan="2"/> <field name="ecologicals" colspan="2"/>
<label name="quality_sample"/>
<field name="quality_sample"/>
<label name="certification"/> <label name="certification"/>
<field name="certification"/> <field name="certification"/>
<label name="alcohol_volume"/> <label name="alcohol_volume"/>

View file

@ -4,7 +4,6 @@
<field name="varieties" tree_invisible="1"/> <field name="varieties" tree_invisible="1"/>
<field name="denominations_of_origin" tree_invisible="1"/> <field name="denominations_of_origin" tree_invisible="1"/>
<field name="ecologicals" tree_invisible="1"/> <field name="ecologicals" tree_invisible="1"/>
<field name="quality_sample" tree_invisible="1"/>
<field name="certification" tree_invisible="1"/> <field name="certification" tree_invisible="1"/>
<field name="alcohol_volume" tree_invisible="1"/> <field name="alcohol_volume" tree_invisible="1"/>
<field name="container" tree_invisible="1"/> <field name="container" tree_invisible="1"/>

View file

@ -0,0 +1,9 @@
<?xml version="1.0"?>
<!-- The COPYRIGHT file at the top level of this repository contains the full
copyright notices and license terms. -->
<data>
<xpath expr="/form/field[@name='allowed_documents']" position="before">
<label name="sample_sequence"/>
<field name="sample_sequence"/>
</xpath>
</data>

View file

@ -1,9 +1,15 @@
<data> <?xml version="1.0"?>
<xpath expr="/form/field[@name='lot']" position="after"> <!-- The COPYRIGHT file at the top level of this repository contains the full
<label name="reference"/> copyright notices and license terms. -->
<field name="reference"/> <form>
<newline/> <label name="collection_date"/>
<label name="origin"/> <field name="collection_date"/>
<field name="origin" colspan="3"/> <label name="code"/>
</xpath> <field name="code"/>
</data> <field name="products" colspan="4"/>
<group colspan="4" id="buttons">
<label name="state"/>
<field name="state"/>
<button name="done"/>
</group>
</form>

View file

@ -0,0 +1,9 @@
<?xml version="1.0"?>
<!-- The COPYRIGHT file at the top level of this repository contains the full
copyright notices and license terms. -->
<tree>
<field name="code"/>
<field name="collection_date" widget="date"/>
<field name="collection_date" widget="time"/>
<field name="state"/>
</tree>