[FIX/IMP] mrp_production_project_estimated_cost: Fix some calculations + refactor methods

This commit is contained in:
Pedro M. Baeza
2015-09-04 01:10:34 +02:00
committed by Oihane Crucelaegui
parent adf3fc0ef4
commit e59097a127

View File

@@ -148,9 +148,26 @@ class MrpProduction(models.Model):
'context': self.env.context
}
def _prepare_cost_analytic_line(self, journal, name, production, product,
general_account=None, workorder=None,
qty=1, amount=0, estim_std=0, estim_avg=0):
@api.model
def _prepare_cost_analytic_line(
self, journal, name, production, product, general_account=None,
workorder=None, qty=1, std_cost=0, avg_cost=0):
"""
Prepare the vals for creating an analytic entry for stimated cost
:param journal: Journal of the entry
:param name: Name of the entry
:param production: Origin product
:param product: Product for the entry
:param general_account: General account for the entry
:param workorder: Origin workorder
:param qty: Quantity for the entry. This quantity will multiply both
standard and average costs for the entry costs.
:param std_cost: Cost for calculating estimated standard cost. If 0,
then product manual standard cost will be used.
:param avg_cost: Cost for calculating estimated average cost. If 0,
then product cost will be used.
:return: Dictionary with the analytic entry vals.
"""
analytic_line_obj = self.env['account.analytic.line']
property_obj = self.env['ir.property']
if not general_account:
@@ -159,11 +176,11 @@ class MrpProduction(models.Model):
product.categ_id.property_account_income_categ or
property_obj.get('property_account_expense_categ',
'product.category'))
if not self.analytic_account_id:
if not production.analytic_account_id:
raise exceptions.Warning(
_('You must define one Analytic Account for this MO: %s') %
(production.name))
vals = {
return {
'name': name,
'mrp_production_id': production.id,
'workorder': workorder and workorder.id or False,
@@ -173,13 +190,121 @@ class MrpProduction(models.Model):
'date': analytic_line_obj._get_default_date(),
'product_id': product and product.id or False,
'unit_amount': qty,
'amount': amount,
'product_uom_id': product and product.uom_id.id or False,
'amount': 0,
'product_uom_id': product.uom_id.id,
'general_account_id': general_account.id,
'estim_std_cost': estim_std,
'estim_avg_cost': estim_avg,
'estim_std_cost': -qty * (std_cost or
product.manual_standard_cost),
'estim_avg_cost': -qty * (avg_cost or product.cost_price),
}
return vals
@api.model
def _create_material_estimated_cost(self, prod, product_line):
if not product_line.product_id:
raise exceptions.Warning(
_("One consume line has no product assigned."))
journal = self.env.ref('mrp_production_project_estimated_cost.'
'analytic_journal_materials', False)
name = _('%s-%s' % (prod.name, product_line.work_order.name or ''))
product = product_line.product_id
qty = product_line.product_qty
vals = self._prepare_cost_analytic_line(
journal, name, prod, product, workorder=product_line.work_order,
qty=qty)
return self.env['account.analytic.line'].create(vals)
@api.model
def _create_pre_operation_estimated_cost(self, prod, wc, workorder):
if (wc.time_start and workorder.workcenter_id.pre_op_product):
product = workorder.workcenter_id.pre_op_product
if not product:
raise exceptions.Warning(
_("Workcenter '%s' doesn't have pre-operation costing "
"product.") % workorder.workcenter_id.name)
journal = self.env.ref('mrp_production_project_estimated_cost.'
'analytic_journal_machines', False)
name = (_('%s-%s Pre-operation') %
(prod.name, workorder.workcenter_id.name))
vals = self._prepare_cost_analytic_line(
journal, name, prod, product, workorder=workorder,
qty=wc.time_start)
return self.env['account.analytic.line'].create(vals)
@api.model
def _create_post_operation_estimated_cost(self, prod, wc, workorder):
if (wc.time_stop and workorder.workcenter_id.post_op_product):
product = workorder.workcenter_id.post_op_product
if not product:
raise exceptions.Warning(
_("Workcenter '%s' doesn't have post-operation costing "
"product.") % workorder.workcenter_id.name)
journal = self.env.ref('mrp_production_project_estimated_cost.'
'analytic_journal_machines', False)
name = (_('%s-%s Post-operation') %
(prod.name, workorder.workcenter_id.name))
vals = self._prepare_cost_analytic_line(
journal, name, prod, product, workorder=workorder,
qty=wc.time_stop)
return self.env['account.analytic.line'].create(vals)
@api.model
def _create_worcenter_cycles_estimated_cost(self, prod, wc, workorder):
if workorder.cycle and workorder.workcenter_id.costs_cycle:
journal = prod.env.ref('mrp_production_project_estimated_cost.'
'analytic_journal_machines', False)
product = workorder.workcenter_id.product_id
if not product:
raise exceptions.Warning(
_("There is at least this workcenter without "
"product: %s") % workorder.workcenter_id.name)
name = (_('%s-%s-C-%s') %
(prod.name, workorder.routing_wc_line.operation.code,
workorder.workcenter_id.name))
cost = workorder.workcenter_id.costs_cycle
vals = self._prepare_cost_analytic_line(
journal, name, prod, product, workorder=workorder,
qty=workorder.cycle, std_cost=cost, avg_cost=cost)
return self.env['account.analytic.line'].create(vals)
@api.model
def _create_worcenter_hours_estimated_cost(self, prod, wc, workorder):
if workorder.hour and workorder.workcenter_id.costs_hour:
product = workorder.workcenter_id.product_id
if not product:
raise exceptions.Warning(
_("There is at least this workcenter without "
"product: %s") % workorder.workcenter_id.name)
journal = self.env.ref('mrp_production_project_estimated_cost.'
'analytic_journal_machines', False)
name = (_('%s-%s-H-%s') %
(prod.name, workorder.routing_wc_line.operation.code,
workorder.workcenter_id.name))
cost = workorder.workcenter_id.costs_hour
vals = self._prepare_cost_analytic_line(
journal, name, prod, product, workorder=workorder,
qty=workorder.hour, std_cost=cost, avg_cost=cost)
return self.env['account.analytic.line'].create(vals)
@api.model
def _create_operators_estimated_cost(self, prod, wc, workorder):
if wc.op_number > 0 and workorder.hour:
product = workorder.workcenter_id.product_id
if not product:
raise exceptions.Warning(
_("There is at least this workcenter without "
"product: %s") % workorder.workcenter_id.name)
journal = self.env.ref(
'mrp_production_project_estimated_cost.'
'analytic_journal_operators', False)
name = (_('%s-%s-%s') %
(prod.name, workorder.routing_wc_line.operation.code,
product.name))
cost = wc.op_avg_cost
qty = workorder.hour * wc.op_number
vals = self._prepare_cost_analytic_line(
journal, name, prod, product, workorder=workorder, qty=qty,
std_cost=cost, avg_cost=cost)
return self.env['account.analytic.line'].create(vals)
@api.multi
def calculate_production_estimated_cost(self):
@@ -187,103 +312,22 @@ class MrpProduction(models.Model):
for record in self:
cond = [('mrp_production_id', '=', record.id)]
analytic_line_obj.search(cond).unlink()
journal = record.env.ref('mrp_production_project_estimated_cost.'
'analytic_journal_materials', False)
for line in record.product_lines:
if not line.product_id:
raise exceptions.Warning(
_("One consume line has no product assigned."))
name = _('%s-%s' % (record.name, line.work_order.name or ''))
product = line.product_id
qty = line.product_qty
vals = record._prepare_cost_analytic_line(
journal, name, record, product, workorder=line.work_order,
qty=qty, estim_std=-(qty * product.manual_standard_cost),
estim_avg=-(qty * product.cost_price))
analytic_line_obj.create(vals)
journal = record.env.ref('mrp_production_project_estimated_cost.'
'analytic_journal_machines', False)
for product_line in record.product_lines:
self._create_material_estimated_cost(
self, record, product_line)
for line in record.workcenter_lines:
op_wc_lines = line.routing_wc_line.op_wc_lines
wc = op_wc_lines.filtered(lambda r: r.workcenter ==
line.workcenter_id) or \
line.workcenter_id
if (wc.time_start and line.workcenter_id.pre_op_product):
name = (_('%s-%s Pre-operation') %
(record.name, line.workcenter_id.name))
product = line.workcenter_id.pre_op_product
amount = product.cost_price * wc.time_start
qty = wc.time_start
vals = record._prepare_cost_analytic_line(
journal, name, record, product, workorder=line,
qty=qty, amount=-amount,
estim_std=-(qty * product.manual_standard_cost),
estim_avg=-(amount))
analytic_line_obj.create(vals)
if (wc.time_stop and line.workcenter_id.post_op_product):
name = (_('%s-%s Post-operation') %
(record.name, line.workcenter_id.name))
product = line.workcenter_id.post_op_product
amount = product.cost_price * wc.time_stop
qty = wc.time_stop
vals = record._prepare_cost_analytic_line(
journal, name, record, product, workorder=line,
qty=qty, amount=-amount,
estim_std=-(qty * product.manual_standard_cost),
estim_avg=-(amount))
analytic_line_obj.create(vals)
if line.cycle and line.workcenter_id.costs_cycle:
if not line.workcenter_id.product_id:
raise exceptions.Warning(
_("There is at least this workcenter without "
"product: %s") % line.workcenter_id.name)
name = (_('%s-%s-C-%s') %
(record.name, line.routing_wc_line.operation.code,
line.workcenter_id.name))
product = line.workcenter_id.product_id
estim_cost = -(line.workcenter_id.costs_cycle * line.cycle)
vals = record._prepare_cost_analytic_line(
journal, name, record, product, workorder=line,
qty=line.cycle, estim_std=estim_cost,
estim_avg=estim_cost)
analytic_line_obj.create(vals)
if line.hour and line.workcenter_id.costs_hour:
if not line.workcenter_id.product_id:
raise exceptions.Warning(
_("There is at least this workcenter without "
"product: %s") % line.workcenter_id.name)
name = (_('%s-%s-H-%s') %
(record.name, line.routing_wc_line.operation.code,
line.workcenter_id.name))
hour = line.hour
if wc.time_stop and not line.workcenter_id.post_op_product:
hour += wc.time_stop
if wc.time_start and not line.workcenter_id.pre_op_product:
hour += wc.time_start
estim_cost = -(hour * line.workcenter_id.costs_hour)
vals = record._prepare_cost_analytic_line(
journal, name, record, line.workcenter_id.product_id,
workorder=line, qty=hour,
estim_std=estim_cost, estim_avg=estim_cost)
analytic_line_obj.create(vals)
if wc.op_number > 0 and line.hour:
if not line.workcenter_id.product_id:
raise exceptions.Warning(
_("There is at least this workcenter without "
"product: %s") % line.workcenter_id.name)
journal = record.env.ref(
'mrp_production_project_estimated_cost.analytic_'
'journal_operators', False)
name = (_('%s-%s-%s') %
(record.name, line.routing_wc_line.operation.code,
line.workcenter_id.product_id.name))
estim_cost = -(wc.op_number * wc.op_avg_cost * line.hour)
qty = line.hour * wc.op_number
vals = record._prepare_cost_analytic_line(
journal, name, record, line.workcenter_id.product_id,
workorder=line, qty=qty, estim_std=estim_cost,
estim_avg=estim_cost)
analytic_line_obj.create(vals)
self._create_pre_operation_estimated_cost(record, wc, line)
self._create_post_operation_estimated_cost(record, wc, line)
done = self._create_worcenter_cycles_estimated_cost(
record, wc, line)
if not done:
self._create_worcenter_hours_estimated_cost(
record, wc, line)
self._create_operators_estimated_cost(record, wc, line)
@api.multi
def load_product_std_price(self):