060224 create fields, searcher and restriction on denomination of origin (#20)
This commit is contained in:
parent
aa599bb50c
commit
30880201af
10
contract.py
10
contract.py
|
@ -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')
|
||||||
|
|
|
@ -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
91
plot.py
|
@ -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)
|
||||||
|
|
|
@ -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"/>
|
||||||
|
|
|
@ -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"/>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
14
weighing.py
14
weighing.py
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue