[ADD] product_variant_cost: Module for cost at variant level

This commit is contained in:
agaldona
2015-05-28 17:56:28 +02:00
committed by Oihane Crucelaegui
parent 31589bb887
commit 03cd3f8895
6 changed files with 121 additions and 69 deletions

View File

@@ -36,6 +36,7 @@
"mrp",
"mrp_operations_extension",
"mrp_project_link",
"product_variant_cost"
],
"data": [
"data/analytic_journal_data.xml",

View File

@@ -24,7 +24,7 @@ class MrpBom(models.Model):
_inherit = "mrp.bom"
product_standard_price = fields.Float(string="Product Standard Price",
related="product_id.standard_price")
related="product_id.cost_price")
product_manual_standard_price = fields.Float(
string="Product Manual Standard Price",
related="product_id.manual_standard_cost")

View File

@@ -63,7 +63,7 @@ class MrpProduction(models.Model):
string="Product Manual Cost",
related="product_id.manual_standard_cost")
product_cost = fields.Float(
string="Product Cost", related="product_id.standard_price")
string="Product Cost", related="product_id.cost_price")
analytic_line_ids = fields.One2many(
comodel_name="account.analytic.line", inverse_name="mrp_production_id",
string="Cost Lines")
@@ -148,6 +148,39 @@ 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):
analytic_line_obj = self.env['account.analytic.line']
property_obj = self.env['ir.property']
if not general_account:
general_account = (
product.property_account_income or
product.categ_id.property_account_income_categ or
property_obj.get('property_account_expense_categ',
'product.category'))
if not self.analytic_account_id:
raise exceptions.Warning(
_('You must define one Analytic Account for this MO: %s') %
(production.name))
vals = {
'name': name,
'mrp_production_id': production.id,
'workorder': workorder and workorder.id or False,
'account_id': self.analytic_account_id.id,
'journal_id': journal.id,
'user_id': self.env.uid,
'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,
'general_account_id': general_account.id,
'estim_std_cost': estim_std,
'estim_avg_cost': estim_avg,
}
return vals
@api.multi
def calculate_production_estimated_cost(self):
analytic_line_obj = self.env['account.analytic.line']
@@ -161,9 +194,12 @@ class MrpProduction(models.Model):
raise exceptions.Warning(
_("One consume line has no product assigned."))
name = _('%s-%s' % (record.name, line.work_order.name or ''))
vals = record._prepare_estim_cost_analytic_line(
journal, name, record, line.work_order, line.product_id,
line.product_qty)
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)
@@ -175,20 +211,26 @@ class MrpProduction(models.Model):
if (wc.time_start and line.workcenter_id.pre_op_product):
name = (_('%s-%s Pre-operation') %
(record.name, line.workcenter_id.name))
vals = record._prepare_estim_cost_analytic_line(
journal, name, record, line,
line.workcenter_id.pre_op_product, wc.time_start)
amount = line.workcenter_id.pre_op_product.standard_price
vals['amount'] = amount
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))
vals = record._prepare_estim_cost_analytic_line(
journal, name, record, line,
line.workcenter_id.post_op_product, wc.time_stop)
amount = line.workcenter_id.post_op_product.standard_price
vals['amount'] = amount
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:
@@ -198,12 +240,12 @@ class MrpProduction(models.Model):
name = (_('%s-%s-C-%s') %
(record.name, line.routing_wc_line.operation.code,
line.workcenter_id.name))
vals = record._prepare_estim_cost_analytic_line(
journal, name, record, line,
line.workcenter_id.product_id, line.cycle)
cost = line.workcenter_id.costs_cycle
vals['estim_avg_cost'] = line.cycle * cost
vals['estim_std_cost'] = vals['estim_avg_cost']
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:
@@ -218,67 +260,38 @@ class MrpProduction(models.Model):
hour += wc.time_stop
if wc.time_start and not line.workcenter_id.pre_op_product:
hour += wc.time_start
vals = record._prepare_estim_cost_analytic_line(
journal, name, record, line,
line.workcenter_id.product_id, hour)
cost = line.workcenter_id.costs_hour
vals['estim_avg_cost'] = hour * cost
vals['estim_std_cost'] = vals['estim_avg_cost']
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_wk = record.env.ref(
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))
vals = record._prepare_estim_cost_analytic_line(
journal_wk, name, record, line,
line.workcenter_id.product_id,
line.hour * wc.op_number)
vals['estim_avg_cost'] = (wc.op_number * wc.op_avg_cost *
line.hour)
vals['estim_std_cost'] = vals['estim_avg_cost']
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)
def _prepare_estim_cost_analytic_line(self, journal, name, production,
workorder, product, qty):
analytic_line_obj = self.env['account.analytic.line']
general_account = (product.property_account_income or
product.categ_id.property_account_income_categ or
False)
if not general_account:
raise exceptions.Warning(
_('You must define Income account in the product "%s", or in'
' the product category') % (product.name))
if not self.analytic_account_id:
raise exceptions.Warning(
_('You must define one Analytic Account for this MO: %s') %
(production.name))
vals = {
'name': name,
'mrp_production_id': production.id,
'workorder': workorder.id,
'account_id': self.analytic_account_id.id,
'journal_id': journal.id,
'user_id': self._uid,
'date': analytic_line_obj._get_default_date(),
'product_id': product.id,
'unit_amount': qty,
'product_uom_id': product.uom_id.id,
'general_account_id': general_account.id,
'estim_std_cost': qty * product.manual_standard_cost,
'estim_avg_cost': qty * product.standard_price,
}
return vals
@api.multi
def load_product_std_price(self):
for record in self:
product = record.product_id
if record.unit_std_cost:
product.manual_standard_cost = record.unit_std_cost
@api.multi
def _get_min_qty_for_production(self, routing=False):
return 1

