[ADD] mrp_production_real_cost

This commit is contained in:
Ainara
2014-11-05 11:30:40 +01:00
committed by Pedro M. Baeza
parent 393d26689e
commit d850270d0d
10 changed files with 517 additions and 0 deletions

View File

@@ -0,0 +1,19 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see http://www.gnu.org/licenses/.
#
##############################################################################
from . import models

View File

@@ -0,0 +1,44 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see http://www.gnu.org/licenses/.
#
##############################################################################
{
"name": "Mrp Real Costs",
"version": "1.0",
"depends": ["analytic",
"project_timesheet",
"mrp_project_link",
"mrp_operations_time_control",
"stock_account",
"mrp_production_project_estimated_cost"],
"author": "OdooMRP team",
"category": "MRP",
"description": """
- This module allows to control the real cost of a production order,
creating lines in the analytic account defined in the order that is
created by the module mrp_project_link.
- Updates product standard price when a production orders final product
is done.
(Product stock * Product standard price + Production real cost) /
(Product stock + Final product quantity)
""",
'data': ["views/mrp_production_view.xml"],
'demo': [],
'installable': True,
'auto_install': False,
}

View File

@@ -0,0 +1,38 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * mrp_production_real_costs
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-11-11 15:06+0000\n"
"PO-Revision-Date: 2014-11-11 16:12+0100\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: \n"
#. module: mrp_production_real_costs
#: model:ir.model,name:mrp_production_real_costs.model_project_task_work
msgid "Project Task Work"
msgstr "Trabajo de tarea"
#. module: mrp_production_real_costs
#: model:ir.model,name:mrp_production_real_costs.model_stock_move
msgid "Stock Move"
msgstr "Movimiento de existencias"
#. module: mrp_production_real_costs
#: model:ir.model,name:mrp_production_real_costs.model_mrp_production_workcenter_line
msgid "Work Order"
msgstr "Orden de trabajo"
#. module: mrp_production_real_costs
#: code:addons/mrp_production_real_costs/models/mrp_production_workcenter_line.py:59
#, python-format
msgid "You must define a general account for this Workcenter: [%s] %s"
msgstr "Es necesario que defina una cuenta contable para este centro de producción: [%s] %s"

View File

@@ -0,0 +1,38 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * mrp_production_real_costs
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-11-11 15:06+0000\n"
"PO-Revision-Date: 2014-11-11 16:09+0100\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: \n"
#. module: mrp_production_real_costs
#: model:ir.model,name:mrp_production_real_costs.model_project_task_work
msgid "Project Task Work"
msgstr ""
#. module: mrp_production_real_costs
#: model:ir.model,name:mrp_production_real_costs.model_stock_move
msgid "Stock Move"
msgstr ""
#. module: mrp_production_real_costs
#: model:ir.model,name:mrp_production_real_costs.model_mrp_production_workcenter_line
msgid "Work Order"
msgstr ""
#. module: mrp_production_real_costs
#: code:addons/mrp_production_real_costs/models/mrp_production_workcenter_line.py:59
#, python-format
msgid "You must define a general account for this Workcenter: [%s] %s"
msgstr ""

View File

@@ -0,0 +1,22 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see http://www.gnu.org/licenses/.
#
##############################################################################
from . import stock_move
from . import mrp_production_workcenter_line
from . import project_task_work
from . import mrp_production

View File

@@ -0,0 +1,47 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see http://www.gnu.org/licenses/.
#
##############################################################################
from openerp import models, fields, api
class MrpProduction(models.Model):
_inherit = 'mrp.production'
@api.one
@api.depends('analytic_line_ids', 'analytic_line_ids.amount',
'product_qty')
def get_real_cost(self):
self.real_cost = sum([-line.amount for line in
self.analytic_line_ids])
self.unit_real_cost = self.real_cost / self.product_qty
real_cost = fields.Float("Total Real Cost", compute="get_real_cost",
store=True)
unit_real_cost = fields.Float("Unit Real Cost", compute="get_real_cost",
store=True)
@api.multi
def action_production_end(self):
res = super(MrpProduction, self).action_production_end()
analytic_line_obj = self.env['account.analytic.line']
for record in self:
cost_lines = analytic_line_obj.search([('mrp_production_id', '=',
record.id)])
record.real_cost = sum([-line.amount for line in cost_lines])
return res

