odoo-addon-mrp-unbuild-restore-origin 16.0.1.0.0.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,104 @@
1
+ ==========================
2
+ Mrp Unbuild Restore Origin
3
+ ==========================
4
+
5
+ ..
6
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
7
+ !! This file is generated by oca-gen-addon-readme !!
8
+ !! changes will be overwritten. !!
9
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
10
+ !! source digest: sha256:4d034a75598bfb9ecc4360b2d4f77bc06fd25ac2c3d6580eafcb1cee3e442139
11
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
12
+
13
+ .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
14
+ :target: https://odoo-community.org/page/development-status
15
+ :alt: Beta
16
+ .. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
17
+ :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
18
+ :alt: License: AGPL-3
19
+ .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fmanufacture-lightgray.png?logo=github
20
+ :target: https://github.com/OCA/manufacture/tree/16.0/mrp_unbuild_restore_origin
21
+ :alt: OCA/manufacture
22
+ .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
23
+ :target: https://translation.odoo-community.org/projects/manufacture-16-0/manufacture-16-0-mrp_unbuild_restore_origin
24
+ :alt: Translate me on Weblate
25
+ .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
26
+ :target: https://runboat.odoo-community.org/builds?repo=OCA/manufacture&target_branch=16.0
27
+ :alt: Try me on Runboat
28
+
29
+ |badge1| |badge2| |badge3| |badge4| |badge5|
30
+
31
+ | This module enhances the unbuild process of Manufacturing Orders by
32
+ retaining
33
+ | information from the original move lines.
34
+
35
+ - | **Owner Retention:** The owner from the original move lines is
36
+ always retained
37
+ | automatically when unbuilding a Manufacturing Order.
38
+
39
+ - | **Location Retention (Optional):** A boolean field is available to
40
+ retain the original
41
+ | source and destination locations of the move lines during the
42
+ unbuild process, if needed.
43
+
44
+ **Table of contents**
45
+
46
+ .. contents::
47
+ :local:
48
+
49
+ Usage
50
+ =====
51
+
52
+ | When unbuilding a completed Manufacturing Order, the owner from the
53
+ original move
54
+ | lines is always retained automatically.
55
+
56
+ | If you want the components to be returned to the same locations they
57
+ were originally
58
+ | consumed from, enable the checkbox labeled **"Restore Components to
59
+ Original Location"**
60
+ | when creating the Unbuild Order. If this option is not enabled, Odoo
61
+ will follow its standard behavior.
62
+
63
+ Bug Tracker
64
+ ===========
65
+
66
+ Bugs are tracked on `GitHub Issues <https://github.com/OCA/manufacture/issues>`_.
67
+ In case of trouble, please check there if your issue has already been reported.
68
+ If you spotted it first, help us to smash it by providing a detailed and welcomed
69
+ `feedback <https://github.com/OCA/manufacture/issues/new?body=module:%20mrp_unbuild_restore_origin%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
70
+
71
+ Do not contact contributors directly about support or help with technical issues.
72
+
73
+ Credits
74
+ =======
75
+
76
+ Authors
77
+ -------
78
+
79
+ * Quartile
80
+
81
+ Contributors
82
+ ------------
83
+
84
+ - `Quartile <https://www.quartile.co>`__:
85
+
86
+ - Aung Ko Ko Lin
87
+ - Yoshi Tashiro
88
+
89
+ Maintainers
90
+ -----------
91
+
92
+ This module is maintained by the OCA.
93
+
94
+ .. image:: https://odoo-community.org/logo.png
95
+ :alt: Odoo Community Association
96
+ :target: https://odoo-community.org
97
+
98
+ OCA, or the Odoo Community Association, is a nonprofit organization whose
99
+ mission is to support the collaborative development of Odoo features and
100
+ promote its widespread use.
101
+
102
+ This module is part of the `OCA/manufacture <https://github.com/OCA/manufacture/tree/16.0/mrp_unbuild_restore_origin>`_ project on GitHub.
103
+
104
+ You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
@@ -0,0 +1 @@
1
+ from . import models
@@ -0,0 +1,13 @@
1
+ # Copyright 2025 Quartile (https://www.quartile.co)
2
+ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3
+ {
4
+ "name": "Mrp Unbuild Restore Origin",
5
+ "version": "16.0.1.0.0",
6
+ "author": "Quartile, Odoo Community Association (OCA)",
7
+ "website": "https://github.com/OCA/manufacture",
8
+ "category": "Stock",
9
+ "license": "AGPL-3",
10
+ "depends": ["mrp"],
11
+ "data": ["views/mrp_unbuild_views.xml"],
12
+ "installable": True,
13
+ }
@@ -0,0 +1,36 @@
1
+ # Translation of Odoo Server.
2
+ # This file contains the translation of the following modules:
3
+ # * mrp_unbuild_restore_origin
4
+ #
5
+ msgid ""
6
+ msgstr ""
7
+ "Project-Id-Version: Odoo Server 16.0\n"
8
+ "Report-Msgid-Bugs-To: \n"
9
+ "Last-Translator: \n"
10
+ "Language-Team: \n"
11
+ "MIME-Version: 1.0\n"
12
+ "Content-Type: text/plain; charset=UTF-8\n"
13
+ "Content-Transfer-Encoding: \n"
14
+ "Plural-Forms: \n"
15
+
16
+ #. module: mrp_unbuild_restore_origin
17
+ #: model:ir.model.fields,help:mrp_unbuild_restore_origin.field_mrp_unbuild__restore_rm_stock_in_origin_loc
18
+ msgid ""
19
+ "If enabled, the source location of the component stock move lines will be "
20
+ "used as the destination location for the unbuild move lines."
21
+ msgstr ""
22
+
23
+ #. module: mrp_unbuild_restore_origin
24
+ #: model:ir.model.fields,field_description:mrp_unbuild_restore_origin.field_mrp_unbuild__restore_rm_stock_in_origin_loc
25
+ msgid "Restore Raw Materials to Consumed Location"
26
+ msgstr ""
27
+
28
+ #. module: mrp_unbuild_restore_origin
29
+ #: model:ir.model,name:mrp_unbuild_restore_origin.model_stock_move
30
+ msgid "Stock Move"
31
+ msgstr ""
32
+
33
+ #. module: mrp_unbuild_restore_origin
34
+ #: model:ir.model,name:mrp_unbuild_restore_origin.model_mrp_unbuild
35
+ msgid "Unbuild Order"
36
+ msgstr ""
@@ -0,0 +1,2 @@
1
+ from . import mrp_unbuild
2
+ from . import stock_move
@@ -0,0 +1,83 @@
1
+ # Copyright 2025 Quartile (https://www.quartile.co)
2
+ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
3
+
4
+ from odoo import fields, models
5
+
6
+
7
+ class MrpUnbuild(models.Model):
8
+ _inherit = "mrp.unbuild"
9
+
10
+ restore_rm_stock_in_origin_loc = fields.Boolean(
11
+ string="Restore Raw Materials to Consumed Location",
12
+ help="If enabled, the source location of the component stock move lines will be used"
13
+ " as the destination location for the unbuild move lines.",
14
+ )
15
+
16
+ def action_unbuild(self):
17
+ self.ensure_one()
18
+ if self.mo_id:
19
+ self = self.with_context(restore_origin=True)
20
+ if self.restore_rm_stock_in_origin_loc:
21
+ self = self.with_context(exact_location=True)
22
+ return super().action_unbuild()
23
+
24
+ def _prepare_move_line_vals(self, move, origin_move_line, taken_quantity):
25
+ vals = super()._prepare_move_line_vals(move, origin_move_line, taken_quantity)
26
+ vals["owner_id"] = origin_move_line.owner_id.id
27
+ if self.env.context.get("exact_location"):
28
+ vals["location_id"] = origin_move_line.location_dest_id.id
29
+ vals["location_dest_id"] = origin_move_line.location_id.id
30
+ return vals
31
+
32
+ def _get_move_line_vals(self, move, move_line):
33
+ vals = {
34
+ "move_id": move.id,
35
+ "owner_id": move_line.owner_id.id,
36
+ "qty_done": min(move.product_uom_qty, move_line.qty_done),
37
+ "product_id": move.product_id.id,
38
+ "product_uom_id": move.product_uom.id,
39
+ "location_id": move.location_id.id,
40
+ "location_dest_id": move.location_dest_id.id,
41
+ }
42
+ if self.env.context.get("exact_location"):
43
+ vals["location_id"] = move_line.location_dest_id.id
44
+ vals["location_dest_id"] = move_line.location_id.id
45
+ return vals
46
+
47
+ def _generate_produce_moves(self):
48
+ """This logic may seem a bit complex, but it's necessary due to how the following
49
+ standard code works:
50
+ https://github.com/OCA/OCB/blob/52bec03/addons/mrp/models/mrp_unbuild.py#L189-L207
51
+ In short, we need to prepare stock.move.line records in advance with the correct
52
+ values, because the standard logic will otherwise generate them incorrectly
53
+ (e.g., with the wrong destination location or no owner).
54
+ """
55
+ if not self.env.context.get("restore_origin"):
56
+ return super()._generate_produce_moves()
57
+ moves = self.env["stock.move"]
58
+ for unbuild in self:
59
+ raw_moves = unbuild.mo_id.move_raw_ids.filtered(
60
+ lambda move: move.state == "done"
61
+ )
62
+ factor = (
63
+ unbuild.product_qty
64
+ / unbuild.mo_id.product_uom_id._compute_quantity(
65
+ unbuild.mo_id.product_qty, unbuild.product_uom_id
66
+ )
67
+ )
68
+ for raw_move in raw_moves:
69
+ move = unbuild._generate_move_from_existing_move(
70
+ raw_move,
71
+ factor,
72
+ raw_move.location_dest_id,
73
+ self.location_dest_id,
74
+ )
75
+ if move.has_tracking == "none":
76
+ vals_list = []
77
+ for move_line in raw_move.move_line_ids:
78
+ vals = self._get_move_line_vals(move, move_line)
79
+ vals_list.append(vals)
80
+ self.env["stock.move.line"].create(vals_list)
81
+ move.write({"state": "confirmed"})
82
+ moves += move
83
+ return moves.with_context(produce_moves=True)
@@ -0,0 +1,19 @@
1
+ # Copyright 2025 Quartile (https://www.quartile.co)
2
+ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3
+
4
+ from odoo import models
5
+
6
+
7
+ class StockMove(models.Model):
8
+ _inherit = "stock.move"
9
+
10
+ def _action_confirm(self, merge=True, merge_into=False):
11
+ # We particularly want to skip
12
+ # https://github.com/OCA/OCB/blob/53e1941/addons/mrp/models/mrp_unbuild.py#L148
13
+ # for component receipts to avoid generation of stock.move.line records with
14
+ # the standard logic.
15
+ if self.env.context.get("restore_origin") and self.env.context.get(
16
+ "produce_moves"
17
+ ):
18
+ return self
19
+ return super()._action_confirm(merge, merge_into)
@@ -0,0 +1,3 @@
1
+ - [Quartile](https://www.quartile.co):
2
+ - Aung Ko Ko Lin
3
+ - Yoshi Tashiro
@@ -0,0 +1,8 @@
1
+ This module enhances the unbuild process of Manufacturing Orders by retaining
2
+ information from the original move lines.
3
+
4
+ - **Owner Retention:** The owner from the original move lines is always retained
5
+ automatically when unbuilding a Manufacturing Order.
6
+
7
+ - **Location Retention (Optional):** A boolean field is available to retain the original
8
+ source and destination locations of the move lines during the unbuild process, if needed.
@@ -0,0 +1,7 @@
1
+ When unbuilding a completed Manufacturing Order, the owner from the original move
2
+ lines is always retained automatically.
3
+
4
+ If you want the components to be returned to the same locations they were originally
5
+ consumed from, enable the checkbox labeled **"Restore Components to Original Location"**
6
+ when creating the Unbuild Order. If this option is not enabled, Odoo will follow its standard
7
+ behavior.
@@ -0,0 +1,463 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5
+ <meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
6
+ <title>Mrp Unbuild Restore Origin</title>
7
+ <style type="text/css">
8
+
9
+ /*
10
+ :Author: David Goodger (goodger@python.org)
11
+ :Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
12
+ :Copyright: This stylesheet has been placed in the public domain.
13
+
14
+ Default cascading style sheet for the HTML output of Docutils.
15
+ Despite the name, some widely supported CSS2 features are used.
16
+
17
+ See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
18
+ customize this style sheet.
19
+ */
20
+
21
+ /* used to remove borders from tables and images */
22
+ .borderless, table.borderless td, table.borderless th {
23
+ border: 0 }
24
+
25
+ table.borderless td, table.borderless th {
26
+ /* Override padding for "table.docutils td" with "! important".
27
+ The right padding separates the table cells. */
28
+ padding: 0 0.5em 0 0 ! important }
29
+
30
+ .first {
31
+ /* Override more specific margin styles with "! important". */
32
+ margin-top: 0 ! important }
33
+
34
+ .last, .with-subtitle {
35
+ margin-bottom: 0 ! important }
36
+
37
+ .hidden {
38
+ display: none }
39
+
40
+ .subscript {
41
+ vertical-align: sub;
42
+ font-size: smaller }
43
+
44
+ .superscript {
45
+ vertical-align: super;
46
+ font-size: smaller }
47
+
48
+ a.toc-backref {
49
+ text-decoration: none ;
50
+ color: black }
51
+
52
+ blockquote.epigraph {
53
+ margin: 2em 5em ; }
54
+
55
+ dl.docutils dd {
56
+ margin-bottom: 0.5em }
57
+
58
+ object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
59
+ overflow: hidden;
60
+ }
61
+
62
+ /* Uncomment (and remove this text!) to get bold-faced definition list terms
63
+ dl.docutils dt {
64
+ font-weight: bold }
65
+ */
66
+
67
+ div.abstract {
68
+ margin: 2em 5em }
69
+
70
+ div.abstract p.topic-title {
71
+ font-weight: bold ;
72
+ text-align: center }
73
+
74
+ div.admonition, div.attention, div.caution, div.danger, div.error,
75
+ div.hint, div.important, div.note, div.tip, div.warning {
76
+ margin: 2em ;
77
+ border: medium outset ;
78
+ padding: 1em }
79
+
80
+ div.admonition p.admonition-title, div.hint p.admonition-title,
81
+ div.important p.admonition-title, div.note p.admonition-title,
82
+ div.tip p.admonition-title {
83
+ font-weight: bold ;
84
+ font-family: sans-serif }
85
+
86
+ div.attention p.admonition-title, div.caution p.admonition-title,
87
+ div.danger p.admonition-title, div.error p.admonition-title,
88
+ div.warning p.admonition-title, .code .error {
89
+ color: red ;
90
+ font-weight: bold ;
91
+ font-family: sans-serif }
92
+
93
+ /* Uncomment (and remove this text!) to get reduced vertical space in
94
+ compound paragraphs.
95
+ div.compound .compound-first, div.compound .compound-middle {
96
+ margin-bottom: 0.5em }
97
+
98
+ div.compound .compound-last, div.compound .compound-middle {
99
+ margin-top: 0.5em }
100
+ */
101
+
102
+ div.dedication {
103
+ margin: 2em 5em ;
104
+ text-align: center ;
105
+ font-style: italic }
106
+
107
+ div.dedication p.topic-title {
108
+ font-weight: bold ;
109
+ font-style: normal }
110
+
111
+ div.figure {
112
+ margin-left: 2em ;
113
+ margin-right: 2em }
114
+
115
+ div.footer, div.header {
116
+ clear: both;
117
+ font-size: smaller }
118
+
119
+ div.line-block {
120
+ display: block ;
121
+ margin-top: 1em ;
122
+ margin-bottom: 1em }
123
+
124
+ div.line-block div.line-block {
125
+ margin-top: 0 ;
126
+ margin-bottom: 0 ;
127
+ margin-left: 1.5em }
128
+
129
+ div.sidebar {
130
+ margin: 0 0 0.5em 1em ;
131
+ border: medium outset ;
132
+ padding: 1em ;
133
+ background-color: #ffffee ;
134
+ width: 40% ;
135
+ float: right ;
136
+ clear: right }
137
+
138
+ div.sidebar p.rubric {
139
+ font-family: sans-serif ;
140
+ font-size: medium }
141
+
142
+ div.system-messages {
143
+ margin: 5em }
144
+
145
+ div.system-messages h1 {
146
+ color: red }
147
+
148
+ div.system-message {
149
+ border: medium outset ;
150
+ padding: 1em }
151
+
152
+ div.system-message p.system-message-title {
153
+ color: red ;
154
+ font-weight: bold }
155
+
156
+ div.topic {
157
+ margin: 2em }
158
+
159
+ h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
160
+ h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
161
+ margin-top: 0.4em }
162
+
163
+ h1.title {
164
+ text-align: center }
165
+
166
+ h2.subtitle {
167
+ text-align: center }
168
+
169
+ hr.docutils {
170
+ width: 75% }
171
+
172
+ img.align-left, .figure.align-left, object.align-left, table.align-left {
173
+ clear: left ;
174
+ float: left ;
175
+ margin-right: 1em }
176
+
177
+ img.align-right, .figure.align-right, object.align-right, table.align-right {
178
+ clear: right ;
179
+ float: right ;
180
+ margin-left: 1em }
181
+
182
+ img.align-center, .figure.align-center, object.align-center {
183
+ display: block;
184
+ margin-left: auto;
185
+ margin-right: auto;
186
+ }
187
+
188
+ table.align-center {
189
+ margin-left: auto;
190
+ margin-right: auto;
191
+ }
192
+
193
+ .align-left {
194
+ text-align: left }
195
+
196
+ .align-center {
197
+ clear: both ;
198
+ text-align: center }
199
+
200
+ .align-right {
201
+ text-align: right }
202
+
203
+ /* reset inner alignment in figures */
204
+ div.align-right {
205
+ text-align: inherit }
206
+
207
+ /* div.align-center * { */
208
+ /* text-align: left } */
209
+
210
+ .align-top {
211
+ vertical-align: top }
212
+
213
+ .align-middle {
214
+ vertical-align: middle }
215
+
216
+ .align-bottom {
217
+ vertical-align: bottom }
218
+
219
+ ol.simple, ul.simple {
220
+ margin-bottom: 1em }
221
+
222
+ ol.arabic {
223
+ list-style: decimal }
224
+
225
+ ol.loweralpha {
226
+ list-style: lower-alpha }
227
+
228
+ ol.upperalpha {
229
+ list-style: upper-alpha }
230
+
231
+ ol.lowerroman {
232
+ list-style: lower-roman }
233
+
234
+ ol.upperroman {
235
+ list-style: upper-roman }
236
+
237
+ p.attribution {
238
+ text-align: right ;
239
+ margin-left: 50% }
240
+
241
+ p.caption {
242
+ font-style: italic }
243
+
244
+ p.credits {
245
+ font-style: italic ;
246
+ font-size: smaller }
247
+
248
+ p.label {
249
+ white-space: nowrap }
250
+
251
+ p.rubric {
252
+ font-weight: bold ;
253
+ font-size: larger ;
254
+ color: maroon ;
255
+ text-align: center }
256
+
257
+ p.sidebar-title {
258
+ font-family: sans-serif ;
259
+ font-weight: bold ;
260
+ font-size: larger }
261
+
262
+ p.sidebar-subtitle {
263
+ font-family: sans-serif ;
264
+ font-weight: bold }
265
+
266
+ p.topic-title {
267
+ font-weight: bold }
268
+
269
+ pre.address {
270
+ margin-bottom: 0 ;
271
+ margin-top: 0 ;
272
+ font: inherit }
273
+
274
+ pre.literal-block, pre.doctest-block, pre.math, pre.code {
275
+ margin-left: 2em ;
276
+ margin-right: 2em }
277
+
278
+ pre.code .ln { color: gray; } /* line numbers */
279
+ pre.code, code { background-color: #eeeeee }
280
+ pre.code .comment, code .comment { color: #5C6576 }
281
+ pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
282
+ pre.code .literal.string, code .literal.string { color: #0C5404 }
283
+ pre.code .name.builtin, code .name.builtin { color: #352B84 }
284
+ pre.code .deleted, code .deleted { background-color: #DEB0A1}
285
+ pre.code .inserted, code .inserted { background-color: #A3D289}
286
+
287
+ span.classifier {
288
+ font-family: sans-serif ;
289
+ font-style: oblique }
290
+
291
+ span.classifier-delimiter {
292
+ font-family: sans-serif ;
293
+ font-weight: bold }
294
+
295
+ span.interpreted {
296
+ font-family: sans-serif }
297
+
298
+ span.option {
299
+ white-space: nowrap }
300
+
301
+ span.pre {
302
+ white-space: pre }
303
+
304
+ span.problematic, pre.problematic {
305
+ color: red }
306
+
307
+ span.section-subtitle {
308
+ /* font-size relative to parent (h1..h6 element) */
309
+ font-size: 80% }
310
+
311
+ table.citation {
312
+ border-left: solid 1px gray;
313
+ margin-left: 1px }
314
+
315
+ table.docinfo {
316
+ margin: 2em 4em }
317
+
318
+ table.docutils {
319
+ margin-top: 0.5em ;
320
+ margin-bottom: 0.5em }
321
+
322
+ table.footnote {
323
+ border-left: solid 1px black;
324
+ margin-left: 1px }
325
+
326
+ table.docutils td, table.docutils th,
327
+ table.docinfo td, table.docinfo th {
328
+ padding-left: 0.5em ;
329
+ padding-right: 0.5em ;
330
+ vertical-align: top }
331
+
332
+ table.docutils th.field-name, table.docinfo th.docinfo-name {
333
+ font-weight: bold ;
334
+ text-align: left ;
335
+ white-space: nowrap ;
336
+ padding-left: 0 }
337
+
338
+ /* "booktabs" style (no vertical lines) */
339
+ table.docutils.booktabs {
340
+ border: 0px;
341
+ border-top: 2px solid;
342
+ border-bottom: 2px solid;
343
+ border-collapse: collapse;
344
+ }
345
+ table.docutils.booktabs * {
346
+ border: 0px;
347
+ }
348
+ table.docutils.booktabs th {
349
+ border-bottom: thin solid;
350
+ text-align: left;
351
+ }
352
+
353
+ h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
354
+ h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
355
+ font-size: 100% }
356
+
357
+ ul.auto-toc {
358
+ list-style-type: none }
359
+
360
+ </style>
361
+ </head>
362
+ <body>
363
+ <div class="document" id="mrp-unbuild-restore-origin">
364
+ <h1 class="title">Mrp Unbuild Restore Origin</h1>
365
+
366
+ <!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
367
+ !! This file is generated by oca-gen-addon-readme !!
368
+ !! changes will be overwritten. !!
369
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
370
+ !! source digest: sha256:4d034a75598bfb9ecc4360b2d4f77bc06fd25ac2c3d6580eafcb1cee3e442139
371
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
372
+ <p><a class="reference external image-reference" 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 image-reference" 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 image-reference" href="https://github.com/OCA/manufacture/tree/16.0/mrp_unbuild_restore_origin"><img alt="OCA/manufacture" src="https://img.shields.io/badge/github-OCA%2Fmanufacture-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/manufacture-16-0/manufacture-16-0-mrp_unbuild_restore_origin"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/manufacture&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
373
+ <div class="line-block">
374
+ <div class="line">This module enhances the unbuild process of Manufacturing Orders by
375
+ retaining</div>
376
+ <div class="line">information from the original move lines.</div>
377
+ </div>
378
+ <ul>
379
+ <li><div class="first line-block">
380
+ <div class="line"><strong>Owner Retention:</strong> The owner from the original move lines is
381
+ always retained</div>
382
+ <div class="line">automatically when unbuilding a Manufacturing Order.</div>
383
+ </div>
384
+ </li>
385
+ <li><div class="first line-block">
386
+ <div class="line"><strong>Location Retention (Optional):</strong> A boolean field is available to
387
+ retain the original</div>
388
+ <div class="line">source and destination locations of the move lines during the
389
+ unbuild process, if needed.</div>
390
+ </div>
391
+ </li>
392
+ </ul>
393
+ <p><strong>Table of contents</strong></p>
394
+ <div class="contents local topic" id="contents">
395
+ <ul class="simple">
396
+ <li><a class="reference internal" href="#usage" id="toc-entry-1">Usage</a></li>
397
+ <li><a class="reference internal" href="#bug-tracker" id="toc-entry-2">Bug Tracker</a></li>
398
+ <li><a class="reference internal" href="#credits" id="toc-entry-3">Credits</a><ul>
399
+ <li><a class="reference internal" href="#authors" id="toc-entry-4">Authors</a></li>
400
+ <li><a class="reference internal" href="#contributors" id="toc-entry-5">Contributors</a></li>
401
+ <li><a class="reference internal" href="#maintainers" id="toc-entry-6">Maintainers</a></li>
402
+ </ul>
403
+ </li>
404
+ </ul>
405
+ </div>
406
+ <div class="section" id="usage">
407
+ <h1><a class="toc-backref" href="#toc-entry-1">Usage</a></h1>
408
+ <div class="line-block">
409
+ <div class="line">When unbuilding a completed Manufacturing Order, the owner from the
410
+ original move</div>
411
+ <div class="line">lines is always retained automatically.</div>
412
+ </div>
413
+ <div class="line-block">
414
+ <div class="line">If you want the components to be returned to the same locations they
415
+ were originally</div>
416
+ <div class="line">consumed from, enable the checkbox labeled <strong>“Restore Components to
417
+ Original Location”</strong></div>
418
+ <div class="line">when creating the Unbuild Order. If this option is not enabled, Odoo
419
+ will follow its standard behavior.</div>
420
+ </div>
421
+ </div>
422
+ <div class="section" id="bug-tracker">
423
+ <h1><a class="toc-backref" href="#toc-entry-2">Bug Tracker</a></h1>
424
+ <p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/manufacture/issues">GitHub Issues</a>.
425
+ In case of trouble, please check there if your issue has already been reported.
426
+ If you spotted it first, help us to smash it by providing a detailed and welcomed
427
+ <a class="reference external" href="https://github.com/OCA/manufacture/issues/new?body=module:%20mrp_unbuild_restore_origin%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
428
+ <p>Do not contact contributors directly about support or help with technical issues.</p>
429
+ </div>
430
+ <div class="section" id="credits">
431
+ <h1><a class="toc-backref" href="#toc-entry-3">Credits</a></h1>
432
+ <div class="section" id="authors">
433
+ <h2><a class="toc-backref" href="#toc-entry-4">Authors</a></h2>
434
+ <ul class="simple">
435
+ <li>Quartile</li>
436
+ </ul>
437
+ </div>
438
+ <div class="section" id="contributors">
439
+ <h2><a class="toc-backref" href="#toc-entry-5">Contributors</a></h2>
440
+ <ul class="simple">
441
+ <li><a class="reference external" href="https://www.quartile.co">Quartile</a>:<ul>
442
+ <li>Aung Ko Ko Lin</li>
443
+ <li>Yoshi Tashiro</li>
444
+ </ul>
445
+ </li>
446
+ </ul>
447
+ </div>
448
+ <div class="section" id="maintainers">
449
+ <h2><a class="toc-backref" href="#toc-entry-6">Maintainers</a></h2>
450
+ <p>This module is maintained by the OCA.</p>
451
+ <a class="reference external image-reference" href="https://odoo-community.org">
452
+ <img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
453
+ </a>
454
+ <p>OCA, or the Odoo Community Association, is a nonprofit organization whose
455
+ mission is to support the collaborative development of Odoo features and
456
+ promote its widespread use.</p>
457
+ <p>This module is part of the <a class="reference external" href="https://github.com/OCA/manufacture/tree/16.0/mrp_unbuild_restore_origin">OCA/manufacture</a> project on GitHub.</p>
458
+ <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>
459
+ </div>
460
+ </div>
461
+ </div>
462
+ </body>
463
+ </html>
@@ -0,0 +1 @@
1
+ from . import test_mrp_unbuild_origin_location
@@ -0,0 +1,163 @@
1
+ # Copyright 2025 Quartile (https://www.quartile.co)
2
+ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
3
+
4
+ from odoo import Command
5
+ from odoo.tests import Form, common
6
+
7
+
8
+ class TestMRPUnbuildOriginLocation(common.TransactionCase):
9
+ @classmethod
10
+ def setUpClass(cls):
11
+ super().setUpClass()
12
+ cls.stock_location = cls.env.ref("stock.stock_location_stock")
13
+ cls.custom_location = cls.env["stock.location"].create(
14
+ {
15
+ "name": "Custom Sub Location",
16
+ "location_id": cls.stock_location.id,
17
+ "usage": "internal",
18
+ }
19
+ )
20
+ Product = cls.env["product.product"]
21
+ BOM = cls.env["mrp.bom"]
22
+
23
+ cls.component_product = Product.create(
24
+ {
25
+ "name": "Component Product",
26
+ "type": "product",
27
+ }
28
+ )
29
+ cls.tracking_product = Product.create(
30
+ {
31
+ "name": "Tracking Component",
32
+ "type": "product",
33
+ "tracking": "lot",
34
+ }
35
+ )
36
+ cls.finished_product = Product.create(
37
+ {
38
+ "name": "Finished Product",
39
+ "type": "product",
40
+ }
41
+ )
42
+ cls.bom = BOM.create(
43
+ {
44
+ "product_tmpl_id": cls.finished_product.product_tmpl_id.id,
45
+ "product_qty": 1.0,
46
+ "type": "normal",
47
+ "bom_line_ids": [
48
+ Command.create(
49
+ {
50
+ "product_id": cls.component_product.id,
51
+ "product_qty": 1.0,
52
+ }
53
+ ),
54
+ Command.create(
55
+ {
56
+ "product_id": cls.tracking_product.id,
57
+ "product_qty": 1.0,
58
+ }
59
+ ),
60
+ ],
61
+ }
62
+ )
63
+ cls.owner = cls.env["res.partner"].create({"name": "Test Owner"})
64
+ quant1 = cls.env["stock.quant"].create(
65
+ {
66
+ "location_id": cls.custom_location.id,
67
+ "product_id": cls.component_product.id,
68
+ "owner_id": cls.owner.id,
69
+ "inventory_quantity": 10,
70
+ }
71
+ )
72
+ quant1.action_apply_inventory()
73
+ cls.lot = cls.env["stock.lot"].create(
74
+ {
75
+ "product_id": cls.tracking_product.id,
76
+ "name": "LOT-001",
77
+ }
78
+ )
79
+ quant2 = cls.env["stock.quant"].create(
80
+ {
81
+ "location_id": cls.custom_location.id,
82
+ "product_id": cls.tracking_product.id,
83
+ "lot_id": cls.lot.id,
84
+ "inventory_quantity": 10,
85
+ }
86
+ )
87
+ quant2.action_apply_inventory()
88
+
89
+ def _create_mo(self):
90
+ mo = self.env["mrp.production"].create(
91
+ {
92
+ "product_id": self.finished_product.id,
93
+ "product_qty": 1.0,
94
+ "bom_id": self.bom.id,
95
+ }
96
+ )
97
+ mo.action_confirm()
98
+ mark_done_action = mo.button_mark_done()
99
+ tracking_move = mo.move_raw_ids.filtered(
100
+ lambda m: m.product_id == self.tracking_product
101
+ )
102
+ tracking_move.quantity_done = 1.0
103
+ tracking_move.move_line_ids.write(
104
+ {
105
+ "lot_id": self.lot.id,
106
+ "qty_done": 1.0,
107
+ }
108
+ )
109
+ immediate_production_wizard = Form(
110
+ self.env["mrp.immediate.production"].with_context(
111
+ **mark_done_action["context"]
112
+ )
113
+ ).save()
114
+ immediate_production_wizard.process()
115
+ return mo
116
+
117
+ def _create_unbuild(self, mo, restore_rm_stock=False):
118
+ unbuild = self.env["mrp.unbuild"].create(
119
+ {
120
+ "mo_id": mo.id,
121
+ "product_id": self.finished_product.id,
122
+ "product_qty": 1.0,
123
+ "restore_rm_stock_in_origin_loc": restore_rm_stock,
124
+ }
125
+ )
126
+ unbuild.action_unbuild()
127
+ return unbuild
128
+
129
+ def test_unbuild_with_restore_rm_stock_true(self):
130
+ mo = self._create_mo()
131
+ unbuild = self._create_unbuild(mo, restore_rm_stock=True)
132
+ move_lines = self.env["stock.move.line"].search(
133
+ [("reference", "=", unbuild.name)]
134
+ )
135
+ for line in move_lines.filtered(
136
+ lambda l: l.product_id in [self.component_product, self.tracking_product]
137
+ ):
138
+ self.assertEqual(line.location_dest_id, self.custom_location)
139
+
140
+ def test_unbuild_with_restore_rm_stock_false(self):
141
+ mo = self._create_mo()
142
+ unbuild = self._create_unbuild(mo, restore_rm_stock=False)
143
+ move_lines = self.env["stock.move.line"].search(
144
+ [("reference", "=", unbuild.name)]
145
+ )
146
+ for line in move_lines.filtered(
147
+ lambda l: l.product_id in [self.component_product, self.tracking_product]
148
+ ):
149
+ self.assertNotEqual(line.location_dest_id, self.custom_location)
150
+
151
+ def test_unbuild_preserves_owner_id(self):
152
+ mo = self._create_mo()
153
+ unbuild = self._create_unbuild(mo, restore_rm_stock=True)
154
+ move_lines = self.env["stock.move.line"].search(
155
+ [("reference", "=", unbuild.name)]
156
+ )
157
+ owner_move_line = move_lines.filtered(
158
+ lambda l: l.product_id == self.component_product
159
+ )
160
+ self.assertTrue(
161
+ owner_move_line, "No move lines found for the component product"
162
+ )
163
+ self.assertEqual(owner_move_line.owner_id, self.owner)
@@ -0,0 +1,29 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <odoo>
3
+ <record id="mrp_unbuild_form_view" model="ir.ui.view">
4
+ <field name="name">mrp.unbuild.form</field>
5
+ <field name="model">mrp.unbuild</field>
6
+ <field name="inherit_id" ref="mrp.mrp_unbuild_form_view" />
7
+ <field name="arch" type="xml">
8
+ <xpath expr="//field[@name='mo_id']" position="after">
9
+ <field
10
+ name="restore_rm_stock_in_origin_loc"
11
+ attrs="{'invisible': [('mo_id', '=', False)]}"
12
+ />
13
+ </xpath>
14
+ </field>
15
+ </record>
16
+ <record id="mrp_unbuild_form_view_simplified" model="ir.ui.view">
17
+ <field name="name">mrp.unbuild.simplified.form</field>
18
+ <field name="model">mrp.unbuild</field>
19
+ <field name="inherit_id" ref="mrp.mrp_unbuild_form_view_simplified" />
20
+ <field name="arch" type="xml">
21
+ <xpath expr="//field[@name='mo_id']" position="after">
22
+ <field
23
+ name="restore_rm_stock_in_origin_loc"
24
+ attrs="{'invisible': [('mo_id', '=', False)]}"
25
+ />
26
+ </xpath>
27
+ </field>
28
+ </record>
29
+ </odoo>
@@ -0,0 +1,119 @@
1
+ Metadata-Version: 2.1
2
+ Name: odoo-addon-mrp_unbuild_restore_origin
3
+ Version: 16.0.1.0.0.2
4
+ Summary: Mrp Unbuild Restore Origin
5
+ Home-page: https://github.com/OCA/manufacture
6
+ Author: Quartile, Odoo Community Association (OCA)
7
+ Author-email: support@odoo-community.org
8
+ License: AGPL-3
9
+ Classifier: Programming Language :: Python
10
+ Classifier: Framework :: Odoo
11
+ Classifier: Framework :: Odoo :: 16.0
12
+ Classifier: License :: OSI Approved :: GNU Affero General Public License v3
13
+ Requires-Python: >=3.10
14
+ Requires-Dist: odoo<16.1dev,>=16.0a
15
+
16
+ ==========================
17
+ Mrp Unbuild Restore Origin
18
+ ==========================
19
+
20
+ ..
21
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
22
+ !! This file is generated by oca-gen-addon-readme !!
23
+ !! changes will be overwritten. !!
24
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
25
+ !! source digest: sha256:4d034a75598bfb9ecc4360b2d4f77bc06fd25ac2c3d6580eafcb1cee3e442139
26
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
27
+
28
+ .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
29
+ :target: https://odoo-community.org/page/development-status
30
+ :alt: Beta
31
+ .. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
32
+ :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
33
+ :alt: License: AGPL-3
34
+ .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fmanufacture-lightgray.png?logo=github
35
+ :target: https://github.com/OCA/manufacture/tree/16.0/mrp_unbuild_restore_origin
36
+ :alt: OCA/manufacture
37
+ .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
38
+ :target: https://translation.odoo-community.org/projects/manufacture-16-0/manufacture-16-0-mrp_unbuild_restore_origin
39
+ :alt: Translate me on Weblate
40
+ .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
41
+ :target: https://runboat.odoo-community.org/builds?repo=OCA/manufacture&target_branch=16.0
42
+ :alt: Try me on Runboat
43
+
44
+ |badge1| |badge2| |badge3| |badge4| |badge5|
45
+
46
+ | This module enhances the unbuild process of Manufacturing Orders by
47
+ retaining
48
+ | information from the original move lines.
49
+
50
+ - | **Owner Retention:** The owner from the original move lines is
51
+ always retained
52
+ | automatically when unbuilding a Manufacturing Order.
53
+
54
+ - | **Location Retention (Optional):** A boolean field is available to
55
+ retain the original
56
+ | source and destination locations of the move lines during the
57
+ unbuild process, if needed.
58
+
59
+ **Table of contents**
60
+
61
+ .. contents::
62
+ :local:
63
+
64
+ Usage
65
+ =====
66
+
67
+ | When unbuilding a completed Manufacturing Order, the owner from the
68
+ original move
69
+ | lines is always retained automatically.
70
+
71
+ | If you want the components to be returned to the same locations they
72
+ were originally
73
+ | consumed from, enable the checkbox labeled **"Restore Components to
74
+ Original Location"**
75
+ | when creating the Unbuild Order. If this option is not enabled, Odoo
76
+ will follow its standard behavior.
77
+
78
+ Bug Tracker
79
+ ===========
80
+
81
+ Bugs are tracked on `GitHub Issues <https://github.com/OCA/manufacture/issues>`_.
82
+ In case of trouble, please check there if your issue has already been reported.
83
+ If you spotted it first, help us to smash it by providing a detailed and welcomed
84
+ `feedback <https://github.com/OCA/manufacture/issues/new?body=module:%20mrp_unbuild_restore_origin%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
85
+
86
+ Do not contact contributors directly about support or help with technical issues.
87
+
88
+ Credits
89
+ =======
90
+
91
+ Authors
92
+ -------
93
+
94
+ * Quartile
95
+
96
+ Contributors
97
+ ------------
98
+
99
+ - `Quartile <https://www.quartile.co>`__:
100
+
101
+ - Aung Ko Ko Lin
102
+ - Yoshi Tashiro
103
+
104
+ Maintainers
105
+ -----------
106
+
107
+ This module is maintained by the OCA.
108
+
109
+ .. image:: https://odoo-community.org/logo.png
110
+ :alt: Odoo Community Association
111
+ :target: https://odoo-community.org
112
+
113
+ OCA, or the Odoo Community Association, is a nonprofit organization whose
114
+ mission is to support the collaborative development of Odoo features and
115
+ promote its widespread use.
116
+
117
+ This module is part of the `OCA/manufacture <https://github.com/OCA/manufacture/tree/16.0/mrp_unbuild_restore_origin>`_ project on GitHub.
118
+
119
+ You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
@@ -0,0 +1,19 @@
1
+ odoo/addons/mrp_unbuild_restore_origin/README.rst,sha256=uS-Mg5kTUPJvTMnSWNGFcJWGDH8B17QulqFagoFNboI,3755
2
+ odoo/addons/mrp_unbuild_restore_origin/__init__.py,sha256=X9EJGOE2GtZbS0G82PtSXmWSZ_R8jEM0rlJTDliQjp4,21
3
+ odoo/addons/mrp_unbuild_restore_origin/__manifest__.py,sha256=l1jA6jGTgXeCByt4T71dw_18N_Y70WYECTGbRmvH37s,449
4
+ odoo/addons/mrp_unbuild_restore_origin/i18n/mrp_unbuild_restore_origin.pot,sha256=C7IqjXUBtsWo-7bvxjyAKEDCN7NO92IVCwkeEjkWd6I,1172
5
+ odoo/addons/mrp_unbuild_restore_origin/models/__init__.py,sha256=fpPNvarbWQmBWMJIMbKQeHYQPLHvyJxPtHyzpyM9nSA,51
6
+ odoo/addons/mrp_unbuild_restore_origin/models/mrp_unbuild.py,sha256=qsz0ojrKo2HrkT7E48iysTTKrvYjrn9Fvm8of5UvluQ,3623
7
+ odoo/addons/mrp_unbuild_restore_origin/models/stock_move.py,sha256=4aGJ-dKeiwkP8lqQi10jeKsxc-DLu1XbdBSy32IWl0E,704
8
+ odoo/addons/mrp_unbuild_restore_origin/readme/CONTRIBUTORS.md,sha256=mbhQ3IpuMBBgONEp9tbizV_71JQO2PEJ74zNZkfBZu8,76
9
+ odoo/addons/mrp_unbuild_restore_origin/readme/DESCRIPTION.md,sha256=MVBXaUfORmYg1hN-JaKz0sFz-4M84bX3KmGtUI1dUiI,445
10
+ odoo/addons/mrp_unbuild_restore_origin/readme/USAGE.md,sha256=8cgSDc20E5WbxcSUyf5pi_5sEODJ9NNVPO1eueiJbdw,407
11
+ odoo/addons/mrp_unbuild_restore_origin/static/description/icon.png,sha256=CgnOEZCwoe6f1vlLwkqFVfc2q_uwBMU0UnXN8j6X5ag,10254
12
+ odoo/addons/mrp_unbuild_restore_origin/static/description/index.html,sha256=ZtsPdZ4-YfYstvalhzOAln9epNBRE79da9wrg3FHk8M,13653
13
+ odoo/addons/mrp_unbuild_restore_origin/tests/__init__.py,sha256=pYSgJmglVqUJmkRoSHQz13NpeZ8n5dyOu-R89b-h_eQ,47
14
+ odoo/addons/mrp_unbuild_restore_origin/tests/test_mrp_unbuild_origin_location.py,sha256=t9faGH1n0_SMayAIGQ0kvGXgcEXkfP4d_ebncQ8RgM8,5633
15
+ odoo/addons/mrp_unbuild_restore_origin/views/mrp_unbuild_views.xml,sha256=GnyKfwHBQ6hr8ovrR-9vs7ZJjIqeQGidLoZENm7YRI8,1192
16
+ odoo_addon_mrp_unbuild_restore_origin-16.0.1.0.0.2.dist-info/METADATA,sha256=SL-czBqcP1T9sJ873JQcsZaG81PFRp2MuxUXoRqRRVc,4281
17
+ odoo_addon_mrp_unbuild_restore_origin-16.0.1.0.0.2.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
18
+ odoo_addon_mrp_unbuild_restore_origin-16.0.1.0.0.2.dist-info/top_level.txt,sha256=qBj40grFkGOfDZ2WDSw3y1RnDlgG0u8rP8pvGNdbz4w,5
19
+ odoo_addon_mrp_unbuild_restore_origin-16.0.1.0.0.2.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: bdist_wheel (0.45.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+