mirror of
https://github.com/OCA/manufacture.git
synced 2025-01-28 16:37:15 +02:00
[FIX/IMP] mrp_production_project_estimated_cost: Fix some calculations + refactor methods
This commit is contained in:
committed by
Oihane Crucelaegui
parent
adf3fc0ef4
commit
e59097a127
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user