Skip to content

Commit 06d274a

Browse files
[MIG] stock_picking_import_serial_number: Migration to 18.0
1 parent cdee984 commit 06d274a

File tree

6 files changed

+51
-135
lines changed

6 files changed

+51
-135
lines changed

stock_picking_import_serial_number/__manifest__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
{
55
"name": "Stock Picking Import Serial Numbers",
66
"summary": "Import S/N from excel file for incoming pickings",
7-
"version": "16.0.1.0.1",
7+
"version": "18.0.1.0.0",
88
"development_status": "Production/Stable",
99
"category": "stock",
1010
"website": "https://github.com/OCA/stock-logistics-workflow",

stock_picking_import_serial_number/tests/common.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,16 @@ def assertUniqueIn(self, element_list):
1111
elements = []
1212
for element in element_list:
1313
if element in elements:
14-
raise Exception("Element %s is not unique in list" % element)
14+
raise Exception(f"Element {element} is not unique in list")
1515
elements.append(element)
1616

1717
@classmethod
1818
def setUpClass(cls):
1919
super().setUpClass()
2020
cls.lot_obj = cls.env["stock.lot"]
2121
cls.warehouse = cls.env.ref("stock.warehouse0")
22-
cls.picking_type_in = cls.env.ref("stock.picking_type_in")
22+
cls.picking_type_in = cls.env.ref("stock.picking_type_out")
2323
cls.picking_type_in.use_create_lots = True
24-
cls.picking_type_in.show_reserved = True
2524
cls.supplier_location = cls.env.ref("stock.stock_location_suppliers")
2625
cls.supplier = cls.env["res.partner"].create({"name": "Supplier - test"})
2726

@@ -34,7 +33,8 @@ def _create_product(cls, tracking="lot", reference=None):
3433
name = f"{tracking}"
3534
vals = {
3635
"name": name,
37-
"type": "product",
36+
"type": "consu",
37+
"is_storable": True,
3838
"tracking": tracking,
3939
}
4040
if reference:

stock_picking_import_serial_number/tests/test_stock_picking_import_serial_number.py

Lines changed: 1 addition & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def _create_wizard(self, pickings=False, filename=False):
4747
default_filename=filename,
4848
)
4949
)
50-
wizard_form.data_file = self._data_file("data/%s" % filename)
50+
wizard_form.data_file = self._data_file(f"data/{filename}")
5151
return wizard_form.save()
5252

5353
@mute_logger("odoo.models.unlink")
@@ -135,76 +135,3 @@ def test_import_serial_number_03(self):
135135
self.assertIn("LOT-2", lot_names)
136136
self.assertIn("LOT-3", lot_names)
137137
self.assertFalse(smls[0].result_package_id)
138-
139-
@mute_logger("odoo.models.unlink")
140-
def test_import_serial_number_no_show_reserved_01(self):
141-
# Full import: Lots + packages (SNImport-1.xls)
142-
self.picking_in_01.picking_type_id.show_reserved = False
143-
picking = self.picking_in_01.copy()
144-
picking.action_confirm()
145-
picking.action_assign()
146-
wiz = self._create_wizard(pickings=picking)
147-
wiz.action_import()
148-
smls = picking.move_line_nosuggest_ids.filtered("lot_name")
149-
self.assertEqual(len(smls), 6)
150-
lot_names = smls.mapped("lot_name")
151-
self.assertIn("LOT-1", lot_names)
152-
self.assertIn("LOT-2", lot_names)
153-
self.assertIn("LOT-3", lot_names)
154-
self.assertIn("LOT-4", lot_names)
155-
self.assertIn("LOT-5", lot_names)
156-
self.assertIn("LOT-6", lot_names)
157-
package_names = smls.mapped("result_package_id.name")
158-
self.assertIn("PACK-1", package_names)
159-
self.assertIn("PACK-2", package_names)
160-
self.assertIn("PACK-3", package_names)
161-
self.assertIn("PACK-4", package_names)
162-
self.assertIn("PACK-5", package_names)
163-
self.assertIn("PACK-6", package_names)
164-
165-
@mute_logger("odoo.models.unlink")
166-
def test_import_serial_number_no_show_reserved_02(self):
167-
# Full import: Lots + packages (SNImport-2.xls)
168-
self.picking_in_01.picking_type_id.show_reserved = False
169-
picking = self.picking_in_01.copy()
170-
picking.action_confirm()
171-
picking.action_assign()
172-
wiz = self._create_wizard(pickings=picking, filename="SNImport-2.xls")
173-
wiz.action_import()
174-
smls = picking.move_line_nosuggest_ids.filtered("lot_name")
175-
self.assertEqual(len(smls), 6)
176-
lot_names = smls.mapped("lot_name")
177-
self.assertIn("LOT-1", lot_names)
178-
self.assertIn("LOT-2", lot_names)
179-
self.assertIn("LOT-3", lot_names)
180-
self.assertIn("LOT-4", lot_names)
181-
self.assertIn("LOT-5", lot_names)
182-
self.assertIn("LOT-6", lot_names)
183-
package_names = smls.mapped("result_package_id.name")
184-
self.assertIn("PACK-1", package_names)
185-
self.assertIn("PACK-2", package_names)
186-
self.assertNotIn("PACK-3", package_names)
187-
self.assertNotIn("PACK-4", package_names)
188-
self.assertNotIn("PACK-5", package_names)
189-
self.assertNotIn("PACK-6", package_names)
190-
191-
@mute_logger("odoo.models.unlink")
192-
def test_import_serial_number_no_show_reserved_03(self):
193-
# Import only lots
194-
self.picking_in_01.picking_type_id.show_reserved = False
195-
picking = self.picking_in_01.copy()
196-
picking.action_confirm()
197-
picking.action_assign()
198-
wiz = self._create_wizard(pickings=picking)
199-
wiz.sn_package_column_index = 10
200-
wiz.action_import()
201-
smls = picking.move_line_nosuggest_ids.filtered("lot_name")
202-
self.assertEqual(len(smls), 6)
203-
lot_names = smls.mapped("lot_name")
204-
self.assertIn("LOT-1", lot_names)
205-
self.assertIn("LOT-2", lot_names)
206-
self.assertIn("LOT-3", lot_names)
207-
self.assertIn("LOT-4", lot_names)
208-
self.assertIn("LOT-5", lot_names)
209-
self.assertIn("LOT-6", lot_names)
210-
self.assertFalse(smls[0].result_package_id)

