060224 create fields, searcher and restriction on denomination of origin (#20)

This commit is contained in:
Àngel Àlvarez Serra 2023-03-15 10:48:01 +01:00 committed by Àngel Àlvarez
parent 839b27c316
commit 3b216a627c
7 changed files with 115 additions and 14 deletions

View File

@ -42,8 +42,8 @@ class AgronomicsContract(Workflow, ModelSQL, ModelView):
fields.Date('Start Date'), 'on_change_with_start_date') fields.Date('Start Date'), 'on_change_with_start_date')
end_date = fields.Function( end_date = fields.Function(
fields.Date('End Date'), 'on_change_with_end_date') fields.Date('End Date'), 'on_change_with_end_date')
producer = fields.Many2One( party = fields.Many2One(
'party.party', "Producer", states=_STATES, depends=_DEPENDS, 'party.party', "Party", states=_STATES, depends=_DEPENDS,
required=True) required=True)
price_list_types = fields.One2Many( price_list_types = fields.One2Many(
'agronomics.contract-product.price_list.type-product.price_list', 'agronomics.contract-product.price_list.type-product.price_list',
@ -89,7 +89,7 @@ class AgronomicsContract(Workflow, ModelSQL, ModelView):
return 'draft' return 'draft'
def get_rec_name(self, name): def get_rec_name(self, name):
ret = self.producer.rec_name ret = self.party and self.party.rec_name or ''
if self.start_date: if self.start_date:
ret += ' - %s' % (self.start_date) ret += ' - %s' % (self.start_date)
return ret return ret
@ -153,9 +153,9 @@ class AgronomicsContractLine(ModelSQL, ModelView):
ondelete='CASCADE') ondelete='CASCADE')
parcel = fields.Many2One('agronomics.parcel', "Parcel", parcel = fields.Many2One('agronomics.parcel', "Parcel",
domain=[ domain=[
('producer', '=', Eval('_parent_contract.producer')), ('producer', '=', Eval('_parent_contract.party')),
('crop', '=', Eval('_parent_contract.crop')) ('crop', '=', Eval('_parent_contract.crop'))
], depends=['contract']) ])
product = fields.Function( product = fields.Function(
fields.Many2One('product.template', "Product"), fields.Many2One('product.template', "Product"),
'on_change_with_product') 'on_change_with_product')

View File

@ -48,5 +48,10 @@ this repository contains the full copyright notices and license terms. -->
<record model="ir.message" id="msg_parcel_without_current_crop"> <record model="ir.message" id="msg_parcel_without_current_crop">
<field name="text">The plantation "%(plantation)s" in the weighing "%(weighing)s" has no parcel of the weighing's crop.</field> <field name="text">The plantation "%(plantation)s" in the weighing "%(weighing)s" has no parcel of the weighing's crop.</field>
</record> </record>
<record model="ir.message" id="msg_weighing_with_table_do">
<field name="text">The weighing "%(weighing)s" has the mark "Table" but has selected denomination of origin.</field>
</record>
</data> </data>
</tryton> </tryton>

91
plot.py
View File

