[MIG] repair_refurbish (mrp_repair_refurbish): Migration to 12.0

This commit is contained in:
Akim Juillerat
2019-03-12 16:10:30 +01:00
committed by Mateu Griful
parent 381026de97
commit 7e94d7f53d
23 changed files with 1166 additions and 0 deletions

106
repair_refurbish/README.rst Normal file
View File

@@ -0,0 +1,106 @@
====================
MRP Repair Refurbish
====================
.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fmanufacture-lightgray.png?logo=github
:target: https://github.com/OCA/manufacture/tree/11.0/mrp_repair_refurbish
:alt: OCA/manufacture
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/manufacture-11-0/manufacture-11-0-mrp_repair_refurbish
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
:target: https://runbot.odoo-community.org/runbot/129/11.0
:alt: Try me on Runbot
|badge1| |badge2| |badge3| |badge4| |badge5|
This module adds the ability to obtain refurbished product as a consequence
of the repair of a product that was defective.
**Table of contents**
.. contents::
:local:
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.
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:%20mrp_repair_refurbish%0Aversion:%2011.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
Authors
~~~~~~~
* Eficent
Contributors
~~~~~~~~~~~~
* Jordi Ballester Alomar <jordi.ballester@eficent.com>
* Lois Rilo <lois.rilo@eficent.com>
Other credits
~~~~~~~~~~~~~
The initial development of this module has been financially supported by:
* Aleph Objects, Inc.
Maintainers
~~~~~~~~~~~
This module is maintained by the OCA.
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
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.
This module is part of the `OCA/manufacture <https://github.com/OCA/manufacture/tree/11.0/mrp_repair_refurbish>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View File

@@ -0,0 +1 @@
from . import models

View File

@@ -0,0 +1,22 @@
# Copyright 2016-18 Eficent Business and IT Consulting Services S.L.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
{
"name": "MRP Repair Refurbish",
"summary": "Create refurbished products during repair",
"version": "12.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": [
'repair',
],
"data": [
"views/repair_view.xml",
"data/stock_data.xml",
"views/product_template_view.xml",
"views/product_product_view.xml",
],
}

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<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>
</odoo>

View File

@@ -0,0 +1,90 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * mrp_repair_refurbish
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2018-12-09 10:43+0000\n"
"Last-Translator: Maria Sparenberg <maria.sparenberg@gmx.net>\n"
"Language-Team: none\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 3.3\n"
#. module: mrp_repair_refurbish
#: model:ir.model,name:mrp_repair_refurbish.model_product_product
msgid "Product"
msgstr "Produkt"
#. module: mrp_repair_refurbish
#: model:ir.model,name:mrp_repair_refurbish.model_product_template
msgid "Product Template"
msgstr "Produktvorlage"
#. module: mrp_repair_refurbish
#: model:ir.ui.view,arch_db:mrp_repair_refurbish.product_normal_form_view
#: model:ir.ui.view,arch_db:mrp_repair_refurbish.product_template_only_form_view
#: model:stock.location,name:mrp_repair_refurbish.stock_location_refurbish
msgid "Refurbish"
msgstr "Wiederaufbereiten"
#. module: mrp_repair_refurbish
#: model:ir.model.fields,field_description:mrp_repair_refurbish.field_product_product_property_stock_refurbish
#: model:ir.model.fields,field_description:mrp_repair_refurbish.field_product_template_property_stock_refurbish
msgid "Refurbish Location"
msgstr "Lagerort für Wiederaufbereitung"
#. module: mrp_repair_refurbish
#: model:ir.model.fields,field_description:mrp_repair_refurbish.field_mrp_repair_refurbish_location_dest_id
msgid "Refurbished Delivery Location"
msgstr "Auslieferungslagerort"
#. module: mrp_repair_refurbish
#: model:ir.model.fields,field_description:mrp_repair_refurbish.field_mrp_repair_refurbish_move_id
msgid "Refurbished Inventory Move"
msgstr "Lagerbewegung"
#. module: mrp_repair_refurbish
#: model:ir.model.fields,field_description:mrp_repair_refurbish.field_mrp_repair_refurbish_lot_id
msgid "Refurbished Lot"
msgstr "Wiederaufbereitetes Los"
#. module: mrp_repair_refurbish
#: model:ir.model.fields,field_description:mrp_repair_refurbish.field_product_product_refurbish_product_id
#: model:ir.model.fields,field_description:mrp_repair_refurbish.field_product_template_refurbish_product_id
msgid "Refurbished Product"
msgstr "Wiederaufbereitetes Produkt"
#. module: mrp_repair_refurbish
#: model:ir.model.fields,field_description:mrp_repair_refurbish.field_mrp_repair_refurbish_product_id
msgid "Refurbished product"
msgstr "Wiederaufbereitetes Produkt"
#. module: mrp_repair_refurbish
#: model:ir.model,name:mrp_repair_refurbish.model_mrp_repair_line
msgid "Repair Line"
msgstr "Instandsetzungslinie"
#. module: mrp_repair_refurbish
#: model:ir.model,name:mrp_repair_refurbish.model_mrp_repair
msgid "Repair Order"
msgstr "Reparaturauftrag"
#. module: mrp_repair_refurbish
#: model:ir.model.fields,help:mrp_repair_refurbish.field_product_product_property_stock_refurbish
#: model:ir.model.fields,help:mrp_repair_refurbish.field_product_template_property_stock_refurbish
msgid "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."
msgstr ""
"Dieser Lagerort wird anstatt des Standardlagerortes als Quelllager für "
"Lagerbewegungen verwendet, die durch Reparaturaufträge bei der "
"Wiederaufbereitung erzeugt werden."
#. module: mrp_repair_refurbish
#: model:ir.model.fields,field_description:mrp_repair_refurbish.field_mrp_repair_to_refurbish
msgid "To Refurbish"
msgstr "Wiederaufbereiten"

View File

@@ -0,0 +1,85 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * mrp_repair_refurbish
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: mrp_repair_refurbish
#: model:ir.model,name:mrp_repair_refurbish.model_product_product
msgid "Product"
msgstr ""
#. module: mrp_repair_refurbish
#: model:ir.model,name:mrp_repair_refurbish.model_product_template
msgid "Product Template"
msgstr ""
#. module: mrp_repair_refurbish
#: model:ir.ui.view,arch_db:mrp_repair_refurbish.product_normal_form_view
#: model:ir.ui.view,arch_db:mrp_repair_refurbish.product_template_only_form_view
#: model:stock.location,name:mrp_repair_refurbish.stock_location_refurbish
msgid "Refurbish"
msgstr ""
#. module: mrp_repair_refurbish
#: model:ir.model.fields,field_description:mrp_repair_refurbish.field_product_product_property_stock_refurbish
#: model:ir.model.fields,field_description:mrp_repair_refurbish.field_product_template_property_stock_refurbish
msgid "Refurbish Location"
msgstr ""
#. module: mrp_repair_refurbish
#: model:ir.model.fields,field_description:mrp_repair_refurbish.field_mrp_repair_refurbish_location_dest_id
msgid "Refurbished Delivery Location"
msgstr ""
#. module: mrp_repair_refurbish
#: model:ir.model.fields,field_description:mrp_repair_refurbish.field_mrp_repair_refurbish_move_id
msgid "Refurbished Inventory Move"
msgstr ""
#. module: mrp_repair_refurbish
#: model:ir.model.fields,field_description:mrp_repair_refurbish.field_mrp_repair_refurbish_lot_id
msgid "Refurbished Lot"
msgstr ""
#. module: mrp_repair_refurbish
#: model:ir.model.fields,field_description:mrp_repair_refurbish.field_product_product_refurbish_product_id
#: model:ir.model.fields,field_description:mrp_repair_refurbish.field_product_template_refurbish_product_id
msgid "Refurbished Product"
msgstr ""
#. module: mrp_repair_refurbish
#: model:ir.model.fields,field_description:mrp_repair_refurbish.field_mrp_repair_refurbish_product_id
msgid "Refurbished product"
msgstr ""
#. module: mrp_repair_refurbish
#: model:ir.model,name:mrp_repair_refurbish.model_mrp_repair_line
msgid "Repair Line"
msgstr ""
#. module: mrp_repair_refurbish
#: model:ir.model,name:mrp_repair_refurbish.model_mrp_repair
msgid "Repair Order"
msgstr ""
#. module: mrp_repair_refurbish
#: model:ir.model.fields,help:mrp_repair_refurbish.field_product_product_property_stock_refurbish
#: model:ir.model.fields,help:mrp_repair_refurbish.field_product_template_property_stock_refurbish
msgid "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."
msgstr ""
#. module: mrp_repair_refurbish
#: model:ir.model.fields,field_description:mrp_repair_refurbish.field_mrp_repair_to_refurbish
msgid "To Refurbish"
msgstr ""

View File

@@ -0,0 +1,4 @@
from . import product_product
from . import product_template
from . import repair
from . import stock_move

View File

@@ -0,0 +1,12 @@
# Copyright 2017-18 Eficent Business and IT Consulting Services S.L.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from odoo 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')]")

View File

@@ -0,0 +1,43 @@
# Copyright 2017-18 Eficent Business and IT Consulting Services S.L.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from odoo 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
@api.multi
def _set_refurbish_product(self):
for rec in self:
if len(rec.product_variant_ids) == 1:
rec.product_variant_ids.refurbish_product_id = \
rec.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)]

View File

@@ -0,0 +1,85 @@
# Copyright 2017-18 Eficent Business and IT Consulting Services S.L.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from odoo import api, fields, models
class RepairOrder(models.Model):
_inherit = 'repair.order'
to_refurbish = fields.Boolean()
location_dest_id = fields.Many2one(
string='Delivery Location', comodel_name='stock.location')
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')
@api.onchange('product_id')
def onchange_product_id(self):
res = super().onchange_product_id()
self.to_refurbish = True if \
self.product_id.refurbish_product_id else False
return res
@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 _get_refurbish_stock_move_dict(self):
return {
'name': self.name,
'product_id': self.refurbish_product_id.id,
'product_uom': self.product_uom.id or
self.refurbish_product_id.uom_id.id,
'product_uom_qty': self.product_qty,
'partner_id': self.address_id and
self.address_id.id or False,
'location_id': self.location_dest_id.id,
'location_dest_id': self.refurbish_location_dest_id.id,
'restrict_lot_id': self.refurbish_lot_id.id,
}
@api.multi
def action_repair_done(self):
res = super(RepairOrder, self.with_context(
force_refurbish_location_dest_id=self.location_dest_id.id
)).action_repair_done()
for repair in self:
if repair.to_refurbish:
move = self.env['stock.move'].create(
repair._get_refurbish_stock_move_dict())
move.quantity_done = repair.product_qty
move._action_done()
repair.refurbish_move_id = move.id
return res
class RepairLine(models.Model):
_inherit = 'repair.line'
@api.onchange('type', 'repair_id')
def onchange_operation_type(self):
res = super(RepairLine, self).onchange_operation_type()
context = self.env.context
if (self.type == 'add' and 'to_refurbish' in context and
context['to_refurbish']):
self.location_dest_id = context['refurbish_location_dest_id']
elif (self.type == 'add' and 'to_refurbish' in context and not
context['to_refurbish']):
scrap_location_id = self.env['stock.location'].search([
('usage', '=', 'customer')], limit=1)
self.location_dest_id = scrap_location_id
return res

View File

@@ -0,0 +1,15 @@
# Copyright 2019 Camptocamp SA
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
from odoo import models, api
class StockMove(models.Model):
_inherit = 'stock.move'
@api.model
def create(self, vals):
if 'force_refurbish_location_dest_id' in self.env.context:
vals['location_dest_id'] = self.env.context[
'force_refurbish_location_dest_id']
return super().create(vals)

View File

@@ -0,0 +1,4 @@
#. 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.

View File

@@ -0,0 +1,3 @@
* Jordi Ballester Alomar <jordi.ballester@eficent.com>
* Lois Rilo <lois.rilo@eficent.com>
* Akim Juillerat <akim.juillerat@camptocamp.com>

View File

@@ -0,0 +1,3 @@
The initial development of this module has been financially supported by:
* Aleph Objects, Inc.

View File

@@ -0,0 +1,2 @@
This module adds the ability to obtain refurbished product as a consequence
of the repair of a product that was defective.

View File

@@ -0,0 +1,12 @@
#. 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.

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -0,0 +1,455 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.14: http://docutils.sourceforge.net/" />
<title>MRP Repair Refurbish</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: grey; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document" id="mrp-repair-refurbish">
<h1 class="title">MRP Repair Refurbish</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/manufacture/tree/11.0/mrp_repair_refurbish"><img alt="OCA/manufacture" src="https://img.shields.io/badge/github-OCA%2Fmanufacture-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/manufacture-11-0/manufacture-11-0-mrp_repair_refurbish"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/129/11.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p>
<p>This module adds the ability to obtain refurbished product as a consequence
of the repair of a product that was defective.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#configuration" id="id1">Configuration</a></li>
<li><a class="reference internal" href="#usage" id="id2">Usage</a></li>
<li><a class="reference internal" href="#bug-tracker" id="id3">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="id4">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="id5">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="id6">Contributors</a></li>
<li><a class="reference internal" href="#other-credits" id="id7">Other credits</a></li>
<li><a class="reference internal" href="#maintainers" id="id8">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="configuration">
<h1><a class="toc-backref" href="#id1">Configuration</a></h1>
<ol class="arabic simple">
<li>For each product that can potentially be refurbished, define the
refurbished version in the product form.</li>
<li>A default Refurbished virtual location is created during module install,
and proposed by default on each product.</li>
</ol>
</div>
<div class="section" id="usage">
<h1><a class="toc-backref" href="#id2">Usage</a></h1>
<ol class="arabic simple">
<li>Create an MRP repair.</li>
<li>Indicate a product to repair, If the product has a proposed refurbished
version, it will be proposed to be used. The destination location</li>
<li>Add operations if needed.</li>
<li>Complete the repair.</li>
</ol>
<p>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.</p>
<p>The components that were added to the repair order will be moved to the
Refurbish location.</p>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#id3">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/manufacture/issues">GitHub Issues</a>.
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
<a class="reference external" href="https://github.com/OCA/manufacture/issues/new?body=module:%20mrp_repair_refurbish%0Aversion:%2011.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1><a class="toc-backref" href="#id4">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#id5">Authors</a></h2>
<ul class="simple">
<li>Eficent</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#id6">Contributors</a></h2>
<ul class="simple">
<li>Jordi Ballester Alomar &lt;<a class="reference external" href="mailto:jordi.ballester&#64;eficent.com">jordi.ballester&#64;eficent.com</a>&gt;</li>
<li>Lois Rilo &lt;<a class="reference external" href="mailto:lois.rilo&#64;eficent.com">lois.rilo&#64;eficent.com</a>&gt;</li>
</ul>
</div>
<div class="section" id="other-credits">
<h2><a class="toc-backref" href="#id7">Other credits</a></h2>
<p>The initial development of this module has been financially supported by:</p>
<ul class="simple">
<li>Aleph Objects, Inc.</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#id8">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<p>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.</p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/manufacture/tree/11.0/mrp_repair_refurbish">OCA/manufacture</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1 @@
from . import test_repair_refurbish

View File

@@ -0,0 +1,91 @@
# Copyright 2018 Eficent Business and IT Consulting Services S.L.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo.tests.common import TransactionCase
class TestMrpMtoWithStock(TransactionCase):
def setUp(self, *args, **kwargs):
super(TestMrpMtoWithStock, self).setUp(*args, **kwargs)
self.repair_obj = self.env['repair.order']
self.repair_line_obj = self.env['repair.line']
self.product_obj = self.env['product.product']
self.move_obj = self.env['stock.move']
self.stock_location_stock = self.env.ref('stock.stock_location_stock')
self.customer_location = self.env.ref('stock.stock_location_customers')
self.refurbish_loc = self.env.ref(
'repair_refurbish.stock_location_refurbish')
self.refurbish_product = self.product_obj.create({
'name': 'Refurbished Awesome Screen',
'type': 'product',
})
self.product = self.product_obj.create({
'name': 'Awesome Screen',
'type': 'product',
'refurbish_product_id': self.refurbish_product.id,
})
self.material = self.product_obj.create({
'name': 'Materials',
'type': 'consu',
})
self._update_product_qty(self.product, self.stock_location_stock, 10.0)
def _update_product_qty(self, product, location, quantity):
product_qty = self.env['stock.change.product.qty'].create({
'location_id': location.id,
'product_id': product.id,
'new_quantity': quantity,
})
product_qty.change_product_qty()
return product_qty
def test_01_repair_refurbish(self):
"""Tests that locations are properly set with a product to
refurbish, then complete repair."""
repair = self.repair_obj.create({
'product_id': self.product.id,
'product_qty': 3.0,
'product_uom': self.product.uom_id.id,
'location_dest_id': self.customer_location.id,
})
repair.onchange_product_id()
self.assertTrue(repair.to_refurbish)
repair._onchange_to_refurbish()
self.assertEqual(repair.refurbish_location_dest_id,
self.customer_location)
self.assertEqual(repair.location_dest_id,
self.product.property_stock_refurbish)
line = self.repair_line_obj.with_context(
to_refurbish=repair.to_refurbish,
refurbish_location_dest_id=repair.refurbish_location_dest_id,
).new({
'name': 'consume stuff to repair',
'repair_id': repair.id,
'type': 'add',
'product_id': self.material.id,
'product_uom': self.material.uom_id.id,
'product_uom_qty': 1.0,
})
line.onchange_product_id()
line.onchange_operation_type()
self.assertEqual(line.location_id, repair.location_id)
self.assertEqual(line.location_dest_id, self.customer_location)
# Complete repair:
repair.action_validate()
repair.action_repair_start()
repair.action_repair_end()
moves = self.move_obj.search([('reference', '=', repair.name)])
self.assertEqual(len(moves), 2)
for m in moves:
self.assertEqual(m.state, 'done')
if m.product_id == self.product:
self.assertEqual(m.location_id, self.stock_location_stock)
self.assertEqual(m.location_dest_id, self.refurbish_loc)
elif m.product_id == self.refurbish_product:
self.assertEqual(m.location_id, self.refurbish_loc)
self.assertEqual(m.location_dest_id, self.customer_location)
else:
self.assertTrue(False, "Unexpected move.")

View 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>

View 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', '&gt;', 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>

View File

@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_repair_order_tree" model="ir.ui.view">
<field name="name">repair.order.tree</field>
<field name="model">repair.order</field>
<field name="inherit_id" ref="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">repair.order.form</field>
<field name="model">repair.order</field>
<field name="inherit_id" ref="repair.view_repair_order_form"/>
<field name="arch" type="xml">
<field name="location_id" position="after">
<field name="location_dest_id" attrs="{'invisible': [('to_refurbish', '=', False)], 'required': [('to_refurbish', '=', True)]}" />
</field>
<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">repair.order.select</field>
<field name="model">repair.order</field>
<field name="inherit_id" ref="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>