View File

@@ -0,0 +1,92 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see http://www.gnu.org/licenses/.
#
##############################################################################
from openerp import models, api
from datetime import datetime
class MrpProductionWorkcenterLine(models.Model):
_inherit = 'mrp.production.workcenter.line'
@api.multi
def _create_analytic_line(self):
self.ensure_one()
analytic_line_obj = self.env['account.analytic.line']
property_obj = self.env['ir.property']
task_obj = self.env['project.task']
if self.workcenter_id.costs_hour > 0.0:
hour_uom = self.env.ref('product.product_uom_hour', False)
operation_line = self.operation_time_lines[-1]
production = self.production_id
workcenter = self.workcenter_id
product = workcenter.product_id
journal_id = workcenter.costs_journal_id or False
if not journal_id:
journal_id = self.env.ref(
'mrp_production_project_estimated_cost.analytic_journal_'
'machines', False)
analytic_account_id = production.analytic_account_id.id or False
task_id = False
if production:
task = task_obj.search([('mrp_production_id', '=',
production.id),
('wk_order', '=', False)])
if task:
task_id = task[0].id
name = ((production.name or '') + '-' +
(self.routing_wc_line.operation.code or '') + '-' +
(product.default_code or ''))
general_acc = (
workcenter.costs_general_account_id.id or
product.property_account_expense.id or
product.categ_id.property_account_expense_categ.id or
property_obj.get('property_account_expense_categ',
'product.category'))
price = workcenter.costs_hour
analytic_vals = {'name': name,
'ref': name,
'date': datetime.now().strftime('%Y-%m-%d'),
'user_id': self.env.uid,
'product_id': product.id,
'product_uom_id': hour_uom.id,
'amount': -(price * operation_line.uptime),
'unit_amount': operation_line.uptime,
'journal_id': journal_id.id,
'account_id': analytic_account_id,
'general_account_id': general_acc,
'task_id': task_id,
'mrp_production_id': production.id or False,
'workorder': self.id,
'estim_avg_cost': 0.0,
'estim_std_cost': 0.0
}
analytic_line = analytic_line_obj.create(analytic_vals)
return analytic_line
@api.multi
def action_pause(self):
result = super(MrpProductionWorkcenterLine, self).action_pause()
self._create_analytic_line()
return result
@api.multi
def action_done(self):
result = super(MrpProductionWorkcenterLine, self).action_done()
self._create_analytic_line()
return result

View File

@@ -0,0 +1,48 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see http://www.gnu.org/licenses/.
#
##############################################################################
from openerp import models, api
class ProjectTaskWork(models.Model):
_inherit = 'project.task.work'
@api.model
def create(self, vals):
result = super(ProjectTaskWork, self).create(vals)
if result.hr_analytic_timesheet_id and result.task_id:
analytic_line = result.hr_analytic_timesheet_id.line_id
task = result.task_id
if task.mrp_production_id or task.wk_order:
analytic_line.write({'mrp_production_id':
task.mrp_production_id.id,
'workorder': task.wk_order.id})
return result
@api.model
def write(self, vals):
result = super(ProjectTaskWork, self).write(vals)
if 'hr_analytic_timesheet_id' in vals or 'task_id' in vals:
analytic_line = self.hr_analytic_timesheet_id.line_id
task = self.task_id
if task.mrp_production_id or task.wk_order:
analytic_line.write({'mrp_production_id':
task.mrp_production_id.id,
'workorder': task.wk_order.id})
return result

View File

