pass quality, certification and sample from input product to output product in production and remove quality_control_sample module dependency to create new model in agronomics #046285
This commit is contained in:
parent
f9247c89a0
commit
a14f712dee
|
@ -34,6 +34,10 @@ def register():
|
|||
weighing.Weighing,
|
||||
weighing.WeighingPlantation,
|
||||
weighing.WeighingDo,
|
||||
quality.Configuration,
|
||||
quality.ConfigurationCompany,
|
||||
quality.ProductQualitySample,
|
||||
quality.QualitySample,
|
||||
quality.QualityTest,
|
||||
quality.QuantitativeTestLine,
|
||||
quality.QualitativeTestLine,
|
||||
|
|
11
product.py
11
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,6 @@ 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'])
|
||||
certification = fields.Many2One('agronomics.certification',
|
||||
'Certification', states={
|
||||
'invisible': ~ Eval('agronomic_type').in_(
|
||||
|
@ -108,6 +102,9 @@ class Product(WineMixin, metaclass=PoolMeta):
|
|||
['wine', 'unfiltered-wine', 'filtered-wine', 'clarified-wine',
|
||||
'bottled-wine']
|
||||
)}, depends=['agronomic_type']), 'get_alcohol_volume')
|
||||
quality_tests = fields.One2Many('quality.test', 'document', 'Quality Tests')
|
||||
quality_samples = fields.Many2Many('product.product-quality.sample',
|
||||
'product', 'sample', 'Quality Samples')
|
||||
|
||||
@classmethod
|
||||
def validate(cls, products):
|
||||
|
|
112
production.py
112
production.py
|
@ -1,5 +1,6 @@
|
|||
# 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.pyson import Eval, Bool, If
|
||||
|
@ -9,7 +10,6 @@ from trytond.transaction import Transaction
|
|||
from trytond.wizard import Wizard, StateView, StateAction, Button
|
||||
from trytond.modules.product import round_price
|
||||
from trytond.model.exceptions import ValidationError
|
||||
from decimal import Decimal
|
||||
|
||||
|
||||
class ProductionTemplate(ModelSQL, ModelView):
|
||||
|
@ -30,6 +30,9 @@ class ProductionTemplate(ModelSQL, ModelView):
|
|||
enology_products = fields.One2Many('production.template.line',
|
||||
'production_template', 'Complementary Products')
|
||||
pass_feature = fields.Boolean('Pass on Feature')
|
||||
pass_quality = fields.Boolean('Pass Quality')
|
||||
pass_certification = fields.Boolean('Pass Certification')
|
||||
pass_quality_sample = fields.Boolean('Pass Quality Sample')
|
||||
cost_distribution_template = fields.Many2One(
|
||||
'production.cost_price.distribution.template',
|
||||
"Default cost distribution template",
|
||||
|
@ -68,8 +71,8 @@ class ProductionTemplate(ModelSQL, ModelView):
|
|||
return
|
||||
|
||||
output_templates = set([o for o in self.outputs])
|
||||
for c in self.cost_distribution_template.cost_distribution_templates:
|
||||
if c.template not in output_templates:
|
||||
for cost in self.cost_distribution_template.cost_distribution_templates:
|
||||
if cost.template not in output_templates:
|
||||
raise ValidationError(
|
||||
gettext('agronomics.msg_check_cost_distribution_template',
|
||||
production=self.rec_name))
|
||||
|
@ -170,19 +173,39 @@ class Production(metaclass=PoolMeta):
|
|||
'production.cost_price.distribution.template',
|
||||
"Cost Distribution Template",
|
||||
domain=[
|
||||
('id', 'in', Eval('production_template_cost_distribution_templates'))
|
||||
('id', 'in',
|
||||
Eval('production_template_cost_distribution_templates'))
|
||||
], states={
|
||||
'readonly': Eval('state').in_(['cancelled', 'done']),
|
||||
}, depends=['state', 'production_template_cost_distribution_templates'])
|
||||
}, depends=['state',
|
||||
'production_template_cost_distribution_templates'])
|
||||
cost_distribution_templates = fields.Function(
|
||||
fields.Many2Many('product.template',
|
||||
None, None, "Cost Product Templates"),
|
||||
'on_change_with_cost_distribution_templates')
|
||||
pass_quality = fields.Boolean('Pass Quality')
|
||||
pass_certification = fields.Boolean('Pass Certification')
|
||||
pass_quality_sample = fields.Boolean('Pass Quality Sample')
|
||||
|
||||
@classmethod
|
||||
def set_allowed_products(cls, productions, name, value):
|
||||
pass
|
||||
|
||||
@fields.depends('production_template')
|
||||
def on_change_with_pass_quality(self):
|
||||
if self.production_template:
|
||||
return self.production_template.pass_quality
|
||||
|
||||
@fields.depends('production_template')
|
||||
def on_change_with_pass_certification(self):
|
||||
if self.production_template:
|
||||
return self.production_template.pass_certification
|
||||
|
||||
@fields.depends('production_template')
|
||||
def on_change_with_pass_quality_sample(self):
|
||||
if self.production_template:
|
||||
return self.production_template.pass_quality_sample
|
||||
|
||||
@fields.depends('production_template')
|
||||
def on_change_production_template(self):
|
||||
if (self.production_template and
|
||||
|
@ -195,8 +218,8 @@ class Production(metaclass=PoolMeta):
|
|||
products = []
|
||||
if not self.production_template:
|
||||
return []
|
||||
for x in self.production_template.inputs:
|
||||
products += x.products
|
||||
for input_ in self.production_template.inputs:
|
||||
products += input_.products
|
||||
return [x.id for x in products]
|
||||
|
||||
@fields.depends('production_template')
|
||||
|
@ -249,7 +272,7 @@ class Production(metaclass=PoolMeta):
|
|||
gettext('agronomics.msg_check_production_percentatge',
|
||||
production=self.rec_name,
|
||||
percentatge=percentatge * 100,
|
||||
))
|
||||
))
|
||||
|
||||
@classmethod
|
||||
def wait(cls, productions):
|
||||
|
@ -300,11 +323,12 @@ class Production(metaclass=PoolMeta):
|
|||
|
||||
for output_product in production.production_template.outputs:
|
||||
delete_outputs += [x for x in production.output_distribution]
|
||||
od = OutputDistribution()
|
||||
od.product = output_product
|
||||
od.uom = od.on_change_with_uom()
|
||||
od.production = production
|
||||
outputs.append(od)
|
||||
output_distribution = OutputDistribution()
|
||||
output_distribution.product = output_product
|
||||
output_distribution.uom = (
|
||||
output_distribution.on_change_with_uom())
|
||||
output_distribution.production = production
|
||||
outputs.append(output_distribution)
|
||||
|
||||
if not production.cost_distributions:
|
||||
if production.cost_distribution_template:
|
||||
|
@ -335,6 +359,45 @@ class Production(metaclass=PoolMeta):
|
|||
product.template = template
|
||||
return product
|
||||
|
||||
def copy_certification(self, new_product):
|
||||
products = [x.product for x in self.inputs if x.product.certification]
|
||||
if not self.pass_certification or len(products) != 1:
|
||||
return new_product
|
||||
certification = products[0].certification
|
||||
new_product.certification = certification
|
||||
return new_product
|
||||
|
||||
def copy_quality_samples(self, new_product):
|
||||
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:
|
||||
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):
|
||||
Quality = Pool().get('quality.test')
|
||||
products = [x.product for x in self.inputs]
|
||||
|
||||
if not self.pass_quality:
|
||||
return
|
||||
|
||||
tests = []
|
||||
for product in products:
|
||||
if tests and product.quality_tests:
|
||||
return
|
||||
tests += product.quality_tests or []
|
||||
new_tests = Quality.copy(tests, {'document': str(new_product)})
|
||||
Quality.confirmed(new_tests)
|
||||
Quality.manager_validate(new_tests)
|
||||
|
||||
def pass_feature(self, product):
|
||||
Variety = Pool().get('product.variety')
|
||||
Uom = Pool().get('product.uom')
|
||||
|
@ -355,17 +418,17 @@ class Production(metaclass=PoolMeta):
|
|||
product.vintages = list(set(vintages))
|
||||
varieties = {}
|
||||
for input in self.inputs:
|
||||
percent = round(input.quantity/total_output, 6)
|
||||
percent = round(input.quantity / total_output, 6)
|
||||
for variety in input.product.varieties:
|
||||
new_variety = varieties.get(variety.variety)
|
||||
if not new_variety:
|
||||
new_variety = Variety()
|
||||
new_variety.percent = 0
|
||||
new_variety.variety = variety.variety
|
||||
new_variety.percent += variety.percent/100.0*percent
|
||||
new_variety.percent += variety.percent / 100.0 * percent
|
||||
varieties[new_variety.variety] = new_variety
|
||||
for key, variety in varieties.items():
|
||||
variety.percent = "%.4f" % round(100.0*variety.percent, 4)
|
||||
variety.percent = "%.4f" % round(100.0 * variety.percent, 4)
|
||||
product.varieties = varieties.values()
|
||||
return product
|
||||
|
||||
|
@ -378,6 +441,7 @@ class Production(metaclass=PoolMeta):
|
|||
product = production.create_variant(distrib.product,
|
||||
production.production_template.pass_feature)
|
||||
product = production.pass_feature(product)
|
||||
product = production.copy_certification(product)
|
||||
move = production._move(
|
||||
production.location,
|
||||
distrib.location,
|
||||
|
@ -388,8 +452,13 @@ class Production(metaclass=PoolMeta):
|
|||
move.production_output = production
|
||||
move.unit_price = Decimal(0)
|
||||
moves.append(move)
|
||||
|
||||
Move.save(moves)
|
||||
super().done(productions)
|
||||
for production in productions:
|
||||
for output in production.outputs:
|
||||
production.copy_quality(output.product)
|
||||
production.copy_quality_samples(output.product)
|
||||
|
||||
@classmethod
|
||||
def set_cost(cls, productions):
|
||||
|
@ -417,7 +486,8 @@ class Production(metaclass=PoolMeta):
|
|||
if output.product not in products:
|
||||
continue
|
||||
has_product = True
|
||||
cost = production_cost * (1 + cdist.percentatge) - production_cost
|
||||
cost = (production_cost * (1 + cdist.percentatge) -
|
||||
production_cost)
|
||||
output_cost += round_price(cost / Decimal(total_output))
|
||||
|
||||
output_cost = output_cost if has_product else Decimal(0)
|
||||
|
@ -492,7 +562,8 @@ class OutputDistribution(ModelSQL, ModelView):
|
|||
context = Transaction().context
|
||||
context['locations'] = [self.location.id]
|
||||
with Transaction().set_context(context):
|
||||
quantities = Product.get_quantity(self.product.products, 'quantity')
|
||||
quantities = Product.get_quantity(self.product.products,
|
||||
'quantity')
|
||||
self.initial_quantity = sum(quantities.values())
|
||||
|
||||
@fields.depends('location', methods=['on_change_product'])
|
||||
|
@ -511,7 +582,8 @@ class OutputDistribution(ModelSQL, ModelView):
|
|||
context = Transaction().context
|
||||
context['locations'] = [self.location.id]
|
||||
with Transaction().set_context(context):
|
||||
quantities = Product.get_quantity(self.product.products, 'quantity')
|
||||
quantities = Product.get_quantity(self.product.products,
|
||||
'quantity')
|
||||
return sum(quantities.values())
|
||||
|
||||
@fields.depends('final_quantity', 'initial_quantity')
|
||||
|
@ -557,7 +629,7 @@ class ProductionCostPriceDistribution(ModelSQL, ModelView):
|
|||
__name__ = 'production.cost_price.distribution'
|
||||
template = fields.Many2One('product.template', "Template", required=True,
|
||||
ondelete='RESTRICT')
|
||||
origin = fields.Reference('Origin', selection='_get_models', required=True,)
|
||||
origin = fields.Reference('Origin', selection='_get_models', required=True)
|
||||
percentatge = fields.Numeric("Percentatge", digits=(16, 4), required=True)
|
||||
|
||||
@classmethod
|
||||
|
|
111
quality.py
111
quality.py
|
@ -1,8 +1,117 @@
|
|||
# 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.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 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(ModelSQL, ModelView):
|
||||
'Quality Sample'
|
||||
__name__ = 'quality.sample'
|
||||
|
||||
code = fields.Char('Code', select=True, readonly=True)
|
||||
reference = fields.Char('Reference')
|
||||
products = fields.Many2Many('product.product-quality.sample', 'sample',
|
||||
'product', 'Products')
|
||||
collection_date = fields.DateTime('Collection Date', required=True)
|
||||
company = fields.Many2One('company.company', 'Company', required=True,
|
||||
select=True)
|
||||
|
||||
@staticmethod
|
||||
def default_company():
|
||||
return Transaction().context.get('company')
|
||||
|
||||
@staticmethod
|
||||
def default_collection_date():
|
||||
return datetime.datetime.now()
|
||||
|
||||
@classmethod
|
||||
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):
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
<tryton>
|
||||
<data>
|
||||
<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">
|
||||
<field name="model">quality.sample</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">quality_sample_form</field>
|
||||
</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>
|
||||
|
||||
<!-- 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>
|
||||
</tryton>
|
|
@ -188,6 +188,7 @@ Create Production Template::
|
|||
>>> production_template.inputs.append(productA.template)
|
||||
>>> production_template.outputs.append(mostflor)
|
||||
>>> production_template.outputs.append(mostprimeres)
|
||||
>>> production_template.pass_quality = True
|
||||
>>> line = ProductionTemplateLine()
|
||||
>>> line.product = product2
|
||||
>>> line.quantity = 100
|
||||
|
@ -202,6 +203,10 @@ Create Production Template::
|
|||
>>> production_template.enology_products.append(line)
|
||||
>>> production_template.save()
|
||||
|
||||
Create Test:
|
||||
|
||||
>>> QualityTest = Model.get('quality.test')
|
||||
>>> Test = QualityTest()
|
||||
|
||||
Create an Inventory::
|
||||
|
||||
|
@ -315,3 +320,5 @@ Create Production
|
|||
[('Parellada', 16.6667), ('Macabeu', 83.3334)]
|
||||
>>> [x.name for x in most.product.denominations_of_origin]
|
||||
['Catalunya']
|
||||
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ depends:
|
|||
product_classification
|
||||
product_classification_taxonomic
|
||||
product_template_form_quantity
|
||||
quality_control_sample
|
||||
quality_control
|
||||
purchase_contract
|
||||
production
|
||||
xml:
|
||||
|
@ -18,3 +18,4 @@ xml:
|
|||
wine.xml
|
||||
message.xml
|
||||
production.xml
|
||||
quality.xml
|
|
@ -5,8 +5,6 @@
|
|||
<field name="varieties" colspan="2"/>
|
||||
<field name="denominations_of_origin" colspan="2"/>
|
||||
<field name="ecologicals" colspan="2"/>
|
||||
<label name="quality_sample"/>
|
||||
<field name="quality_sample"/>
|
||||
<label name="certification"/>
|
||||
<field name="certification"/>
|
||||
<label name="alcohol_volume"/>
|
||||
|
@ -180,6 +178,7 @@
|
|||
<label name="wine_tasting_phase_success"/>
|
||||
<field name="wine_tasting_phase_success"/>
|
||||
|
||||
<field name="quality_samples" colspan="6"/>
|
||||
<separator name="wine_quality_comment" colspan="6"/>
|
||||
<field name="wine_quality_comment" widget="richtext" toolbar="0" yexpand="1" yfill="1" colspan="6"/>
|
||||
</page>
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
<field name="varieties" tree_invisible="1"/>
|
||||
<field name="denominations_of_origin" tree_invisible="1"/>
|
||||
<field name="ecologicals" tree_invisible="1"/>
|
||||
<field name="quality_sample" tree_invisible="1"/>
|
||||
<field name="certification" tree_invisible="1"/>
|
||||
<field name="alcohol_volume" tree_invisible="1"/>
|
||||
<field name="container" tree_invisible="1"/>
|
||||
<field name="capacity" tree_invisible="1"/>
|
||||
<field name="quality_samples" tree_invisible="1"/>
|
||||
|
||||
<field name="wine_likely_alcohol_content" tree_invisible="1"/>
|
||||
<field name="wine_likely_alcohol_content_comment" tree_invisible="1"/>
|
||||
|
|
|
@ -6,6 +6,14 @@ this repository contains the full copyright notices and license terms. -->
|
|||
<label name="production_template"/>
|
||||
<field name="production_template"/>
|
||||
</xpath>
|
||||
<xpath expr="/form/notebook/page[@id='other']/field[@name='done_by']" position="after">
|
||||
<label name="pass_quality"/>
|
||||
<field name="pass_quality"/>
|
||||
<label name="pass_quality_sample"/>
|
||||
<field name="pass_quality_sample"/>
|
||||
<label name="pass_certification"/>
|
||||
<field name="pass_certification"/>
|
||||
</xpath>
|
||||
<xpath expr="/form/notebook" position="inside">
|
||||
<page name="enology_products">
|
||||
<field name="enology_products" colspan="4"/>
|
||||
|
|
|
@ -4,12 +4,26 @@ this repository contains the full copyright notices and license terms. -->
|
|||
<form>
|
||||
<label name="name"/>
|
||||
<field name="name"/>
|
||||
<label name="pass_feature"/>
|
||||
<field name="pass_feature"/>
|
||||
<newline/>
|
||||
<group colspan="2" col="4" id="quantities">
|
||||
<label name="quantity"/>
|
||||
<field name="quantity"/>
|
||||
<label name="uom"/>
|
||||
<field name="uom"/>
|
||||
</group>
|
||||
<group colspan="2" col="2" id="pass_features">
|
||||
<label name="pass_feature"/>
|
||||
<field name="pass_feature"/>
|
||||
<newline/>
|
||||
<label name="pass_quality"/>
|
||||
<field name="pass_quality"/>
|
||||
<newline/>
|
||||
<label name="pass_quality_sample"/>
|
||||
<field name="pass_quality_sample"/>
|
||||
<newline/>
|
||||
<label name="pass_certification"/>
|
||||
<field name="pass_certification"/>
|
||||
</group>
|
||||
<field name="inputs" colspan="2"/>
|
||||
<field name="outputs" colspan="2"/>
|
||||
<field name="enology_products" colspan="4"/>
|
||||
|
|
|
@ -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>
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- The COPYRIGHT file at the top level of this repository contains the full
|
||||
copyright notices and license terms. -->
|
||||
<form>
|
||||
<label name="collection_date"/>
|
||||
<field name="collection_date"/>
|
||||
<label name="code"/>
|
||||
<field name="code"/>
|
||||
<label name="company"/>
|
||||
<field name="company"/>
|
||||
<field name="products" colspan="4"/>
|
||||
</form>
|
|
@ -0,0 +1,8 @@
|
|||
<?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"/>
|
||||
</tree>
|
38
weighing.py
38
weighing.py
|
@ -100,7 +100,11 @@ class Weighing(Workflow, ModelSQL, ModelView):
|
|||
], "State", readonly=True, required=True)
|
||||
state_string = state.translated('state')
|
||||
all_do = fields.Function(fields.Char('All DO'), 'get_all_do')
|
||||
quality_test = fields.Many2One('quality.test', 'Test')
|
||||
quality_test = fields.Function(fields.Many2One('quality.test', 'Test',
|
||||
states={
|
||||
'readonly': Eval('state').in_(['done', 'cancelled']),
|
||||
}),
|
||||
'get_quality_test', 'set_quality_test')
|
||||
product_created = fields.Many2One('product.product', 'Product Created',
|
||||
readonly=True)
|
||||
|
||||
|
@ -157,6 +161,19 @@ class Weighing(Workflow, ModelSQL, ModelView):
|
|||
def get_all_do(self, name):
|
||||
return ",".join([x.name for x in self.denomination_origin])
|
||||
|
||||
def get_quality_test(self, name):
|
||||
if not self.product_created:
|
||||
return
|
||||
tests = self.product_created.quality_tests
|
||||
return tests and tests[0] and tests[0].id
|
||||
|
||||
@classmethod
|
||||
def set_quality_test(cls, weighings, name, value):
|
||||
Test = Pool().get('quality.test')
|
||||
if not value:
|
||||
return
|
||||
|
||||
|
||||
@fields.depends('weighing_date')
|
||||
def on_change_with_crop(self):
|
||||
Crop = Pool().get('agronomics.crop')
|
||||
|
@ -252,19 +269,29 @@ class Weighing(Workflow, ModelSQL, ModelView):
|
|||
def analysis(cls, weighings):
|
||||
pool = Pool()
|
||||
Product = pool.get('product.product')
|
||||
Quality = pool.get('quality.test')
|
||||
Variety = Pool().get('product.variety')
|
||||
default_product_values = Product.default_get(Product._fields.keys(),
|
||||
with_rec_name=False)
|
||||
product = Product(**default_product_values)
|
||||
for weighing in weighings:
|
||||
product.template = weighing.product
|
||||
product.denominations_of_origin = weighing.denomination_origin
|
||||
product.ecologicals = [weighing.ecological]
|
||||
product.varieties = [weighing.variety.id]
|
||||
if weighing.ecological:
|
||||
product.ecologicals = [weighing.ecological]
|
||||
if weighing.variety:
|
||||
new_variety = Variety()
|
||||
new_variety.percent = 100
|
||||
new_variety.variety = weighing.variety
|
||||
product.varieties = [new_variety]
|
||||
product.vintages = [weighing.crop.id]
|
||||
weighing.product_created = product
|
||||
weighing.quality_test = weighing.create_quality_test()
|
||||
|
||||
cls.save(weighings)
|
||||
tests = []
|
||||
for weighing in weighings:
|
||||
tests.append(weighing.create_quality_test())
|
||||
Quality.save(tests)
|
||||
|
||||
def create_quality_test(self):
|
||||
pool = Pool()
|
||||
|
@ -277,7 +304,7 @@ class Weighing(Workflow, ModelSQL, ModelView):
|
|||
test = QualityTest(
|
||||
test_date=datetime.now(),
|
||||
templates=[template],
|
||||
document=str(self))
|
||||
document=str(self.product_created))
|
||||
test.apply_template_values()
|
||||
|
||||
return test
|
||||
|
@ -343,6 +370,7 @@ class Weighing(Workflow, ModelSQL, ModelView):
|
|||
else:
|
||||
default = default.copy()
|
||||
default.setdefault('beneficiaries', None)
|
||||
default.setdefault('product_created', None)
|
||||
return super().copy(weighings, default=default)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue