mirror of
https://github.com/OCA/manufacture.git
synced 2025-01-28 16:37:15 +02:00
[IMP] mrp_production_project_estimated_cost: Cost load in positive.
[IMP] mrp_production_real_costs: The quant's cost will be loaded every Consume or Produce action and when ends a MO. New configurable check to load final product cost in analytic or not Closes #1001 #1010
This commit is contained in:
@@ -17,3 +17,4 @@
|
||||
##############################################################################
|
||||
|
||||
from . import models
|
||||
from . import wizard
|
||||
|
||||
@@ -32,7 +32,8 @@
|
||||
"category": "MRP",
|
||||
'data': [
|
||||
"data/analytic_journal_data.xml",
|
||||
"views/mrp_production_view.xml"
|
||||
"views/mrp_production_view.xml",
|
||||
"views/res_config_view.xml"
|
||||
],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
|
||||
@@ -21,3 +21,4 @@ from . import mrp_production_workcenter_line
|
||||
from . import project_task_work
|
||||
from . import mrp_production
|
||||
from . import mrp_bom
|
||||
from . import mrp_config
|
||||
|
||||
43
mrp_production_real_cost/models/mrp_config.py
Normal file
43
mrp_production_real_cost/models/mrp_config.py
Normal file
@@ -0,0 +1,43 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) 2015 Ainara Galdona - AvanzOSC
|
||||
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
|
||||
|
||||
from openerp import api, fields, models
|
||||
|
||||
|
||||
class MrpConfigSettings(models.TransientModel):
|
||||
_inherit = 'mrp.config.settings'
|
||||
|
||||
final_product_analytic_cost = fields.Boolean(
|
||||
string='Load final product analytic cost',
|
||||
help='This will allow you to define if those BoM passed back to draft'
|
||||
' are still activated or not')
|
||||
|
||||
def _get_parameter(self, key, default=False):
|
||||
param_obj = self.env['ir.config_parameter']
|
||||
rec = param_obj.search([('key', '=', key)])
|
||||
return rec or default
|
||||
|
||||
def _write_or_create_param(self, key, value):
|
||||
param_obj = self.env['ir.config_parameter']
|
||||
rec = self._get_parameter(key)
|
||||
if rec:
|
||||
if not value:
|
||||
rec.unlink()
|
||||
else:
|
||||
rec.value = value
|
||||
elif value:
|
||||
param_obj.create({'key': key, 'value': value})
|
||||
|
||||
@api.multi
|
||||
def get_default_parameters(self):
|
||||
def get_value(key, default=''):
|
||||
rec = self._get_parameter(key)
|
||||
return rec and rec.value or default
|
||||
return {'final_product_analytic_cost': get_value('final.product.cost',
|
||||
False)}
|
||||
|
||||
@api.multi
|
||||
def set_parameters(self):
|
||||
self._write_or_create_param('final.product.cost',
|
||||
self.final_product_analytic_cost)
|
||||
@@ -52,16 +52,45 @@ class MrpProduction(models.Model):
|
||||
|
||||
@api.multi
|
||||
def action_production_end(self):
|
||||
task_obj = self.env['project.task']
|
||||
analytic_line_obj = self.env['account.analytic.line']
|
||||
res = super(MrpProduction, self).action_production_end()
|
||||
for record in self:
|
||||
mrp_cost = record.calc_mrp_real_cost()
|
||||
done_lines = record.move_created_ids2.filtered(lambda l:
|
||||
l.state == 'done')
|
||||
done_lines.create_produce_cost_line(mrp_cost)
|
||||
create_cost = self.env['mrp.config.settings']._get_parameter(
|
||||
'final.product.cost')
|
||||
if create_cost and create_cost.value and mrp_cost > 0.0:
|
||||
journal_id = self.env.ref('mrp.analytic_journal_materials',
|
||||
False)
|
||||
qty = sum([l.product_qty for l in done_lines])
|
||||
name = ('Final product - ' + (record.name or '') +
|
||||
'-' + (record.product_id.default_code or ''))
|
||||
vals = record._prepare_real_cost_analytic_line(
|
||||
journal_id, name, record, record.product_id, qty=qty,
|
||||
amount=mrp_cost)
|
||||
task = task_obj.search([('mrp_production_id', '=', record.id),
|
||||
('wk_order', '=', False)])
|
||||
vals['task_id'] = task and task[0].id or False
|
||||
analytic_line_obj.create(vals)
|
||||
record.real_cost = mrp_cost
|
||||
done_lines.product_price_update_production_done()
|
||||
# Reload produced quants cost to consider all production costs.
|
||||
# Material, machine and manual costs.
|
||||
self.load_final_quant_cost()
|
||||
return res
|
||||
|
||||
@api.multi
|
||||
def load_final_quant_cost(self):
|
||||
for production in self:
|
||||
mrp_cost = production.calc_mrp_real_cost()
|
||||
done_lines = production.move_created_ids2.filtered(
|
||||
lambda l: l.state == 'done')
|
||||
total_qty = sum([l.product_qty for l in done_lines])
|
||||
quants = done_lines.mapped('quant_ids')
|
||||
quants.write({'cost': mrp_cost / total_qty})
|
||||
|
||||
@api.model
|
||||
def _prepare_real_cost_analytic_line(
|
||||
self, journal, name, production, product, general_account=None,
|
||||
|
||||
@@ -24,86 +24,53 @@ class StockMove(models.Model):
|
||||
_inherit = 'stock.move'
|
||||
|
||||
@api.multi
|
||||
def create_produce_cost_line(self, amount):
|
||||
def action_done(self):
|
||||
task_obj = self.env['project.task']
|
||||
analytic_line_obj = self.env['account.analytic.line']
|
||||
result = super(StockMove, self).action_done()
|
||||
for record in self:
|
||||
if amount > 0.0:
|
||||
if record.production_id:
|
||||
product = record.product_id
|
||||
production = record.production_id
|
||||
journal_id = self.env.ref(
|
||||
'mrp.analytic_journal_materials', False)
|
||||
name = ('Final product - ' + (production.name or '') +
|
||||
'-' + (product.default_code or ''))
|
||||
vals = production._prepare_real_cost_analytic_line(
|
||||
journal_id, name, production, product,
|
||||
qty=record.product_qty, amount=amount)
|
||||
task = task_obj.search(
|
||||
[('mrp_production_id', '=', production.id),
|
||||
('wk_order', '=', False)])
|
||||
vals['task_id'] = task and task[0].id or False
|
||||
analytic_line_obj.create(vals)
|
||||
|
||||
@api.multi
|
||||
def action_consume(self, product_qty, location_id=False,
|
||||
restrict_lot_id=False, restrict_partner_id=False,
|
||||
consumed_for=False):
|
||||
task_obj = self.env['project.task']
|
||||
analytic_line_obj = self.env['account.analytic.line']
|
||||
result = super(StockMove, self).action_consume(
|
||||
product_qty, location_id=location_id,
|
||||
restrict_lot_id=restrict_lot_id,
|
||||
restrict_partner_id=restrict_partner_id, consumed_for=consumed_for)
|
||||
for record in self:
|
||||
price = record.product_id.cost_price
|
||||
if price > 0.0:
|
||||
if record.raw_material_production_id:
|
||||
product = record.product_id
|
||||
journal_id = self.env.ref(
|
||||
'mrp.analytic_journal_materials', False)
|
||||
production = record.raw_material_production_id
|
||||
name = (
|
||||
(production.name or '') + '-' +
|
||||
(record.work_order.routing_wc_line.operation.code or
|
||||
'') + '-' + (product.default_code or ''))
|
||||
analytic_vals = (
|
||||
production._prepare_real_cost_analytic_line(
|
||||
journal_id, name, production, product,
|
||||
workorder=record.work_order,
|
||||
qty=record.product_qty,
|
||||
amount=(-price * record.product_qty)))
|
||||
task = task_obj.search(
|
||||
[('mrp_production_id', '=', production.id),
|
||||
('wk_order', '=', False)])
|
||||
analytic_vals['task_id'] = task and task[0].id or False
|
||||
analytic_line_obj.create(analytic_vals)
|
||||
if (not record.raw_material_production_id or not
|
||||
record.product_id.cost_price):
|
||||
continue
|
||||
journal_id = self.env.ref('mrp.analytic_journal_materials', False)
|
||||
production = record.raw_material_production_id
|
||||
name = ((production.name or '') + '-' +
|
||||
(record.work_order.routing_wc_line.operation.code or '') +
|
||||
'-' + (record.product_id.default_code or ''))
|
||||
analytic_vals = (production._prepare_real_cost_analytic_line(
|
||||
journal_id, name, production, record.product_id,
|
||||
workorder=record.work_order, qty=record.product_qty,
|
||||
amount=(-record.product_id.cost_price * record.product_qty)))
|
||||
task = task_obj.search([('mrp_production_id', '=', production.id),
|
||||
('wk_order', '=', False)])
|
||||
analytic_vals['task_id'] = task and task[0].id or False
|
||||
analytic_line_obj.create(analytic_vals)
|
||||
return result
|
||||
|
||||
@api.multi
|
||||
def product_price_update_production_done(self):
|
||||
for move in self:
|
||||
if (move.production_id) and (move.product_id.cost_method ==
|
||||
'average'):
|
||||
prod_total_cost = move.production_id.calc_mrp_real_cost()
|
||||
product = move.product_id
|
||||
product_avail = product.qty_available
|
||||
amount_unit = product.cost_price
|
||||
template_avail = product.product_tmpl_id.qty_available
|
||||
template_price = product.standard_price
|
||||
if move.state == 'done':
|
||||
product_avail -= move.product_qty
|
||||
template_avail -= move.product_qty
|
||||
new_cost_price = ((amount_unit * product_avail +
|
||||
prod_total_cost) /
|
||||
((product_avail >= 0.0 and product_avail or
|
||||
0.0) + move.product_qty))
|
||||
new_std_price = ((template_price * template_avail +
|
||||
prod_total_cost) /
|
||||
((template_avail >= 0.0 and template_avail or
|
||||
0.0) + move.product_qty))
|
||||
product.sudo().write({'cost_price': new_cost_price,
|
||||
'standard_price': new_std_price})
|
||||
if (not move.production_id or move.product_id.cost_method !=
|
||||
'average'):
|
||||
continue
|
||||
prod_total_cost = move.production_id.calc_mrp_real_cost()
|
||||
product = move.product_id
|
||||
product_avail = product.qty_available
|
||||
amount_unit = product.cost_price
|
||||
template_avail = product.product_tmpl_id.qty_available
|
||||
template_price = product.standard_price
|
||||
if move.state == 'done':
|
||||
product_avail -= move.product_qty
|
||||
template_avail -= move.product_qty
|
||||
new_cost_price = ((amount_unit * product_avail + prod_total_cost) /
|
||||
((product_avail >= 0.0 and product_avail or 0.0)
|
||||
+ move.product_qty))
|
||||
new_std_price = ((template_price * template_avail +
|
||||
prod_total_cost) /
|
||||
((template_avail >= 0.0 and template_avail or
|
||||
0.0) + move.product_qty))
|
||||
product.sudo().write({'cost_price': new_cost_price,
|
||||
'standard_price': new_std_price})
|
||||
|
||||
@api.model
|
||||
def get_price_unit(self, move):
|
||||
|
||||
18
mrp_production_real_cost/views/res_config_view.xml
Normal file
18
mrp_production_real_cost/views/res_config_view.xml
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<record model="ir.ui.view" id="mrp_config_settings_costs">
|
||||
<field name="name">mrp.config.settings.costs</field>
|
||||
<field name="model">mrp.config.settings</field>
|
||||
<field name="inherit_id" ref="mrp.view_mrp_config" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='module_mrp_repair']/.." position="after">
|
||||
<div>
|
||||
<field name="final_product_analytic_cost" class="oe_inline"/>
|
||||
<label for="final_product_analytic_cost"/>
|
||||
</div>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
6
mrp_production_real_cost/wizard/__init__.py
Normal file
6
mrp_production_real_cost/wizard/__init__.py
Normal file
@@ -0,0 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
# For copyright and license notices, see __openerp__.py file in root directory
|
||||
##############################################################################
|
||||
|
||||
from . import mrp_product_produce
|
||||
20
mrp_production_real_cost/wizard/mrp_product_produce.py
Normal file
20
mrp_production_real_cost/wizard/mrp_product_produce.py
Normal file
@@ -0,0 +1,20 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
# For copyright and license notices, see __openerp__.py file in root directory
|
||||
##############################################################################
|
||||
from openerp import models, api
|
||||
|
||||
|
||||
class MrpProductProduce(models.TransientModel):
|
||||
|
||||
_inherit = 'mrp.product.produce'
|
||||
|
||||
# Reload produced quants cost every consume or produce action in a MO.
|
||||
@api.multi
|
||||
def do_produce(self):
|
||||
res = super(MrpProductProduce, self).do_produce()
|
||||
production_obj = self.env['mrp.production']
|
||||
production_id = self.env.context.get('active_id', False)
|
||||
production = production_obj.browse(production_id)
|
||||
production.load_final_quant_cost()
|
||||
return res
|
||||
Reference in New Issue
Block a user