View File

@@ -20,6 +20,9 @@
<field name="model">account.analytic.line</field>
<field name="inherit_id" ref="account.view_account_analytic_line_tree"/>
<field name="arch" type="xml">
<field name="journal_id" position="before">
<field name="product_id"/>
</field>
<field name="journal_id" position="after">
<field name="estim_std_cost" />
<field name="estim_avg_cost" />
@@ -36,6 +39,7 @@
<field name="date"/>
<field name="ref"/>
<field name="name"/>
<field name="product_id"/>
<field name="journal_id"/>
<field name="estim_avg_cost"/>
<field name="estim_std_cost"/>
@@ -49,5 +53,19 @@
</field>
</record>
<record id="action_show_production_anaytic_lines" model="ir.actions.act_window">
<field name="name">Production Analytic Lines</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">account.analytic.line</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" eval="estimated_cost_list_view"/>
<field name="context">{'default_mrp_production_id': active_id,
'search_default_group_production': 1,
'search_default_group_workorder': 1,
'search_default_group_journal': 1}</field>
<field name="domain">[('mrp_production_id','=',active_id)]</field>
</record>
</data>
</openerp>

View File

@@ -83,10 +83,16 @@
<div name="buttons" position="inside">
<button class="oe_inline oe_stat_button"
type="object"
string="Estim. Costs"
string="Costs analysis"
name="action_show_estimated_costs"
icon="fa-bar-chart">
</button>
<button class="oe_inline oe_stat_button"
type="action"
string="Production Costs"
name="%(action_show_production_anaytic_lines)d"
icon="fa-list">
</button>
</div>
</field>
</record>

View File

@@ -9,7 +9,7 @@ class WizCreateFictitiousOf(models.TransientModel):
_name = "wiz.create.fictitious.of"
date_planned = fields.Datetime(
string='Scheduled Date', required=True, default=fields.Datetime.now())
string='Scheduled Date', required=True, default=fields.Datetime.now)
load_on_product = fields.Boolean("Load cost on product")
project_id = fields.Many2one("project.project", string="Project")
@@ -17,6 +17,7 @@ class WizCreateFictitiousOf(models.TransientModel):
def do_create_fictitious_of(self):
production_obj = self.env['mrp.production']
product_obj = self.env['product.product']
routing_obj = self.env['mrp.routing']
self.ensure_one()
active_ids = self.env.context['active_ids']
active_model = self.env.context['active_model']
@@ -34,8 +35,21 @@ class WizCreateFictitiousOf(models.TransientModel):
'user_id': self._uid,
'active': False,
'product_uom': product.uom_id.id,
'project_id': self.project_id.id
'project_id': self.project_id.id,
'analytic_account_id': (
self.project_id.analytic_account_id.id)
}
prod_vals = production_obj.product_id_change(product.id,
1)['value']
vals.update(prod_vals)
if 'routing_id' in vals:
routing = routing_obj.browse(vals['routing_id'])
product_qty = production_obj._get_min_qty_for_production(
routing)
vals['product_qty'] = product_qty
prod_vals = production_obj.product_id_change(
product.id, product_qty)['value']
vals.update(prod_vals)
new_production = production_obj.create(vals)
new_production.action_compute()
production_list.append(new_production.id)