diff --git a/mrp_request_bom_structure/__init__.py b/mrp_request_bom_structure/__init__.py
new file mode 100644
index 000000000..0650744f6
--- /dev/null
+++ b/mrp_request_bom_structure/__init__.py
@@ -0,0 +1 @@
+from . import models
diff --git a/mrp_request_bom_structure/__manifest__.py b/mrp_request_bom_structure/__manifest__.py
new file mode 100644
index 000000000..ccda5cb57
--- /dev/null
+++ b/mrp_request_bom_structure/__manifest__.py
@@ -0,0 +1,21 @@
+# © 2020 David BEAL @ Akretion
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
+
+{
+ "name": "MRP Request Bom Structure",
+ "version": "12.0.1.0.0",
+ "license": "AGPL-3",
+ "author": "Akretion,"
+ "Odoo Community Association (OCA)",
+ "summary": "Shortcut between Manufacturing Request and Bom report",
+ "website": "https://github.com/OCA/manufacture",
+ "category": "Manufacturing",
+ "depends": [
+ "mrp_production_request",
+ ],
+ "data": [
+ "data/config_parameter.xml",
+ "views/mrp_request.xml",
+ ],
+ "installable": True
+}
diff --git a/mrp_request_bom_structure/data/config_parameter.xml b/mrp_request_bom_structure/data/config_parameter.xml
new file mode 100644
index 000000000..d3e089fcd
--- /dev/null
+++ b/mrp_request_bom_structure/data/config_parameter.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+ request_bom_structure
+ {}
+
+
+
+
diff --git a/mrp_request_bom_structure/i18n/fr.po b/mrp_request_bom_structure/i18n/fr.po
new file mode 100644
index 000000000..b46e3acba
--- /dev/null
+++ b/mrp_request_bom_structure/i18n/fr.po
@@ -0,0 +1,42 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * mrp_request_bom_structure
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2020-12-04 10:35+0000\n"
+"PO-Revision-Date: 2020-12-04 10:35+0000\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_request_bom_structure
+#: model:ir.model,name:mrp_request_bom_structure.model_report_mrp_report_bom_structure
+msgid "BOM Structure Report"
+msgstr "Rapport de structure de nomenclature"
+
+#. module: mrp_request_bom_structure
+#: model_terms:ir.ui.view,arch_db:mrp_request_bom_structure.view_mrp_production_request_form
+msgid "Bom Structure"
+msgstr "Structure de nomenclature"
+
+#. module: mrp_request_bom_structure
+#: model_terms:ir.ui.view,arch_db:mrp_request_bom_structure.view_mrp_production_request_form
+msgid "Go to Bom Structure report"
+msgstr "Se rendre vers le rapport de Structure de nomenclature"
+
+#. module: mrp_request_bom_structure
+#: model:ir.model,name:mrp_request_bom_structure.model_mrp_production_request
+msgid "Manufacturing Request"
+msgstr "Demande de fabrication"
+
+#. module: mrp_request_bom_structure
+#: code:addons/mrp_request_bom_structure/models/mrp_request.py:26
+#, python-format
+msgid "Structure"
+msgstr "Structure"
diff --git a/mrp_request_bom_structure/models/__init__.py b/mrp_request_bom_structure/models/__init__.py
new file mode 100644
index 000000000..f579071c3
--- /dev/null
+++ b/mrp_request_bom_structure/models/__init__.py
@@ -0,0 +1,2 @@
+from . import mrp_request
+from . import bom_structure
diff --git a/mrp_request_bom_structure/models/bom_structure.py b/mrp_request_bom_structure/models/bom_structure.py
new file mode 100644
index 000000000..9c2b81cc8
--- /dev/null
+++ b/mrp_request_bom_structure/models/bom_structure.py
@@ -0,0 +1,24 @@
+# © 2020 David BEAL @ Akretion
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
+
+import json
+
+from odoo import api, models
+
+
+class ReportBomStructure(models.AbstractModel):
+ _inherit = "report.mrp.report_bom_structure"
+
+ @api.model
+ def get_html(self, bom_id=False, searchQty=1, searchVariant=False):
+ """Set quantity from stored parameter"""
+ IConf = self.env["ir.config_parameter"].sudo()
+ param = IConf.get_param("request_bom_structure")
+ param = json.loads(param)
+ if self.env.context.get("model") == "mrp.production.request" and searchQty == 1:
+ # We don't want used stored quantity when we are in an other situation
+ # to avoid break native behavior
+ searchQty = param.get(str(self.env.context.get("uid"))) or searchQty
+ return super().get_html(
+ bom_id=bom_id, searchQty=searchQty, searchVariant=searchVariant
+ )
diff --git a/mrp_request_bom_structure/models/mrp_request.py b/mrp_request_bom_structure/models/mrp_request.py
new file mode 100644
index 000000000..d6a7f3e69
--- /dev/null
+++ b/mrp_request_bom_structure/models/mrp_request.py
@@ -0,0 +1,35 @@
+# © 2020 David BEAL @ Akretion
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
+
+import json
+
+from odoo import _, models
+
+
+class MrpProductionRequest(models.Model):
+ _inherit = "mrp.production.request"
+
+ def button_open_structure_report(self):
+ """ - store quantity in parameter
+ - return action client
+ """
+ self.ensure_one()
+ IConf = self.env["ir.config_parameter"].sudo()
+ try:
+ param = json.loads(IConf.get_param("request_bom_structure")) or {}
+ except Exception:
+ param = {}
+ param[str(self.env.context.get("uid"))] = self.product_qty
+ # bom structure report'll use this stored param
+ IConf.set_param("request_bom_structure", json.dumps(param))
+ return {
+ "name": _("Structure"),
+ "res_model": "report.mrp.report_bom_structure",
+ "context": {
+ "model": "report.mrp.report_bom_structure",
+ "active_id": self.bom_id.id,
+ },
+ "target": "current",
+ "tag": "mrp_bom_report",
+ "type": "ir.actions.client",
+ }
diff --git a/mrp_request_bom_structure/readme/CONTRIBUTORS.rst b/mrp_request_bom_structure/readme/CONTRIBUTORS.rst
new file mode 100644
index 000000000..46ce034b1
--- /dev/null
+++ b/mrp_request_bom_structure/readme/CONTRIBUTORS.rst
@@ -0,0 +1 @@
+* David Béal
diff --git a/mrp_request_bom_structure/readme/DESCRIPTION.rst b/mrp_request_bom_structure/readme/DESCRIPTION.rst
new file mode 100644
index 000000000..79240cc7c
--- /dev/null
+++ b/mrp_request_bom_structure/readme/DESCRIPTION.rst
@@ -0,0 +1 @@
+Add a button in Manufacturing Request to dive into 'BoM Structure & Cost' report with the quantity of the request.
diff --git a/mrp_request_bom_structure/readme/ROADMAP.rst b/mrp_request_bom_structure/readme/ROADMAP.rst
new file mode 100644
index 000000000..af43d3236
--- /dev/null
+++ b/mrp_request_bom_structure/readme/ROADMAP.rst
@@ -0,0 +1,2 @@
+Find a better way to send quantity to report instead of storing data in config
+Actually given context in ir.actions.client is lost in http stack.
diff --git a/mrp_request_bom_structure/readme/USAGE.rst b/mrp_request_bom_structure/readme/USAGE.rst
new file mode 100644
index 000000000..7d9b7920b
--- /dev/null
+++ b/mrp_request_bom_structure/readme/USAGE.rst
@@ -0,0 +1,5 @@
+To use this module, you need to:
+
+#. Go to *Manufacturing > Operations > Manufacturing Requests*.
+#. Put any product quantity on your request
+#. Click on 'Bom Structure'
diff --git a/mrp_request_bom_structure/tests/__init__.py b/mrp_request_bom_structure/tests/__init__.py
new file mode 100644
index 000000000..2c1a9ef4b
--- /dev/null
+++ b/mrp_request_bom_structure/tests/__init__.py
@@ -0,0 +1 @@
+from . import test_request_structure
diff --git a/mrp_request_bom_structure/tests/test_request_structure.py b/mrp_request_bom_structure/tests/test_request_structure.py
new file mode 100644
index 000000000..1d4dd4259
--- /dev/null
+++ b/mrp_request_bom_structure/tests/test_request_structure.py
@@ -0,0 +1,34 @@
+# © 2020 David BEAL @ Akretion
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
+
+import json
+
+from odoo.tests.common import SavepointCase
+
+
+class TestRequest2Structure(SavepointCase):
+ def setUp(self, *args, **kwargs):
+ super().setUp(*args, **kwargs)
+ product = self.env.ref("mrp.product_product_wood_panel")
+ self.bom = self.env.ref("mrp.mrp_bom_wood_panel")
+ self.request = self.env["mrp.production.request"].create(
+ {
+ "name": "Test",
+ "product_qty": 777.0,
+ "product_id": product.id,
+ "bom_id": self.bom.id,
+ }
+ )
+
+ def test_generate_bom_structure_with_right_qty(self):
+ action = self.request.with_context(uid=2).button_open_structure_report()
+ param = self.env["ir.config_parameter"].get_param("request_bom_structure")
+ param = json.loads(param)
+ assert param == {"2": 777.0}
+ res = (
+ self.env["report.mrp.report_bom_structure"]
+ .with_context(model="mrp.production.request", uid=2)
+ .get_html(bom_id=self.bom.id)
+ )
+ assert res["bom_qty"] == 777.0
+ return action
diff --git a/mrp_request_bom_structure/views/mrp_request.xml b/mrp_request_bom_structure/views/mrp_request.xml
new file mode 100644
index 000000000..80efca7b5
--- /dev/null
+++ b/mrp_request_bom_structure/views/mrp_request.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+ mrp.production.request
+
+
+
+
+
+
+
+
+
+