@@ -0,0 +1,153 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see http://www.gnu.org/licenses/.
#
##############################################################################
from openerp import models, api
from datetime import datetime
import math
class StockMove(models.Model):
_inherit = 'stock.move'
@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']
property_obj = self.env['ir.property']
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.standard_price
if price > 0.0:
if record.production_id or record.raw_material_production_id:
product = record.product_id
journal_id = self.env.ref(
'mrp_production_project_estimated_cost.analytic_'
'journal_materials', False)
production_id = False
analytic_account_id = False
task_id = False
if record.production_id:
production = record.production_id
elif record.raw_material_production_id:
production = record.raw_material_production_id
if production:
production_id = production.id
analytic_account_id = production.analytic_account_id.id
task = task_obj.search(
[('mrp_production_id', '=', production_id),
('wk_order', '=', False)])
if task:
task_id = task[0].id
name = (
(production.name or '') + '-' +
(record.work_order.routing_wc_line.operation.code or
'') + '-' + (product.default_code or ''))
general_account = (
product.property_account_expense.id or
product.categ_id.property_account_expense_categ.id or
property_obj.get('property_account_expense_categ',
'product.category'))
date = datetime.now().strftime('%Y-%m-%d')
uom_id = record.product_id.uom_id.id
if record.raw_material_production_id:
analytic_vals = {'name': name,
'ref': name,
'date': date,
'user_id': self.env.uid,
'product_id': product.id,
'product_uom_id': uom_id,
'amount': -(price * product_qty),
'unit_amount': product_qty,
'journal_id': journal_id.id,
'account_id': analytic_account_id,
'general_account_id': general_account,
'task_id': task_id,
'mrp_production_id': production_id,
'workorder': record.work_order.id,
'estim_avg_cost': 0.0,
'estim_std_cost': 0.0
}
analytic_line_obj.create(analytic_vals)
elif record.production_id:
amount = 0.0
unit_amount = 0.0
for wc in production.workcenter_lines:
cycle_cost = wc.workcenter_id.costs_cycle
cycle_units = wc.workcenter_id.capacity_per_cycle
cycle = int(math.ceil(product_qty / cycle_units))
amount += cycle * cycle_cost
unit_amount += cycle
analytic_vals = {'name': name,
'ref': name,
'date': date,
'user_id': self.env.uid,
'product_id': product.id,
'product_uom_id': uom_id,
'amount': amount,
'unit_amount': unit_amount,
'journal_id': journal_id.id,
'account_id': analytic_account_id,
'general_account_id': general_account,
'task_id': task_id,
'mrp_production_id': production_id,
'workorder': record.work_order.id,
'estim_avg_cost': 0.0,
'estim_std_cost': 0.0
}
analytic_line_obj.create(analytic_vals)
return result
@api.multi
def product_price_update_before_done(self):
analytic_line_obj = self.env['account.analytic.line']
super(StockMove, self).product_price_update_before_done()
for move in self:
# adapt standard price on production final moves if the
# product cost_method is 'average'
if (move.production_id) and (move.product_id.cost_method ==
'average'):
analytic_lines = analytic_line_obj.search(
[('mrp_production_id', '=', move.production_id.id)])
prod_total_cost = sum([-line.amount for line in
analytic_lines])
product = move.product_id
product_avail = product.qty_available
amount_unit = product.standard_price
new_std_price = ((amount_unit * product_avail +
prod_total_cost) / (product_avail >= 0.0 or
0.0 + move.product_qty))
# Write the standard price, as SUPERUSER_ID because a warehouse
# manager may not have the right to write on products
product.sudo().write({'standard_price': new_std_price})
@api.multi
def get_unit_price(self):
self.ensure_one()
if self.production_id:
analytic_line_obj = self.env['account.analytic.line']
analytic_lines = analytic_line_obj.search(
[('mrp_production_id', '=', self.production_id.id)])
return sum([-line.amount for line in analytic_lines])
else:
return super(StockMove, self).get_unit_price()

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="mrp_production_project_form_view_inh_estimatedcost" model="ir.ui.view">
<field name="name">mrp.production.project.form.view.inh.estimatedcost</field>
<field name="model">mrp.production</field>
<field name="inherit_id" ref="mrp_production_project_estimated_cost.mrp_production_form_view_inh_estimatedcost"/>
<field name="arch" type="xml">
<field name="unit_avg_cost" position="after">
<field name="real_cost" attrs="{'invisible': [('state', '!=', 'done')]}"/>
<field name="unit_real_cost" attrs="{'invisible': [('state', '!=', 'done')]}"/>
</field>
</field>
</record>
</data>
</openerp>