odoo-addon-shipment-advice 16.0.1.7.2.3__py3-none-any.whl → 18.0.1.0.0.4__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/shipment_advice/README.rst +29 -28
- odoo/addons/shipment_advice/__manifest__.py +4 -4
- odoo/addons/shipment_advice/data/queue_job_channel.xml +4 -4
- odoo/addons/shipment_advice/data/queue_job_function.xml +18 -15
- odoo/addons/shipment_advice/i18n/it.po +2 -2
- odoo/addons/shipment_advice/i18n/shipment_advice.pot +78 -109
- odoo/addons/shipment_advice/models/shipment_advice.py +32 -67
- odoo/addons/shipment_advice/models/stock_move_line.py +23 -21
- odoo/addons/shipment_advice/models/stock_package_level.py +12 -1
- odoo/addons/shipment_advice/models/stock_picking.py +7 -5
- odoo/addons/shipment_advice/readme/CONTRIBUTORS.md +12 -0
- odoo/addons/shipment_advice/report/report_shipment_advice.xml +1 -1
- odoo/addons/shipment_advice/static/description/index.html +17 -20
- odoo/addons/shipment_advice/tests/common.py +6 -7
- odoo/addons/shipment_advice/tests/test_shipment_advice.py +2 -2
- odoo/addons/shipment_advice/tests/test_shipment_advice_async.py +3 -3
- odoo/addons/shipment_advice/tests/test_shipment_advice_load.py +12 -4
- odoo/addons/shipment_advice/tests/test_shipment_advice_picking_values.py +2 -2
- odoo/addons/shipment_advice/tests/test_shipment_advice_stock_user.py +1 -1
- odoo/addons/shipment_advice/tests/test_shipment_advice_unload.py +6 -6
- odoo/addons/shipment_advice/views/res_config_settings.xml +28 -33
- odoo/addons/shipment_advice/views/shipment_advice.xml +42 -64
- odoo/addons/shipment_advice/views/stock_move.xml +4 -1
- odoo/addons/shipment_advice/views/stock_move_line.xml +9 -8
- odoo/addons/shipment_advice/views/stock_package_level.xml +5 -5
- odoo/addons/shipment_advice/views/stock_picking.xml +9 -16
- odoo/addons/shipment_advice/wizards/load_shipment.py +15 -15
- odoo/addons/shipment_advice/wizards/load_shipment.xml +9 -20
- odoo/addons/shipment_advice/wizards/plan_shipment.py +10 -10
- odoo/addons/shipment_advice/wizards/plan_shipment.xml +6 -16
- odoo/addons/shipment_advice/wizards/unload_shipment.py +6 -6
- odoo/addons/shipment_advice/wizards/unload_shipment.xml +4 -11
- odoo/addons/shipment_advice/wizards/unplan_shipment.py +6 -6
- odoo/addons/shipment_advice/wizards/unplan_shipment.xml +5 -16
- {odoo_addon_shipment_advice-16.0.1.7.2.3.dist-info → odoo_addon_shipment_advice-18.0.1.0.0.4.dist-info}/METADATA +37 -36
- odoo_addon_shipment_advice-18.0.1.0.0.4.dist-info/RECORD +56 -0
- {odoo_addon_shipment_advice-16.0.1.7.2.3.dist-info → odoo_addon_shipment_advice-18.0.1.0.0.4.dist-info}/WHEEL +1 -1
- odoo_addon_shipment_advice-18.0.1.0.0.4.dist-info/top_level.txt +1 -0
- odoo/addons/shipment_advice/readme/CONTRIBUTORS.rst +0 -13
- odoo/addons/shipment_advice/readme/CREDITS.rst +0 -6
- odoo_addon_shipment_advice-16.0.1.7.2.3.dist-info/RECORD +0 -57
- odoo_addon_shipment_advice-16.0.1.7.2.3.dist-info/top_level.txt +0 -1
- /odoo/addons/shipment_advice/readme/{DESCRIPTION.rst → DESCRIPTION.md} +0 -0
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
# Copyright 2025 Jacques-Etienne Baudoux (BCIM) <je@bcim.be>
|
|
4
4
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
|
|
5
5
|
|
|
6
|
-
from odoo import
|
|
6
|
+
from odoo import api, fields, models
|
|
7
7
|
from odoo.exceptions import UserError
|
|
8
8
|
|
|
9
9
|
from odoo.addons.queue_job.delay import chain, group
|
|
@@ -17,9 +17,8 @@ class ShipmentAdvice(models.Model):
|
|
|
17
17
|
_order = "arrival_date DESC, id DESC"
|
|
18
18
|
|
|
19
19
|
def _default_warehouse_id(self):
|
|
20
|
-
|
|
21
|
-
wh
|
|
22
|
-
return wh.id
|
|
20
|
+
wh = self.env.ref("stock.warehouse0", raise_if_not_found=False)
|
|
21
|
+
return wh.id or False
|
|
23
22
|
|
|
24
23
|
name = fields.Char(
|
|
25
24
|
default="/", copy=False, index=True, required=True, readonly=True
|
|
@@ -43,9 +42,7 @@ class ShipmentAdvice(models.Model):
|
|
|
43
42
|
ondelete="cascade",
|
|
44
43
|
string="Warehouse",
|
|
45
44
|
required=True,
|
|
46
|
-
|
|
47
|
-
readonly=True,
|
|
48
|
-
check_company=False,
|
|
45
|
+
check_company=True,
|
|
49
46
|
default=_default_warehouse_id,
|
|
50
47
|
)
|
|
51
48
|
company_id = fields.Many2one(
|
|
@@ -68,26 +65,16 @@ class ShipmentAdvice(models.Model):
|
|
|
68
65
|
comodel_name="stock.dock",
|
|
69
66
|
ondelete="restrict",
|
|
70
67
|
string="Loading dock",
|
|
71
|
-
states={"draft": [("readonly", False)], "confirmed": [("readonly", False)]},
|
|
72
|
-
readonly=True,
|
|
73
68
|
index=True,
|
|
74
69
|
domain="[('warehouse_id', '=', warehouse_id)]",
|
|
75
70
|
)
|
|
76
71
|
arrival_date = fields.Datetime(
|
|
77
|
-
states={"draft": [("readonly", False)], "confirmed": [("readonly", False)]},
|
|
78
|
-
readonly=True,
|
|
79
72
|
help=(
|
|
80
73
|
"When will the shipment arrive at the (un)loading dock. It is a "
|
|
81
74
|
"planned date until in progress, then it represents the real one."
|
|
82
75
|
),
|
|
83
76
|
)
|
|
84
77
|
departure_date = fields.Datetime(
|
|
85
|
-
states={
|
|
86
|
-
"draft": [("readonly", False)],
|
|
87
|
-
"confirmed": [("readonly", False)],
|
|
88
|
-
"in_progress": [("readonly", False)],
|
|
89
|
-
},
|
|
90
|
-
readonly=True,
|
|
91
78
|
help=(
|
|
92
79
|
"When will the shipment leave the (un)loading dock. It is a "
|
|
93
80
|
"planned date until in progress, then it represents the real one."
|
|
@@ -95,12 +82,6 @@ class ShipmentAdvice(models.Model):
|
|
|
95
82
|
)
|
|
96
83
|
ref = fields.Char(
|
|
97
84
|
string="Consignment/Truck Ref.",
|
|
98
|
-
states={
|
|
99
|
-
"draft": [("readonly", False)],
|
|
100
|
-
"confirmed": [("readonly", False)],
|
|
101
|
-
"in_progress": [("readonly", False)],
|
|
102
|
-
},
|
|
103
|
-
readonly=True,
|
|
104
85
|
)
|
|
105
86
|
total_load = fields.Float(
|
|
106
87
|
string="Total load (kg)",
|
|
@@ -111,12 +92,6 @@ class ShipmentAdvice(models.Model):
|
|
|
111
92
|
comodel_name="stock.move",
|
|
112
93
|
inverse_name="shipment_advice_id",
|
|
113
94
|
string="Planned content list",
|
|
114
|
-
states={
|
|
115
|
-
"draft": [("readonly", False)],
|
|
116
|
-
"confirmed": [("readonly", False)],
|
|
117
|
-
"in_progress": [("readonly", False)],
|
|
118
|
-
},
|
|
119
|
-
readonly=True,
|
|
120
95
|
check_company=True,
|
|
121
96
|
)
|
|
122
97
|
planned_moves_count = fields.Integer(compute="_compute_count")
|
|
@@ -130,25 +105,13 @@ class ShipmentAdvice(models.Model):
|
|
|
130
105
|
comodel_name="stock.move.line",
|
|
131
106
|
inverse_name="shipment_advice_id",
|
|
132
107
|
string="Loaded content list",
|
|
133
|
-
states={
|
|
134
|
-
"draft": [("readonly", False)],
|
|
135
|
-
"confirmed": [("readonly", False)],
|
|
136
|
-
"in_progress": [("readonly", False)],
|
|
137
|
-
},
|
|
138
|
-
readonly=True,
|
|
139
108
|
check_company=True,
|
|
140
109
|
)
|
|
141
110
|
loaded_move_line_without_package_ids = fields.One2many(
|
|
142
111
|
comodel_name="stock.move.line",
|
|
143
112
|
inverse_name="shipment_advice_id",
|
|
144
113
|
string="Loaded content list (w/o packages)",
|
|
145
|
-
states={
|
|
146
|
-
"draft": [("readonly", False)],
|
|
147
|
-
"confirmed": [("readonly", False)],
|
|
148
|
-
"in_progress": [("readonly", False)],
|
|
149
|
-
},
|
|
150
114
|
domain=[("package_level_id", "=", False)],
|
|
151
|
-
readonly=True,
|
|
152
115
|
check_company=True,
|
|
153
116
|
)
|
|
154
117
|
loaded_move_lines_without_package_count = fields.Integer(compute="_compute_count")
|
|
@@ -275,14 +238,15 @@ class ShipmentAdvice(models.Model):
|
|
|
275
238
|
for shipment in self:
|
|
276
239
|
if shipment.state != "draft":
|
|
277
240
|
raise UserError(
|
|
278
|
-
|
|
279
|
-
shipment.name
|
|
241
|
+
self.env._(
|
|
242
|
+
"Shipment %s is not draft, operation aborted.", shipment.name
|
|
280
243
|
)
|
|
281
244
|
)
|
|
282
245
|
if not shipment.arrival_date:
|
|
283
246
|
raise UserError(
|
|
284
|
-
|
|
285
|
-
shipment.
|
|
247
|
+
self.env._(
|
|
248
|
+
"Arrival date should be set on the shipment advice %s.",
|
|
249
|
+
shipment.name,
|
|
286
250
|
)
|
|
287
251
|
)
|
|
288
252
|
shipment.state = "confirmed"
|
|
@@ -292,14 +256,15 @@ class ShipmentAdvice(models.Model):
|
|
|
292
256
|
for shipment in self:
|
|
293
257
|
if shipment.state != "confirmed":
|
|
294
258
|
raise UserError(
|
|
295
|
-
|
|
296
|
-
|
|
259
|
+
self.env._(
|
|
260
|
+
"Shipment %s is not confirmed, operation aborted.",
|
|
261
|
+
shipment.name,
|
|
297
262
|
)
|
|
298
263
|
)
|
|
299
264
|
if not shipment.dock_id:
|
|
300
265
|
raise UserError(
|
|
301
|
-
|
|
302
|
-
shipment.name
|
|
266
|
+
self.env._(
|
|
267
|
+
"Dock should be set on the shipment advice %s.", shipment.name
|
|
303
268
|
)
|
|
304
269
|
)
|
|
305
270
|
if not shipment.arrival_date:
|
|
@@ -311,7 +276,7 @@ class ShipmentAdvice(models.Model):
|
|
|
311
276
|
"""Lock records for the current SQL transaction."""
|
|
312
277
|
if not records:
|
|
313
278
|
return
|
|
314
|
-
sql = "SELECT id FROM
|
|
279
|
+
sql = f"SELECT id FROM {records._table} WHERE ID IN %s FOR UPDATE"
|
|
315
280
|
self.env.cr.execute(sql, (tuple(records.ids),), log_exceptions=False)
|
|
316
281
|
|
|
317
282
|
def action_done(self):
|
|
@@ -345,7 +310,7 @@ class ShipmentAdvice(models.Model):
|
|
|
345
310
|
*[
|
|
346
311
|
self.delayable(
|
|
347
312
|
identity_key=identity_exact,
|
|
348
|
-
description=_(
|
|
313
|
+
description=self.env._(
|
|
349
314
|
"%(sa)s: %(pick)s background validation",
|
|
350
315
|
sa=self.name,
|
|
351
316
|
pick=picking.name,
|
|
@@ -367,8 +332,8 @@ class ShipmentAdvice(models.Model):
|
|
|
367
332
|
for shipment in self:
|
|
368
333
|
if shipment.state not in ("in_progress", "error"):
|
|
369
334
|
raise UserError(
|
|
370
|
-
|
|
371
|
-
shipment.name
|
|
335
|
+
self.env._(
|
|
336
|
+
"Shipment %s is not started, operation aborted.", shipment.name
|
|
372
337
|
)
|
|
373
338
|
)
|
|
374
339
|
|
|
@@ -401,7 +366,7 @@ class ShipmentAdvice(models.Model):
|
|
|
401
366
|
return
|
|
402
367
|
moves_to_unplan = (
|
|
403
368
|
self.loaded_move_line_ids.move_id | self.planned_move_ids
|
|
404
|
-
).filtered(lambda m: m.state not in ("cancel", "done") and not m.
|
|
369
|
+
).filtered(lambda m: m.state not in ("cancel", "done") and not m.picked)
|
|
405
370
|
moves_to_unplan.shipment_advice_id = False
|
|
406
371
|
|
|
407
372
|
def _postprocess_action_done(self):
|
|
@@ -414,7 +379,7 @@ class ShipmentAdvice(models.Model):
|
|
|
414
379
|
self.write(
|
|
415
380
|
{
|
|
416
381
|
"state": "error",
|
|
417
|
-
"error_message": _(
|
|
382
|
+
"error_message": self.env._(
|
|
418
383
|
"One of the pickings to process failed to validate"
|
|
419
384
|
),
|
|
420
385
|
}
|
|
@@ -430,7 +395,7 @@ class ShipmentAdvice(models.Model):
|
|
|
430
395
|
|
|
431
396
|
@api.model
|
|
432
397
|
def _get_error_message(self, error, related_object):
|
|
433
|
-
return _(
|
|
398
|
+
return self.env._(
|
|
434
399
|
"An error occurred while processing:\n- %(related_object_name)s: %(error)s",
|
|
435
400
|
related_object_name=related_object.display_name,
|
|
436
401
|
error=str(error),
|
|
@@ -459,8 +424,8 @@ class ShipmentAdvice(models.Model):
|
|
|
459
424
|
for shipment in self:
|
|
460
425
|
if shipment.state not in ("confirmed", "in_progress"):
|
|
461
426
|
raise UserError(
|
|
462
|
-
|
|
463
|
-
shipment.name
|
|
427
|
+
self.env._(
|
|
428
|
+
"Shipment %s is not started, operation aborted.", shipment.name
|
|
464
429
|
)
|
|
465
430
|
)
|
|
466
431
|
shipment.state = "cancel"
|
|
@@ -469,8 +434,8 @@ class ShipmentAdvice(models.Model):
|
|
|
469
434
|
for shipment in self:
|
|
470
435
|
if shipment.state != "cancel":
|
|
471
436
|
raise UserError(
|
|
472
|
-
|
|
473
|
-
shipment.name
|
|
437
|
+
self.env._(
|
|
438
|
+
"Shipment %s is not canceled, operation aborted.", shipment.name
|
|
474
439
|
)
|
|
475
440
|
)
|
|
476
441
|
shipment.state = "draft"
|
|
@@ -485,7 +450,7 @@ class ShipmentAdvice(models.Model):
|
|
|
485
450
|
action_xmlid = "stock.stock_move_action"
|
|
486
451
|
action = self.env["ir.actions.act_window"]._for_xml_id(action_xmlid)
|
|
487
452
|
action["views"] = [
|
|
488
|
-
(self.env.ref("stock.view_picking_move_tree").id, "
|
|
453
|
+
(self.env.ref("stock.view_picking_move_tree").id, "list"),
|
|
489
454
|
]
|
|
490
455
|
action["domain"] = [("id", "in", self.planned_move_ids.ids)]
|
|
491
456
|
action["context"] = {} # Disable filters
|
|
@@ -540,21 +505,21 @@ class ShipmentAdvice(models.Model):
|
|
|
540
505
|
def button_open_deliveries_in_progress(self):
|
|
541
506
|
action_xmlid = "stock.action_picking_tree_all"
|
|
542
507
|
action = self.env["ir.actions.act_window"]._for_xml_id(action_xmlid)
|
|
543
|
-
|
|
508
|
+
view_list = self.env.ref(
|
|
544
509
|
"shipment_advice.stock_picking_loading_progress_view_tree"
|
|
545
510
|
)
|
|
546
|
-
|
|
547
|
-
action["views"][
|
|
511
|
+
list_view_index = action["views"].index((False, "list"))
|
|
512
|
+
action["views"][list_view_index] = (view_list.id, "list")
|
|
548
513
|
action["domain"] = self._domain_open_deliveries_in_progress()
|
|
549
514
|
return action
|
|
550
515
|
|
|
551
516
|
def button_open_receptions_in_progress(self):
|
|
552
517
|
action_xmlid = "stock.action_picking_tree_all"
|
|
553
518
|
action = self.env["ir.actions.act_window"]._for_xml_id(action_xmlid)
|
|
554
|
-
|
|
519
|
+
view_list = self.env.ref(
|
|
555
520
|
"shipment_advice.stock_picking_loading_progress_view_tree"
|
|
556
521
|
)
|
|
557
|
-
|
|
558
|
-
action["views"][
|
|
522
|
+
list_view_index = action["views"].index((False, "list"))
|
|
523
|
+
action["views"][list_view_index] = (view_list.id, "list")
|
|
559
524
|
action["domain"] = [("id", "in", self.planned_picking_ids.ids)]
|
|
560
525
|
return action
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Copyright 2021 Camptocamp SA
|
|
2
2
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
|
|
3
3
|
|
|
4
|
-
from odoo import
|
|
4
|
+
from odoo import fields, models
|
|
5
5
|
from odoo.exceptions import UserError
|
|
6
6
|
from odoo.tools import float_is_zero
|
|
7
7
|
|
|
@@ -31,8 +31,9 @@ class StockMoveLine(models.Model):
|
|
|
31
31
|
for move_line in self:
|
|
32
32
|
if move_line.package_level_id:
|
|
33
33
|
package_lines = move_line.package_level_id.move_line_ids.filtered(
|
|
34
|
-
lambda
|
|
34
|
+
lambda ml: ml.state in ("partially_available", "assigned")
|
|
35
35
|
)
|
|
36
|
+
|
|
36
37
|
if not set(package_lines.ids).issubset(set(self.ids)):
|
|
37
38
|
return False
|
|
38
39
|
return True
|
|
@@ -46,14 +47,14 @@ class StockMoveLine(models.Model):
|
|
|
46
47
|
products = move_lines.product_id.mapped("display_name")
|
|
47
48
|
packages = move_lines.package_id.mapped("display_name")
|
|
48
49
|
raise UserError(
|
|
49
|
-
_(
|
|
50
|
+
self.env._(
|
|
50
51
|
"You cannot load this move line alone, you have to "
|
|
51
52
|
"move the whole package content.\n%(info)s",
|
|
52
53
|
info="\n".join(
|
|
53
54
|
[
|
|
54
|
-
_("Transfers: %s", ", ".join(pickings)),
|
|
55
|
-
_("Products: %s", ", ".join(products)),
|
|
56
|
-
_("Packages: %s", ", ".join(packages)),
|
|
55
|
+
self.env._("Transfers: %s", ", ".join(pickings)),
|
|
56
|
+
self.env._("Products: %s", ", ".join(products)),
|
|
57
|
+
self.env._("Packages: %s", ", ".join(packages)),
|
|
57
58
|
]
|
|
58
59
|
),
|
|
59
60
|
)
|
|
@@ -63,22 +64,25 @@ class StockMoveLine(models.Model):
|
|
|
63
64
|
planned_shipment = move_line.move_id.shipment_advice_id
|
|
64
65
|
if planned_shipment and planned_shipment != shipment_advice:
|
|
65
66
|
raise UserError(
|
|
66
|
-
_(
|
|
67
|
+
self.env._(
|
|
67
68
|
"You cannot load this into this shipment as it has been "
|
|
68
|
-
"planned to be loaded in
|
|
69
|
-
|
|
69
|
+
"planned to be loaded in %s",
|
|
70
|
+
planned_shipment.name,
|
|
71
|
+
)
|
|
70
72
|
)
|
|
71
73
|
# If no planned shipment, allow the loading only if the shipment
|
|
72
74
|
# is not a planned one
|
|
73
75
|
elif not planned_shipment and shipment_advice.planned_move_ids:
|
|
74
76
|
raise UserError(
|
|
75
|
-
_(
|
|
77
|
+
self.env._(
|
|
76
78
|
"You cannot load this into this shipment because its "
|
|
77
79
|
"content is planned already.\n%(info)s",
|
|
78
80
|
info="\n".join(
|
|
79
81
|
[
|
|
80
|
-
_("Transfer: %s", move_line.picking_id.name),
|
|
81
|
-
_(
|
|
82
|
+
self.env._("Transfer: %s", move_line.picking_id.name),
|
|
83
|
+
self.env._(
|
|
84
|
+
"Product: %s", move_line.product_id.display_name
|
|
85
|
+
),
|
|
82
86
|
]
|
|
83
87
|
),
|
|
84
88
|
)
|
|
@@ -88,7 +92,7 @@ class StockMoveLine(models.Model):
|
|
|
88
92
|
and move_line.shipment_advice_id != shipment_advice
|
|
89
93
|
):
|
|
90
94
|
raise UserError(
|
|
91
|
-
_(
|
|
95
|
+
self.env._(
|
|
92
96
|
"This move is already loaded in another shipment."
|
|
93
97
|
"\nProduct: %(product)s.\nPicking: %(picking)s",
|
|
94
98
|
product=move_line.product_id.display_name,
|
|
@@ -97,31 +101,29 @@ class StockMoveLine(models.Model):
|
|
|
97
101
|
)
|
|
98
102
|
move_line.shipment_advice_id = shipment_advice
|
|
99
103
|
uom = move_line.product_uom_id or move_line.product_id.uom_id
|
|
100
|
-
if float_is_zero(
|
|
101
|
-
move_line.reserved_uom_qty, precision_rounding=uom.rounding
|
|
102
|
-
):
|
|
104
|
+
if float_is_zero(move_line.quantity, precision_rounding=uom.rounding):
|
|
103
105
|
raise UserError(
|
|
104
|
-
_(
|
|
106
|
+
self.env._(
|
|
105
107
|
"Nothing to load for %(product)s.\nPicking: %(picking)s",
|
|
106
108
|
product=move_line.product_id.display_name,
|
|
107
109
|
picking=move_line.picking_id.name,
|
|
108
110
|
)
|
|
109
111
|
)
|
|
110
112
|
if move_line.state in ("partially_available", "assigned"):
|
|
111
|
-
move_line.
|
|
113
|
+
move_line.picked = True
|
|
112
114
|
|
|
113
115
|
def _unload_from_shipment(self):
|
|
114
116
|
"""Unload the move lines from their related shipment advice."""
|
|
115
117
|
if not self._check_entire_package():
|
|
116
118
|
raise UserError(
|
|
117
|
-
_(
|
|
119
|
+
self.env._(
|
|
118
120
|
"You cannot unload this move line alone, you have to "
|
|
119
121
|
"unload the whole package content."
|
|
120
122
|
)
|
|
121
123
|
)
|
|
122
124
|
self.shipment_advice_id = False
|
|
123
|
-
self.
|
|
125
|
+
self.picked = False
|
|
124
126
|
|
|
125
127
|
def _is_loaded_in_shipment(self):
|
|
126
128
|
"""Return `True` if the move lines are loaded in a shipment."""
|
|
127
|
-
return all([line.
|
|
129
|
+
return all([line.picked and line.shipment_advice_id for line in self])
|
|
@@ -9,7 +9,15 @@ class StockPackageLevel(models.Model):
|
|
|
9
9
|
|
|
10
10
|
shipment_advice_id = fields.Many2one(related="move_line_ids.shipment_advice_id")
|
|
11
11
|
package_shipping_weight = fields.Float(related="package_id.shipping_weight")
|
|
12
|
-
|
|
12
|
+
package_shipping_weight_uom_name = fields.Char(
|
|
13
|
+
compute="_compute_package_shipping_weight_uom_name", store=False
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
def _compute_package_shipping_weight_uom_name(self):
|
|
17
|
+
for package_level in self:
|
|
18
|
+
package_level.package_shipping_weight_uom_name = self.env[
|
|
19
|
+
"product.template"
|
|
20
|
+
]._get_weight_uom_name_from_ir_config_parameter()
|
|
13
21
|
|
|
14
22
|
def button_load_in_shipment(self):
|
|
15
23
|
action_xmlid = "shipment_advice.wizard_load_shipment_picking_action"
|
|
@@ -28,7 +36,10 @@ class StockPackageLevel(models.Model):
|
|
|
28
36
|
|
|
29
37
|
def _unload_from_shipment(self):
|
|
30
38
|
"""Unload the package levels from their related shipment advice."""
|
|
39
|
+
# Workaround: Odoo's stock.package_level.is_done computed field doesn't include
|
|
40
|
+
# move_line_ids.picked in its @api.depends, so we manually invalidate the cache
|
|
31
41
|
self.move_line_ids._unload_from_shipment()
|
|
42
|
+
self.invalidate_recordset(fnames=["is_done"])
|
|
32
43
|
|
|
33
44
|
def _is_loaded_in_shipment(self):
|
|
34
45
|
"""Return `True` if the package levels are loaded in a shipment."""
|
|
@@ -79,7 +79,7 @@ class StockPicking(models.Model):
|
|
|
79
79
|
# otherwise overloaded container would be marked as partially loaded
|
|
80
80
|
picking.is_fully_loaded_in_shipment = (
|
|
81
81
|
all(
|
|
82
|
-
line.shipment_advice_id and line.
|
|
82
|
+
line.shipment_advice_id and line.picked
|
|
83
83
|
for line in picking.move_line_ids
|
|
84
84
|
)
|
|
85
85
|
if picking.move_line_ids
|
|
@@ -88,7 +88,7 @@ class StockPicking(models.Model):
|
|
|
88
88
|
picking.is_partially_loaded_in_shipment = (
|
|
89
89
|
not picking.is_fully_loaded_in_shipment
|
|
90
90
|
and any(
|
|
91
|
-
line.shipment_advice_id and line.
|
|
91
|
+
line.shipment_advice_id and line.picked
|
|
92
92
|
for line in picking.move_line_ids
|
|
93
93
|
)
|
|
94
94
|
)
|
|
@@ -131,7 +131,7 @@ class StockPicking(models.Model):
|
|
|
131
131
|
[
|
|
132
132
|
ml
|
|
133
133
|
for ml in picking.move_line_ids_without_package
|
|
134
|
-
if ml.shipment_advice_id and ml.
|
|
134
|
+
if ml.shipment_advice_id and ml.picked
|
|
135
135
|
]
|
|
136
136
|
)
|
|
137
137
|
picking.loaded_move_lines_progress_f = (
|
|
@@ -147,7 +147,7 @@ class StockPicking(models.Model):
|
|
|
147
147
|
picking.loaded_weight = sum(
|
|
148
148
|
ml.result_package_id.shipping_weight or ml.move_id.weight
|
|
149
149
|
for ml in picking.move_line_ids_without_package
|
|
150
|
-
if ml.shipment_advice_id and ml.
|
|
150
|
+
if ml.shipment_advice_id and ml.picked
|
|
151
151
|
) + sum(
|
|
152
152
|
pl.package_id.shipping_weight
|
|
153
153
|
for pl in picking.package_level_ids
|
|
@@ -163,9 +163,11 @@ class StockPicking(models.Model):
|
|
|
163
163
|
waiting_moves = picking.move_ids.filtered(
|
|
164
164
|
lambda ml: ml.state not in ["done", "cancel"]
|
|
165
165
|
)
|
|
166
|
+
|
|
166
167
|
picking.loaded_waiting_quantity = sum(
|
|
167
168
|
waiting_moves.mapped("product_qty")
|
|
168
|
-
) - sum(waiting_moves.mapped("
|
|
169
|
+
) - sum(waiting_moves.mapped("quantity"))
|
|
170
|
+
|
|
169
171
|
# Overall progress based on the operation type
|
|
170
172
|
if picking.picking_type_id.show_entire_packs:
|
|
171
173
|
picking.loaded_progress_f = picking.loaded_packages_progress_f
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
- Sébastien Alix \<sebastien.alix@camptocamp.com\>
|
|
2
|
+
- Guewen Baconnier \<guewen.baconnier@camptocamp.com\>
|
|
3
|
+
- Simone Orsi \<simahawk@gmail.com\>
|
|
4
|
+
- [Trobz](https://trobz.com):
|
|
5
|
+
- Dung Tran \<dungtd@trobz.com\>
|
|
6
|
+
- Michael Tietz (MT Software) \<mtietz@mt-software.de\>
|
|
7
|
+
- Jacques-Etienne Baudoux \<je@bcim.be\>
|
|
8
|
+
|
|
9
|
+
## Design
|
|
10
|
+
|
|
11
|
+
- Joël Grand-Guillaume \<joel.grandguillaume@camptocamp.com\>
|
|
12
|
+
- Jacques-Etienne Baudoux \<je@bcim.be\>
|
|
@@ -367,9 +367,9 @@ ul.auto-toc {
|
|
|
367
367
|
!! This file is generated by oca-gen-addon-readme !!
|
|
368
368
|
!! changes will be overwritten. !!
|
|
369
369
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
370
|
-
!! source digest: sha256:
|
|
370
|
+
!! source digest: sha256:95c96f19154e5730489d76cddc8ddbd8a5a8e273db29d5aa9c871fc51fa22d33
|
|
371
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/stock-logistics-transport/tree/
|
|
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/stock-logistics-transport/tree/18.0/shipment_advice"><img alt="OCA/stock-logistics-transport" src="https://img.shields.io/badge/github-OCA%2Fstock--logistics--transport-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/stock-logistics-transport-18-0/stock-logistics-transport-18-0-shipment_advice"><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/stock-logistics-transport&target_branch=18.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
|
|
373
373
|
<p>Manage your (un)loading process through shipment advices.</p>
|
|
374
374
|
<p><strong>Table of contents</strong></p>
|
|
375
375
|
<div class="contents local topic" id="contents">
|
|
@@ -377,10 +377,11 @@ ul.auto-toc {
|
|
|
377
377
|
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-1">Bug Tracker</a></li>
|
|
378
378
|
<li><a class="reference internal" href="#credits" id="toc-entry-2">Credits</a><ul>
|
|
379
379
|
<li><a class="reference internal" href="#authors" id="toc-entry-3">Authors</a></li>
|
|
380
|
-
<li><a class="reference internal" href="#contributors" id="toc-entry-4">Contributors</a
|
|
380
|
+
<li><a class="reference internal" href="#contributors" id="toc-entry-4">Contributors</a><ul>
|
|
381
381
|
<li><a class="reference internal" href="#design" id="toc-entry-5">Design</a></li>
|
|
382
|
-
|
|
383
|
-
|
|
382
|
+
</ul>
|
|
383
|
+
</li>
|
|
384
|
+
<li><a class="reference internal" href="#maintainers" id="toc-entry-6">Maintainers</a></li>
|
|
384
385
|
</ul>
|
|
385
386
|
</li>
|
|
386
387
|
</ul>
|
|
@@ -390,7 +391,7 @@ ul.auto-toc {
|
|
|
390
391
|
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/stock-logistics-transport/issues">GitHub Issues</a>.
|
|
391
392
|
In case of trouble, please check there if your issue has already been reported.
|
|
392
393
|
If you spotted it first, help us to smash it by providing a detailed and welcomed
|
|
393
|
-
<a class="reference external" href="https://github.com/OCA/stock-logistics-transport/issues/new?body=module:%20shipment_advice%0Aversion:%
|
|
394
|
+
<a class="reference external" href="https://github.com/OCA/stock-logistics-transport/issues/new?body=module:%20shipment_advice%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
|
|
394
395
|
<p>Do not contact contributors directly about support or help with technical issues.</p>
|
|
395
396
|
</div>
|
|
396
397
|
<div class="section" id="credits">
|
|
@@ -399,6 +400,7 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
|
|
|
399
400
|
<h2><a class="toc-backref" href="#toc-entry-3">Authors</a></h2>
|
|
400
401
|
<ul class="simple">
|
|
401
402
|
<li>Camptocamp</li>
|
|
403
|
+
<li>BCIM</li>
|
|
402
404
|
</ul>
|
|
403
405
|
</div>
|
|
404
406
|
<div class="section" id="contributors">
|
|
@@ -407,30 +409,23 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
|
|
|
407
409
|
<li>Sébastien Alix <<a class="reference external" href="mailto:sebastien.alix@camptocamp.com">sebastien.alix@camptocamp.com</a>></li>
|
|
408
410
|
<li>Guewen Baconnier <<a class="reference external" href="mailto:guewen.baconnier@camptocamp.com">guewen.baconnier@camptocamp.com</a>></li>
|
|
409
411
|
<li>Simone Orsi <<a class="reference external" href="mailto:simahawk@gmail.com">simahawk@gmail.com</a>></li>
|
|
410
|
-
<li><a class="reference external" href="https://trobz.com">Trobz</a
|
|
411
|
-
|
|
412
|
+
<li><a class="reference external" href="https://trobz.com">Trobz</a>:<ul>
|
|
413
|
+
<li>Dung Tran <<a class="reference external" href="mailto:dungtd@trobz.com">dungtd@trobz.com</a>></li>
|
|
414
|
+
</ul>
|
|
415
|
+
</li>
|
|
412
416
|
<li>Michael Tietz (MT Software) <<a class="reference external" href="mailto:mtietz@mt-software.de">mtietz@mt-software.de</a>></li>
|
|
413
417
|
<li>Jacques-Etienne Baudoux <<a class="reference external" href="mailto:je@bcim.be">je@bcim.be</a>></li>
|
|
414
418
|
</ul>
|
|
415
|
-
</div>
|
|
416
419
|
<div class="section" id="design">
|
|
417
|
-
<
|
|
420
|
+
<h3><a class="toc-backref" href="#toc-entry-5">Design</a></h3>
|
|
418
421
|
<ul class="simple">
|
|
419
422
|
<li>Joël Grand-Guillaume <<a class="reference external" href="mailto:joel.grandguillaume@camptocamp.com">joel.grandguillaume@camptocamp.com</a>></li>
|
|
420
423
|
<li>Jacques-Etienne Baudoux <<a class="reference external" href="mailto:je@bcim.be">je@bcim.be</a>></li>
|
|
421
424
|
</ul>
|
|
422
425
|
</div>
|
|
423
|
-
<div class="section" id="other-credits">
|
|
424
|
-
<h2><a class="toc-backref" href="#toc-entry-6">Other credits</a></h2>
|
|
425
|
-
<p><strong>Financial support</strong></p>
|
|
426
|
-
<ul class="simple">
|
|
427
|
-
<li>Cosanum</li>
|
|
428
|
-
<li>Camptocamp R&D</li>
|
|
429
|
-
</ul>
|
|
430
|
-
<p>The migration of this module from 13.0 to 14.0 was financially supported by Camptocamp</p>
|
|
431
426
|
</div>
|
|
432
427
|
<div class="section" id="maintainers">
|
|
433
|
-
<h2><a class="toc-backref" href="#toc-entry-
|
|
428
|
+
<h2><a class="toc-backref" href="#toc-entry-6">Maintainers</a></h2>
|
|
434
429
|
<p>This module is maintained by the OCA.</p>
|
|
435
430
|
<a class="reference external image-reference" href="https://odoo-community.org">
|
|
436
431
|
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
|
|
@@ -438,7 +433,9 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
|
|
|
438
433
|
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
|
|
439
434
|
mission is to support the collaborative development of Odoo features and
|
|
440
435
|
promote its widespread use.</p>
|
|
441
|
-
<p>
|
|
436
|
+
<p>Current <a class="reference external" href="https://odoo-community.org/page/maintainer-role">maintainer</a>:</p>
|
|
437
|
+
<p><a class="reference external image-reference" href="https://github.com/jbaudoux"><img alt="jbaudoux" src="https://github.com/jbaudoux.png?size=40px" /></a></p>
|
|
438
|
+
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/stock-logistics-transport/tree/18.0/shipment_advice">OCA/stock-logistics-transport</a> project on GitHub.</p>
|
|
442
439
|
<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>
|
|
443
440
|
</div>
|
|
444
441
|
</div>
|
|
@@ -3,14 +3,15 @@
|
|
|
3
3
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
|
|
4
4
|
|
|
5
5
|
from odoo import fields
|
|
6
|
-
from odoo.tests
|
|
6
|
+
from odoo.tests import Form, new_test_user
|
|
7
7
|
|
|
8
|
+
from odoo.addons.base.tests.common import BaseCommon
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
|
|
11
|
+
class Common(BaseCommon):
|
|
10
12
|
@classmethod
|
|
11
13
|
def setUpClass(cls):
|
|
12
14
|
super().setUpClass()
|
|
13
|
-
cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True))
|
|
14
15
|
# Configuration
|
|
15
16
|
cls.dock = cls.env.ref("shipment_advice.stock_dock_demo")
|
|
16
17
|
cls.picking_type_out = cls.env.ref("stock.picking_type_out")
|
|
@@ -110,8 +111,6 @@ class Common(TransactionCase):
|
|
|
110
111
|
"warehouse_id": picking_type.warehouse_id.id,
|
|
111
112
|
"picking_type_id": picking_type.id,
|
|
112
113
|
"group_id": group and group.id or False,
|
|
113
|
-
# "procure_method": "make_to_order",
|
|
114
|
-
# "state": "draft",
|
|
115
114
|
}
|
|
116
115
|
)
|
|
117
116
|
move._assign_picking()
|
|
@@ -198,10 +197,10 @@ class Common(TransactionCase):
|
|
|
198
197
|
return wiz
|
|
199
198
|
|
|
200
199
|
@classmethod
|
|
201
|
-
def validate_picking(cls, picking
|
|
200
|
+
def validate_picking(cls, picking):
|
|
202
201
|
picking.ensure_one()
|
|
203
202
|
for ml in picking.move_line_ids:
|
|
204
|
-
ml.
|
|
203
|
+
ml.picked = True
|
|
205
204
|
action_data = picking.button_validate()
|
|
206
205
|
if action_data is True:
|
|
207
206
|
return cls.env["stock.picking"]
|
|
@@ -44,7 +44,7 @@ class TestShipmentAdvice(Common):
|
|
|
44
44
|
self.plan_records_in_shipment(self.shipment_advice_in, picking)
|
|
45
45
|
self.progress_shipment_advice(self.shipment_advice_in)
|
|
46
46
|
for ml in picking.move_line_ids:
|
|
47
|
-
ml.
|
|
47
|
+
ml.picked = True
|
|
48
48
|
picking._action_done()
|
|
49
49
|
self.shipment_advice_in.action_done()
|
|
50
50
|
self.assertEqual(self.shipment_advice_in.state, "done")
|
|
@@ -66,7 +66,7 @@ class TestShipmentAdvice(Common):
|
|
|
66
66
|
self.progress_shipment_advice(self.shipment_advice_in)
|
|
67
67
|
# Receive it (making its related transfer partially received)
|
|
68
68
|
for ml in self.move_product_in1.move_line_ids:
|
|
69
|
-
ml.
|
|
69
|
+
ml.picked = True
|
|
70
70
|
self.assertEqual(picking, self.move_product_in2.picking_id)
|
|
71
71
|
# When validating the shipment, a backorder is created for unprocessed moves
|
|
72
72
|
self.shipment_advice_in.action_done()
|