diff --git a/__init__.py b/__init__.py
index 233a325..3ef1a4f 100644
--- a/__init__.py
+++ b/__init__.py
@@ -25,23 +25,24 @@ def register():
sale.AduanaDetailedStart,
crop.Kind,
crop.Activity,
- crop.CropActivity,
- crop.CropActivitySupply,
- crop.FarmingVariety,
- crop.FarmingVarietyActivity,
- crop.FarmingActivitySupply,
+ crop.Variety,
+ crop.VarietyStage,
+ crop.VarietyStageActivity,
+ crop.VarietyStageActivitySupply,
crop.FarmingActivityShipmentInternal,
crop.FarmingStage,
- crop.FarmingCrop,
+ crop.Crop,
crop.CropStage,
+ crop.CropStageActivity,
+ crop.CropStageActivitySupply,
crop.FarmingCropLot,
crop.FarmingCropLotBed,
crop.CropForecastStart,
crop.CropForecastWeekStart,
crop.CropActivitiesStart,
crop.CropSuppliesStart,
- crop.FarmingVarietyCycle,
crop.SupplyMoves,
+ crop.CropStageLoss,
location.FarmingLocationLotBed,
location.FarmingLocationLot,
location.FarmingLocation,
diff --git a/crop.py b/crop.py
index 5b94b6d..3f4a3ad 100644
--- a/crop.py
+++ b/crop.py
@@ -26,29 +26,16 @@ class FarmingStage(ModelSQL, ModelView):
name = fields.Char('Name', required=True)
-class FarmingVarietyCycle(ModelSQL, ModelView):
- "Farming Variety Cycle"
- __name__ = "farming.variety.cycle"
- variety = fields.Many2One('farming.variety', 'Variety')
- lot = fields.Many2One('farming.location.lot', 'Lot')
- sequence = fields.Integer('Sequence', required=True)
- stage = fields.Many2One('farming.stage', 'Stage', required=True)
- start_time = fields.Integer('Start Time', help='Harvest week',
- required=True)
- production_rate = fields.Float('Production Rate', digits=(3, 2))
-
-
-class FarmingVariety(ModelSQL, ModelView):
- 'Farming Variety'
+class Variety(ModelSQL, ModelView):
+ 'Variety'
__name__ = 'farming.variety'
product = fields.Many2One('product.product', 'Product', required=True)
production_rate = fields.Float('Production Rate', digits=(16, 2))
production_uom = fields.Many2One('product.uom', 'UoM')
standard_cycle = fields.Integer('Standard Cycle', help='In weeks')
- activities = fields.One2Many('farming.variety.activity', 'variety',
- 'Activities')
+ stages = fields.One2Many('farming.variety.stage', 'variety', 'Stages')
location = fields.Many2One('farming.location', 'Location')
- cycles = fields.One2Many('farming.variety.cycle', 'variety', 'Cycles')
+ # cycles = fields.One2Many('farming.variety.cycle', 'variety', 'Cycles')
def get_rec_name(self, name=None):
if self.location:
@@ -57,22 +44,59 @@ class FarmingVariety(ModelSQL, ModelView):
return self.product.template.name
-class FarmingActivitySupply(ModelSQL, ModelView):
- 'Farming Activity Supply'
- __name__ = 'farming.variety.activity.supply'
- activity = fields.Many2One('farming.variety.activity', 'Activity')
+class VarietyStage(ModelSQL, ModelView):
+ "Variety Stage"
+ __name__ = "farming.variety.stage"
+ variety = fields.Many2One('farming.variety', 'Variety')
+ lot = fields.Many2One('farming.location.lot', 'Lot')
+ sequence = fields.Integer('Sequence', required=True)
+ stage = fields.Many2One('farming.stage', 'Stage', required=True)
+ start_time = fields.Integer('Start Time', help='Harvest week',
+ required=True)
+ production_rate = fields.Float('Production Rate', digits=(3, 2))
+ activities = fields.One2Many('farming.variety.stage.activity', 'stage',
+ 'Activities')
+
+
+class VarietyStageActivity(ModelSQL, ModelView):
+ 'Variety Stage Activity'
+ # 'farming.variety.activity' => 'farming.variety.stage.activity'
+ __name__ = 'farming.variety.stage.activity'
+ # variety = fields.Many2One('farming.variety', 'Variety')
+ stage = fields.Many2One('farming.variety.stage', 'Stage')
+ sequence = fields.Integer('Sequence', required=True)
+ kind = fields.Many2One('farming.activity.kind', 'Kind', required=True)
+ work_time = fields.Numeric('Work Time', required=True)
+ cost_per_hour = fields.Numeric('Cost Per Hour', digits=(16, 2))
+ uom = fields.Many2One('product.uom', 'Unit')
+ uom_time = fields.Many2One('product.uom', 'Unit of Time')
+ supplies = fields.One2Many('farming.variety.stage.activity.supply',
+ 'activity', 'Supply')
+ time_of_realization = fields.Integer('Time of Realization', required=True,
+ help='In weeks')
+
+ @fields.depends('kind', 'uom')
+ def on_change_kind(self):
+ if self.kind:
+ self.uom = self.kind.uom.id
+
+
+class VarietyStageActivitySupply(ModelSQL, ModelView):
+ 'Variety Stage Activity Supply'
+ __name__ = 'farming.variety.stage.activity.supply'
+ # farming.variety.activity.supply => farming.variety.stage.activity.supply
+ activity = fields.Many2One('farming.variety.stage.activity', 'Activity')
product = fields.Many2One("product.product", "Product", required=True)
quantity = fields.Float('Quantity', required=True)
- unit = fields.Many2One('product.uom', 'Unit',
- domain=[
+ 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'),
+ ], depends=['product_uom_category'])
+ product_uom_category = fields.Function(fields.Many2One(
+ 'product.uom.category', 'Product Uom Category'),
'on_change_with_product_uom_category')
+ unit_price = fields.Numeric('Unit Price', digits=(16, 2))
@fields.depends('product')
def on_change_with_unit(self, name=None):
@@ -88,43 +112,79 @@ class FarmingActivitySupply(ModelSQL, ModelView):
return None
-class FarmingVarietyActivity(ModelSQL, ModelView):
- 'Farming Variety Activity'
- __name__ = 'farming.variety.activity'
- variety = fields.Many2One('farming.variety', 'Variety')
- sequence = fields.Integer('Sequence', required=True)
- kind = fields.Many2One('farming.activity.kind', 'Kind', required=True)
- work_time = fields.Numeric('Work Time', required=True)
- cost_per_hour = fields.Numeric('Cost Per Hour', digits=(16, 2))
- uom = fields.Many2One('product.uom', 'Unit')
- uom_time = fields.Many2One('product.uom', 'Unit of Time')
- supplies = fields.One2Many('farming.variety.activity.supply', 'activity',
- 'Supply')
- time_of_realization = fields.Integer('Time of Realization', required=True,
- help='In weeks')
-
- @fields.depends('kind', 'uom')
- def on_change_kind(self):
- if self.kind:
- self.uom = self.kind.uom.id
-
-
-class CropStage(ModelSQL, ModelView):
+class CropStage(Workflow, ModelSQL, ModelView):
"Crop Stage"
__name__ = "farming.crop.stage"
+ sequence = fields.Integer('Sequence', required=True)
crop = fields.Many2One('farming.crop', 'Crop', required=True)
- activity = fields.Many2One('farming.crop.activity', 'Activity',
- states={"invisible": False})
stage = fields.Many2One('farming.stage', 'Stage', 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')
+ activities = fields.One2Many('farming.crop.stage.activity', 'stage',
+ 'Activity')
production_rate = fields.Float('Production Rate', digits=(3, 2))
quantity_planned = fields.Function(fields.Float('Qty. Planned',
digits=(6, 2)), 'get_quantity_planned')
quantity_produced = fields.Float('Qty. Produced', digits=(6, 2))
+ total_cost = fields.Function(fields.Numeric(
+ 'Total Cost', digits=(16, 2)), 'get_total_cost')
+ losses = fields.One2Many('farming.crop.stage.loss', 'stage', 'Losses')
+ total_losses = fields.Function(fields.Numeric(
+ 'Total Losses', digits=(16, 2)), 'get_total_losses')
+ state = fields.Selection([
+ ('pending', 'Pending'),
+ ('running', 'Running'),
+ ('finished', 'Finished'),
+ ('cancelled', 'Cancelled'),
+ ], 'State', readonly=True, required=True)
+
+ @classmethod
+ def __setup__(cls):
+ super(CropStage, cls).__setup__()
+ cls._order.insert(0, ('sequence', 'ASC'))
+ cls._transitions |= set((
+ ('pending', 'running'),
+ ('running', 'finished'),
+ ('running', 'pending'),
+ ))
+ cls._buttons.update({
+ 'pending': {
+ 'invisible': Eval('state').in_(['pending', 'finished'])
+ },
+ 'running': {
+ 'invisible': Eval('state').in_(['finished', 'running']),
+ },
+ 'finished': {
+ 'invisible': Eval('state') != 'running',
+ }})
+
+ @classmethod
+ @ModelView.button
+ @Workflow.transition('pending')
+ def pending(cls, records):
+ pass
+
+ @classmethod
+ @ModelView.button
+ @Workflow.transition('running')
+ def running(cls, records):
+ pass
+
+ @classmethod
+ @ModelView.button
+ @Workflow.transition('finished')
+ def finished(cls, records):
+ pass
+
+ @staticmethod
+ def default_state():
+ return 'pending'
+
+ def get_total_losses(self, name=None):
+ return sum(lo.quantity for lo in self.losses)
+
+ def get_total_cost(self, name=None):
+ return sum(act.total_cost or 0 for act in self.activities)
def get_quantity_planned(self, name=None):
res = 0
@@ -133,6 +193,15 @@ class CropStage(ModelSQL, ModelView):
return round(res, 2)
+class CropStageLoss(Workflow, ModelSQL, ModelView):
+ 'Crop Stage Loss'
+ __name__ = 'farming.crop.stage.loss'
+ stage = fields.Many2One('farming.crop.stage', 'Stage', ondelete='CASCADE')
+ date = fields.Date('Date', required=True)
+ quantity = fields.Integer('Quantity', required=True)
+ reason = fields.Text('Reason', required=True)
+
+
class Kind(ModelSQL, ModelView):
"Activity Kind"
__name__ = "farming.activity.kind"
@@ -142,7 +211,7 @@ class Kind(ModelSQL, ModelView):
help="Unit of time, according to activity time")
-class FarmingCrop(Workflow, ModelSQL, ModelView):
+class Crop(Workflow, ModelSQL, ModelView):
'Farming Crop'
__name__ = 'farming.crop'
_rec_name = 'number'
@@ -162,12 +231,13 @@ class FarmingCrop(Workflow, ModelSQL, ModelView):
total_plants = fields.Integer('Total Plants')
quantity_planned = fields.Function(fields.Float('Quantity Planned'),
'get_quantity_planned')
+ quantity_planned_net = fields.Function(fields.Float('Net. Quantity Planned'),
+ 'get_quantity_planned_net')
quantity_produced = fields.Float('Quantity Produced', states=STATES)
production_uom = fields.Many2One('product.uom', 'Production UoM', states=STATES)
lots = fields.One2Many('farming.crop.lot', 'crop', 'Lots', states=STATES)
stages = fields.One2Many('farming.crop.stage', 'crop', 'Stages',
states=STATES)
- activities = fields.One2Many('farming.crop.activity', 'crop', 'Activities')
seed = fields.Many2One('farming.seed', 'Seed', required=True)
analytic_account = fields.Many2One('analytic_account.account', 'Analytic Account')
production_rate = fields.Float('Production Rate')
@@ -179,22 +249,29 @@ class FarmingCrop(Workflow, ModelSQL, ModelView):
('cancelled', 'Cancelled'),
], 'State', readonly=True, required=True)
# moves for supplies
- supplies = fields.One2Many('farming.crop.activity.supply', 'crop', 'Supply')
+ # supplies = fields.One2Many('farming.crop.stage.activity.supply',
+ # 'crop', 'Supply')
# 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'),
+ performance = fields.Function(fields.Float('Performance', digits=(4, 2)),
'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')
+ # Deprecation warning: activities was moved to farming.crop.stage
+ # activities = fields.One2Many('farming.crop.activity', 'crop', 'Activities')
+ total_cost = fields.Function(fields.Numeric(
+ 'Total Cost', digits=(16, 2)), 'get_total_cost')
+ total_losses = fields.Function(fields.Numeric(
+ 'Total Losses', digits=(16, 2)), 'get_total_losses')
@classmethod
def __setup__(cls):
- super(FarmingCrop, cls).__setup__()
+ super(Crop, cls).__setup__()
cls._order.insert(0, ('create_date', 'DESC'))
cls._order.insert(1, ('id', 'DESC'))
cls._transitions |= set((
@@ -210,7 +287,7 @@ class FarmingCrop(Workflow, ModelSQL, ModelView):
'cancel': {
'invisible': Eval('state') == 'finished',
},
- 'load_activities': {
+ 'load_stages': {
'invisible': Eval('lines', []) | (Eval('state') != 'draft'),
'depends': ['state'],
},
@@ -263,6 +340,12 @@ class FarmingCrop(Workflow, ModelSQL, ModelView):
for record in records:
record.set_number()
+ def get_total_cost(self, name=None):
+ return sum(act.total_cost or 0 for act in self.stages)
+
+ def get_total_losses(self, name=None):
+ return sum(st.total_losses for st in self.stages)
+
@classmethod
def clear_bed_lines(cls, crops):
Line = Pool().get('farming.crop.lot.bed')
@@ -320,82 +403,134 @@ class FarmingCrop(Workflow, ModelSQL, ModelView):
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:
- effective_date = crop.start_date + timedelta(weeks=stage.start_time)
- line = Line(
- crop=crop.id,
- stage=stage.stage.id,
- production_rate=stage.production_rate,
- week=stage.start_time,
- effective_date=effective_date,
- )
- lines.append(line)
- Line.save(lines)
+ def _create_supplies(self, activity, crop_activity):
+ Supply = Pool().get('farming.crop.stage.activity.supply')
+ res = []
+ for sup in activity.supplies:
+ unit_price = sup.unit_price
+ if not unit_price:
+ unit_price = sup.product.cost_price
+ qty = sup.quantity * self.total_plants
+ amount = round(qty * float(unit_price), 2)
+ supply = Supply(
+ activity=crop_activity.id,
+ product=sup.product.id,
+ unit=sup.unit.id,
+ unit_price=unit_price,
+ quantity=qty,
+ cost_planned=amount,
+ cost_real=amount
+ )
+ res.append(supply)
+ return res
+
+ def _create_activities(self, stage, crop_stage):
+ Activity = Pool().get('farming.crop.stage.activity')
+ res = []
+ crop = crop_stage.crop
+ for act in stage.activities:
+ _date = crop.start_date + timedelta(weeks=act.time_of_realization)
+ work_time = act.work_time * crop.total_plants
+ # if act.uom_time.symbol == 'min':
+ # _cost = round((act.cost_per_hour / 60) * work_time, 2)
+ # elif act.uom_time.symbol == 'h':
+ # _cost = round(act.cost_per_hour * work_time, 2)
+ # elif act.uom_time.symbol == 's':
+ # _cost = round((act.cost_per_hour / 3600) * work_time, 2)
+ # else:
+ # _cost = round(act.cost_per_hour * work_time, 2)
+
+ activity = Activity(
+ stage=crop_stage.id,
+ sequence=act.sequence,
+ kind=act.kind.id,
+ work_time=work_time,
+ uom_time=act.uom_time.id,
+ week=act.time_of_realization,
+ planned_date=_date,
+ effective_date=_date,
+ )
+ supplies = self._create_supplies(act, activity)
+ activity.supplies = supplies
+ res.append(activity)
+ return res
+
+ def create_stages(self):
+ CropStage = Pool().get('farming.crop.stage')
+ to_save = []
+ for stage in self.variety.stages:
+ effec_date = self.start_date + timedelta(weeks=stage.start_time)
+ _stage = CropStage(
+ sequence=stage.sequence,
+ crop=self.id,
+ stage=stage.stage.id,
+ production_rate=stage.production_rate,
+ week=stage.start_time,
+ effective_date=effec_date,
+ )
+ _stage.activities = self._create_activities(stage, _stage)
+ to_save.append(_stage)
+ CropStage.save(to_save)
@classmethod
def clear_stages_lines(cls, crops):
Line = Pool().get('farming.crop.stage')
- lines_to_delete = []
+ to_delete = []
for crop in crops:
for stage in crop.stages:
- lines_to_delete.append(stage)
- Line.delete(lines_to_delete)
+ to_delete.append(stage)
+ Line.delete(to_delete)
- @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)
+ # @classmethod
+ # def clear_activities_lines(cls, crops):
+ # Line = Pool().get('farming.crop.stage.activity')
+ # lines_to_delete = []
+ # for crop in crops:
+ # for activity in crop.activities:
+ # lines_to_delete.append(activity)
+ # Line.delete(lines_to_delete)
- @classmethod
- def create_activities_lines(cls, crops):
- Line = Pool().get('farming.crop.activity')
- lines = []
- for crop in crops:
- for act in crop.variety.activities:
- _date = crop.start_date + timedelta(
- weeks=act.time_of_realization)
- work_time = act.work_time * crop.total_plants
- if act.uom_time.symbol == 'min':
- _cost = round((act.cost_per_hour / 60) * work_time, 2)
- elif act.uom_time.symbol == 'h':
- _cost = round(act.cost_per_hour * work_time, 2)
- elif act.uom_time.symbol == 's':
- _cost = round((act.cost_per_hour / 3600) * work_time, 2)
- else:
- _cost = round(act.cost_per_hour * work_time, 2)
-
- line = Line(
- crop=crop.id,
- sequence=act.sequence,
- kind=act.kind.id,
- work_time=work_time,
- workforce_cost=_cost,
- uom=act.uom.id,
- uom_time=act.uom_time.id,
- week=act.time_of_realization,
- planned_date=_date,
- effective_date=_date,
- )
- lines.append(line)
- Line.save(lines)
- cls.create_activity_supplies_lines(crops)
+ # @classmethod
+ # def create_activities_lines(cls, crops):
+ # Line = Pool().get('farming.crop.activity')
+ # lines = []
+ # for crop in crops:
+ # for act in crop.variety.activities:
+ # _date = crop.start_date + timedelta(
+ # weeks=act.time_of_realization)
+ # work_time = act.work_time * crop.total_plants
+ # if act.uom_time.symbol == 'min':
+ # _cost = round((act.cost_per_hour / 60) * work_time, 2)
+ # elif act.uom_time.symbol == 'h':
+ # _cost = round(act.cost_per_hour * work_time, 2)
+ # elif act.uom_time.symbol == 's':
+ # _cost = round((act.cost_per_hour / 3600) * work_time, 2)
+ # else:
+ # _cost = round(act.cost_per_hour * work_time, 2)
+ #
+ # line = Line(
+ # crop=crop.id,
+ # sequence=act.sequence,
+ # kind=act.kind.id,
+ # work_time=work_time,
+ # workforce_cost=_cost,
+ # uom=act.uom.id,
+ # uom_time=act.uom_time.id,
+ # week=act.time_of_realization,
+ # planned_date=_date,
+ # effective_date=_date,
+ # )
+ # lines.append(line)
+ # Line.save(lines)
+ # cls.create_activity_supplies_lines(crops)
@classmethod
def create_activity_supplies_lines(cls, crops):
- Line = Pool().get('farming.crop.activity.supply')
+ Line = Pool().get('farming.crop.stage.activity.supply')
lines = []
for crop in crops:
- for act_crop, act_variety in zip(crop.activities, crop.variety.activities):
+ for act_crop, act_variety in zip(
+ crop.activities, crop.variety.activities):
for supply in act_variety.supplies:
line = Line(
activity=act_crop.id,
@@ -413,9 +548,10 @@ class FarmingCrop(Workflow, ModelSQL, ModelView):
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)
+ for stage in crop.stages:
+ for activity in stage.activities:
+ for supply in activity.supplies:
+ lines_to_delete.append(supply)
Line.delete(lines_to_delete)
@classmethod
@@ -432,12 +568,14 @@ class FarmingCrop(Workflow, ModelSQL, ModelView):
@classmethod
@ModelView.button
- def load_activities(cls, crops):
+ def load_stages(cls, crops):
cls.clear_stages_lines(crops)
- cls.create_stages_lines(crops)
- cls.clear_supplies_lines(crops)
- cls.clear_activities_lines(crops)
- cls.create_activities_lines(crops)
+ for crop in crops:
+ crop.create_stages()
+ # cls.clear_stages_lines(crops)
+ # cls.clear_supplies_lines(crops)
+ # cls.clear_activities_lines(crops)
+ # cls.create_activities_lines(crops)
@classmethod
@ModelView.button
@@ -471,6 +609,10 @@ class FarmingCrop(Workflow, ModelSQL, ModelView):
number = config.farming_production_sequence.get()
self.write([self], {'number': number})
+ def get_quantity_planned_net(self, name=None):
+ return self.quantity_planned - (
+ self.total_losses * self.production_rate)
+
def get_quantity_planned(self, name=None):
res = []
_append = res.append
@@ -494,7 +636,7 @@ class FarmingCrop(Workflow, ModelSQL, ModelView):
return res
def get_performance(self, name):
- res = 0
+ res = (self.quantity_produced / self.quantity_planned_net) * 100
return res
def get_gross_profit_rate(self, name):
@@ -510,7 +652,7 @@ class FarmingCrop(Workflow, ModelSQL, ModelView):
if self.stages:
res = []
for stage in self.stages:
- res.append(stage.quantity_produced)
+ res.append(stage.quantity_produced or 0)
self.quantity_produced = sum(res)
@fields.depends('variety', 'production_uom', 'production_rate')
@@ -595,20 +737,19 @@ class FarmingCropLotBed(ModelSQL, ModelView):
quantity_plants = fields.Integer('Quantity Plants')
-class CropActivity(Workflow, ModelSQL, ModelView):
- 'Crop Activity'
- __name__ = 'farming.crop.activity'
- crop = fields.Many2One('farming.crop', 'Crop', ondelete='CASCADE',
- required=True)
- stage = fields.Many2One('farming.crop.stage', 'Stage')
+class CropStageActivity(Workflow, ModelSQL, ModelView):
+ 'Crop Stage Activity'
+ # farming.crop.activity => farming.crop.stage.activity
+ __name__ = 'farming.crop.stage.activity'
+ # crop = fields.Many2One('farming.crop', 'Crop', ondelete='CASCADE')
+ stage = fields.Many2One('farming.crop.stage', 'Stage', ondelete='CASCADE')
sequence = fields.Char('Sequence', states=STATES)
kind = fields.Many2One('farming.activity.kind', 'Kind')
work_time = fields.Numeric('Work Time')
- workforce_cost = fields.Numeric('Workforce Cost', digits=(16, 2))
- uom = fields.Many2One('product.uom', 'Unit')
+ # uom = fields.Many2One('product.uom', 'Unit')
uom_time = fields.Many2One('product.uom', 'UoM of Time')
- supplies = fields.One2Many('farming.crop.activity.supply', 'activity',
- 'Supply')
+ supplies = fields.One2Many('farming.crop.stage.activity.supply',
+ 'activity', 'Supply')
week = fields.Integer('Week')
planned_date = fields.Date('Planned Date')
effective_date = fields.Date('Effective Date')
@@ -618,12 +759,20 @@ class CropActivity(Workflow, ModelSQL, ModelView):
('finished', 'Finished'),
('cancelled', 'Cancelled'),
], 'State', readonly=True, required=True)
+ workforce_cost = fields.Function(fields.Numeric(
+ 'Workforce Cost', digits=(16, 2)), 'get_cost')
+ materials_cost = fields.Function(fields.Numeric(
+ 'Materials Cost', digits=(16, 2)), 'get_cost')
+ indirect_cost = fields.Function(fields.Numeric(
+ 'Indirect Cost', digits=(16, 2)), 'get_cost')
+ total_cost = fields.Function(fields.Numeric(
+ 'Total Cost', digits=(16, 2)), 'get_cost')
@classmethod
def generate_shipment(cls, records):
pool = Pool()
company = Transaction().context.get('company')
- Supply = pool.get('farming.crop.activity.supply')
+ Supply = pool.get('farming.crop.stage.activity.supply')
supplies = []
for record in records:
location = record.crop.location.warehouse
@@ -634,14 +783,14 @@ class CropActivity(Workflow, ModelSQL, ModelView):
unit=supplyRec.unit,
quantity=supplyRec.quantity,
)
- move = record._move(
- record,
- location.output_location,
- location.production_location,
- company,
- supplyRec.product,
- supplyRec.unit,
- supplyRec.quantity)
+ # move = record._move(
+ # record,
+ # location.output_location,
+ # location.production_location,
+ # company,
+ # supplyRec.product,
+ # supplyRec.unit,
+ # supplyRec.quantity)
supplies.append(supply)
Supply.save(supplies)
@@ -666,6 +815,15 @@ class CropActivity(Workflow, ModelSQL, ModelView):
Move.save([move])
return move
+ def get_cost(self, name=None):
+ res = []
+ for supply in self.supplies:
+ _name, _name_cost = name.split('_')
+ print(name, _name, _name_cost)
+ if supply.product.template.cost_type == _name or _name == 'total':
+ res.append(supply.cost_planned)
+ return sum(res)
+
@classmethod
def create_supply_moves(cls, location):
# pool = Pool()
@@ -697,7 +855,7 @@ class CropActivity(Workflow, ModelSQL, ModelView):
@classmethod
def __setup__(cls):
- super(CropActivity, cls).__setup__()
+ super(CropStageActivity, cls).__setup__()
cls._order.insert(0, ('planned_date', 'ASC'))
cls._transitions |= set((
('draft', 'production'),
@@ -800,24 +958,26 @@ class CropActivity(Workflow, ModelSQL, ModelView):
pass
-class CropActivitySupply(ModelSQL, ModelView):
- 'Crop Activity Supply'
- __name__ = 'farming.crop.activity.supply'
- crop = fields.Many2One('farming.crop', 'Crop')
- activity = fields.Many2One('farming.crop.activity', 'Activity',
+class CropStageActivitySupply(ModelSQL, ModelView):
+ 'Crop Stage Activity Supply'
+ # farming.crop.activity.supply => farming.crop.stage.activity.supply
+ __name__ = 'farming.crop.stage.activity.supply'
+ # crop = fields.Many2One('farming.crop', 'Crop')
+ activity = fields.Many2One('farming.crop.stage.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)
+ unit_price = fields.Numeric('Unit Price')
analytic_account = fields.Many2One('analytic_account.account',
'Analytic Account')
cost_planned = fields.Numeric('Cost Planned', readonly=True)
cost_real = fields.Numeric('Cost Real')
- def get_unity(self, name=None):
- unity = self.product.default_uom.name
- return unity
+ # def get_unit(self, name=None):
+ # unit = self.product.default_uom.name
+ # return unit
class Activity(Workflow, ModelSQL, ModelView):
diff --git a/crop.xml b/crop.xml
index b1db29f..9e39f8d 100644
--- a/crop.xml
+++ b/crop.xml
@@ -6,12 +6,12 @@ this repository contains the full copyright notices and license terms. -->
farming.crop.stage
tree
- farming_crop_stage_tree
+ crop_stage_tree
farming.crop.stage
form
- farming_crop_stage_form
+ crop_stage_form
@@ -25,15 +25,15 @@ this repository contains the full copyright notices and license terms. -->
farming_stage_form
-
- farming.variety.cycle
+
+ farming.variety.stage
tree
- variety_cycle_tree
+ variety_stage_tree
-
- farming.variety.cycle
+
+ farming.variety.stage
form
- variety_cycle_form
+ variety_stage_form
@@ -64,20 +64,20 @@ this repository contains the full copyright notices and license terms. -->
action="act_farming_variety_tree" id="menu_farming_variety_tree"/>
- farming.variety.activity.supply
+ farming.variety.stage.activity.supply
tree
- farming_activity_supply_tree
+ variety_activity_stage_supply_tree
-
- farming.variety.activity
+
+ farming.variety.stage.activity
tree
- variety_activity_tree
+ variety_stage_activity_tree
-
- farming.variety.activity
+
+ farming.variety.stage.activity
form
- variety_activity_form
+ variety_stage_activity_form
@@ -111,12 +111,12 @@ this repository contains the full copyright notices and license terms. -->
farming.crop
form
- farming_crop_form
+ crop_form
farming.crop
tree
- farming_crop_tree
+ crop_tree
Crop
@@ -187,26 +187,26 @@ this repository contains the full copyright notices and license terms. -->
farming_crop_lot_bed_form
-
- farming.crop.activity
+
+ farming.crop.stage.activity
tree
- farming_crop_activity_tree
+ crop_stage_activity_tree
-
- farming.crop.activity
+
+ farming.crop.stage.activity
form
- farming_crop_activity_form
+ crop_stage_activity_form
-
- farming.crop.activity.supply
+
+ farming.crop.stage.activity.supply
tree
- farming_crop_supply_tree
+ crop_stage_activity_supply_tree
-
- farming.crop.activity.supply
+
+ farming.crop.stage.activity.supply
form
- farming_crop_supply_form
+ crop_stage_activity_supply_form
@@ -324,8 +324,19 @@ this repository contains the full copyright notices and license terms. -->
-
-
-
-
+
+
+
@@ -27,22 +27,24 @@ this repository contains the full copyright notices and license terms. -->
-
+
+
+
+
+
+
-
-
-
-
+
@@ -55,9 +57,9 @@ this repository contains the full copyright notices and license terms. -->
-
+
@@ -65,18 +67,16 @@ this repository contains the full copyright notices and license terms. -->
-
+
+
+
-
-
-
-
+
+
+
+
diff --git a/view/farming_crop_activity_form.xml b/view/crop_stage_activity_form.xml
similarity index 76%
rename from view/farming_crop_activity_form.xml
rename to view/crop_stage_activity_form.xml
index 7d26fdc..22cf511 100644
--- a/view/farming_crop_activity_form.xml
+++ b/view/crop_stage_activity_form.xml
@@ -15,10 +15,16 @@ this repository contains the full copyright notices and license terms. -->
-
-
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/view/farming_crop_supply_form.xml b/view/crop_stage_activity_supply_form.xml
similarity index 89%
rename from view/farming_crop_supply_form.xml
rename to view/crop_stage_activity_supply_form.xml
index 9b80f76..9c47dcc 100644
--- a/view/farming_crop_supply_form.xml
+++ b/view/crop_stage_activity_supply_form.xml
@@ -6,8 +6,8 @@ this repository contains the full copyright notices and license terms. -->
-
-
+
+
diff --git a/view/farming_crop_supply_tree.xml b/view/crop_stage_activity_supply_tree.xml
similarity index 90%
rename from view/farming_crop_supply_tree.xml
rename to view/crop_stage_activity_supply_tree.xml
index 407617b..4275854 100644
--- a/view/farming_crop_supply_tree.xml
+++ b/view/crop_stage_activity_supply_tree.xml
@@ -3,8 +3,9 @@
this repository contains the full copyright notices and license terms. -->
-
+
+
diff --git a/view/farming_crop_activity_tree.xml b/view/crop_stage_activity_tree.xml
similarity index 100%
rename from view/farming_crop_activity_tree.xml
rename to view/crop_stage_activity_tree.xml
diff --git a/view/farming_crop_stage_form.xml b/view/crop_stage_form.xml
similarity index 61%
rename from view/farming_crop_stage_form.xml
rename to view/crop_stage_form.xml
index 6043065..dd335a0 100644
--- a/view/farming_crop_stage_form.xml
+++ b/view/crop_stage_form.xml
@@ -4,15 +4,24 @@ this repository contains the full copyright notices and license terms. -->
diff --git a/view/crop_stage_loss_form.xml b/view/crop_stage_loss_form.xml
new file mode 100644
index 0000000..1b19930
--- /dev/null
+++ b/view/crop_stage_loss_form.xml
@@ -0,0 +1,11 @@
+
+
+
diff --git a/view/crop_stage_loss_tree.xml b/view/crop_stage_loss_tree.xml
new file mode 100644
index 0000000..2b0a46b
--- /dev/null
+++ b/view/crop_stage_loss_tree.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/view/farming_crop_stage_tree.xml b/view/crop_stage_tree.xml
similarity index 73%
rename from view/farming_crop_stage_tree.xml
rename to view/crop_stage_tree.xml
index b007c9c..fb3715d 100644
--- a/view/farming_crop_stage_tree.xml
+++ b/view/crop_stage_tree.xml
@@ -1,9 +1,12 @@
+
+
+
diff --git a/view/farming_crop_tree.xml b/view/crop_tree.xml
similarity index 100%
rename from view/farming_crop_tree.xml
rename to view/crop_tree.xml
diff --git a/view/template_form.xml b/view/template_form.xml
index 73deab2..b6f492d 100644
--- a/view/template_form.xml
+++ b/view/template_form.xml
@@ -6,6 +6,8 @@ this repository contains the full copyright notices and license terms. -->
position="after">
+
+
diff --git a/view/farming_activity_supply_tree.xml b/view/variety_activity_stage_supply_tree.xml
similarity index 88%
rename from view/farming_activity_supply_tree.xml
rename to view/variety_activity_stage_supply_tree.xml
index 2e0fd06..c6485cb 100644
--- a/view/farming_activity_supply_tree.xml
+++ b/view/variety_activity_stage_supply_tree.xml
@@ -5,4 +5,5 @@ this repository contains the full copyright notices and license terms. -->
+
diff --git a/view/variety_form.xml b/view/variety_form.xml
index 439cee2..6c98222 100644
--- a/view/variety_form.xml
+++ b/view/variety_form.xml
@@ -13,6 +13,6 @@ this repository contains the full copyright notices and license terms. -->
-
-
+
+
diff --git a/view/variety_activity_form.xml b/view/variety_stage_activity_form.xml
similarity index 88%
rename from view/variety_activity_form.xml
rename to view/variety_stage_activity_form.xml
index d1dd3b1..f97ccf9 100644
--- a/view/variety_activity_form.xml
+++ b/view/variety_stage_activity_form.xml
@@ -14,8 +14,5 @@ this repository contains the full copyright notices and license terms. -->
-
-
-
diff --git a/view/variety_activity_tree.xml b/view/variety_stage_activity_tree.xml
similarity index 100%
rename from view/variety_activity_tree.xml
rename to view/variety_stage_activity_tree.xml
diff --git a/view/variety_cycle_form.xml b/view/variety_stage_form.xml
similarity index 90%
rename from view/variety_cycle_form.xml
rename to view/variety_stage_form.xml
index 59e08c9..fbcd2c3 100644
--- a/view/variety_cycle_form.xml
+++ b/view/variety_stage_form.xml
@@ -10,4 +10,5 @@ this repository contains the full copyright notices and license terms. -->
+
diff --git a/view/variety_cycle_tree.xml b/view/variety_stage_tree.xml
similarity index 100%
rename from view/variety_cycle_tree.xml
rename to view/variety_stage_tree.xml