mirror of
https://github.com/OCA/manufacture.git
synced 2025-01-28 16:37:15 +02:00
78
mrp_repair_refurbish/README.rst
Normal file
78
mrp_repair_refurbish/README.rst
Normal file
@@ -0,0 +1,78 @@
|
||||
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
|
||||
:target: https://www.gnu.org/licenses/agpl-3.0-standalone.html
|
||||
:alt: License: AGPL-3
|
||||
|
||||
====================
|
||||
MRP Repair Refurbish
|
||||
====================
|
||||
|
||||
This module adds the ability to obtain refurbished product as a consequence
|
||||
of the repair of a product that was defective.
|
||||
|
||||
|
||||
Configuration
|
||||
=============
|
||||
|
||||
#. For each product that can potentially be refurbished, define the
|
||||
refurbished version in the product form.
|
||||
|
||||
#. A default 'Refurbished' virtual location is created during module install,
|
||||
and proposed by default on each product.
|
||||
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
#. Create an MRP repair.
|
||||
#. Indicate a product to repair, If the product has a proposed refurbished
|
||||
version, it will be proposed to be used. The destination location
|
||||
#. Add operations if needed.
|
||||
#. Complete the repair.
|
||||
|
||||
The initial product will be moved to the 'Scrap' location, and the
|
||||
refurbished product will be moved from a 'Refurbish' location to the desired
|
||||
destination location.
|
||||
|
||||
The components that were added to the repair order will be moved to the
|
||||
'Refurbish' location.
|
||||
|
||||
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
|
||||
:alt: Try me on Runbot
|
||||
:target: https://runbot.odoo-community.org/runbot/129/9.0
|
||||
|
||||
|
||||
Bug Tracker
|
||||
===========
|
||||
|
||||
Bugs are tracked on `GitHub Issues
|
||||
<https://github.com/OCA/manufacture/issues>`_. In case of trouble, please
|
||||
check there if your issue has already been reported. If you spotted it first,
|
||||
help us smashing it by providing a detailed and welcomed `feedback
|
||||
<https://github.com/OCA/
|
||||
manufacture/issues/new?body=module:%20
|
||||
mrp_bom_dismantling%0Aversion:%20
|
||||
9.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
|
||||
|
||||
Credits
|
||||
=======
|
||||
|
||||
Contributors
|
||||
------------
|
||||
|
||||
* Jordi Ballester Alomar <jordi.ballester@eficent.com>
|
||||
* Lois Rilo <lois.rilo@eficent.com>
|
||||
|
||||
Maintainer
|
||||
----------
|
||||
|
||||
.. image:: https://odoo-community.org/logo.png
|
||||
:alt: Odoo Community Association
|
||||
:target: https://odoo-community.org
|
||||
|
||||
This module is maintained by the OCA.
|
||||
|
||||
OCA, or the Odoo Community Association, is a nonprofit organization whose
|
||||
mission is to support the collaborative development of Odoo features and
|
||||
promote its widespread use.
|
||||
|
||||
To contribute to this module, please visit https://odoo-community.org.
|
||||
5
mrp_repair_refurbish/__init__.py
Normal file
5
mrp_repair_refurbish/__init__.py
Normal file
@@ -0,0 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Cyril Gaudin (Camptocamp)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from . import models
|
||||
23
mrp_repair_refurbish/__openerp__.py
Normal file
23
mrp_repair_refurbish/__openerp__.py
Normal file
@@ -0,0 +1,23 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Cyril Gaudin (Camptocamp)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
{
|
||||
"name": "MRP Repair Refurbish",
|
||||
"summary": "Create refurbished products during repair",
|
||||
"version": "9.0.1.0.1",
|
||||
"category": "Manufacturing",
|
||||
"website": "https://github.com/OCA/manufacture",
|
||||
"author": "Eficent, Odoo Community Association (OCA)",
|
||||
"license": "AGPL-3",
|
||||
"application": False,
|
||||
"installable": True,
|
||||
"depends": [
|
||||
'mrp_repair',
|
||||
],
|
||||
"data": [
|
||||
"views/mrp_repair_view.xml",
|
||||
"data/stock_data.xml",
|
||||
"views/product_template_view.xml",
|
||||
"views/product_product_view.xml",
|
||||
],
|
||||
}
|
||||
26
mrp_repair_refurbish/data/stock_data.xml
Normal file
26
mrp_repair_refurbish/data/stock_data.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="stock_location_refurbish" model="stock.location">
|
||||
<field name="name">Refurbish</field>
|
||||
<field name="location_id"
|
||||
ref="stock.stock_location_locations_virtual"/>
|
||||
<field name="usage">production</field>
|
||||
<field name="company_id"></field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
<data noupdate="1">
|
||||
|
||||
<record forcecreate="True" id="property_stock_refurbish"
|
||||
model="ir.property">
|
||||
<field name="name">property_stock_refurbish</field>
|
||||
<field name="fields_id"
|
||||
search="[('model','=','product.template'),('name','=','property_stock_refurbish')]"/>
|
||||
<field eval="'stock.location,'+str(stock_location_refurbish)"
|
||||
name="value"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
7
mrp_repair_refurbish/models/__init__.py
Normal file
7
mrp_repair_refurbish/models/__init__.py
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Cyril Gaudin (Camptocamp)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from . import product_product
|
||||
from . import product_template
|
||||
from . import mrp_repair
|
||||
96
mrp_repair_refurbish/models/mrp_repair.py
Normal file
96
mrp_repair_refurbish/models/mrp_repair.py
Normal file
@@ -0,0 +1,96 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Cyril Gaudin (Camptocamp)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from openerp.osv import orm
|
||||
from openerp import api, fields, models
|
||||
|
||||
|
||||
class mrp_repair(orm.Model):
|
||||
"""To inherit using old api is needed here in order to be able to modify
|
||||
the onchange method for `product_id`.
|
||||
NOTE: This should be moved to new api in v10, when the standard is also
|
||||
migrated.
|
||||
"""
|
||||
_inherit = 'mrp.repair'
|
||||
|
||||
def onchange_product_id(self, cr, uid, ids, product_id=None):
|
||||
res = super(mrp_repair, self).onchange_product_id(
|
||||
cr, uid, ids, product_id=product_id)
|
||||
product = self.pool['product.product'].browse(cr, uid, product_id)
|
||||
res['value']['to_refurbish'] = True if \
|
||||
product.refurbish_product_id else False
|
||||
return res
|
||||
|
||||
|
||||
class MrpRepair(models.Model):
|
||||
_inherit = 'mrp.repair'
|
||||
|
||||
to_refurbish = fields.Boolean('To refurbish')
|
||||
refurbish_location_dest_id = fields.Many2one(
|
||||
string='Refurbished Delivery Location', comodel_name='stock.location')
|
||||
refurbish_product_id = fields.Many2one(
|
||||
string='Refurbished product', comodel_name='product.product')
|
||||
refurbish_lot_id = fields.Many2one(
|
||||
string='Refurbished Lot', comodel_name='stock.production.lot')
|
||||
refurbish_move_id = fields.Many2one(
|
||||
string='Refurbished Inventory Move', comodel_name='stock.move')
|
||||
product_id = fields.Many2one(comodel_name='product.product')
|
||||
|
||||
@api.onchange('to_refurbish', 'product_id')
|
||||
def _onchange_to_refurbish(self):
|
||||
if self.to_refurbish:
|
||||
self.refurbish_product_id = self.product_id.refurbish_product_id
|
||||
self.refurbish_location_dest_id = self.location_dest_id
|
||||
self.location_dest_id = self.product_id.property_stock_refurbish
|
||||
else:
|
||||
self.location_dest_id = self.refurbish_location_dest_id
|
||||
self.refurbish_product_id = False
|
||||
self.refurbish_location_dest_id = False
|
||||
|
||||
@api.multi
|
||||
def action_repair_done(self):
|
||||
res = super(MrpRepair, self).action_repair_done()
|
||||
for repair in self:
|
||||
if repair.to_refurbish:
|
||||
move = self.env['stock.move'].create({
|
||||
'name': repair.name,
|
||||
'product_id': repair.refurbish_product_id.id,
|
||||
'product_uom': repair.product_uom.id or
|
||||
repair.refurbish_product_id.uom_id.id,
|
||||
'product_uom_qty': repair.product_qty,
|
||||
'partner_id': repair.address_id and
|
||||
repair.address_id.id or False,
|
||||
'location_id': repair.location_dest_id.id,
|
||||
'location_dest_id': repair.refurbish_location_dest_id.id,
|
||||
'restrict_lot_id': repair.refurbish_lot_id.id,
|
||||
})
|
||||
move.action_done()
|
||||
repair.refurbish_move_id = move.id
|
||||
return res
|
||||
|
||||
|
||||
class mrp_repair_line(orm.Model):
|
||||
"""To inherit using old api is needed here in order to be able to modify
|
||||
the onchange method for `type`.
|
||||
NOTE: This should be moved to new api in v10, when the standard is also
|
||||
migrated.
|
||||
"""
|
||||
_inherit = 'mrp.repair.line'
|
||||
|
||||
def onchange_operation_type(self, cr, uid, ids, type, guarantee_limit,
|
||||
company_id=False, context=None):
|
||||
res = super(mrp_repair_line, self).onchange_operation_type(
|
||||
cr, uid, ids, type, guarantee_limit, company_id=company_id,
|
||||
context=context)
|
||||
|
||||
if (type == 'add' and 'to_refurbish' in context and
|
||||
context['to_refurbish']):
|
||||
res['value']['location_dest_id'] = context[
|
||||
'refurbish_location_dest_id']
|
||||
elif (type == 'add' and 'to_refurbish' in context and not
|
||||
context['to_refurbish']):
|
||||
scrap_location_ids = self.pool['stock.location'].search(cr, uid, [
|
||||
('usage', '=', 'customer')], context=context)
|
||||
res['value']['location_dest_id'] = scrap_location_ids[0]
|
||||
return res
|
||||
14
mrp_repair_refurbish/models/product_product.py
Normal file
14
mrp_repair_refurbish/models/product_product.py
Normal file
@@ -0,0 +1,14 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2017 Eficent Business and IT Consulting Services S.L.
|
||||
# © 2016 Cyril Gaudin (Camptocamp)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from openerp import fields, models
|
||||
|
||||
|
||||
class ProductProduct(models.Model):
|
||||
_inherit = 'product.product'
|
||||
|
||||
refurbish_product_id = fields.Many2one(
|
||||
comodel_name='product.product', string='Refurbished Product',
|
||||
domain="[('type', '=', 'product')]")
|
||||
45
mrp_repair_refurbish/models/product_template.py
Normal file
45
mrp_repair_refurbish/models/product_template.py
Normal file
@@ -0,0 +1,45 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Cyril Gaudin (Camptocamp)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from openerp import api, fields, models
|
||||
|
||||
|
||||
class ProductTemplate(models.Model):
|
||||
_inherit = 'product.template'
|
||||
|
||||
refurbish_product_id = fields.Many2one(
|
||||
comodel_name='product.product', string='Refurbished Product',
|
||||
compute='_compute_refurbish_product',
|
||||
inverse='_set_refurbish_product', search='_search_refurbish_product',
|
||||
domain="[('type', '=', 'product')]")
|
||||
|
||||
property_stock_refurbish = fields.Many2one(
|
||||
comodel_name='stock.location', string="Refurbish Location",
|
||||
company_dependent=True, domain=[('usage', 'like', 'production')],
|
||||
help="This stock location will be used, instead of the "
|
||||
"default one, as the source location for "
|
||||
"stock moves generated by repair orders when refurbishing takes "
|
||||
"place.")
|
||||
|
||||
@api.depends('product_variant_ids',
|
||||
'product_variant_ids.refurbish_product_id')
|
||||
def _compute_refurbish_product(self):
|
||||
unique_variants = self.filtered(lambda template:
|
||||
len(template.product_variant_ids) == 1)
|
||||
for template in unique_variants:
|
||||
template.refurbish_product_id = \
|
||||
template.product_variant_ids.refurbish_product_id
|
||||
for template in (self - unique_variants):
|
||||
template.refurbish_product_id = False
|
||||
|
||||
@api.one
|
||||
def _set_refurbish_product(self):
|
||||
if len(self.product_variant_ids) == 1:
|
||||
self.product_variant_ids.refurbish_product_id = \
|
||||
self.refurbish_product_id
|
||||
|
||||
def _search_refurbish_product(self, operator, value):
|
||||
products = self.env['product.product'].search([
|
||||
('refurbish_product_id', operator, value)], limit=None)
|
||||
return [('id', 'in', products.mapped('product_tmpl_id').ids)]
|
||||
54
mrp_repair_refurbish/views/mrp_repair_view.xml
Normal file
54
mrp_repair_refurbish/views/mrp_repair_view.xml
Normal file
@@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="view_repair_order_tree" model="ir.ui.view">
|
||||
<field name="name">mrp.repair.tree</field>
|
||||
<field name="model">mrp.repair</field>
|
||||
<field name="inherit_id" ref="mrp_repair.view_repair_order_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="product_id" position="after">
|
||||
<field name="refurbish_product_id"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_repair_order_form" model="ir.ui.view">
|
||||
<field name="name">mrp.repair.form</field>
|
||||
<field name="model">mrp.repair</field>
|
||||
<field name="inherit_id" ref="mrp_repair.view_repair_order_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//group[1]" position="inside">
|
||||
<group>
|
||||
<field name="to_refurbish"/>
|
||||
</group>
|
||||
<group attrs="{'invisible': [('to_refurbish', '=', False)]}">
|
||||
<field name="refurbish_product_id"
|
||||
attrs="{'required': [('to_refurbish', '=', True)]}"/>
|
||||
<field name="refurbish_lot_id"
|
||||
domain="[('product_id', '=', refurbish_product_id)]"
|
||||
context="{'default_product_id': refurbish_product_id}"
|
||||
groups="stock.group_production_lot"/>
|
||||
<field name="refurbish_location_dest_id"
|
||||
attrs="{'required': [('to_refurbish', '=', True)]}"/>
|
||||
</group>
|
||||
</xpath>
|
||||
<field name="operations"
|
||||
position='attributes'>
|
||||
<attribute name='context'>{'default_product_uom_qty': product_qty, 'to_refurbish': to_refurbish, 'refurbish_location_dest_id': location_dest_id}</attribute>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_repair_order_form_filter" model="ir.ui.view">
|
||||
<field name="name">mrp.repair.select</field>
|
||||
<field name="model">mrp.repair</field>
|
||||
<field name="inherit_id" ref="mrp_repair.view_repair_order_form_filter"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="product_id" position="after">
|
||||
<field name="to_refurbish"/>
|
||||
<field name="refurbish_product_id"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
17
mrp_repair_refurbish/views/product_product_view.xml
Normal file
17
mrp_repair_refurbish/views/product_product_view.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="product_normal_form_view" model="ir.ui.view">
|
||||
<field name="name">product.product.form</field>
|
||||
<field name="model">product.product</field>
|
||||
<field name="inherit_id" ref="product.product_normal_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<group name="inventory" position="after">
|
||||
<group name="refurbish" string="Refurbish">
|
||||
<field name="refurbish_product_id"/>
|
||||
</group>
|
||||
</group>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
31
mrp_repair_refurbish/views/product_template_view.xml
Normal file
31
mrp_repair_refurbish/views/product_template_view.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="product_template_only_form_view" model="ir.ui.view">
|
||||
<field name="name">product.template.product.form</field>
|
||||
<field name="model">product.template</field>
|
||||
<field name="inherit_id" ref="product.product_template_only_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<group name="inventory" position="after">
|
||||
<group name="refurbish" string="Refurbish" attrs="{'invisible':[('product_variant_count', '>', 1)]}">
|
||||
<field name="refurbish_product_id"/>
|
||||
</group>
|
||||
</group>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_template_property_form" model="ir.ui.view">
|
||||
<field name="name">product.template.stock.property.form.inherit</field>
|
||||
<field name="model">product.template</field>
|
||||
<field name="inherit_id" ref="stock.view_template_property_form"/>
|
||||
<field name="arch" type="xml">
|
||||
|
||||
<field name="property_stock_production"
|
||||
position="after">
|
||||
<field name="property_stock_refurbish"
|
||||
domain="[('usage','=','production')]"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user