diff --git a/__init__.py b/__init__.py
index ee9cb6d..1860311 100644
--- a/__init__.py
+++ b/__init__.py
@@ -38,6 +38,7 @@ def register():
weighing.Weighing,
weighing.WeighingPlantation,
weighing.WeighingDo,
+ weighing.WeighingParcel,
quality.Configuration,
quality.ConfigurationCompany,
quality.ProductQualitySample,
diff --git a/message.xml b/message.xml
index 4f54a39..9256c1b 100644
--- a/message.xml
+++ b/message.xml
@@ -36,6 +36,9 @@ this repository contains the full copyright notices and license terms. -->
The move cannot be done because the amount of the move exceeds the set maximum amount.
+
+ The weighin weight is not distributed and its not being forced to analysis
+
diff --git a/plot.py b/plot.py
index 956c9d1..678f0ad 100644
--- a/plot.py
+++ b/plot.py
@@ -110,6 +110,16 @@ class Parcel(ModelSQL, ModelView):
beneficiaries = fields.One2Many('agronomics.beneficiary', 'parcel',
'Beneficiaries')
all_do = fields.Function(fields.Char('All DO'), 'get_all_do')
+ weighings = fields.One2Many('agronomics.weighing-agronomics.parcel',
+ 'parcel', 'Weighings')
+ bought_quantity = fields.Function(
+ fields.Float("Bought Quantity", digits=(16, 2)), 'get_bought_quantity')
+ remaining_quantity = fields.Function(
+ fields.Float("Remainig Quantity", digits=(16, 2)), 'get_remaining_quantity')
+
+ def get_rec_name(self, name):
+ if self.plantation and self.crop:
+ return self.plantation.code + ' - ' + self.crop.rec_name
@classmethod
def validate(cls, records):
@@ -138,6 +148,12 @@ class Parcel(ModelSQL, ModelView):
return round(float(min([x.max_production for x in max_production])
)*self.surface, 2)
+ def get_bought_quantity(self, name):
+ return sum([w.netweight for w in self.weighings if not w.table])
+
+ def get_remaining_quantity(self, name):
+ return (self.max_production or 0) - (self.bought_quantity or 0)
+
class ParcelDo(ModelSQL):
"Parcel - Denomination Origin"
diff --git a/view/parcel_form.xml b/view/parcel_form.xml
index 5883ba5..ac1ecac 100644
--- a/view/parcel_form.xml
+++ b/view/parcel_form.xml
@@ -25,9 +25,14 @@
+
+
+
+
+
diff --git a/view/parcel_list.xml b/view/parcel_list.xml
index 68f11e0..3b7fcc0 100644
--- a/view/parcel_list.xml
+++ b/view/parcel_list.xml
@@ -10,5 +10,7 @@
+
+
diff --git a/view/weighing_form.xml b/view/weighing_form.xml
index d8f0b87..ed706b7 100644
--- a/view/weighing_form.xml
+++ b/view/weighing_form.xml
@@ -34,6 +34,7 @@
+
@@ -45,7 +46,8 @@
-
+
+
diff --git a/view/weighing_parcel_form.xml b/view/weighing_parcel_form.xml
new file mode 100644
index 0000000..e29d2a7
--- /dev/null
+++ b/view/weighing_parcel_form.xml
@@ -0,0 +1,10 @@
+
diff --git a/view/weighing_parcel_list.xml b/view/weighing_parcel_list.xml
new file mode 100644
index 0000000..254e96a
--- /dev/null
+++ b/view/weighing_parcel_list.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/view/weighing_plantation_list.xml b/view/weighing_plantation_list.xml
new file mode 100644
index 0000000..12f4abd
--- /dev/null
+++ b/view/weighing_plantation_list.xml
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/weighing.py b/weighing.py
index 6e01053..803f305 100644
--- a/weighing.py
+++ b/weighing.py
@@ -1,11 +1,13 @@
# 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 trytond.model import fields, ModelSQL, ModelView, Workflow
+from trytond.model import fields, ModelSQL, ModelView, Workflow, sequence_ordered
from trytond.pyson import Id, Eval, If
from trytond.pool import Pool
from trytond.i18n import gettext
from trytond.exceptions import UserError
from trytond.transaction import Transaction
+from trytond.wizard import (Wizard, StateView, StateTransition, StateAction,
+ Button)
from datetime import datetime
class WeighingCenter(ModelSQL, ModelView):
@@ -19,8 +21,8 @@ class WeighingCenter(ModelSQL, ModelView):
])
-READONLY = ['processing', 'in_analysis', 'done', 'cancelled']
-READONLY2 = ['draft', 'in_analysis', 'done', 'cancelled']
+READONLY = ['processing', 'distributed', 'in_analysis', 'done', 'cancelled']
+READONLY2 = ['draft', 'distributed', 'in_analysis', 'done', 'cancelled']
class Weighing(Workflow, ModelSQL, ModelView):
""" Weighing """
@@ -86,14 +88,15 @@ class Weighing(Workflow, ModelSQL, ModelView):
'readonly': Eval('state').in_(READONLY2),
'required': Eval('state') == 'in_analysis',
})
- plantations = fields.Many2Many('agronomics.weighing-agronomics.plantation',
- 'weighing', 'plantation', 'plantations', states={
+ plantations = fields.One2Many('agronomics.weighing-agronomics.plantation',
+ 'weighing', 'plantations', states={
'readonly': Eval('state').in_(READONLY),
'required': Eval('state') == 'process',
}, size=4)
state = fields.Selection([
('draft', "Draft"),
('processing', "Processing"),
+ ('distributed', "Distributed"),
('in_analysis', "In Analysis"),
('done', "Done"),
('cancelled', "Cancelled"),
@@ -107,6 +110,11 @@ class Weighing(Workflow, ModelSQL, ModelView):
'get_quality_test', 'set_quality_test')
product_created = fields.Many2One('product.product', 'Product Created',
readonly=True)
+ parcels = fields.One2Many('agronomics.weighing-agronomics.parcel',
+ 'weighing', 'Parcels', readonly=True)
+ not_assigned_weight = fields.Function(
+ fields.Float('Not Assigned Weight'), 'get_not_assigned_weight')
+ forced_analysis = fields.Boolean('Forced Analysis')
@classmethod
def __setup__(cls):
@@ -118,6 +126,9 @@ class Weighing(Workflow, ModelSQL, ModelView):
cls._transitions |= set((
('draft', 'processing'),
('processing', 'draft'),
+ ('processing', 'distributed'),
+ ('distributed', 'in_analysis'),
+ ('distributed', 'draft'),
('processing', 'in_analysis'),
('draft', 'cancelled'),
('processing', 'cancelled'),
@@ -133,7 +144,7 @@ class Weighing(Workflow, ModelSQL, ModelView):
'depends': ['state'],
},
'draft': {
- 'invisible': ~Eval('state').in_(['processing']),
+ 'invisible': ~Eval('state').in_(['processing', 'distributed']),
'icon': If(Eval('state') == 'cancelled',
'tryton-undo',
'tryton-back'),
@@ -143,10 +154,14 @@ class Weighing(Workflow, ModelSQL, ModelView):
'invisible': Eval('state') != 'draft',
'depends': ['state'],
},
- 'analysis': {
+ 'distribute': {
'invisible': Eval('state') != 'processing',
'depends': ['state'],
},
+ 'force_analysis': {
+ 'invisible': Eval('state') != 'distributed',
+ 'depends': ['state'],
+ },
})
@staticmethod
@@ -173,7 +188,6 @@ class Weighing(Workflow, ModelSQL, ModelView):
if not value:
return
-
@fields.depends('weighing_date')
def on_change_with_crop(self):
Crop = Pool().get('agronomics.crop')
@@ -186,8 +200,8 @@ class Weighing(Workflow, ModelSQL, ModelView):
def get_parcel(self):
if not self.plantations:
return
- plantation = self.plantations[0]
- if not plantation.parcels:
+ plantation = self.plantations[0].plantation
+ if not plantation or not plantation.parcels:
return
return plantation.parcels[0]
@@ -202,7 +216,7 @@ class Weighing(Workflow, ModelSQL, ModelView):
def on_change_with_denomination_origin(self):
parcel = self.get_parcel()
if not parcel:
- return
+ return []
return [x.id for x in parcel.denomination_origin]
@@ -262,7 +276,7 @@ class Weighing(Workflow, ModelSQL, ModelView):
if record.beneficiaries and abs(100 - round(percent, 2)) > 0.0001:
raise UserError(gettext('agronomics.msg_beneficiaris_percent',
crop=record.crop.rec_name,
- plantation=record.plantations[0].rec_name))
+ plantation=record.plantations[0].plantation.rec_name))
@classmethod
@Workflow.transition('in_analysis')
@@ -275,6 +289,8 @@ class Weighing(Workflow, ModelSQL, ModelView):
with_rec_name=False)
product = Product(**default_product_values)
for weighing in weighings:
+ if weighing.not_assigned_weight and not weighing.forced_analysis:
+ raise UserError(gettext('agronomics.msg_not_assigned_weight'))
product.template = weighing.product
product.denominations_of_origin = weighing.denomination_origin
if weighing.ecological:
@@ -293,6 +309,75 @@ class Weighing(Workflow, ModelSQL, ModelView):
tests.append(weighing.create_quality_test())
Quality.save(tests)
+ @classmethod
+ @ModelView.button
+ @Workflow.transition('distributed')
+ def distribute(cls, weighings):
+ pool = Pool()
+ WeighingParcel = pool.get('agronomics.weighing-agronomics.parcel')
+ weighing_parcel_to_save = []
+ to_analysis = []
+ for weighing in weighings:
+ if not weighing.table:
+ if weighing.parcels:
+ WeighingParcel.delete(weighing.parcels)
+ allowed_parcels = []
+ remaining_weight = weighing.netweight
+ for wp in weighing.plantations:
+ plantation = wp.plantation
+ if plantation:
+ for parcel in plantation.parcels:
+ if parcel.crop == weighing.crop:
+ allowed_parcels.append(parcel)
+ break
+ for parcel in allowed_parcels:
+ if not remaining_weight:
+ break
+ weighing_parcel = WeighingParcel()
+ weighing_parcel.parcel = parcel
+ weighing_parcel.weighing = weighing
+ if parcel.remaining_quantity - remaining_weight >= 0:
+ weighing_parcel.netweight = remaining_weight
+ remaining_weight = 0
+ else:
+ remaining_weight -= parcel.remaining_quantity
+ weighing_parcel.netweight = parcel.remaining_quantity
+ if weighing_parcel.netweight:
+ weighing_parcel_to_save.append(weighing_parcel)
+ if remaining_weight == 0:
+ to_analysis.append(weighing)
+ else:
+ parcel = weighing.get_parcel()
+ weighing_parcel = WeighingParcel()
+ weighing_parcel.parcel = parcel
+ weighing_parcel.weighing = weighing
+ weighing_parcel.netweight = weighing.netweight
+ weighing_parcel.table = True
+ weighing_parcel_to_save.append(weighing_parcel)
+ to_analysis.append(weighing)
+ WeighingParcel.save(weighing_parcel_to_save)
+ cls.save(weighings)
+ cls.analysis(to_analysis)
+
+ def get_not_assigned_weight(self, name):
+ return self.netweight - sum([p.netweight for p in self.parcels])
+
+ @classmethod
+ @ModelView.button
+ def force_analysis(cls, weighings):
+ to_copy_values = {}
+ for weighing in weighings:
+ to_copy_values[weighing.id] = {'netweight': weighing.not_assigned_weight}
+ cls.copy(weighings, default={
+ 'netweight': lambda d: (
+ to_copy_values[d['id']]['netweight']),
+ })
+ for weighing in weighings:
+ weighing.forced_analysis = True
+ weighing.netweight -= weighing.not_assigned_weight
+ cls.save(weighings)
+ cls.analysis(weighings)
+
def create_quality_test(self):
pool = Pool()
QualityTest = pool.get('quality.test')
@@ -371,6 +456,8 @@ class Weighing(Workflow, ModelSQL, ModelView):
default = default.copy()
default.setdefault('beneficiaries', None)
default.setdefault('product_created', None)
+ default.setdefault('number', None)
+ default.setdefault('parcels', None)
return super().copy(weighings, default=default)
@@ -383,10 +470,26 @@ class WeighingDo(ModelSQL):
'Denomination Origin')
-class WeighingPlantation(ModelSQL):
+class WeighingPlantation(sequence_ordered(), ModelSQL, ModelView):
'Weighing - Plantations'
__name__ = 'agronomics.weighing-agronomics.plantation'
weighing = fields.Many2One('agronomics.weighing', 'Weighing')
plantation = fields.Many2One('agronomics.plantation',
'Plantation')
+ party = fields.Function(fields.Many2One('party.party', 'Party'), 'get_party')
+
+ def get_party(self, name):
+ if self.plantation:
+ return self.plantation.party.id
+
+
+class WeighingParcel(ModelSQL, ModelView):
+ "Wheighing-Parcel"
+ __name__ = 'agronomics.weighing-agronomics.parcel'
+
+ weighing = fields.Many2One('agronomics.weighing', 'Weighing',
+ ondelete='CASCADE')
+ parcel = fields.Many2One('agronomics.parcel', 'Parcel')
+ netweight = fields.Float('Net Weight')
+ table = fields.Boolean('Table')
diff --git a/weighning.xml b/weighning.xml
index 840b6ca..66f0932 100644
--- a/weighning.xml
+++ b/weighning.xml
@@ -168,11 +168,6 @@
-
- analysis
- Analysis
-
-
@@ -198,5 +193,42 @@
+
+ distribute
+ Analysis
+
+
+
+
+
+
+
+
+ force_analysis
+ Force Analysis
+
+
+
+
+
+
+
+
+ agronomics.weighing-agronomics.parcel
+ form
+ weighing_parcel_form
+
+
+ agronomics.weighing-agronomics.parcel
+ tree
+ weighing_parcel_list
+
+
+
+ agronomics.weighing-agronomics.plantation
+ tree
+ weighing_plantation_list
+
+