odoo-addon-stock-move-location 16.0.1.4.1__py3-none-any.whl → 18.0.1.0.0.3__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.
- odoo/addons/stock_move_location/README.rst +8 -7
- odoo/addons/stock_move_location/__manifest__.py +1 -1
- odoo/addons/stock_move_location/i18n/stock_move_location.pot +37 -10
- odoo/addons/stock_move_location/init_hook.py +1 -5
- odoo/addons/stock_move_location/models/stock_picking.py +9 -7
- odoo/addons/stock_move_location/readme/CONTRIBUTORS.md +2 -0
- odoo/addons/stock_move_location/readme/USAGE.md +0 -1
- odoo/addons/stock_move_location/static/description/index.html +6 -5
- odoo/addons/stock_move_location/tests/test_common.py +16 -13
- odoo/addons/stock_move_location/tests/test_move_location.py +19 -24
- odoo/addons/stock_move_location/tests/test_stock_fillwithstock.py +23 -28
- odoo/addons/stock_move_location/views/stock_picking.xml +1 -3
- odoo/addons/stock_move_location/views/stock_picking_type_views.xml +4 -7
- odoo/addons/stock_move_location/wizard/stock_move_location.py +46 -65
- odoo/addons/stock_move_location/wizard/stock_move_location.xml +60 -32
- odoo/addons/stock_move_location/wizard/stock_move_location_line.py +18 -30
- {odoo_addon_stock_move_location-16.0.1.4.1.dist-info → odoo_addon_stock_move_location-18.0.1.0.0.3.dist-info}/METADATA +13 -12
- {odoo_addon_stock_move_location-16.0.1.4.1.dist-info → odoo_addon_stock_move_location-18.0.1.0.0.3.dist-info}/RECORD +20 -20
- {odoo_addon_stock_move_location-16.0.1.4.1.dist-info → odoo_addon_stock_move_location-18.0.1.0.0.3.dist-info}/WHEEL +1 -1
- odoo_addon_stock_move_location-18.0.1.0.0.3.dist-info/top_level.txt +1 -0
- odoo_addon_stock_move_location-16.0.1.4.1.dist-info/top_level.txt +0 -1
@@ -5,11 +5,8 @@
|
|
5
5
|
<field name="model">stock.picking.type</field>
|
6
6
|
<field name="inherit_id" ref="stock.view_picking_type_form" />
|
7
7
|
<field name="arch" type="xml">
|
8
|
-
<field name="
|
9
|
-
<field
|
10
|
-
name="show_move_onhand"
|
11
|
-
attrs='{"invisible": [("code", "not in", ["internal", "outgoing"])]}'
|
12
|
-
/>
|
8
|
+
<field name="create_backorder" position="after">
|
9
|
+
<field name="show_move_onhand" invisible="code != 'internal'" />
|
13
10
|
</field>
|
14
11
|
</field>
|
15
12
|
</record>
|
@@ -20,7 +17,7 @@
|
|
20
17
|
<field name="code" position="after">
|
21
18
|
<field name="show_move_onhand" />
|
22
19
|
</field>
|
23
|
-
<
|
20
|
+
<button name="get_action_picking_tree_ready" position="after">
|
24
21
|
<div t-if="record.show_move_onhand.raw_value">
|
25
22
|
<button
|
26
23
|
name="action_move_location"
|
@@ -31,7 +28,7 @@
|
|
31
28
|
Move On Hand
|
32
29
|
</button>
|
33
30
|
</div>
|
34
|
-
</
|
31
|
+
</button>
|
35
32
|
</field>
|
36
33
|
</record>
|
37
34
|
</odoo>
|
@@ -3,9 +3,8 @@
|
|
3
3
|
# Copyright 2019 Sergio Teruel - Tecnativa <sergio.teruel@tecnativa.com>
|
4
4
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
|
5
5
|
|
6
|
-
from itertools import groupby
|
7
6
|
|
8
|
-
from odoo import api, fields, models
|
7
|
+
from odoo import Command, api, fields, models
|
9
8
|
from odoo.fields import first
|
10
9
|
from odoo.osv import expression
|
11
10
|
|
@@ -39,17 +38,20 @@ class StockMoveLocationWizard(models.TransientModel):
|
|
39
38
|
"move_location_wizard_id",
|
40
39
|
string="Move Location lines",
|
41
40
|
)
|
41
|
+
company_id = fields.Many2one("res.company", default=lambda self: self.env.company)
|
42
42
|
picking_type_id = fields.Many2one(
|
43
43
|
compute="_compute_picking_type_id",
|
44
44
|
comodel_name="stock.picking.type",
|
45
45
|
readonly=False,
|
46
46
|
store=True,
|
47
|
+
domain="[('company_id', '=', company_id), ('code', '=', 'internal')]",
|
47
48
|
)
|
48
49
|
picking_id = fields.Many2one(
|
49
50
|
string="Connected Picking", comodel_name="stock.picking"
|
50
51
|
)
|
51
52
|
edit_locations = fields.Boolean(default=True)
|
52
53
|
apply_putaway_strategy = fields.Boolean()
|
54
|
+
exclude_reserved_qty = fields.Boolean(default=True)
|
53
55
|
|
54
56
|
@api.depends("edit_locations")
|
55
57
|
def _compute_readonly_locations(self):
|
@@ -67,15 +69,20 @@ class StockMoveLocationWizard(models.TransientModel):
|
|
67
69
|
@api.depends_context("company")
|
68
70
|
@api.depends("origin_location_id")
|
69
71
|
def _compute_picking_type_id(self):
|
70
|
-
company_id = self.env.context.get("company_id") or self.env.company.id
|
71
72
|
for rec in self:
|
72
73
|
picking_type = self.env["stock.picking.type"]
|
73
74
|
base_domain = [
|
74
|
-
("code", "
|
75
|
-
("warehouse_id.company_id", "=", company_id),
|
75
|
+
("code", "=", "internal"),
|
76
|
+
("warehouse_id.company_id", "=", self.company_id.id),
|
76
77
|
]
|
77
78
|
if rec.origin_location_id:
|
78
79
|
location_id = rec.origin_location_id
|
80
|
+
if (
|
81
|
+
location_id
|
82
|
+
and rec.picking_type_id
|
83
|
+
and rec.picking_type_id.default_location_src_id == location_id
|
84
|
+
):
|
85
|
+
continue
|
79
86
|
while location_id and not picking_type:
|
80
87
|
domain = [("default_location_src_id", "=", location_id.id)]
|
81
88
|
domain = expression.AND([base_domain, domain])
|
@@ -102,8 +109,7 @@ class StockMoveLocationWizard(models.TransientModel):
|
|
102
109
|
@api.model
|
103
110
|
def _prepare_wizard_move_lines(self, quants):
|
104
111
|
res = []
|
105
|
-
|
106
|
-
if not exclude_reserved_qty:
|
112
|
+
if not self.exclude_reserved_qty:
|
107
113
|
res = [
|
108
114
|
(
|
109
115
|
0,
|
@@ -113,6 +119,7 @@ class StockMoveLocationWizard(models.TransientModel):
|
|
113
119
|
"move_quantity": quant.quantity,
|
114
120
|
"max_quantity": quant.quantity,
|
115
121
|
"reserved_quantity": quant.reserved_quantity,
|
122
|
+
"total_quantity": quant.quantity,
|
116
123
|
"origin_location_id": quant.location_id.id,
|
117
124
|
"lot_id": quant.lot_id.id,
|
118
125
|
"package_id": quant.package_id.id,
|
@@ -125,12 +132,13 @@ class StockMoveLocationWizard(models.TransientModel):
|
|
125
132
|
]
|
126
133
|
else:
|
127
134
|
# if need move only available qty per product on location
|
128
|
-
for
|
129
|
-
# we need only one quant per product
|
130
|
-
quant = list(quant)[0]
|
135
|
+
for quant in quants:
|
131
136
|
qty = quant._get_available_quantity(
|
132
137
|
quant.product_id,
|
133
138
|
quant.location_id,
|
139
|
+
quant.lot_id,
|
140
|
+
quant.package_id,
|
141
|
+
quant.owner_id,
|
134
142
|
)
|
135
143
|
if qty:
|
136
144
|
res.append(
|
@@ -142,6 +150,7 @@ class StockMoveLocationWizard(models.TransientModel):
|
|
142
150
|
"move_quantity": qty,
|
143
151
|
"max_quantity": qty,
|
144
152
|
"reserved_quantity": quant.reserved_quantity,
|
153
|
+
"total_quantity": quant.quantity,
|
145
154
|
"origin_location_id": quant.location_id.id,
|
146
155
|
"lot_id": quant.lot_id.id,
|
147
156
|
"package_id": quant.package_id.id,
|
@@ -153,16 +162,6 @@ class StockMoveLocationWizard(models.TransientModel):
|
|
153
162
|
)
|
154
163
|
return res
|
155
164
|
|
156
|
-
@api.onchange("origin_location_id")
|
157
|
-
def _onchange_origin_location_id(self):
|
158
|
-
if not self.env.context.get("origin_location_disable", False):
|
159
|
-
self._clear_lines()
|
160
|
-
|
161
|
-
@api.onchange("destination_location_id")
|
162
|
-
def _onchange_destination_location_id(self):
|
163
|
-
for line in self.stock_move_location_line_ids:
|
164
|
-
line.destination_location_id = self.destination_location_id
|
165
|
-
|
166
165
|
def _clear_lines(self):
|
167
166
|
self.stock_move_location_line_ids = False
|
168
167
|
|
@@ -196,8 +195,7 @@ class StockMoveLocationWizard(models.TransientModel):
|
|
196
195
|
groups = self.group_lines()
|
197
196
|
moves = self.env["stock.move"]
|
198
197
|
for lines in groups.values():
|
199
|
-
|
200
|
-
moves |= move
|
198
|
+
moves |= self._create_move(picking, lines)
|
201
199
|
return moves
|
202
200
|
|
203
201
|
def _get_move_values(self, picking, lines):
|
@@ -224,17 +222,8 @@ class StockMoveLocationWizard(models.TransientModel):
|
|
224
222
|
lines.create_move_lines(picking, move)
|
225
223
|
if self.env.context.get("planned"):
|
226
224
|
for line in lines:
|
227
|
-
available_quantity = self.env["stock.quant"]._get_available_quantity(
|
228
|
-
line.product_id,
|
229
|
-
line.origin_location_id,
|
230
|
-
lot_id=line.lot_id,
|
231
|
-
package_id=line.package_id,
|
232
|
-
owner_id=line.owner_id,
|
233
|
-
strict=True,
|
234
|
-
)
|
235
225
|
move._update_reserved_quantity(
|
236
226
|
line.move_quantity,
|
237
|
-
available_quantity,
|
238
227
|
line.origin_location_id,
|
239
228
|
lot_id=line.lot_id,
|
240
229
|
package_id=line.package_id,
|
@@ -244,10 +233,11 @@ class StockMoveLocationWizard(models.TransientModel):
|
|
244
233
|
# Force the state to be assigned, instead of _action_assign,
|
245
234
|
# to avoid discarding the selected move_location_line.
|
246
235
|
move.state = "assigned"
|
236
|
+
move.move_line_ids.filtered(lambda ml: not ml.quantity).unlink()
|
247
237
|
move.move_line_ids.write({"state": "assigned"})
|
248
238
|
return move
|
249
239
|
|
250
|
-
def _unreserve_moves(self):
|
240
|
+
def _unreserve_moves(self, picking):
|
251
241
|
"""
|
252
242
|
Try to unreserve moves that they has reserved quantity before user
|
253
243
|
moves products from a location to other one and change move origin
|
@@ -256,9 +246,9 @@ class StockMoveLocationWizard(models.TransientModel):
|
|
256
246
|
"""
|
257
247
|
moves_to_reassign = self.env["stock.move"]
|
258
248
|
lines_to_ckeck_reverve = self.stock_move_location_line_ids.filtered(
|
259
|
-
lambda
|
260
|
-
|
261
|
-
and not
|
249
|
+
lambda line: (
|
250
|
+
line.move_quantity > line.max_quantity
|
251
|
+
and not line.origin_location_id.should_bypass_reservation()
|
262
252
|
)
|
263
253
|
)
|
264
254
|
for line in lines_to_ckeck_reverve:
|
@@ -270,7 +260,8 @@ class StockMoveLocationWizard(models.TransientModel):
|
|
270
260
|
("lot_id", "=", line.lot_id.id),
|
271
261
|
("package_id", "=", line.package_id.id),
|
272
262
|
("owner_id", "=", line.owner_id.id),
|
273
|
-
("
|
263
|
+
("quantity", ">", 0.0),
|
264
|
+
("picking_id", "!=", picking.id),
|
274
265
|
]
|
275
266
|
)
|
276
267
|
moves_to_unreserve = move_lines.mapped("move_id")
|
@@ -281,17 +272,10 @@ class StockMoveLocationWizard(models.TransientModel):
|
|
281
272
|
|
282
273
|
def action_move_location(self):
|
283
274
|
self.ensure_one()
|
284
|
-
if
|
285
|
-
picking = self._create_picking()
|
286
|
-
else:
|
287
|
-
picking = self.picking_id
|
288
|
-
# Prevent putaway rules to be excuted when we don't need to
|
289
|
-
picking = picking.with_context(
|
290
|
-
avoid_putaway_rules=not self.apply_putaway_strategy
|
291
|
-
)
|
275
|
+
picking = self.picking_id if self.picking_id else self._create_picking()
|
292
276
|
self._create_moves(picking)
|
293
277
|
if not self.env.context.get("planned"):
|
294
|
-
moves_to_reassign = self._unreserve_moves()
|
278
|
+
moves_to_reassign = self._unreserve_moves(picking)
|
295
279
|
picking.button_validate()
|
296
280
|
moves_to_reassign._action_assign()
|
297
281
|
self.picking_id = picking
|
@@ -322,7 +306,7 @@ class StockMoveLocationWizard(models.TransientModel):
|
|
322
306
|
"quantity:sum",
|
323
307
|
"reserved_quantity:sum",
|
324
308
|
],
|
325
|
-
groupby=["product_id", "lot_id", "package_id", "owner_id"],
|
309
|
+
groupby=["id", "product_id", "lot_id", "package_id", "owner_id"],
|
326
310
|
orderby="id",
|
327
311
|
lazy=False,
|
328
312
|
)
|
@@ -339,12 +323,18 @@ class StockMoveLocationWizard(models.TransientModel):
|
|
339
323
|
and self.destination_location_id._get_putaway_strategy(product).id
|
340
324
|
or self.destination_location_id.id
|
341
325
|
)
|
326
|
+
res_qty = group.get("reserved_quantity", 0.0)
|
327
|
+
total_qty = group.get("quantity", 0.0)
|
328
|
+
max_qty = (
|
329
|
+
total_qty if not self.exclude_reserved_qty else total_qty - res_qty
|
330
|
+
)
|
342
331
|
product_data.append(
|
343
332
|
{
|
344
333
|
"product_id": product.id,
|
345
|
-
"move_quantity":
|
346
|
-
"max_quantity":
|
347
|
-
"reserved_quantity":
|
334
|
+
"move_quantity": max_qty,
|
335
|
+
"max_quantity": max_qty,
|
336
|
+
"reserved_quantity": res_qty,
|
337
|
+
"total_quantity": total_qty,
|
348
338
|
"origin_location_id": self.origin_location_id.id,
|
349
339
|
"destination_location_id": location_dest_id,
|
350
340
|
# cursor returns None instead of False
|
@@ -361,21 +351,7 @@ class StockMoveLocationWizard(models.TransientModel):
|
|
361
351
|
)
|
362
352
|
return product_data
|
363
353
|
|
364
|
-
|
365
|
-
lines = []
|
366
|
-
line_model = self.env["wiz.stock.move.location.line"]
|
367
|
-
for line_val in self._get_stock_move_location_lines_values():
|
368
|
-
if line_val.get("max_quantity") <= 0:
|
369
|
-
continue
|
370
|
-
line = line_model.create(line_val)
|
371
|
-
line.max_quantity = line.get_max_quantity()
|
372
|
-
line.reserved_quantity = line.reserved_quantity
|
373
|
-
lines.append(line)
|
374
|
-
self.update(
|
375
|
-
{"stock_move_location_line_ids": [(6, 0, [line.id for line in lines])]}
|
376
|
-
)
|
377
|
-
|
378
|
-
@api.onchange("origin_location_id")
|
354
|
+
@api.onchange("origin_location_id", "exclude_reserved_qty")
|
379
355
|
def onchange_origin_location(self):
|
380
356
|
# Get origin_location_disable context key to prevent load all origin
|
381
357
|
# location products when user opens the wizard from stock quants to
|
@@ -384,7 +360,12 @@ class StockMoveLocationWizard(models.TransientModel):
|
|
384
360
|
not self.env.context.get("origin_location_disable")
|
385
361
|
and self.origin_location_id
|
386
362
|
):
|
387
|
-
|
363
|
+
lines = [Command.clear()] + [
|
364
|
+
Command.create(line_vals)
|
365
|
+
for line_vals in self._get_stock_move_location_lines_values()
|
366
|
+
if line_vals.get("max_quantity", 0.0) > 0.0
|
367
|
+
]
|
368
|
+
self.update({"stock_move_location_line_ids": lines})
|
388
369
|
|
389
370
|
def clear_lines(self):
|
390
371
|
self._clear_lines()
|
@@ -10,15 +10,24 @@
|
|
10
10
|
<form>
|
11
11
|
<sheet>
|
12
12
|
<div class="oe_button_box" name="button_box" />
|
13
|
-
<
|
13
|
+
<div>
|
14
|
+
<label for="edit_locations">
|
15
|
+
Edit Locations
|
16
|
+
</label>
|
14
17
|
<field name="edit_locations" widget="boolean_toggle" />
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
/>
|
21
|
-
</
|
18
|
+
</div>
|
19
|
+
<div>
|
20
|
+
<label for="exclude_reserved_qty">
|
21
|
+
Exclude Reserved Quantities
|
22
|
+
</label>
|
23
|
+
<field name="exclude_reserved_qty" widget="boolean_toggle" />
|
24
|
+
</div>
|
25
|
+
<div groups="stock.group_stock_multi_locations">
|
26
|
+
<label for="apply_putaway_strategy">
|
27
|
+
Apply putaway strategy for moving products
|
28
|
+
</label>
|
29
|
+
<field name="apply_putaway_strategy" widget="boolean_toggle" />
|
30
|
+
</div>
|
22
31
|
<group name="picking_type">
|
23
32
|
<field name="picking_type_id" />
|
24
33
|
</group>
|
@@ -26,24 +35,23 @@
|
|
26
35
|
<field name="origin_location_disable" invisible="True" />
|
27
36
|
<field
|
28
37
|
name="origin_location_id"
|
29
|
-
|
38
|
+
readonly="origin_location_disable"
|
30
39
|
/>
|
31
40
|
<field name="destination_location_disable" invisible="True" />
|
32
41
|
<field
|
33
42
|
name="destination_location_id"
|
34
|
-
|
43
|
+
readonly="destination_location_disable"
|
35
44
|
/>
|
36
|
-
|
37
|
-
<group name="filters">
|
45
|
+
<field name="company_id" invisible="1" />
|
38
46
|
</group>
|
39
47
|
<group name="lines">
|
40
48
|
<field
|
41
49
|
name="stock_move_location_line_ids"
|
42
50
|
nolabel="1"
|
43
|
-
mode="
|
51
|
+
mode="list,kanban"
|
44
52
|
colspan="2"
|
45
53
|
>
|
46
|
-
<
|
54
|
+
<list
|
47
55
|
editable="bottom"
|
48
56
|
decoration-info="move_quantity != max_quantity"
|
49
57
|
decoration-danger="(move_quantity < 0) or (move_quantity > max_quantity)"
|
@@ -58,6 +66,11 @@
|
|
58
66
|
string="UoM"
|
59
67
|
groups="uom.group_uom"
|
60
68
|
/>
|
69
|
+
<field
|
70
|
+
name="product_uom_id"
|
71
|
+
string="UoM"
|
72
|
+
column_invisible="1"
|
73
|
+
/>
|
61
74
|
<field
|
62
75
|
name="origin_location_id"
|
63
76
|
readonly="1"
|
@@ -85,7 +98,7 @@
|
|
85
98
|
<field name="custom" invisible="1" />
|
86
99
|
<field
|
87
100
|
name="max_quantity"
|
88
|
-
|
101
|
+
readonly="not custom"
|
89
102
|
force_save="1"
|
90
103
|
/>
|
91
104
|
<field
|
@@ -93,27 +106,42 @@
|
|
93
106
|
readonly="1"
|
94
107
|
force_save="1"
|
95
108
|
/>
|
96
|
-
|
109
|
+
<field
|
110
|
+
name="total_quantity"
|
111
|
+
readonly="1"
|
112
|
+
force_save="1"
|
113
|
+
/>
|
114
|
+
</list>
|
97
115
|
<kanban class="o_kanban_mobile">
|
98
116
|
<templates>
|
99
|
-
<t t-name="
|
100
|
-
<
|
101
|
-
|
102
|
-
|
103
|
-
|
117
|
+
<t t-name="card">
|
118
|
+
<field name="product_id" class="fw-bolder" />
|
119
|
+
<div
|
120
|
+
groups="stock.group_production_lot"
|
121
|
+
invisible="not lot_id"
|
122
|
+
>
|
123
|
+
Lot/SN:
|
124
|
+
<field
|
125
|
+
name="lot_id"
|
126
|
+
invisible="not lot_id"
|
127
|
+
/>
|
128
|
+
</div>
|
129
|
+
<div groups="stock.group_stock_multi_locations">
|
130
|
+
<field name="origin_location_id" />
|
131
|
+
→
|
132
|
+
<field name="destination_location_id" />
|
133
|
+
</div>
|
134
|
+
<div class="row">
|
135
|
+
<div class="col-6">
|
104
136
|
<field
|
105
|
-
name="
|
106
|
-
|
137
|
+
name="move_quantity"
|
138
|
+
string="Quantity"
|
139
|
+
/>
|
140
|
+
<field
|
141
|
+
name="product_uom_id"
|
142
|
+
string="Unit of Measure"
|
143
|
+
groups="uom.group_uom"
|
107
144
|
/>
|
108
|
-
<field name="origin_location_id" />
|
109
|
-
<field name="destination_location_id" />
|
110
|
-
</div>
|
111
|
-
<div class="o_kanban_record_bottom">
|
112
|
-
<div class="oe_kanban_bottom_right">
|
113
|
-
<span>
|
114
|
-
<field name="move_quantity" />
|
115
|
-
</span>
|
116
|
-
</div>
|
117
145
|
</div>
|
118
146
|
</div>
|
119
147
|
</t>
|
@@ -22,7 +22,9 @@ class StockMoveLocationWizardLine(models.TransientModel):
|
|
22
22
|
string="Origin Location", comodel_name="stock.location"
|
23
23
|
)
|
24
24
|
destination_location_id = fields.Many2one(
|
25
|
-
string="Destination Location",
|
25
|
+
string="Destination Location",
|
26
|
+
comodel_name="stock.location",
|
27
|
+
compute="_compute_destination_location_id",
|
26
28
|
)
|
27
29
|
product_uom_id = fields.Many2one(
|
28
30
|
string="Product Unit of Measure", comodel_name="uom.uom"
|
@@ -44,9 +46,19 @@ class StockMoveLocationWizardLine(models.TransientModel):
|
|
44
46
|
max_quantity = fields.Float(
|
45
47
|
string="Maximum available quantity", digits="Product Unit of Measure"
|
46
48
|
)
|
49
|
+
total_quantity = fields.Float(
|
50
|
+
string="Total existence quantity", digits="Product Unit of Measure"
|
51
|
+
)
|
47
52
|
reserved_quantity = fields.Float(digits="Product Unit of Measure")
|
48
53
|
custom = fields.Boolean(string="Custom line", default=True)
|
49
54
|
|
55
|
+
@api.depends("move_location_wizard_id.destination_location_id")
|
56
|
+
def _compute_destination_location_id(self):
|
57
|
+
for record in self:
|
58
|
+
record.destination_location_id = (
|
59
|
+
record.move_location_wizard_id.destination_location_id
|
60
|
+
)
|
61
|
+
|
50
62
|
@staticmethod
|
51
63
|
def _compare(qty1, qty2, precision_rounding):
|
52
64
|
return float_compare(qty1, qty2, precision_rounding=precision_rounding)
|
@@ -64,32 +76,10 @@ class StockMoveLocationWizardLine(models.TransientModel):
|
|
64
76
|
_("Move quantity can not exceed max quantity or be negative")
|
65
77
|
)
|
66
78
|
|
67
|
-
def get_max_quantity(self):
|
68
|
-
self.product_uom_id = self.product_id.uom_id
|
69
|
-
search_args = [
|
70
|
-
("location_id", "=", self.origin_location_id.id),
|
71
|
-
("product_id", "=", self.product_id.id),
|
72
|
-
]
|
73
|
-
if self.lot_id:
|
74
|
-
search_args.append(("lot_id", "=", self.lot_id.id))
|
75
|
-
else:
|
76
|
-
search_args.append(("lot_id", "=", False))
|
77
|
-
if self.package_id:
|
78
|
-
search_args.append(("package_id", "=", self.package_id.id))
|
79
|
-
else:
|
80
|
-
search_args.append(("package_id", "=", False))
|
81
|
-
if self.owner_id:
|
82
|
-
search_args.append(("owner_id", "=", self.owner_id.id))
|
83
|
-
else:
|
84
|
-
search_args.append(("owner_id", "=", False))
|
85
|
-
res = self.env["stock.quant"].read_group(search_args, ["quantity"], [])
|
86
|
-
max_quantity = res[0]["quantity"]
|
87
|
-
return max_quantity
|
88
|
-
|
89
79
|
def create_move_lines(self, picking, move):
|
90
80
|
for line in self:
|
91
81
|
values = line._get_move_line_values(picking, move)
|
92
|
-
if not self.env.context.get("planned") and values.get("
|
82
|
+
if not self.env.context.get("planned") and values.get("quantity") <= 0:
|
93
83
|
continue
|
94
84
|
self.env["stock.move.line"].create(values)
|
95
85
|
return True
|
@@ -101,7 +91,7 @@ class StockMoveLocationWizardLine(models.TransientModel):
|
|
101
91
|
and self.destination_location_id._get_putaway_strategy(self.product_id).id
|
102
92
|
or self.destination_location_id.id
|
103
93
|
)
|
104
|
-
|
94
|
+
qty_done = self._get_available_quantity()
|
105
95
|
return {
|
106
96
|
"product_id": self.product_id.id,
|
107
97
|
"lot_id": self.lot_id.id,
|
@@ -110,7 +100,7 @@ class StockMoveLocationWizardLine(models.TransientModel):
|
|
110
100
|
"owner_id": self.owner_id.id,
|
111
101
|
"location_id": self.origin_location_id.id,
|
112
102
|
"location_dest_id": location_dest_id,
|
113
|
-
"
|
103
|
+
"quantity": qty_done,
|
114
104
|
"product_uom_id": self.product_uom_id.id,
|
115
105
|
"picking_id": picking.id,
|
116
106
|
"move_id": move.id,
|
@@ -126,7 +116,7 @@ class StockMoveLocationWizardLine(models.TransientModel):
|
|
126
116
|
return 0
|
127
117
|
if self.env.context.get("planned"):
|
128
118
|
# for planned transfer we don't care about the amounts at all
|
129
|
-
return
|
119
|
+
return 0.0
|
130
120
|
search_args = [
|
131
121
|
("location_id", "=", self.origin_location_id.id),
|
132
122
|
("product_id", "=", self.product_id.id),
|
@@ -153,6 +143,4 @@ class StockMoveLocationWizardLine(models.TransientModel):
|
|
153
143
|
available_qty_lt_move_qty = (
|
154
144
|
self._compare(available_qty, self.move_quantity, rounding) == -1
|
155
145
|
)
|
156
|
-
if available_qty_lt_move_qty
|
157
|
-
return available_qty
|
158
|
-
return 0, self.move_quantity
|
146
|
+
return available_qty if available_qty_lt_move_qty else self.move_quantity
|
@@ -1,17 +1,17 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: odoo-addon-stock_move_location
|
3
|
-
Version:
|
3
|
+
Version: 18.0.1.0.0.3
|
4
|
+
Requires-Python: >=3.10
|
5
|
+
Requires-Dist: odoo==18.0.*
|
4
6
|
Summary: This module allows to move all stock in a stock location to an other one.
|
5
7
|
Home-page: https://github.com/OCA/stock-logistics-warehouse
|
8
|
+
License: AGPL-3
|
6
9
|
Author: Julius Network Solutions, BCIM,Camptocamp,Odoo Community Association (OCA)
|
7
10
|
Author-email: support@odoo-community.org
|
8
|
-
License: AGPL-3
|
9
11
|
Classifier: Programming Language :: Python
|
10
12
|
Classifier: Framework :: Odoo
|
11
|
-
Classifier: Framework :: Odoo ::
|
13
|
+
Classifier: Framework :: Odoo :: 18.0
|
12
14
|
Classifier: License :: OSI Approved :: GNU Affero General Public License v3
|
13
|
-
Requires-Python: >=3.10
|
14
|
-
Requires-Dist: odoo<16.1dev,>=16.0a
|
15
15
|
|
16
16
|
===================
|
17
17
|
Move Stock Location
|
@@ -22,7 +22,7 @@ Move Stock Location
|
|
22
22
|
!! This file is generated by oca-gen-addon-readme !!
|
23
23
|
!! changes will be overwritten. !!
|
24
24
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
25
|
-
!! source digest: sha256:
|
25
|
+
!! source digest: sha256:d4e4ea6fb0a6f2f34b451c22d5ab139e4f867621b65786664f6b93d57558b66d
|
26
26
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
27
27
|
|
28
28
|
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
|
@@ -32,13 +32,13 @@ Move Stock Location
|
|
32
32
|
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
|
33
33
|
:alt: License: AGPL-3
|
34
34
|
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstock--logistics--warehouse-lightgray.png?logo=github
|
35
|
-
:target: https://github.com/OCA/stock-logistics-warehouse/tree/
|
35
|
+
:target: https://github.com/OCA/stock-logistics-warehouse/tree/18.0/stock_move_location
|
36
36
|
:alt: OCA/stock-logistics-warehouse
|
37
37
|
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
|
38
|
-
:target: https://translation.odoo-community.org/projects/stock-logistics-warehouse-
|
38
|
+
:target: https://translation.odoo-community.org/projects/stock-logistics-warehouse-18-0/stock-logistics-warehouse-18-0-stock_move_location
|
39
39
|
:alt: Translate me on Weblate
|
40
40
|
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
|
41
|
-
:target: https://runboat.odoo-community.org/builds?repo=OCA/stock-logistics-warehouse&target_branch=
|
41
|
+
:target: https://runboat.odoo-community.org/builds?repo=OCA/stock-logistics-warehouse&target_branch=18.0
|
42
42
|
:alt: Try me on Runboat
|
43
43
|
|
44
44
|
|badge1| |badge2| |badge3| |badge4| |badge5|
|
@@ -58,7 +58,6 @@ Usage
|
|
58
58
|
where 2 locations can be specified.
|
59
59
|
- Select origin and destination locations and press "IMMEDIATE TRANSFER"
|
60
60
|
or "PLANNED TRANSFER"
|
61
|
-
- Press ADD ALL button to add all products available
|
62
61
|
- Those lines can be edited. Move quantity can't be more than a max
|
63
62
|
available quantity
|
64
63
|
- Move doesn't care about the reservations and will move stuff anyway
|
@@ -121,7 +120,7 @@ Bug Tracker
|
|
121
120
|
Bugs are tracked on `GitHub Issues <https://github.com/OCA/stock-logistics-warehouse/issues>`_.
|
122
121
|
In case of trouble, please check there if your issue has already been reported.
|
123
122
|
If you spotted it first, help us to smash it by providing a detailed and welcomed
|
124
|
-
`feedback <https://github.com/OCA/stock-logistics-warehouse/issues/new?body=module:%20stock_move_location%0Aversion:%
|
123
|
+
`feedback <https://github.com/OCA/stock-logistics-warehouse/issues/new?body=module:%20stock_move_location%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
|
125
124
|
|
126
125
|
Do not contact contributors directly about support or help with technical issues.
|
127
126
|
|
@@ -148,6 +147,7 @@ Contributors
|
|
148
147
|
|
149
148
|
- Sergio Teruel
|
150
149
|
- João Marques
|
150
|
+
- Carlos Roca
|
151
151
|
|
152
152
|
- Jacques-Etienne Baudoux <je@bcim.be>
|
153
153
|
- Iryna Vyshnevska <i.vyshnevska@mobilunity.com>
|
@@ -158,6 +158,7 @@ Contributors
|
|
158
158
|
- Aung Ko Ko Lin
|
159
159
|
|
160
160
|
- Laurent Mignon <laurent.mignon@acsone.eu>
|
161
|
+
- Maksym Yankin <maksym.yankin@camptocamp.com>
|
161
162
|
|
162
163
|
Maintainers
|
163
164
|
-----------
|
@@ -172,6 +173,6 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose
|
|
172
173
|
mission is to support the collaborative development of Odoo features and
|
173
174
|
promote its widespread use.
|
174
175
|
|
175
|
-
This module is part of the `OCA/stock-logistics-warehouse <https://github.com/OCA/stock-logistics-warehouse/tree/
|
176
|
+
This module is part of the `OCA/stock-logistics-warehouse <https://github.com/OCA/stock-logistics-warehouse/tree/18.0/stock_move_location>`_ project on GitHub.
|
176
177
|
|
177
178
|
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
|