stock_picking_import_serial_number/views/res_config_settings_views.xml

Lines changed: 29 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -4,63 +4,48 @@
44
<field name="model">res.config.settings</field>
55
<field name="inherit_id" ref="stock.res_config_settings_view_form" />
66
<field name="arch" type="xml">
7-
<div id="production_lot_info" position="after">
8-
<h2>Import S/N</h2>
9-
<div class="row mt16 o_settings_container" id="serial_number_importer">
10-
<div class="col-12 col-lg-6 o_setting_box">
11-
<div class="o_setting_left_pane" />
12-
<div class="o_setting_right_pane">
13-
<span class="o_form_label">Field to search products</span>
14-
<div class="text-muted">
7+
<block id="production_lot_info" position="after">
8+
<block title="Import S/N">
9+
<setting>
10+
<span class="o_form_label">Field to search products</span>
11+
<div class="text-muted">
1512
Select the field to search products
1613
</div>
17-
<div class="text-muted">
18-
<field name="default_sn_search_product_by_field" />
19-
</div>
14+
<div class="text-muted">
15+
<field name="default_sn_search_product_by_field" />
2016
</div>
21-
</div>
22-
<div class="col-12 col-lg-6 o_setting_box">
23-
<div class="o_setting_left_pane" />
24-
<div class="o_setting_right_pane">
25-
<span
26-
class="o_form_label"
27-
>File column index for products</span>
28-
<div class="text-muted">
17+
</setting>
18+
<setting>
19+
<span class="o_form_label">File column index for products</span>
20+
<div class="text-muted">
2921
Select the index file column which contains the product info
3022
</div>
31-
<div class="text-muted">
32-
<field name="default_sn_product_column_index" />
33-
</div>
23+
<div class="text-muted">
24+
<field name="default_sn_product_column_index" />
3425
</div>
35-
</div>
36-
<div class="col-12 col-lg-6 o_setting_box">
37-
<div class="o_setting_right_pane">
38-
<span
39-
class="o_form_label"
40-
>File column index for serial number</span>
41-
<div class="text-muted">
26+
</setting>
27+
<setting>
28+
<span
29+
class="o_form_label"
30+
>File column index for serial number</span>
31+
<div class="text-muted">
4232
Select the index file column which contains the serial numbers info
4333
</div>
44-
<div class="text-muted">
34+
<div class="text-muted">s
4535
<field name="default_sn_serial_column_index" />
4636
</div>
47-
</div>
48-
</div>
49-
<div class="col-12 col-lg-6 o_setting_box">
50-
<div class="o_setting_right_pane">
51-
<span
52-
class="o_form_label"
53-
>File column index for package</span>
54-
<div class="text-muted">
37+
</setting>
38+
<setting>
39+
<span class="o_form_label">File column index for package</span>
40+
<div class="text-muted">
5541
Select the index file column which contains the package info
5642
</div>
57-
<div class="text-muted">
58-
<field name="default_sn_package_column_index" />
59-
</div>
43+
<div class="text-muted">
44+
<field name="default_sn_package_column_index" />
6045
</div>
61-
</div>
62-
</div>
63-
</div>
46+
</setting>
47+
</block>
48+
</block>
6449
</field>
6550
</record>
6651
</odoo>