@ -1,5 +1,6 @@
# 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.
from sql.aggregate import Min, Sum
from trytond.model import fields, ModelSQL, ModelView from trytond.model import fields, ModelSQL, ModelView
from trytond.pool import Pool from trytond.pool import Pool
@ -68,12 +69,100 @@ class Plantation(ModelSQL, ModelView):
parcels = fields.One2Many('agronomics.parcel', 'plantation', "Parcel") parcels = fields.One2Many('agronomics.parcel', 'plantation', "Parcel")
plantation_year = fields.Integer("Plantation Year") plantation_year = fields.Integer("Plantation Year")
plantation_owner = fields.Many2One('party.party', "Plantation Owner") plantation_owner = fields.Many2One('party.party', "Plantation Owner")
varieties = fields.Function(fields.Char('Varieties'), 'get_varieties',
searcher='search_varieties')
do = fields.Function(fields.Char('DO'), 'get_do', searcher='search_do')
remaining_quantity = fields.Function(
fields.Float("Remainig Quantity", digits=(16, 2)),
'get_remaining_quantity', searcher='search_remaining_quantity')
def get_rec_name(self, name): def get_rec_name(self, name):
if self.code: if self.code:
return self.code return self.code
return self.name return self.name
def get_do(self, name):
do = []
for y in self.parcels:
do += [x.name for x in y.denomination_origin]
return ",".join(list(set(do)))
def get_varieties(self, name):
if not self.parcels:
return []
varieties = [y.variety.name for y in self.parcerls if y.variety]
return ",".join(list(set(varieties)))
def get_remaining_quantity(self, name):
return sum([y.remaining_quantity or 0 for y in self.parcels])
@classmethod
def search_varieties(cls, name, clause):
pool = Pool()
Variety = pool.get('product.taxon')
Parcel = pool.get('agronomics.parcel')
variety = Variety.__table__()
parcel = Parcel.__table__()
Operator = fields.SQL_OPERATORS[clause[1]]
query = parcel.join(variety, condition=parcel.variety == variety.id)
_, operator, value = clause
query = query.select(parcel.plantation)
query.where = Operator(variety.name, value)
return [('id', 'in', query)]
@classmethod
def search_do(cls, name, clause):
pool = Pool()
DO = pool.get('agronomics.denomination_of_origin')
PARCEL_DO = pool.get('agronomics.parcel-agronomics.do')
Parcel = pool.get('agronomics.parcel')
do = DO.__table__()
parcel = Parcel.__table__()
parcel_do = PARCEL_DO.__table__()
Operator = fields.SQL_OPERATORS[clause[1]]
query = parcel.join(parcel_do, condition=parcel.id == parcel_do.parcel)
query = query.join(do, condition=parcel_do.do==parcel_do.do)
print(query)
_, operator, value = clause
query = query.select(parcel.plantation)
query.where = Operator(do.name, value)
return [('id', 'in', query)]
@classmethod
def search_remaining_quantity(cls, name, clause):
pool = Pool()
DO = pool.get('agronomics.denomination_of_origin')
PARCEL_DO = pool.get('agronomics.parcel-agronomics.do')
Parcel = pool.get('agronomics.parcel')
Weighing = pool.get('agronomics.weighing-agronomics.parcel')
MaxProductionAllowed = pool.get('agronomics.max.production.allowed')
do = DO.__table__()
parcel = Parcel.__table__()
parcel_do = PARCEL_DO.__table__()
weighing = Weighing.__table__()
max_production = MaxProductionAllowed.__table__()
_, operator, value = clause
Operator = fields.SQL_OPERATORS[operator]
join1 = weighing.join(parcel, type_='RIGHT',
condition=((weighing.parcel==parcel.id) &
(weighing.table != True)))
join2 = join1.join(parcel_do, type_= 'LEFT',
condition=parcel.id==parcel_do.parcel)
join3 = join2.join(max_production, type_='LEFT',
condition=((max_production.crop == parcel.crop) &
(max_production.variety == parcel.variety)))
query2 = join3.select(parcel.plantation,
Sum(max_production.max_production*parcel.surface -
weighing.netweight).as_('remaining_quantity'),
group_by=parcel.plantation)
query = query2.select(query2.plantation)
query.where = Operator(query2.remaining_quantity, value)
return [('id' , 'in', query)]
class Ecological(ModelSQL, ModelView): class Ecological(ModelSQL, ModelView):
"Ecological" "Ecological"
@ -136,7 +225,7 @@ class Parcel(ModelSQL, ModelView):
)*self.surface, 2) )*self.surface, 2)
def get_purchased_quantity(self, name): def get_purchased_quantity(self, name):
return sum([w.netweight for w in self.weighings if not w.table]) return sum([(w.netweight or 0) for w in self.weighings if not w.table])
def get_remaining_quantity(self, name): def get_remaining_quantity(self, name):
return (self.max_production or 0) - (self.purchased_quantity or 0) return (self.max_production or 0) - (self.purchased_quantity or 0)

View File

