Files
odoo_source/addons/mrp_account/models/mrp_production.py
T
Simon Lejeune e972d25400 [REF] mrp_account: add an extra_cost notion on the manufacturing order
This is a preliminary work to handle the price of subcontracting. We put
this field in the generic `mrp_account` module because we also want to
support adding an extra cost on a finished move without having to work
with the wokorders, on a future task.

task 1831382
2019-04-03 13:51:05 +00:00

72 lines
3.4 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models
from odoo.tools import float_is_zero
class MrpProductionWorkcenterLineTime(models.Model):
_inherit = 'mrp.workcenter.productivity'
cost_already_recorded = fields.Boolean('Cost Recorded', help="Technical field automatically checked when a ongoing production posts journal entries for its costs. This way, we can record one production's cost multiple times and only consider new entries in the work centers time lines.")
class MrpProduction(models.Model):
_inherit = 'mrp.production'
extra_cost = fields.Float(copy=False, help='Extra cost per produced unit')
def _cal_price(self, consumed_moves):
"""Set a price unit on the finished move according to `consumed_moves`.
"""
super(MrpProduction, self)._cal_price(consumed_moves)
work_center_cost = 0
finished_move = self.move_finished_ids.filtered(lambda x: x.product_id == self.product_id and x.state not in ('done', 'cancel') and x.quantity_done > 0)
if finished_move:
finished_move.ensure_one()
for work_order in self.workorder_ids:
time_lines = work_order.time_ids.filtered(lambda x: x.date_end and not x.cost_already_recorded)
duration = sum(time_lines.mapped('duration'))
time_lines.write({'cost_already_recorded': True})
work_center_cost += (duration / 60.0) * work_order.workcenter_id.costs_hour
if finished_move.product_id.cost_method in ('fifo', 'average'):
qty_done = finished_move.product_uom._compute_quantity(finished_move.quantity_done, finished_move.product_id.uom_id)
extra_cost = self.extra_cost * qty_done
finished_move.price_unit = (sum([-m.value for m in consumed_moves]) + work_center_cost + extra_cost) / qty_done
finished_move.value = sum([-m.value for m in consumed_moves]) + work_center_cost + extra_cost
return True
def _prepare_wc_analytic_line(self, wc_line):
wc = wc_line.workcenter_id
hours = wc_line.duration / 60.0
value = hours * wc.costs_hour
account = wc.costs_hour_account_id.id
return {
'name': wc_line.name + ' (H)',
'amount': -value,
'account_id': account,
'ref': wc.code,
'unit_amount': hours,
}
def _costs_generate(self):
""" Calculates total costs at the end of the production.
"""
self.ensure_one()
AccountAnalyticLine = self.env['account.analytic.line'].sudo()
for wc_line in self.workorder_ids.filtered('workcenter_id.costs_hour_account_id'):
vals = self._prepare_wc_analytic_line(wc_line)
precision_rounding = wc_line.workcenter_id.costs_hour_account_id.currency_id.rounding
if not float_is_zero(vals.get('amount', 0.0), precision_rounding=precision_rounding):
# we use SUPERUSER_ID as we do not guarantee an mrp user
# has access to account analytic lines but still should be
# able to produce orders
AccountAnalyticLine.create(vals)
@api.multi
def button_mark_done(self):
self.ensure_one()
res = super(MrpProduction, self).button_mark_done()
self._costs_generate()
return res