stock_picking_import_serial_number/views/stock_picking.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
<field name="model">stock.picking</field>
44
<field name="inherit_id" ref="stock.view_picking_form" />
55
<field name="arch" type="xml">
6-
<button name="action_toggle_is_locked" position="after">
6+
<button name="action_cancel" position="before">
77
<button
88
name="%(action_import_serial_number)d"
99
string="Import S/N"
10-
attrs="{'invisible': ['|', ('state', '!=', 'assigned'), ('picking_type_code', '!=', 'incoming')]}"
10+
invisible="state != 'assigned' or picking_type_code != 'incoming'"
1111
type="action"
1212
groups="base.group_user"
1313
/>

stock_picking_import_serial_number/wizard/import_serial_number_wizard.py

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
import xlrd
88

9-
from odoo import _, api, fields, models
9+
from odoo import api, fields, models
1010
from odoo.exceptions import UserError
1111

1212

@@ -49,13 +49,13 @@ def default_get(self, fields):
4949
def action_import(self):
5050
if self.picking_ids.filtered(lambda p: not p.picking_type_id.use_create_lots):
5151
raise UserError(
52-
_(
52+
self.env._(
5353
"You only can import S/N for picking operations with"
5454
" creation lots checked"
5555
)
5656
)
5757
if not self.data_file:
58-
raise UserError(_("You must upload file to import records"))
58+
raise UserError(self.env._("You must upload file to import records"))
5959
xl_workbook = False
6060
xl_sheet = False
6161
if self.filename.split(".")[1] in ["xls", "xlsx"]:
@@ -91,8 +91,7 @@ def _prepare_stock_move_line_vals(self, picking, product):
9191
"location_dest_id": picking.location_dest_id.id,
9292
"product_id": product.id,
9393
"product_uom_id": product.uom_id.id,
94-
"reserved_uom_qty": 0.0,
95-
"qty_done": 1.0,
94+
"quantity": 1.0,
9695
}
9796

9897
def _import_serial_number(self, xl_sheet, stock_move_lines, picking):
@@ -115,26 +114,31 @@ def _import_serial_number(self, xl_sheet, stock_move_lines, picking):
115114
)
116115
for item in serial_list:
117116
product = products.filtered(
118-
lambda p: p[self.sn_search_product_by_field] == item[0]
117+
lambda p, item=item[0]: p[self.sn_search_product_by_field] == item
119118
)
120-
if picking.picking_type_id.show_reserved:
121-
smls = stock_move_lines.filtered(lambda ln: ln.product_id == product)
119+
if picking.picking_type_code != "incoming":
120+
smls = stock_move_lines.filtered(
121+
lambda ln, product=product: ln.product_id == product
122+
)
123+
122124
for sml in smls:
123125
if not sml.lot_name or self.overwrite_serial:
124126
sml.lot_name = item[1]
125-
sml.qty_done = 1.0
127+
sml.quantity = 1.0
126128
if item[2]:
127129
sml.result_package_id = self._search_or_create_package(
128130
picking, item[2]
129131
)
130132
# Only assign one serial
131133
break
132134
# TODO: Check if product is present on initial demand??
133-
# elif product and picking.move_lines.filtered(lambda ln: ln.product_id == product)
135+
# elif product and picking.move_lines.filtered(
136+
# lambda ln: ln.product_id == product)
134137
elif product:
135138
vals = self._prepare_stock_move_line_vals(picking, product)
136139
vals.update(lot_name=item[1])
137140
if item[2]:
138141
package = self._search_or_create_package(picking, item[2])
139142
vals.update(result_package_id=package.id)
143+
140144
self.env["stock.move.line"].create(vals)

0 commit comments

Comments
 (0)