@ -5,8 +5,8 @@ this repository contains the full copyright notices and license terms. -->
<label name="reference"/> <label name="reference"/>
<field name="reference"/> <field name="reference"/>
<newline/> <newline/>
<label name="producer"/> <label name="party"/>
<field name="producer"/> <field name="party"/>
<label name="crop"/> <label name="crop"/>
<field name="crop"/> <field name="crop"/>
<label name="start_date"/> <label name="start_date"/>

View File

@ -3,7 +3,7 @@
this repository contains the full copyright notices and license terms. --> this repository contains the full copyright notices and license terms. -->
<tree> <tree>
<field name="reference"/> <field name="reference"/>
<field name="producer"/> <field name="party"/>
<field name="crop"/> <field name="crop"/>
<field name="start_date"/> <field name="start_date"/>
<field name="end_date"/> <field name="end_date"/>

View File

@ -1,6 +1,9 @@
<tree> <tree>
<field name="code"/> <field name="code"/>
<field name="party"/> <field name="party"/>
<field name="varieties"/>
<field name="do"/>
<field name="remaining_quantity"/>
<field name="plantation_year" tree_invisible="1"/> <field name="plantation_year" tree_invisible="1"/>
<field name="plantation_owner" tree_invisible="1"/> <field name="plantation_owner" tree_invisible="1"/>
</tree> </tree>

View File

@ -1,7 +1,7 @@
# 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.
from trytond.model import fields, ModelSQL, ModelView, Workflow, sequence_ordered from trytond.model import fields, ModelSQL, ModelView, Workflow, sequence_ordered
from trytond.pyson import Id, Eval, If from trytond.pyson import Id, Eval, If, Bool
from trytond.pool import Pool from trytond.pool import Pool
from trytond.i18n import gettext from trytond.i18n import gettext
from trytond.exceptions import UserError from trytond.exceptions import UserError
@ -86,7 +86,7 @@ class Weighing(Workflow, ModelSQL, ModelView):
}) })
denomination_origin = fields.Many2Many('agronomics.weighing-agronomics.do', denomination_origin = fields.Many2Many('agronomics.weighing-agronomics.do',
'weighing', 'do', 'Denomination of Origin', states={ 'weighing', 'do', 'Denomination of Origin', states={
'readonly': Eval('state').in_(READONLY2), 'readonly': Eval('state').in_(READONLY2) | Bool(Eval('table')),
'required': Eval('state') == 'in_analysis', 'required': Eval('state') == 'in_analysis',
}) })
beneficiaries_invoices_line = fields.Many2Many( beneficiaries_invoices_line = fields.Many2Many(
@ -269,7 +269,7 @@ class Weighing(Workflow, ModelSQL, ModelView):
return return
contract_lines = ContractLine.search([ contract_lines = ContractLine.search([
('parcel', '=', parcel), ('parcel', '=', parcel),
('contract.producer', '=', producer), ('contract.party', '=', producer),
('contract.state', '=', 'active'), ('contract.state', '=', 'active'),
], limit=1) ], limit=1)
if not contract_lines: if not contract_lines:
@ -398,7 +398,8 @@ class Weighing(Workflow, ModelSQL, ModelView):
cls.analysis(to_analysis) cls.analysis(to_analysis)
def get_not_assigned_weight(self, name): def get_not_assigned_weight(self, name):
return self.netweight - sum([p.netweight for p in self.parcels]) return (self.netweight or 0) - sum([(p.netweight or 0)
for p in self.parcels])
@classmethod @classmethod
@ModelView.button @ModelView.button
@ -536,8 +537,11 @@ class Weighing(Workflow, ModelSQL, ModelView):
if weighing.beneficiaries: if weighing.beneficiaries:
Beneficiary.delete([x for x in weighing.beneficiaries]) Beneficiary.delete([x for x in weighing.beneficiaries])
parcel = weighing.get_parcel() if weighing.table and weighing.denomination_origin:
raise UserError(gettext('agronomics.msg_weighing_with_table_do',
weighing=weighing.rec_name))
parcel = weighing.get_parcel()
# Check if all plantations has a parcel in the weighing's crop # Check if all plantations has a parcel in the weighing's crop
for plantation in weighing.plantations: for plantation in weighing.plantations:
plantation = plantation.plantation plantation = plantation.plantation