2021-11-02 18:25:11 +01:00
|
|
|
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
|
|
|
# this repository contains the full copyright notices and license terms.
|
2022-11-01 21:16:44 +01:00
|
|
|
#from calendar import different_locale, month, week, monthrange
|
|
|
|
from calendar import monthrange
|
2021-11-02 18:25:11 +01:00
|
|
|
from decimal import Decimal
|
2022-08-22 23:18:51 +02:00
|
|
|
from datetime import date, datetime, timedelta
|
2022-09-02 22:15:15 +02:00
|
|
|
from itertools import product
|
2022-08-22 23:18:51 +02:00
|
|
|
import copy
|
2021-11-02 18:25:11 +01:00
|
|
|
from trytond.model import Workflow, ModelView, ModelSQL, fields
|
2022-09-02 22:15:15 +02:00
|
|
|
from trytond.pyson import Eval, If, Bool, In, Get
|
2021-11-02 18:25:11 +01:00
|
|
|
from trytond.transaction import Transaction
|
|
|
|
from trytond.pool import Pool
|
|
|
|
from trytond.exceptions import UserError
|
2022-08-16 06:50:49 +02:00
|
|
|
from trytond.report import Report
|
|
|
|
from trytond.wizard import (Wizard, StateReport, StateView,
|
|
|
|
Button, StateTransition)
|
2022-10-22 19:05:32 +02:00
|
|
|
from pprint import pprint
|
2021-11-02 18:25:11 +01:00
|
|
|
|
|
|
|
STATES = {
|
|
|
|
'readonly': (Eval('state') != 'draft'),
|
|
|
|
}
|
2022-08-22 23:18:51 +02:00
|
|
|
MAX_WEEKS = 14
|
2021-11-02 18:25:11 +01:00
|
|
|
|
2022-08-19 05:05:25 +02:00
|
|
|
class FarmingStage(ModelSQL, ModelView):
|
|
|
|
"Farming Stage"
|
|
|
|
__name__ = "farming.stage"
|
|
|
|
name = fields.Char('Name', required=True)
|
|
|
|
|
|
|
|
|
|
|
|
class FarmingVarietyCycle(ModelSQL, ModelView):
|
|
|
|
"Farming Variety Cycle"
|
|
|
|
__name__ = "farming.variety.cycle"
|
|
|
|
variety = fields.Many2One('farming.variety', 'Variety', required=True)
|
2022-08-19 16:59:05 +02:00
|
|
|
sequence = fields.Integer('Sequence', required=True)
|
2022-08-19 05:05:25 +02:00
|
|
|
stage = fields.Many2One('farming.stage', 'Stage', required=True)
|
2022-08-19 19:10:12 +02:00
|
|
|
start_time = fields.Integer('Start Time', help='Harvest week',
|
|
|
|
required=True)
|
2022-08-19 05:05:25 +02:00
|
|
|
production_rate = fields.Float('Production Rate', digits=(3, 2))
|
|
|
|
|
|
|
|
|
2022-08-16 06:50:49 +02:00
|
|
|
class FarmingVariety(ModelSQL, ModelView):
|
|
|
|
'Farming Variety'
|
|
|
|
__name__ = 'farming.variety'
|
|
|
|
product = fields.Many2One('product.product', 'Product', required=True)
|
2022-08-22 23:18:51 +02:00
|
|
|
production_rate = fields.Float('Production Rate', digits=(16, 2))
|
|
|
|
production_uom = fields.Many2One('product.uom', 'Uom')
|
2022-08-19 05:05:25 +02:00
|
|
|
standard_cycle = fields.Integer('Standard Cycle', help='In weeks')
|
2022-08-16 06:50:49 +02:00
|
|
|
activities = fields.One2Many('farming.variety.activity', 'variety',
|
|
|
|
'Activities')
|
2022-11-01 21:16:44 +01:00
|
|
|
location = fields.Many2One('farming.location', 'Location')
|
2022-08-19 05:05:25 +02:00
|
|
|
cycles = fields.One2Many('farming.variety.cycle', 'variety', 'Cycles')
|
2022-08-16 06:50:49 +02:00
|
|
|
|
|
|
|
def get_rec_name(self, name=None):
|
2022-11-01 21:16:44 +01:00
|
|
|
return self.product.template.name + '\u2014' +self.location.name
|
2022-08-16 06:50:49 +02:00
|
|
|
|
|
|
|
|
2022-09-02 22:15:15 +02:00
|
|
|
class FarmingActivitySupply(ModelSQL, ModelView):
|
|
|
|
'Farming Activity Supply'
|
|
|
|
__name__ = 'farming.variety.activity.supply'
|
|
|
|
activity = fields.Many2One('farming.variety.activity', 'Activity')
|
|
|
|
product = fields.Many2One("product.product", "Product", required=True,
|
|
|
|
select=True)
|
|
|
|
quantity = fields.Float('Quantity', required=True)
|
2022-10-22 19:05:32 +02:00
|
|
|
unit = fields.Many2One('product.uom', 'Unit',
|
|
|
|
domain=[
|
|
|
|
If(Bool(Eval('product_uom_category')),
|
|
|
|
('category', '=', Eval('product_uom_category')),
|
|
|
|
('category', '!=', -1)),
|
|
|
|
],
|
|
|
|
depends=['product_uom_category'])
|
|
|
|
|
|
|
|
product_uom_category = fields.Function(
|
|
|
|
fields.Many2One('product.uom.category', 'Product Uom Category'),
|
|
|
|
'on_change_with_product_uom_category')
|
2022-09-02 22:15:15 +02:00
|
|
|
|
2022-09-24 16:49:22 +02:00
|
|
|
@fields.depends('product')
|
2022-10-22 19:05:32 +02:00
|
|
|
def on_change_with_unit(self, name=None):
|
|
|
|
if self.product:
|
|
|
|
unit = self.product.default_uom.id
|
|
|
|
return unit
|
2022-09-02 22:15:15 +02:00
|
|
|
|
2022-10-22 19:05:32 +02:00
|
|
|
@fields.depends('product')
|
|
|
|
def on_change_with_product_uom_category(self, name=None):
|
|
|
|
if self.product:
|
|
|
|
return self.product.default_uom_category.id
|
|
|
|
else:
|
|
|
|
return None
|
2022-09-02 22:15:15 +02:00
|
|
|
|
2022-08-16 06:50:49 +02:00
|
|
|
class FarmingVarietyActivity(ModelSQL, ModelView):
|
|
|
|
'Farming Variety Activity'
|
|
|
|
__name__ = 'farming.variety.activity'
|
|
|
|
variety = fields.Many2One('farming.variety', 'Variety', required=True)
|
2022-09-02 22:15:15 +02:00
|
|
|
sequence = fields.Integer('Sequence', required=True )
|
2022-08-16 06:50:49 +02:00
|
|
|
kind = fields.Many2One('farming.activity.kind', 'Kind', required=True)
|
2022-09-02 22:15:15 +02:00
|
|
|
work_time = fields.Numeric('Work Time')
|
2022-09-24 16:49:22 +02:00
|
|
|
price_per_hour = fields.Numeric('Price Per Hour', digits=(16, 2))
|
|
|
|
uom = fields.Many2One('product.uom', 'Unit')
|
2022-09-02 22:15:15 +02:00
|
|
|
supplies = fields.One2Many('farming.variety.activity.supply', 'activity', 'Supply')
|
2022-08-16 06:50:49 +02:00
|
|
|
time_of_realization = fields.Integer('Time Of Realization', required=True,
|
|
|
|
help='In weeks')
|
|
|
|
|
|
|
|
|
2022-08-19 16:59:05 +02:00
|
|
|
class CropStage(ModelSQL, ModelView):
|
|
|
|
"Crop Stage"
|
2022-10-22 19:05:32 +02:00
|
|
|
__name__ = "farming.crop.stage"
|
2022-08-19 16:59:05 +02:00
|
|
|
crop = fields.Many2One('farming.crop', 'Crop', required=True)
|
2022-10-22 19:05:32 +02:00
|
|
|
activity = fields.Many2One('farming.crop.activity', 'Activity', states={"invisible":False})
|
2022-08-19 16:59:05 +02:00
|
|
|
stage = fields.Many2One('farming.stage', 'Stage', required=True)
|
2022-10-22 19:05:32 +02:00
|
|
|
# activity_time = fields.Float('Act. Time', required=True)
|
|
|
|
week = fields.Float('Week', required=True)
|
|
|
|
effective_date = fields.Date('Effective Date')
|
|
|
|
analytic_account = fields.Many2One('analytic_account.account', 'Analytic Account')
|
|
|
|
activities = fields.One2Many('farming.crop.activity', 'stage', 'Activity')
|
2022-08-22 23:18:51 +02:00
|
|
|
production_rate = fields.Float('Production Rate', digits=(3, 2))
|
2022-08-19 16:59:05 +02:00
|
|
|
|
|
|
|
|
2021-11-02 18:25:11 +01:00
|
|
|
class Kind(ModelSQL, ModelView):
|
|
|
|
"Kind"
|
|
|
|
__name__ = "farming.activity.kind"
|
|
|
|
name = fields.Char('Name', required=True)
|
|
|
|
activity_time = fields.Float('Act. Time', required=True)
|
|
|
|
|
|
|
|
|
2022-08-16 06:50:49 +02:00
|
|
|
class FarmingCrop(Workflow, ModelSQL, ModelView):
|
|
|
|
'Farming Crop'
|
|
|
|
__name__ = 'farming.crop'
|
2021-11-02 18:25:11 +01:00
|
|
|
_rec_name = 'number'
|
|
|
|
number = fields.Char('Number', readonly=True)
|
2022-08-16 06:50:49 +02:00
|
|
|
variety = fields.Many2One('farming.variety', 'Variety', required=True,
|
2021-11-02 18:25:11 +01:00
|
|
|
states=STATES)
|
|
|
|
location = fields.Many2One('farming.location', 'Location', required=True,
|
|
|
|
states=STATES)
|
|
|
|
company = fields.Many2One('company.company', 'Company', required=True,
|
|
|
|
states=STATES, domain=[('id', If(In('company',
|
|
|
|
Eval('context', {})), '=', '!='), Get(Eval('context', {}),
|
|
|
|
'company', 0)), ])
|
|
|
|
start_date = fields.Date('Start Date', states=STATES, depends=['state'])
|
|
|
|
end_date = fields.Date('End Date', states=STATES, depends=['state'])
|
|
|
|
field_size = fields.Float('Field Size', states=STATES, select=True, help='In hectares')
|
2022-09-24 16:49:22 +02:00
|
|
|
total_plants = fields.Integer('Total Plants')
|
2022-08-19 05:05:25 +02:00
|
|
|
quantity_produced_planned = fields.Function(fields.Float('Quantity Produced'),
|
|
|
|
'get_quantity_produced_planned')
|
2021-11-02 18:25:11 +01:00
|
|
|
quantity_produced = fields.Float('Quantity Produced', states=STATES)
|
2022-08-22 23:18:51 +02:00
|
|
|
production_uom = fields.Many2One('product.uom', 'Production UoM', states=STATES)
|
2022-08-19 16:59:05 +02:00
|
|
|
lots = fields.One2Many('farming.crop.lot', 'crop', 'Lots', states=STATES)
|
|
|
|
stages = fields.One2Many('farming.crop.stage', 'crop', 'Stages',
|
2022-06-30 04:08:43 +02:00
|
|
|
states=STATES)
|
2022-09-24 16:49:22 +02:00
|
|
|
activities = fields.One2Many('farming.crop.activity', 'crop', 'Activities')
|
2022-08-19 05:05:25 +02:00
|
|
|
seed = fields.Many2One('farming.seed', 'Seed', required=True)
|
2022-10-22 19:05:32 +02:00
|
|
|
analytic_account = fields.Many2One('analytic_account.account', 'Analytic Account')
|
2022-08-22 23:18:51 +02:00
|
|
|
production_rate = fields.Float('Production Rate')
|
2021-11-02 18:25:11 +01:00
|
|
|
notes = fields.Text('Notes', states=STATES)
|
|
|
|
state = fields.Selection([
|
|
|
|
('draft', 'Draft'),
|
|
|
|
('production', 'Production'),
|
|
|
|
('finished', 'Finished'),
|
|
|
|
('cancelled', 'Cancelled'),
|
|
|
|
], 'State', readonly=True, required=True)
|
2022-09-27 22:42:52 +02:00
|
|
|
#moves for supplies
|
2022-10-22 19:05:32 +02:00
|
|
|
supplies = fields.One2Many('farming.crop.activity.supply', 'crop', 'Supply')
|
2021-11-02 18:25:11 +01:00
|
|
|
# Financial indicators
|
|
|
|
production_time = fields.Function(fields.Integer('Production Time'),
|
|
|
|
'get_production_time')
|
|
|
|
production_cost = fields.Function(fields.Numeric('Production Cost'),
|
|
|
|
'get_production_cost')
|
|
|
|
performance = fields.Function(fields.Numeric('Performance'),
|
|
|
|
'get_performance')
|
|
|
|
gross_profit_rate = fields.Function(fields.Float('Gross Profit Rate'),
|
|
|
|
'get_gross_profit_rate')
|
|
|
|
gross_profit = fields.Function(fields.Numeric('Gross Profit'),
|
|
|
|
'get_gross_profit')
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def __setup__(cls):
|
2022-08-16 06:50:49 +02:00
|
|
|
super(FarmingCrop, cls).__setup__()
|
2021-11-02 18:25:11 +01:00
|
|
|
cls._order.insert(0, ('create_date', 'DESC'))
|
|
|
|
cls._order.insert(1, ('id', 'DESC'))
|
|
|
|
cls._transitions |= set((
|
|
|
|
('draft', 'production'),
|
|
|
|
('production', 'draft'),
|
|
|
|
('production', 'finished'),
|
|
|
|
('production', 'cancelled'),
|
|
|
|
))
|
|
|
|
cls._buttons.update({
|
|
|
|
'draft': {
|
|
|
|
'invisible': Eval('state').in_(['draft', 'finished'])
|
|
|
|
},
|
|
|
|
'cancel': {
|
|
|
|
'invisible': Eval('state') == 'finished',
|
|
|
|
},
|
2022-09-02 22:15:15 +02:00
|
|
|
'load_configuration': {
|
|
|
|
'invisible': (Eval('lines', [])
|
|
|
|
| (Eval('state') != 'draft')),
|
|
|
|
'depends': ['state'],
|
|
|
|
},
|
2022-11-01 21:16:44 +01:00
|
|
|
'load_location': {
|
|
|
|
'invisible': (Eval('lines', [])
|
|
|
|
| (Eval('state') != 'draft')),
|
|
|
|
'depends': ['state'],
|
|
|
|
},
|
2021-11-02 18:25:11 +01:00
|
|
|
'production': {
|
|
|
|
'invisible': Eval('state').in_(['cancelled', 'finished']),
|
|
|
|
},
|
|
|
|
'finished': {
|
|
|
|
'invisible': Eval('state') != 'production',
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
2022-09-02 22:15:15 +02:00
|
|
|
@staticmethod
|
|
|
|
def default_start_date():
|
|
|
|
return date.today()
|
|
|
|
|
2021-11-02 18:25:11 +01:00
|
|
|
@staticmethod
|
|
|
|
def default_company():
|
|
|
|
return Transaction().context.get('company') or False
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def default_state():
|
|
|
|
return 'draft'
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
@ModelView.button
|
|
|
|
@Workflow.transition('finished')
|
|
|
|
def finished(cls, records):
|
|
|
|
pass
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
@ModelView.button
|
|
|
|
@Workflow.transition('cancelled')
|
|
|
|
def cancel(cls, services):
|
|
|
|
pass
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
@ModelView.button
|
|
|
|
@Workflow.transition('draft')
|
|
|
|
def draft(cls, records):
|
|
|
|
pass
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
@ModelView.button
|
|
|
|
@Workflow.transition('production')
|
|
|
|
def production(cls, records):
|
|
|
|
for record in records:
|
|
|
|
record.set_number()
|
|
|
|
|
2022-09-02 22:15:15 +02:00
|
|
|
@classmethod
|
|
|
|
def clear_bed_lines(cls, crops):
|
|
|
|
Line = Pool().get('farming.crop.lot.bed')
|
|
|
|
lines_to_delete = []
|
|
|
|
for crop in crops:
|
|
|
|
for lot in crop.lots:
|
|
|
|
for bed in lot.beds:
|
|
|
|
lines_to_delete.append(bed)
|
|
|
|
Line.delete(lines_to_delete)
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def create_beds_lines(cls, crops):
|
|
|
|
Line = Pool().get('farming.crop.lot.bed')
|
|
|
|
lines = []
|
|
|
|
for crop in crops:
|
|
|
|
for lot in crop.lots:
|
|
|
|
for bed in lot.lot.beds:
|
|
|
|
line = Line(
|
|
|
|
lot = lot.id,
|
|
|
|
bed = bed.id,
|
|
|
|
quantity_plants = bed.quantity,
|
|
|
|
unit = 20,
|
|
|
|
production_rate = 10,
|
|
|
|
)
|
|
|
|
lines.append(line)
|
|
|
|
Line.save(lines)
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def create_lots_lines(cls, crops):
|
|
|
|
Line = Pool().get('farming.crop.lot')
|
|
|
|
lines = []
|
|
|
|
cls.clear_bed_lines(crops)
|
|
|
|
cls.clear_lots_lines(crops)
|
|
|
|
for crop in crops:
|
|
|
|
for lot in crop.location.lots:
|
|
|
|
line = Line(
|
|
|
|
crop = crop.id,
|
|
|
|
lot = lot.id,
|
|
|
|
cycle = 0,
|
|
|
|
beds = [],
|
|
|
|
activities = [],
|
|
|
|
total_plants = lot.quantity
|
|
|
|
)
|
|
|
|
lines.append(line)
|
|
|
|
Line.save(lines)
|
|
|
|
cls.create_beds_lines(crops)
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def clear_lots_lines(cls, crops):
|
|
|
|
Line = Pool().get('farming.crop.lot')
|
|
|
|
lines_to_delete = []
|
|
|
|
for crop in crops:
|
|
|
|
for lot in crop.lots:
|
|
|
|
lines_to_delete.append(lot)
|
|
|
|
Line.delete(lines_to_delete)
|
|
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def create_stages_lines(cls, crops):
|
|
|
|
Line = Pool().get('farming.crop.stage')
|
|
|
|
lines = []
|
|
|
|
cls.clear_stages_lines(crops)
|
|
|
|
for crop in crops:
|
|
|
|
for stage in crop.variety.cycles:
|
|
|
|
line = Line(
|
|
|
|
crop = crop.id,
|
|
|
|
stage = stage.stage.id,
|
2022-10-22 19:05:32 +02:00
|
|
|
production_rate = stage.production_rate,
|
|
|
|
week = stage.start_time,
|
|
|
|
effective_date = date.today() + timedelta(weeks = stage.start_time),
|
2022-09-02 22:15:15 +02:00
|
|
|
)
|
|
|
|
lines.append(line)
|
|
|
|
Line.save(lines)
|
2022-09-24 16:49:22 +02:00
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def clear_stages_lines(cls, crops):
|
|
|
|
Line = Pool().get('farming.crop.stage')
|
|
|
|
lines_to_delete = []
|
|
|
|
for crop in crops:
|
|
|
|
for stage in crop.stages:
|
|
|
|
lines_to_delete.append(stage)
|
|
|
|
Line.delete(lines_to_delete)
|
2022-09-02 22:15:15 +02:00
|
|
|
|
2022-11-01 21:16:44 +01:00
|
|
|
@classmethod
|
|
|
|
def clear_activities_lines(cls, crops):
|
|
|
|
Line = Pool().get('farming.crop.activity')
|
|
|
|
lines_to_delete = []
|
|
|
|
for crop in crops:
|
|
|
|
for activity in crop.activities:
|
|
|
|
lines_to_delete.append(activity)
|
|
|
|
Line.delete(lines_to_delete)
|
|
|
|
|
|
|
|
|
2022-09-02 22:15:15 +02:00
|
|
|
@classmethod
|
|
|
|
def create_activities_lines(cls, crops):
|
2022-09-24 16:49:22 +02:00
|
|
|
Line = Pool().get('farming.crop.activity')
|
2022-09-02 22:15:15 +02:00
|
|
|
lines = []
|
2022-09-24 16:49:22 +02:00
|
|
|
#cls.clear_activities_lines(crops)
|
2022-09-02 22:15:15 +02:00
|
|
|
for crop in crops:
|
2022-09-24 16:49:22 +02:00
|
|
|
for activity in crop.variety.activities:
|
2022-09-02 22:15:15 +02:00
|
|
|
line = Line(
|
|
|
|
crop = crop.id,
|
2022-09-24 16:49:22 +02:00
|
|
|
sequence = activity.sequence,
|
|
|
|
kind = activity.kind.id,
|
2022-11-01 21:16:44 +01:00
|
|
|
work_time = activity.work_time * crop.total_plants,
|
2022-10-22 19:05:32 +02:00
|
|
|
workforce_price = 0,
|
|
|
|
uom = None,
|
2022-11-01 21:16:44 +01:00
|
|
|
week = activity.time_of_realization,
|
2022-10-22 19:05:32 +02:00
|
|
|
planned_date = date.today() + timedelta(weeks = activity.time_of_realization),
|
|
|
|
effective_date = date.today() + timedelta(weeks = activity.time_of_realization),
|
2022-09-02 22:15:15 +02:00
|
|
|
)
|
|
|
|
lines.append(line)
|
|
|
|
Line.save(lines)
|
2022-10-22 19:05:32 +02:00
|
|
|
cls.create_activity_supplies_lines(crops)
|
2022-11-01 21:16:44 +01:00
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def clear_activities_lines(cls, crops):
|
|
|
|
Line = Pool().get('farming.crop.activity')
|
|
|
|
lines_to_delete = []
|
|
|
|
for crop in crops:
|
|
|
|
for activity in crop.activities:
|
|
|
|
lines_to_delete.append(activity)
|
|
|
|
Line.delete(lines_to_delete)
|
2022-09-02 22:15:15 +02:00
|
|
|
|
2022-09-24 16:49:22 +02:00
|
|
|
@classmethod
|
|
|
|
def create_activity_supplies_lines(cls, crops):
|
|
|
|
Line = Pool().get('farming.crop.activity.supply')
|
|
|
|
lines = []
|
|
|
|
#cls.clear_activities_lines(crops)
|
|
|
|
for crop in crops:
|
|
|
|
for activity_crop, activity_variety in zip(crop.activities, crop.variety.activities):
|
|
|
|
for supply in activity_variety.supplies:
|
|
|
|
line = Line(
|
|
|
|
activity = activity_crop.id,
|
|
|
|
product = supply.product.id,
|
2022-10-22 19:05:32 +02:00
|
|
|
unit = supply.unit,
|
2022-11-01 21:16:44 +01:00
|
|
|
quantity = supply.quantity * crop.total_plants,
|
2022-09-24 16:49:22 +02:00
|
|
|
cost_planned = supply.product.cost_price,
|
|
|
|
cost_real = supply.product.cost_price
|
|
|
|
)
|
|
|
|
lines.append(line)
|
|
|
|
Line.save(lines)
|
2022-11-01 21:16:44 +01:00
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def clear_supplies_lines(cls, crops):
|
|
|
|
Line = Pool().get('farming.crop.lot.bed')
|
|
|
|
lines_to_delete = []
|
|
|
|
for crop in crops:
|
|
|
|
for activity in crop.activities:
|
|
|
|
for supply in activity.supplies:
|
|
|
|
lines_to_delete.append(supply)
|
|
|
|
Line.delete(lines_to_delete)
|
2022-09-02 22:15:15 +02:00
|
|
|
|
|
|
|
@classmethod
|
2022-09-24 16:49:22 +02:00
|
|
|
def get_total_plants(cls, crops):
|
|
|
|
Line = Pool().get('farming.crop')
|
|
|
|
lines = []
|
2022-09-02 22:15:15 +02:00
|
|
|
for crop in crops:
|
2022-09-24 16:49:22 +02:00
|
|
|
quantity = 0
|
|
|
|
for lot in crop.lots:
|
|
|
|
quantity += lot.total_plants
|
|
|
|
crop.total_plants = quantity
|
|
|
|
lines.append(crop)
|
|
|
|
Line.save(lines)
|
2022-09-02 22:15:15 +02:00
|
|
|
|
|
|
|
@classmethod
|
|
|
|
@ModelView.button
|
|
|
|
def load_configuration(cls, crops):
|
|
|
|
cls.clear_stages_lines(crops)
|
2022-11-01 21:16:44 +01:00
|
|
|
cls.create_stages_lines(crops)
|
|
|
|
cls.clear_supplies_lines(crops)
|
|
|
|
cls.clear_activities_lines(crops)
|
|
|
|
cls.create_activities_lines(crops)
|
|
|
|
#cls.suppliesShipment(crops)
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
@ModelView.button
|
|
|
|
def load_location(cls, crops):
|
2022-09-02 22:15:15 +02:00
|
|
|
cls.clear_bed_lines(crops)
|
|
|
|
cls.clear_lots_lines(crops)
|
|
|
|
cls.create_lots_lines(crops)
|
2022-09-24 16:49:22 +02:00
|
|
|
cls.get_total_plants(crops)
|
2022-11-01 21:16:44 +01:00
|
|
|
|
|
|
|
|
2022-09-27 22:42:52 +02:00
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def suppliesShipment(cls, records):
|
|
|
|
pool = Pool()
|
|
|
|
SupplyMoves = pool.get('crop.supply.moves')
|
|
|
|
supplyMoves = []
|
|
|
|
for record in records:
|
|
|
|
for activity in record.activities:
|
|
|
|
for supply in activity.supplies:
|
|
|
|
supplyMove = SupplyMoves(
|
|
|
|
crop = record.id,
|
|
|
|
product = supply.product,
|
|
|
|
unit = supply.unit,
|
|
|
|
quantity = supply.quantity,
|
|
|
|
)
|
|
|
|
supplyMoves.append(supplyMove)
|
|
|
|
SupplyMoves.save(supplyMoves)
|
2022-09-02 22:15:15 +02:00
|
|
|
|
2021-11-02 18:25:11 +01:00
|
|
|
def set_number(self):
|
|
|
|
Config = Pool().get('farming.configuration')
|
|
|
|
config = Config.get_config()
|
|
|
|
if not config.farming_production_sequence:
|
|
|
|
raise UserError('missing_sequence_farming_production')
|
|
|
|
|
|
|
|
number = config.farming_production_sequence.get()
|
|
|
|
self.write([self], {'number': number})
|
|
|
|
|
2022-08-19 05:05:25 +02:00
|
|
|
def get_quantity_produced_planned(self, name=None):
|
|
|
|
res = []
|
|
|
|
_append = res.append
|
|
|
|
for lot in self.lots:
|
2022-08-22 23:18:51 +02:00
|
|
|
if self.production_rate and lot.total_plants:
|
|
|
|
_append(self.production_rate * lot.total_plants)
|
2022-08-19 05:05:25 +02:00
|
|
|
return sum(res)
|
|
|
|
|
|
|
|
def get_production_time(self, name=None):
|
2021-11-02 18:25:11 +01:00
|
|
|
res = None
|
|
|
|
if self.start_date:
|
|
|
|
today = date.today()
|
|
|
|
if self.end_date:
|
|
|
|
res = (self.end_date - self.start_date).days
|
|
|
|
else:
|
|
|
|
res = (today - self.start_date).days
|
|
|
|
return res
|
|
|
|
|
|
|
|
def get_production_cost(self, name):
|
|
|
|
res = 0
|
|
|
|
return res
|
|
|
|
|
|
|
|
def get_performance(self, name):
|
|
|
|
res = 0
|
|
|
|
return res
|
|
|
|
|
|
|
|
def get_gross_profit_rate(self, name):
|
|
|
|
res = 0
|
|
|
|
return res
|
|
|
|
|
|
|
|
def get_gross_profit(self, name):
|
|
|
|
res = 0
|
|
|
|
return res
|
|
|
|
|
2022-08-22 23:18:51 +02:00
|
|
|
@fields.depends('variety', 'production_uom', 'production_rate')
|
|
|
|
def on_change_variety(self):
|
|
|
|
if self.variety and self.variety.production_uom:
|
|
|
|
self.production_uom = self.variety.production_uom.id
|
|
|
|
self.production_rate = self.variety.production_rate
|
2022-09-02 22:15:15 +02:00
|
|
|
if self.variety.standard_cycle:
|
|
|
|
self.end_date = date.today() + timedelta(weeks=self.variety.standard_cycle)
|
|
|
|
|
2022-09-24 16:49:22 +02:00
|
|
|
@fields.depends('start_date', 'variety')
|
|
|
|
def on_change_start_date(self):
|
|
|
|
if self.variety:
|
|
|
|
self.end_date = self.start_date + timedelta(weeks=self.variety.standard_cycle)
|
|
|
|
|
|
|
|
@fields.depends('lots')
|
|
|
|
def on_change_with_total_plants(self, name = None):
|
|
|
|
quantity = 0
|
|
|
|
for lot in self.lots:
|
2022-11-01 22:40:23 +01:00
|
|
|
if lot.total_plants:
|
|
|
|
quantity += lot.total_plants
|
2022-09-24 16:49:22 +02:00
|
|
|
return quantity
|
|
|
|
|
2021-11-02 18:25:11 +01:00
|
|
|
|
2022-09-27 22:42:52 +02:00
|
|
|
class SupplyMoves(ModelSQL, ModelView):
|
|
|
|
'Supply moves'
|
|
|
|
__name__ = 'crop.supply.moves'
|
|
|
|
crop = fields.Many2One('farming.crop', 'Crop', ondelete='CASCADE', required=True)
|
|
|
|
product = fields.Many2One("product.product", "Product", required=True,
|
|
|
|
select=True)
|
|
|
|
unit = fields.Many2One('product.uom', 'Unit')
|
|
|
|
quantity = fields.Float('Quantity', required=True)
|
|
|
|
origin = fields.Reference('Origin', selection='get_origin', select=True)
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def _get_origin(cls):
|
|
|
|
'Return list of Model names for origin Reference'
|
|
|
|
return ['stock.move']
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def get_origin(cls):
|
|
|
|
Model = Pool().get('ir.model')
|
|
|
|
get_name = Model.get_name
|
|
|
|
models = cls._get_origin()
|
|
|
|
return [(None, '')] + [(m, get_name(m)) for m in models]
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-08-16 06:50:49 +02:00
|
|
|
class FarmingCropLot(ModelSQL, ModelView):
|
|
|
|
'Farming Crop Lot'
|
|
|
|
__name__ = 'farming.crop.lot'
|
2022-08-22 23:18:51 +02:00
|
|
|
_rec_name = 'number'
|
2022-09-02 22:15:15 +02:00
|
|
|
crop = fields.Many2One('farming.crop', 'Crop', ondelete='CASCADE', required=True)
|
2022-08-22 23:18:51 +02:00
|
|
|
lot = fields.Many2One('farming.location.lot', 'Lot', required=True)
|
2022-08-16 06:50:49 +02:00
|
|
|
cycle = fields.Float('Cycle', digits=(16, 2), help="In weeks")
|
|
|
|
beds = fields.One2Many('farming.crop.lot.bed', 'lot', 'Beds')
|
|
|
|
activities = fields.One2Many('farming.activity', 'lot', 'Activities')
|
2022-10-22 19:05:32 +02:00
|
|
|
analytic_account = fields.Many2One('analytic_account.account', 'Analytic Account')
|
2022-09-02 22:15:15 +02:00
|
|
|
total_plants = fields.Integer('Total Plants', states = {'readonly': Bool(Eval('beds'))}, depends=['beds'])
|
|
|
|
|
|
|
|
@fields.depends('beds')
|
|
|
|
def on_change_with_total_plants(self, name = None):
|
|
|
|
quantity = 0
|
|
|
|
if self.beds:
|
|
|
|
for bed in self.beds:
|
|
|
|
if bed.quantity_plants:
|
|
|
|
quantity += bed.quantity_plants
|
|
|
|
return quantity
|
2022-08-16 06:50:49 +02:00
|
|
|
|
|
|
|
class FarmingCropLotBed(ModelSQL, ModelView):
|
|
|
|
'Crop Lot Bed'
|
|
|
|
__name__ = 'farming.crop.lot.bed'
|
|
|
|
_rec_name = 'code'
|
2022-09-02 22:15:15 +02:00
|
|
|
lot = fields.Many2One('farming.crop.lot', 'Lot', ondelete='CASCADE', required=True)
|
|
|
|
bed = fields.Many2One('farming.location.lot.bed', 'Bed', ondelete='CASCADE', required=True)
|
2022-06-30 04:08:43 +02:00
|
|
|
quantity_plants = fields.Integer('Quantity Plants')
|
2022-09-02 22:15:15 +02:00
|
|
|
unit = fields.Many2One('product.uom', 'Unit', ondelete='CASCADE')
|
2022-07-15 09:01:45 +02:00
|
|
|
production_rate = fields.Float('Production Rate', digits=(16, 2),
|
2022-08-16 06:50:49 +02:00
|
|
|
help="In the unit of measure")
|
2022-06-30 04:08:43 +02:00
|
|
|
|
2022-09-24 16:49:22 +02:00
|
|
|
class CropActivity(Workflow, ModelSQL, ModelView):
|
|
|
|
'Crop Activity'
|
|
|
|
__name__ = 'farming.crop.activity'
|
|
|
|
crop = fields.Many2One('farming.crop', 'Crop', ondelete='CASCADE', required=True)
|
2022-10-22 19:05:32 +02:00
|
|
|
stage = fields.Many2One('farming.crop.stage', 'Stage')
|
2022-09-24 16:49:22 +02:00
|
|
|
sequence = fields.Char('Sequence', states=STATES)
|
|
|
|
kind = fields.Many2One('farming.activity.kind', 'Kind')
|
|
|
|
work_time = fields.Numeric('Work Time', digits=(16, 2))
|
|
|
|
workforce_price = fields.Numeric('workforce Price', digits=(16, 2))
|
|
|
|
uom = fields.Many2One('product.uom', 'Unit')
|
|
|
|
supplies = fields.One2Many('farming.crop.activity.supply', 'activity', 'Supply')
|
2022-10-22 19:05:32 +02:00
|
|
|
#time_of_realization = fields.Date('Time Of Realization',
|
|
|
|
# help='In weeks')
|
2022-11-01 21:16:44 +01:00
|
|
|
week = fields.Integer('Week')
|
2022-10-22 19:05:32 +02:00
|
|
|
planned_date = fields.Date('Planned Date',
|
|
|
|
help='In weeks')
|
|
|
|
effective_date = fields.Date('Effective Date',
|
2022-09-24 16:49:22 +02:00
|
|
|
help='In weeks')
|
2022-10-22 19:05:32 +02:00
|
|
|
|
2022-09-24 16:49:22 +02:00
|
|
|
state = fields.Selection([
|
|
|
|
('draft', 'Draft'),
|
|
|
|
('production', 'Production'),
|
|
|
|
('finished', 'Finished'),
|
|
|
|
('cancelled', 'Cancelled'),
|
|
|
|
], 'State', readonly=True, required=True)
|
|
|
|
|
2022-09-27 22:42:52 +02:00
|
|
|
@classmethod
|
|
|
|
def generateShipment(cls, records):
|
|
|
|
pool = Pool()
|
2022-10-22 19:05:32 +02:00
|
|
|
company = Transaction().context.get('company')
|
|
|
|
Supply = pool.get('farming.crop.activity.supply')
|
|
|
|
supplies = []
|
2022-09-27 22:42:52 +02:00
|
|
|
for record in records:
|
2022-10-22 19:05:32 +02:00
|
|
|
location = record.crop.location.warehouse
|
|
|
|
for supplyRec in record.supplies:
|
|
|
|
supply = Supply(
|
2022-09-27 22:42:52 +02:00
|
|
|
crop = record.crop,
|
2022-10-22 19:05:32 +02:00
|
|
|
product = supplyRec.product,
|
|
|
|
unit = supplyRec.unit,
|
|
|
|
quantity = supplyRec.quantity,
|
2022-09-27 22:42:52 +02:00
|
|
|
)
|
2022-10-22 19:05:32 +02:00
|
|
|
move = record._move(record, location.output_location, location.production_location,
|
|
|
|
company, supplyRec.product, supplyRec.unit, supplyRec.quantity)
|
|
|
|
supplies.append(supply)
|
|
|
|
Supply.save(supplies)
|
2022-09-27 22:42:52 +02:00
|
|
|
|
|
|
|
@classmethod
|
|
|
|
@ModelView.button
|
|
|
|
def generateShipmentButton(cls, records):
|
2022-11-01 21:16:44 +01:00
|
|
|
#cls.generateShipment(records)
|
|
|
|
pass
|
2022-09-27 22:42:52 +02:00
|
|
|
|
2022-10-22 19:05:32 +02:00
|
|
|
def _move(self, activity, from_location, to_location, company, product, uom,
|
|
|
|
quantity):
|
|
|
|
Move = Pool().get('stock.move')
|
|
|
|
move = Move(
|
|
|
|
product=product,
|
|
|
|
uom=uom,
|
|
|
|
quantity=quantity,
|
|
|
|
from_location=from_location,
|
|
|
|
to_location=to_location,
|
|
|
|
company=company,
|
|
|
|
origin=str(activity),
|
|
|
|
state='draft'
|
|
|
|
)
|
|
|
|
Move.save([move])
|
|
|
|
return move
|
|
|
|
|
2022-09-24 16:49:22 +02:00
|
|
|
@classmethod
|
2022-10-22 19:05:32 +02:00
|
|
|
def create_supply_moves(cls, location):
|
2022-09-24 16:49:22 +02:00
|
|
|
pool = Pool()
|
|
|
|
Move = pool.get('stock.move')
|
2022-10-22 19:05:32 +02:00
|
|
|
Location = pool.get('stock.location')
|
2022-09-24 16:49:22 +02:00
|
|
|
Date = pool.get('ir.date')
|
|
|
|
Shipment = pool.get('stock.shipment.internal')
|
|
|
|
moves = []
|
2022-10-22 19:05:32 +02:00
|
|
|
# for supply in activity.supplies:
|
|
|
|
# print(supply.unit, 'esto no es correcto')
|
|
|
|
# move = Move(
|
|
|
|
# quantity = supply.quantity,
|
|
|
|
# uom = supply.unit.id,
|
|
|
|
# product = supply.product.id,
|
|
|
|
# from_location =
|
|
|
|
# to_location =
|
|
|
|
# state = 'draft',
|
|
|
|
# company = Transaction().context.get('company'),
|
|
|
|
# unit_price = supply.product.cost_price,
|
|
|
|
# planned_date = Date.today(),
|
|
|
|
# #origin = ['production']
|
|
|
|
# )
|
|
|
|
# moves.append(move)
|
|
|
|
# shipment.moves = moves
|
|
|
|
# Shipment.save([shipment])
|
|
|
|
# #Move.save(moves)
|
|
|
|
# #BUG(ERROR: SHIPMENT INTERRUPTS STATUS, NOT GENERATED)
|
2022-09-24 16:49:22 +02:00
|
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def __setup__(cls):
|
|
|
|
super(CropActivity, cls).__setup__()
|
2022-10-22 19:05:32 +02:00
|
|
|
cls._order.insert(0, ('planned_date', 'ASC'))
|
2022-09-24 16:49:22 +02:00
|
|
|
cls._transitions |= set((
|
|
|
|
('draft', 'production'),
|
|
|
|
('production', 'draft'),
|
|
|
|
('production', 'finished'),
|
|
|
|
('production', 'cancelled'),
|
2022-10-22 19:05:32 +02:00
|
|
|
('finished', 'production'), # only developings
|
2022-09-24 16:49:22 +02:00
|
|
|
))
|
|
|
|
cls._buttons.update({
|
|
|
|
'draft': {
|
|
|
|
'invisible': Eval('state').in_(['draft', 'finished'])
|
|
|
|
},
|
|
|
|
'cancel': {
|
|
|
|
'invisible': Eval('state') == 'finished',
|
|
|
|
},
|
|
|
|
'load_configuration': {
|
|
|
|
'invisible': (Eval('lines', [])
|
|
|
|
| (Eval('state') != 'draft')),
|
|
|
|
'depends': ['state'],
|
|
|
|
},
|
|
|
|
'production': {
|
2022-10-22 19:05:32 +02:00
|
|
|
#'invisible': Eval('state').in_(['cancelled', 'finished']),
|
2022-09-24 16:49:22 +02:00
|
|
|
},
|
|
|
|
'finished': {
|
|
|
|
'invisible': Eval('state') != 'production',
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def default_state():
|
|
|
|
return 'draft'
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
@ModelView.button
|
|
|
|
@Workflow.transition('finished')
|
|
|
|
def finished(cls, records):
|
2022-10-22 19:05:32 +02:00
|
|
|
pool = Pool()
|
|
|
|
AccountMove = pool.get('account.move')
|
|
|
|
Journal = pool.get('account.journal')
|
|
|
|
journal = Journal.search([('type', '=', 'expense')])
|
|
|
|
AccountMoveLine = pool.get('account.move.line')
|
|
|
|
for record in records:
|
|
|
|
account_move = {
|
|
|
|
'company' : Transaction().context.get('company'),
|
|
|
|
'journal' : journal[0].id,
|
|
|
|
'date' : date.today(),
|
|
|
|
'origin' : str(record.crop),
|
|
|
|
'lines' : None,
|
|
|
|
}
|
|
|
|
account_move_lines = []
|
|
|
|
for supply in record.supplies:
|
|
|
|
product = supply.product
|
|
|
|
account = product.account_category
|
|
|
|
product_name = product.name
|
|
|
|
lineC = {
|
|
|
|
'debit' : Decimal(0),
|
|
|
|
'credit' : product.cost_price,
|
|
|
|
'account' : account.account_stock.id,
|
|
|
|
'description' : product_name,
|
|
|
|
}
|
|
|
|
lineD = {
|
|
|
|
'debit' : product.cost_price,
|
|
|
|
'credit' : Decimal(0),
|
|
|
|
'account' : account.account_expense.id,
|
|
|
|
'description' : product_name,
|
|
|
|
'analytic_lines' : [('create', [{
|
|
|
|
'debit' : product.cost_price,
|
|
|
|
'credit' : Decimal(0),
|
|
|
|
'account' : supply.analytic_account,
|
|
|
|
'date' : date.today()
|
|
|
|
}])]
|
|
|
|
}
|
|
|
|
account_move_lines.append(lineC)
|
|
|
|
account_move_lines.append(lineD)
|
|
|
|
account_move['lines'] = [('create', account_move_lines)]
|
|
|
|
AccountMove.create([account_move])
|
2022-09-24 16:49:22 +02:00
|
|
|
|
|
|
|
@classmethod
|
|
|
|
@ModelView.button
|
|
|
|
@Workflow.transition('cancelled')
|
|
|
|
def cancel(cls, services):
|
|
|
|
pass
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
@ModelView.button
|
|
|
|
@Workflow.transition('draft')
|
|
|
|
def draft(cls, records):
|
|
|
|
pass
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
@ModelView.button
|
|
|
|
@Workflow.transition('production')
|
|
|
|
def production(cls, records):
|
|
|
|
for record in records:
|
2022-10-22 19:05:32 +02:00
|
|
|
#cls.create_shipment(record)
|
|
|
|
cls.generateShipment([record])
|
2022-09-24 16:49:22 +02:00
|
|
|
record.set_number()
|
|
|
|
|
|
|
|
def set_number(self):
|
2022-11-01 21:16:44 +01:00
|
|
|
#Config = Pool().get('farming.configuration')
|
|
|
|
#config = Config.get_config()
|
|
|
|
#if not config.farming_production_sequence:
|
|
|
|
# raise UserError('missing_sequence_farming_production')
|
|
|
|
pass
|
2022-09-24 16:49:22 +02:00
|
|
|
|
|
|
|
class CropActivitySupply(ModelSQL, ModelView):
|
2022-10-22 19:05:32 +02:00
|
|
|
'Crop Activity Supply'
|
|
|
|
__name__ = 'farming.crop.activity.supply'
|
|
|
|
crop = fields.Many2One('farming.crop', 'Crop')
|
|
|
|
activity = fields.Many2One('farming.crop.activity', 'Activity', states={"invisible":False})
|
|
|
|
product = fields.Many2One("product.product", "Product", required=True,
|
|
|
|
select=True)
|
|
|
|
unit = fields.Many2One('product.uom', 'Unit')
|
|
|
|
quantity = fields.Float('Quantity', required=True)
|
|
|
|
analytic_account = fields.Many2One('analytic_account.account', 'Analytic Account')
|
|
|
|
cost_planned = fields.Numeric('Cost Planned', readonly=True)
|
|
|
|
cost_real = fields.Numeric('Cost Real')
|
2022-09-24 16:49:22 +02:00
|
|
|
|
2022-10-22 19:05:32 +02:00
|
|
|
def get_unity(self, name=None):
|
|
|
|
unity = self.product.default_uom.name
|
|
|
|
return unity
|
2022-06-30 04:08:43 +02:00
|
|
|
|
2021-11-02 18:25:11 +01:00
|
|
|
class Activity(Workflow, ModelSQL, ModelView):
|
|
|
|
'Activity'
|
|
|
|
__name__ = 'farming.activity'
|
|
|
|
_rec_name = 'kind'
|
|
|
|
sequence = fields.Char('Sequence', states=STATES)
|
2022-08-16 06:50:49 +02:00
|
|
|
lot = fields.Many2One('farming.crop.lot', 'Lot', required=True,
|
|
|
|
states=STATES)
|
|
|
|
employee = fields.Many2One('party.party', 'Employee', states=STATES)
|
2021-11-02 18:25:11 +01:00
|
|
|
planned_date = fields.Date('Planned Date', states=STATES, required=True)
|
|
|
|
start_date = fields.Date('Start Date', states=STATES, required=True)
|
|
|
|
end_date = fields.Date('End Date', states=STATES)
|
|
|
|
kind = fields.Many2One('farming.activity.kind', 'Kind', states=STATES)
|
|
|
|
notes = fields.Text('Notes', states=STATES)
|
|
|
|
days = fields.Function(fields.Integer('Days', states=STATES), 'get_days')
|
|
|
|
shipments = fields.Many2Many('farming.activity-shipment.internal',
|
|
|
|
'activity', 'shipment', 'Shipments', states=STATES)
|
2022-08-16 06:50:49 +02:00
|
|
|
# works = fields.One2Many('farming.crop.work', 'activity', 'Works',
|
|
|
|
# states=STATES)
|
2021-11-02 18:25:11 +01:00
|
|
|
state = fields.Selection([
|
|
|
|
('draft', 'Draft'),
|
|
|
|
('execution', 'Execution'),
|
|
|
|
('done', 'Done'),
|
|
|
|
('cancelled', 'Cancelled'),
|
|
|
|
], 'State', readonly=True, required=True)
|
2022-08-16 06:50:49 +02:00
|
|
|
amount = fields.Function(fields.Numeric('Amount', digits=(16, 2)),
|
|
|
|
'get_amount')
|
2021-11-02 18:25:11 +01:00
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def __setup__(cls):
|
|
|
|
super(Activity, cls).__setup__()
|
|
|
|
cls._order.insert(0, ('planned_date', 'DESC'))
|
|
|
|
cls._order.insert(1, ('id', 'DESC'))
|
|
|
|
cls._transitions |= set((
|
|
|
|
('draft', 'execution'),
|
|
|
|
('execution', 'done'),
|
|
|
|
('execution', 'draft'),
|
|
|
|
('execution', 'cancelled'),
|
|
|
|
('cancelled', 'draft'),
|
|
|
|
))
|
|
|
|
cls._buttons.update({
|
|
|
|
'draft': {
|
|
|
|
'invisible': Eval('state').in_(['draft', 'done']),
|
|
|
|
},
|
|
|
|
'cancel': {
|
|
|
|
'invisible': Eval('state').in_(['cancelled', 'done']),
|
|
|
|
},
|
|
|
|
'execution': {
|
|
|
|
'invisible': Eval('state') != 'draft',
|
|
|
|
},
|
|
|
|
'done': {
|
|
|
|
'invisible': Eval('state') != 'execution',
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def default_company():
|
|
|
|
return Transaction().context.get('company') or False
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def default_state():
|
|
|
|
return 'draft'
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
@ModelView.button
|
|
|
|
@Workflow.transition('done')
|
|
|
|
def done(cls, records):
|
|
|
|
pass
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
@ModelView.button
|
|
|
|
@Workflow.transition('execution')
|
|
|
|
def execution(cls, records):
|
|
|
|
for record in records:
|
|
|
|
record.set_number()
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
@ModelView.button
|
|
|
|
@Workflow.transition('cancelled')
|
|
|
|
def cancel(cls, records):
|
|
|
|
pass
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
@ModelView.button
|
|
|
|
@Workflow.transition('draft')
|
|
|
|
def draft(cls, records):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def get_amount(self, name):
|
|
|
|
res = 0
|
|
|
|
for shipment in self.shipments:
|
|
|
|
for m in shipment.outgoing_moves:
|
|
|
|
res += m.product.template.cost_price * Decimal(m.quantity)
|
|
|
|
for w in self.works:
|
|
|
|
res += w.unit_price * Decimal(w.quantity)
|
|
|
|
return res
|
|
|
|
|
|
|
|
def get_days(self, name):
|
|
|
|
res = 0
|
|
|
|
if self.start_date and self.end_date:
|
|
|
|
res = (self.end_date - self.start_date).days
|
|
|
|
return res
|
|
|
|
|
|
|
|
|
2022-08-16 06:50:49 +02:00
|
|
|
class CropForecastStart(ModelView):
|
|
|
|
'Crop Forecast Start'
|
|
|
|
__name__ = 'farming.crop_forecast.start'
|
|
|
|
company = fields.Many2One('company.company', 'Company', required=True)
|
2022-08-17 00:46:41 +02:00
|
|
|
start_date = fields.Date("Start Date", required=True)
|
2022-08-22 23:18:51 +02:00
|
|
|
end_date = fields.Date("End Date", required=True)
|
2022-08-16 06:50:49 +02:00
|
|
|
# storage = fields.Many2One('stock.location', 'Location', required=True,
|
|
|
|
# domain=[('type', '=', 'storage')])
|
2021-11-02 18:25:11 +01:00
|
|
|
|
2022-08-16 06:50:49 +02:00
|
|
|
@staticmethod
|
|
|
|
def default_company():
|
|
|
|
return Transaction().context.get('company')
|
2021-11-02 18:25:11 +01:00
|
|
|
|
|
|
|
|
2022-08-16 06:50:49 +02:00
|
|
|
class CropForecast(Wizard):
|
|
|
|
'Crop Forecast'
|
|
|
|
__name__ = 'farming.crop_forecast'
|
|
|
|
start = StateView('farming.crop_forecast.start',
|
|
|
|
'farming.farming_crop_forecast_start_view_form', [
|
|
|
|
Button('Cancel', 'end', 'tryton-cancel'),
|
|
|
|
Button('Print', 'print_', 'tryton-ok', default=True),
|
|
|
|
])
|
|
|
|
print_ = StateReport('farming.crop_forecast.report')
|
|
|
|
|
|
|
|
def do_print_(self, action):
|
|
|
|
data = {
|
|
|
|
'company': self.start.company.id,
|
2022-08-17 00:46:41 +02:00
|
|
|
'start_date': self.start.start_date,
|
2022-08-16 06:50:49 +02:00
|
|
|
}
|
|
|
|
return action, data
|
|
|
|
|
|
|
|
def transition_print_(self):
|
|
|
|
return 'end'
|
|
|
|
|
|
|
|
|
|
|
|
class CropForecastReport(Report):
|
|
|
|
'Crop Forecast Report'
|
|
|
|
__name__ = 'farming.crop_forecast.report'
|
2022-08-22 23:18:51 +02:00
|
|
|
|
2022-08-16 06:50:49 +02:00
|
|
|
@classmethod
|
|
|
|
def get_context(cls, records, header, data):
|
|
|
|
report_context = super().get_context(records, header, data)
|
|
|
|
pool = Pool()
|
|
|
|
Company = pool.get('company.company')
|
2022-08-17 00:46:41 +02:00
|
|
|
Crop = pool.get('farming.crop')
|
2022-08-22 23:18:51 +02:00
|
|
|
|
|
|
|
stages = {}
|
|
|
|
stages_convert = {}
|
|
|
|
week_range = []
|
|
|
|
for nd in range(MAX_WEEKS):
|
|
|
|
week_n = 'day' + str((nd + 1))
|
|
|
|
first_date = data['start_date'] + timedelta(nd * 7)
|
|
|
|
last_date = first_date + timedelta(7)
|
|
|
|
data[week_n] = first_date
|
|
|
|
data['total_' + week_n] = 0
|
2022-08-17 00:46:41 +02:00
|
|
|
# data[('revenue_' + day_n)] = 0
|
|
|
|
# data[('rate_' + day_n)] = 0
|
2022-08-22 23:18:51 +02:00
|
|
|
stages[week_n] = ''
|
|
|
|
stages[first_date] = week_n
|
|
|
|
week_range.append((first_date, last_date))
|
|
|
|
#stages_convert[tdate] = day_n
|
2022-08-17 00:46:41 +02:00
|
|
|
|
|
|
|
|
|
|
|
target_crops = data['start_date'] - timedelta(days=300)
|
|
|
|
crops = Crop.search([
|
2022-08-22 23:18:51 +02:00
|
|
|
('start_date', '>=', target_crops),
|
2022-08-17 00:46:41 +02:00
|
|
|
])
|
2022-08-16 06:50:49 +02:00
|
|
|
|
2022-08-22 23:18:51 +02:00
|
|
|
records = {}
|
|
|
|
|
|
|
|
for crop in crops:
|
|
|
|
stages_cycle = copy.deepcopy(stages)
|
2022-09-02 22:15:15 +02:00
|
|
|
production_rate = crop.variety.production_rate
|
2022-08-22 23:18:51 +02:00
|
|
|
records[crop] = []
|
|
|
|
quantity_produced = crop.quantity_produced
|
|
|
|
start_date = crop.start_date
|
|
|
|
for stage in crop.stages:
|
2022-09-02 22:15:15 +02:00
|
|
|
#production_rate = stage.production_rate
|
2022-08-22 23:18:51 +02:00
|
|
|
if production_rate:
|
|
|
|
production_date = start_date + timedelta(days=stage.activity_time * 7)
|
|
|
|
production = (production_rate / 100) * quantity_produced
|
|
|
|
for (start_week, end_week) in week_range:
|
|
|
|
if production_date >= start_week and production_date <= end_week:
|
|
|
|
week_n = stages[start_week]
|
|
|
|
stages_cycle[week_n] = production
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
|
|
for lot in crop.lots:
|
|
|
|
record = {
|
|
|
|
'number': lot.lot.number,
|
|
|
|
}
|
|
|
|
record.update(stages_cycle)
|
|
|
|
records[crop].append(record)
|
|
|
|
|
|
|
|
|
|
|
|
#for line in lines:
|
|
|
|
# _delta = (line.departure_date - line.arrival_date).days
|
|
|
|
# for i in range(_delta):
|
|
|
|
# dt = line.arrival_date + timedelta(i)
|
|
|
|
# if dt >= date_init and dt < date_limit \
|
|
|
|
# and dt >= data['date']:
|
|
|
|
# dayn = alldays_convert[dt]
|
|
|
|
# records[line.crop.id][dayn] = "X"
|
|
|
|
# data['total_' + dayn] += 1
|
|
|
|
# data['revenue_' + dayn] += float(line.unit_price) / 1000000
|
|
|
|
#for i in range(MAX_DAYS):
|
|
|
|
# day_n = 'day' + str((i + 1))
|
|
|
|
# data['rate_' + day_n] = (data['total_' + day_n] * 100.0) / len(crops)
|
|
|
|
|
|
|
|
report_context['records'] = records.items()
|
|
|
|
|
|
|
|
report_context['start_date'] = start_date
|
|
|
|
#data['date']
|
2022-11-01 21:16:44 +01:00
|
|
|
#report_context['company'] = Company(data['company']).party.name
|
|
|
|
report_context['company'] = Transaction().context.get('company')
|
2022-08-16 06:50:49 +02:00
|
|
|
return report_context
|
2022-08-22 23:18:51 +02:00
|
|
|
|
2022-08-16 06:50:49 +02:00
|
|
|
|
|
|
|
|
|
|
|
# class FarmingWork(ModelSQL, ModelView):
|
|
|
|
# 'Farming Work'
|
|
|
|
# __name__ = 'farming.crop.work'
|
|
|
|
# sequence = fields.Integer('Sequence', select=True)
|
|
|
|
# activity = fields.Many2One('farming.activity', 'Activity', select=True,
|
|
|
|
# ondelete='CASCADE', required=True)
|
|
|
|
# method = fields.Selection([
|
|
|
|
# ('by_day', 'By Day'),
|
|
|
|
# ('by_productivity', 'By Productivity'),
|
|
|
|
# ], 'Method', required=True)
|
|
|
|
# quantity = fields.Float('Quantity', required=True)
|
|
|
|
# unit_price = fields.Numeric('Unit Price', digits=(16, 2), required=True)
|
|
|
|
# amount = fields.Function(fields.Numeric('Amount', digits=(16, 2)), 'get_amount')
|
|
|
|
# employee = fields.Many2One('company.employee', 'Employee')
|
|
|
|
#
|
|
|
|
# @classmethod
|
|
|
|
# def __setup__(cls):
|
|
|
|
# super(FarmingWork, cls).__setup__()
|
|
|
|
#
|
|
|
|
# def get_amount(self, name):
|
|
|
|
# res = 0
|
|
|
|
# if self.quantity and self.unit_price:
|
|
|
|
# res = Decimal(self.quantity) * self.unit_price
|
|
|
|
# return res
|
|
|
|
#
|
|
|
|
# @staticmethod
|
|
|
|
# def default_method():
|
|
|
|
# return 'by_day'
|
2021-11-02 18:25:11 +01:00
|
|
|
|
|
|
|
|
|
|
|
class FarmingActivityShipmentInternal(ModelSQL):
|
|
|
|
'Farming Activity - Shipment Internal'
|
|
|
|
__name__ = 'farming.activity-shipment.internal'
|
|
|
|
_table = 'farming_activity_shipment_internal_rel'
|
|
|
|
activity = fields.Many2One('farming.activity', 'Activity',
|
|
|
|
ondelete='CASCADE', select=True, required=True)
|
|
|
|
shipment = fields.Many2One('stock.shipment.internal', 'Tax',
|
|
|
|
ondelete='RESTRICT', required=True)
|
2022-09-24 16:49:22 +02:00
|
|
|
|
|
|
|
|
|
|
|
class ActivityTask(ModelView, ModelSQL):
|
|
|
|
"Execute Activity"
|
|
|
|
__name__ = 'crop.activity.task'
|
|
|
|
STATES = {
|
|
|
|
'readonly': Eval('state') == 'finished',
|
|
|
|
}
|
|
|
|
effective_date = fields.Date('Effective Date ', states=STATES,
|
|
|
|
required=True)
|
|
|
|
employee = fields.Many2One('company.employee', 'Employee',
|
|
|
|
states=STATES)
|
|
|
|
quantity = fields.Float('Quantity', states=STATES, required=True)
|
|
|
|
start_time = fields.DateTime('Start Time')
|
|
|
|
production = fields.Many2One('production', 'Production', states=STATES)
|
|
|
|
state = fields.Selection([
|
|
|
|
('draft', 'Draft'),
|
|
|
|
('processing', 'Processing'),
|
|
|
|
('finished', 'Finished'),
|
|
|
|
], 'State', select=True)
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def default_state():
|
2022-10-22 19:05:32 +02:00
|
|
|
return 'draft'
|
|
|
|
|
|
|
|
|
|
|
|
class CropActivitiesStart(ModelView):
|
|
|
|
'Crop Activities Start'
|
|
|
|
__name__ = 'farming.crop_activities.start'
|
2022-11-01 21:16:44 +01:00
|
|
|
company = fields.Many2One('company.company', 'Company', required=True)
|
|
|
|
crop = fields.Many2One('farming.crop', 'Crop')
|
|
|
|
start_date = fields.Date("Start Date")
|
|
|
|
location = fields.Many2One('farming.location', 'Location', required=True)
|
2022-10-22 19:05:32 +02:00
|
|
|
@staticmethod
|
|
|
|
def default_company():
|
|
|
|
return Transaction().context.get('company')
|
|
|
|
|
2022-11-01 21:16:44 +01:00
|
|
|
def default_start_date():
|
|
|
|
return datetime.today()
|
|
|
|
|
2022-10-22 19:05:32 +02:00
|
|
|
|
|
|
|
class CropActivitiesWizard(Wizard):
|
|
|
|
'Crop Activities'
|
|
|
|
__name__ = 'farming.crop_activities'
|
|
|
|
start = StateView('farming.crop_activities.start',
|
|
|
|
'farming.farming_crop_activities_start_view_form', [
|
|
|
|
Button('Cancel', 'end', 'tryton-cancel'),
|
|
|
|
Button('Print', 'print_', 'tryton-ok', default=True),
|
|
|
|
])
|
|
|
|
print_ = StateReport('farming.crop_activities.report')
|
|
|
|
|
|
|
|
def do_print_(self, action):
|
|
|
|
data = {
|
2022-11-01 21:16:44 +01:00
|
|
|
#'crop': self.start.crop.id,
|
2022-10-22 19:05:32 +02:00
|
|
|
'company': self.start.company.id,
|
|
|
|
'start_date': self.start.start_date,
|
2022-11-01 21:16:44 +01:00
|
|
|
'location': self.start.location.id,
|
|
|
|
#'end_date': self.start.end_date,
|
2022-10-22 19:05:32 +02:00
|
|
|
}
|
|
|
|
return action, data
|
|
|
|
|
|
|
|
def transition_print_(self):
|
|
|
|
return 'end'
|
|
|
|
|
|
|
|
|
2022-11-01 21:16:44 +01:00
|
|
|
|
2022-10-22 19:05:32 +02:00
|
|
|
class CropActivitiesReport(Report):
|
|
|
|
'Crop Activities Report'
|
|
|
|
__name__ = 'farming.crop_activities.report'
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def get_context(cls, records, header, data):
|
|
|
|
report_context = super().get_context(records, header, data)
|
|
|
|
pool = Pool()
|
|
|
|
Company = pool.get('company.company')
|
2022-11-01 21:16:44 +01:00
|
|
|
|
|
|
|
date_start = date(data['start_date'].year, data['start_date'].month, 1)
|
|
|
|
date_end = date(data['start_date'].year, data['start_date'].month + 2, 28)
|
|
|
|
week_list = []
|
|
|
|
date_calculate_week = date_start + timedelta(7)
|
|
|
|
for w in range(13):
|
|
|
|
week_data = {
|
|
|
|
'number': date_calculate_week.isocalendar()[1],
|
|
|
|
'range': date_calculate_week
|
|
|
|
}
|
|
|
|
week_list.append(week_data)
|
|
|
|
date_calculate_week = date_calculate_week + timedelta(days=7)
|
|
|
|
|
|
|
|
Location = pool.get('farming.location')
|
|
|
|
locations = Location.search([('id', '=', data['location'])])
|
|
|
|
location_list = []
|
|
|
|
for location in locations:
|
|
|
|
Crop = pool.get('farming.crop')
|
|
|
|
crops = Crop.search([
|
|
|
|
('location', '=', location.id),
|
|
|
|
('start_date', '<=', date_start),
|
|
|
|
('end_date', '>=', date_end),
|
|
|
|
('activities', '!=', None)
|
|
|
|
])
|
|
|
|
crop_list = []
|
|
|
|
total_list = [0 for x in range(13) ]
|
|
|
|
|
|
|
|
for crop in crops:
|
|
|
|
crop_report = {
|
|
|
|
'lots': []
|
|
|
|
}
|
|
|
|
activity_list = []
|
|
|
|
lots_report = []
|
|
|
|
for lot in crop.lots:
|
|
|
|
beds = ''
|
|
|
|
for bed in lot.beds:
|
|
|
|
beds = beds + '-' +bed.bed.number
|
|
|
|
lot_dict = {
|
|
|
|
'number': '',
|
|
|
|
'variety': '',
|
|
|
|
'lot': 'Lote: ' + lot.lot.number,
|
|
|
|
'total_plants': lot.total_plants,
|
|
|
|
'beds': 'Camas: ' + beds,
|
|
|
|
'activities': []
|
|
|
|
}
|
|
|
|
lots_report.append(lot_dict)
|
|
|
|
crop_report['lots'] = lots_report
|
|
|
|
Activity = pool.get('farming.crop.activity')
|
|
|
|
activities = Activity.search(['crop', "=", crop.id])
|
|
|
|
|
|
|
|
for activity in activities:
|
|
|
|
activity_week = activity.planned_date.isocalendar()[1]
|
|
|
|
for week in week_list:
|
|
|
|
act = {
|
|
|
|
'name': '',
|
|
|
|
'date': '',
|
|
|
|
'time': ''
|
|
|
|
}
|
|
|
|
activity_list.append(act)
|
|
|
|
for index, week in enumerate(week_list):
|
|
|
|
week_number = week['number']
|
|
|
|
if activity_week == week_number:
|
|
|
|
activity_list[index-1] = {
|
|
|
|
'name': activity.kind.name + ' (' + str(activity.week) + ')',
|
|
|
|
'date': activity.planned_date,
|
|
|
|
'time': activity.work_time,
|
|
|
|
}
|
|
|
|
total_list[index-1] = total_list[index-1] + activity.work_time
|
|
|
|
break
|
|
|
|
#crop_report['activities'] = activity_list
|
|
|
|
lots_report[0]['activities'] = activity_list
|
|
|
|
crop_report['lots'][0]['activities'] = activity_list
|
|
|
|
crop_report['lots'][0]['number'] = crop.number
|
|
|
|
crop_report['lots'][0]['variety'] = crop.variety.product.name
|
|
|
|
crop_list.append(crop_report)
|
|
|
|
location_list.append({'name':location.name, 'crops':crop_list, 'total_time': total_list})
|
|
|
|
|
|
|
|
report_context['weeks'] = week_list
|
|
|
|
report_context['records'] = location_list
|
|
|
|
#report_context['totals'] = total_report
|
|
|
|
#report_context['company'] = .party.name
|
|
|
|
report_context['company'] = Company(data['company'])
|
|
|
|
report_context['date_start'] = date_start
|
|
|
|
report_context['date_end'] = date_end
|
|
|
|
return report_context
|
|
|
|
|
|
|
|
|
|
|
|
class CropSuppliesStart(ModelView):
|
|
|
|
'Crop Activities Start'
|
|
|
|
__name__ = 'farming.crop_supplies.start'
|
|
|
|
company = fields.Many2One('company.company', 'Company', required=True)
|
|
|
|
crop = fields.Many2One('farming.crop', 'Crop')
|
|
|
|
start_date = fields.Date("Start Date")
|
|
|
|
location = fields.Many2One('farming.location', 'Location', required=True)
|
|
|
|
@staticmethod
|
|
|
|
def default_company():
|
|
|
|
return Transaction().context.get('company')
|
|
|
|
|
|
|
|
def default_start_date():
|
|
|
|
return datetime.today()
|
|
|
|
|
|
|
|
|
|
|
|
class CropSuppliesWizard(Wizard):
|
|
|
|
'Crop Activities'
|
|
|
|
__name__ = 'farming.crop_supplies'
|
|
|
|
start = StateView('farming.crop_activities.start',
|
|
|
|
'farming.farming_crop_activities_start_view_form', [
|
|
|
|
Button('Cancel', 'end', 'tryton-cancel'),
|
|
|
|
Button('Print', 'print_', 'tryton-ok', default=True),
|
|
|
|
])
|
|
|
|
print_ = StateReport('farming.crop_supplies.report')
|
|
|
|
|
|
|
|
def do_print_(self, action):
|
|
|
|
data = {
|
|
|
|
#'crop': self.start.crop.id,
|
|
|
|
'company': self.start.company.id,
|
|
|
|
'start_date': self.start.start_date,
|
|
|
|
'location': self.start.location.id,
|
|
|
|
#'end_date': self.start.end_date,
|
|
|
|
}
|
|
|
|
return action, data
|
|
|
|
|
|
|
|
def transition_print_(self):
|
|
|
|
return 'end'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CropSuppliesReport(Report):
|
|
|
|
'Crop Activities Report'
|
|
|
|
__name__ = 'farming.crop_supplies.report'
|
|
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def get_context(cls, records, header, data):
|
|
|
|
report_context = super().get_context(records, header, data)
|
|
|
|
pool = Pool()
|
|
|
|
Company = pool.get('company.company')
|
|
|
|
|
|
|
|
date_start = date(data['start_date'].year, data['start_date'].month, 1)
|
|
|
|
date_end = date(data['start_date'].year, data['start_date'].month + 2, 28)
|
|
|
|
week_list = []
|
|
|
|
date_calculate_week = date_start + timedelta(7)
|
|
|
|
for w in range(13):
|
|
|
|
week_data = {
|
|
|
|
'number': date_calculate_week.isocalendar()[1],
|
|
|
|
'range': date_calculate_week
|
|
|
|
}
|
|
|
|
week_list.append(week_data)
|
|
|
|
date_calculate_week = date_calculate_week + timedelta(days=7)
|
|
|
|
|
|
|
|
Location = pool.get('farming.location')
|
|
|
|
locations = Location.search([('id', '=', data['location'])])
|
|
|
|
location_list = []
|
|
|
|
for location in locations:
|
|
|
|
Crop = pool.get('farming.crop')
|
|
|
|
crops = Crop.search([
|
|
|
|
('location', '=', location.id),
|
|
|
|
('start_date', '<=', date_start),
|
|
|
|
('end_date', '>=', date_end),
|
|
|
|
('activities', '!=', None)
|
|
|
|
])
|
|
|
|
crop_list = []
|
|
|
|
total_list = [0 for x in range(13) ]
|
|
|
|
|
|
|
|
for crop in crops:
|
|
|
|
crop_report = {
|
|
|
|
'lots': []
|
|
|
|
}
|
|
|
|
activity_list = []
|
|
|
|
lots_report = []
|
|
|
|
for lot in crop.lots:
|
|
|
|
beds = ''
|
|
|
|
for bed in lot.beds:
|
|
|
|
beds = beds + '-' +bed.bed.number
|
|
|
|
lot_dict = {
|
|
|
|
'number': '',
|
|
|
|
'variety': '',
|
|
|
|
'lot': lot.lot.number,
|
|
|
|
'total_plants': lot.total_plants,
|
|
|
|
'beds': 'Camas' + beds,
|
|
|
|
'activities': []
|
|
|
|
}
|
|
|
|
lots_report.append(lot_dict)
|
|
|
|
crop_report['lots'] = lots_report
|
|
|
|
Activity = pool.get('farming.crop.activity')
|
|
|
|
activities = Activity.search(['crop', "=", crop.id])
|
|
|
|
|
|
|
|
for activity in activities:
|
|
|
|
activity_week = activity.planned_date.isocalendar()[1]
|
|
|
|
for week in week_list:
|
|
|
|
act = {
|
|
|
|
'supplies': ''
|
|
|
|
}
|
|
|
|
activity_list.append(act)
|
|
|
|
for index, week in enumerate(week_list):
|
|
|
|
week_number = week['number']
|
|
|
|
if activity_week == week_number:
|
|
|
|
activity_list[index-1] = {
|
|
|
|
'supplies': activity.supplies,
|
|
|
|
}
|
|
|
|
total_list[index-1] = total_list[index-1] + activity.work_time
|
|
|
|
break
|
|
|
|
#crop_report['activities'] = activity_list
|
|
|
|
lots_report[0]['activities'] = activity_list
|
|
|
|
crop_report['lots'][0]['activities'] = activity_list
|
|
|
|
crop_report['lots'][0]['number'] = crop.number
|
|
|
|
crop_report['lots'][0]['variety'] = crop.variety.product.name
|
|
|
|
crop_list.append(crop_report)
|
|
|
|
location_list.append({'name':location.name, 'crops':crop_list, 'total_time': total_list})
|
|
|
|
|
|
|
|
report_context['weeks'] = week_list
|
|
|
|
report_context['records'] = location_list
|
|
|
|
#report_context['totals'] = total_report
|
|
|
|
#report_context['company'] = .party.name
|
|
|
|
report_context['company'] = Company(data['company'])
|
|
|
|
report_context['date_start'] = date_start
|
|
|
|
report_context['date_end'] = date_end
|
|
|
|
return report_context
|
|
|
|
|
|
|
|
|
|
|
|
class CropForecastWeekStart(ModelView):
|
|
|
|
'Crop Activities Start'
|
|
|
|
__name__ = 'farming.crop_forecast_week.start'
|
|
|
|
company = fields.Many2One('company.company', 'Company', required=True)
|
|
|
|
crop = fields.Many2One('farming.crop', 'Crop')
|
|
|
|
start_date = fields.Date("Start Date")
|
|
|
|
location = fields.Many2One('farming.location', 'Location', required=True)
|
|
|
|
@staticmethod
|
|
|
|
def default_company():
|
|
|
|
return Transaction().context.get('company')
|
|
|
|
|
|
|
|
def default_start_date():
|
|
|
|
return datetime.today()
|
|
|
|
|
|
|
|
|
|
|
|
class CropForecastWeekWizard(Wizard):
|
|
|
|
'Crop Activities'
|
|
|
|
__name__ = 'farming.crop_forecast_week'
|
|
|
|
start = StateView('farming.crop_forecast_week.start',
|
|
|
|
'farming.farming_crop_forecast_week_start_view_form', [
|
|
|
|
Button('Cancel', 'end', 'tryton-cancel'),
|
|
|
|
Button('Print', 'print_', 'tryton-ok', default=True),
|
|
|
|
])
|
|
|
|
print_ = StateReport('farming.crop_forecast_week.report')
|
|
|
|
|
|
|
|
def do_print_(self, action):
|
|
|
|
data = {
|
|
|
|
#'crop': self.start.crop.id,
|
|
|
|
'company': self.start.company.id,
|
|
|
|
'start_date': self.start.start_date,
|
|
|
|
'location': self.start.location.id,
|
|
|
|
#'end_date': self.start.end_date,
|
|
|
|
}
|
|
|
|
return action, data
|
|
|
|
|
|
|
|
def transition_print_(self):
|
|
|
|
return 'end'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CropForecastWeekReport(Report):
|
|
|
|
'Crop Activities Report'
|
|
|
|
__name__ = 'farming.crop_forecast_week.report'
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def get_context(cls, records, header, data):
|
|
|
|
report_context = super().get_context(records, header, data)
|
|
|
|
pool = Pool()
|
|
|
|
Company = pool.get('company.company')
|
|
|
|
|
|
|
|
date_start = date(data['start_date'].year, data['start_date'].month, 1)
|
|
|
|
date_end = date(data['start_date'].year, data['start_date'].month + 2, 28)
|
|
|
|
week_list = []
|
|
|
|
date_calculate_week = date_start + timedelta(7)
|
|
|
|
for w in range(13):
|
|
|
|
week_data = {
|
|
|
|
'number': date_calculate_week.isocalendar()[1],
|
|
|
|
'range': date_calculate_week
|
|
|
|
}
|
|
|
|
week_list.append(week_data)
|
|
|
|
date_calculate_week = date_calculate_week + timedelta(days=7)
|
|
|
|
|
|
|
|
Location = pool.get('farming.location')
|
|
|
|
locations = Location.search([('id', '=', data['location'])])
|
|
|
|
location_list = []
|
|
|
|
for location in locations:
|
|
|
|
Crop = pool.get('farming.crop')
|
|
|
|
crops = Crop.search([
|
|
|
|
('location', '=', location.id),
|
|
|
|
#('start_date', '<=', date_start),
|
|
|
|
('end_date', '>=', date_end),
|
|
|
|
('activities', '!=', None)
|
|
|
|
])
|
|
|
|
crop_list = []
|
|
|
|
total_list = [0 for x in range(13) ]
|
|
|
|
|
|
|
|
for crop in crops:
|
|
|
|
crop_report = {
|
|
|
|
'lots': []
|
|
|
|
}
|
|
|
|
lots_report = []
|
|
|
|
for lot in crop.lots:
|
|
|
|
beds = ''
|
|
|
|
for bed in lot.beds:
|
|
|
|
beds = beds + '-' +bed.bed.number
|
|
|
|
lot_dict = {
|
|
|
|
'number': '',
|
|
|
|
'variety': crop.variety.product.name,
|
|
|
|
'lot': 'Lote: ' + lot.lot.number,
|
|
|
|
'total_plants': lot.total_plants,
|
|
|
|
'beds': 'Camas: ' + beds,
|
|
|
|
'stages': []
|
|
|
|
}
|
|
|
|
lots_report.append(lot_dict)
|
|
|
|
crop_report['lots'] = lots_report
|
|
|
|
Stage = pool.get('farming.crop.stage')
|
|
|
|
stages = Stage.search(['crop', "=", crop.id])
|
|
|
|
|
|
|
|
for lot_report in lots_report:
|
|
|
|
stage_list = []
|
|
|
|
for stage in stages:
|
|
|
|
stage_week = stage.effective_date.isocalendar()[1]
|
|
|
|
for week in week_list:
|
|
|
|
act = {
|
|
|
|
'name': '',
|
|
|
|
'production_rate': 0
|
|
|
|
}
|
|
|
|
stage_list.append(act)
|
|
|
|
for index, week in enumerate(week_list):
|
|
|
|
week_number = week['number']
|
|
|
|
if stage_week == week_number:
|
|
|
|
stage_list[index-1] = {
|
|
|
|
'name': stage.stage.name,
|
|
|
|
'production_rate': stage.production_rate * lot_report['total_plants'] * crop.production_rate
|
|
|
|
}
|
|
|
|
break
|
|
|
|
lot_report['stages'] = stage_list
|
|
|
|
pprint(stage_list)
|
|
|
|
|
|
|
|
crop_list.append(crop_report)
|
|
|
|
location_list.append({'name':location.name, 'crops':crop_list, 'total_time': total_list})
|
|
|
|
|
|
|
|
report_context['weeks'] = week_list
|
|
|
|
report_context['records'] = location_list
|
|
|
|
#report_context['totals'] = total_report
|
|
|
|
#report_context['company'] = .party.name
|
|
|
|
report_context['company'] = Company(data['company'])
|
|
|
|
report_context['date_start'] = date_start
|
|
|
|
report_context['date_end'] = date_end
|
2022-10-22 19:05:32 +02:00
|
|
|
return report_context
|