[IMP] stock_cubiscan: Handle unit without packaging

This commit is contained in:
Akim Juillerat
2020-04-16 16:25:31 +02:00
committed by Guewen Baconnier
parent 3eb8429ef8
commit 94ddeb32b7
5 changed files with 156 additions and 58 deletions

View File

@@ -13,10 +13,12 @@
"web_tree_dynamic_colored_field",
"product_packaging_dimension",
"product_packaging_type_required",
"product_dimension",
],
"external_dependencies": {"python": ["cubiscan"]},
"website": "https://github.com/OCA/stock-logistics-warehouse",
"data": [
"data/uom.xml",
"views/assets.xml",
"views/cubiscan_view.xml",
"wizard/cubiscan_wizard.xml",

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<record id="product_uom_mm" model="uom.uom">
<field name="category_id" ref="uom.uom_categ_length"/>
<field name="name">mm</field>
<field name="factor" eval="1000"/>
<field name="uom_type">smaller</field>
</record>
</odoo>

View File

@@ -1,3 +1,2 @@
* The UI could get some improvements
* Being able to open the Cubiscan screen from a product would be nice
* The wizard should allow to set weight and size for a single unit in addition to the packaging

View File

@@ -32,7 +32,6 @@ class TestCubiscanWizard(SavepointCase):
cls.cs_wizard = cls.env["cubiscan.wizard"]
PackType = cls.env["product.packaging.type"]
pack_type_data = [
("unit", 2, 0, 0),
("internal", 3, 1, 0),
("retail", 10, 1, 1),
("transport", 20, 1, 1),
@@ -105,10 +104,27 @@ class TestCubiscanWizard(SavepointCase):
)
self.wizard.action_save()
mm_uom = self.env.ref("stock_cubiscan.product_uom_mm")
self.assertEqual(
self.product_1.read(
[
"product_length", "product_width", "product_height",
"weight", "volume", "dimensional_uom_id"
]
)[0],
{
"id": self.product_1.id,
"product_length": 1000,
"product_width": 1000,
"product_height": 1000,
"weight": 1.0,
"volume": 1.0,
"dimensional_uom_id": (mm_uom.id, mm_uom.name)
}
)
packagings = self.product_1.packaging_ids.sorted()
self.assertEqual(len(packagings), 6)
for idx, packaging in enumerate(packagings):
self.assertEqual(len(packagings), 5)
for idx, packaging in enumerate(packagings, 1):
self.assertEqual(
packaging.read(["lngth", "width", "height", "max_weight", "volume"])[0],
{

View File

@@ -1,7 +1,7 @@
# Copyright 2019 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import _, api, fields, models
from odoo import _, api, exceptions, fields, models
class CubiscanWizard(models.TransientModel):
@@ -23,46 +23,90 @@ class CubiscanWizard(models.TransientModel):
def onchange_product_id(self):
if self.product_id:
to_create = []
packaging_types = self.env["product.packaging.type"].search([])
for seq, pack_type in enumerate(packaging_types):
pack = self.env["product.packaging"].search(
[
("product_id", "=", self.product_id.id),
("packaging_type_id", "=", pack_type.id),
],
limit=1,
)
vals = {
"wizard_id": self.id,
"sequence": seq + 1,
"name": pack_type.name,
"qty": 0,
"max_weight": 0,
"lngth": 0,
"width": 0,
"height": 0,
"barcode": False,
"packaging_type_id": pack_type.id,
}
if pack:
vals.update(
{
"qty": pack.qty,
"max_weight": pack.max_weight,
"lngth": pack.lngth,
"width": pack.width,
"height": pack.height,
"barcode": pack.barcode,
"packaging_id": pack.id,
"packaging_type_id": pack_type.id,
}
)
to_create.append(vals)
to_create += self._prepare_unit_line()
to_create += self._prepare_packaging_lines()
recs = self.env["cubiscan.wizard.line"].create(to_create)
self.line_ids = recs
else:
self.line_ids = [(5, 0, 0)]
def _prepare_unit_line(self):
vals = {
"wizard_id": self.id,
"sequence": 0,
"name": "Unit",
"qty": 1,
"max_weight": self.product_id.weight,
"lngth": self.product_id.product_length,
"width": self.product_id.product_width,
"height": self.product_id.product_height,
}
product_dimension_uom = self.product_id.dimensional_uom_id
cubiscan_mm_uom = self.env.ref(
"stock_cubiscan.product_uom_mm", raise_if_not_found=False
)
if not cubiscan_mm_uom:
raise exceptions.UserError(
_(
"Cannot find 'mm' Unit of measure, please update "
"`stock_cubiscan` module"
)
)
if cubiscan_mm_uom != product_dimension_uom:
vals.update(
{
"lngth": product_dimension_uom._compute_quantity(
self.product_id.product_length, cubiscan_mm_uom
),
"width": product_dimension_uom._compute_quantity(
self.product_id.product_width, cubiscan_mm_uom
),
"height": product_dimension_uom._compute_quantity(
self.product_id.product_height, cubiscan_mm_uom
),
}
)
return [vals]
def _prepare_packaging_lines(self):
vals_list = []
packaging_types = self.env["product.packaging.type"].search([])
for seq, pack_type in enumerate(packaging_types):
pack = self.env["product.packaging"].search(
[
("product_id", "=", self.product_id.id),
("packaging_type_id", "=", pack_type.id),
],
limit=1,
)
vals = {
"wizard_id": self.id,
"sequence": seq + 1,
"name": pack_type.name,
"qty": 0,
"max_weight": 0,
"lngth": 0,
"width": 0,
"height": 0,
"barcode": False,
"packaging_type_id": pack_type.id,
}
if pack:
vals.update(
{
"qty": pack.qty,
"max_weight": pack.max_weight,
"lngth": pack.lngth,
"width": pack.width,
"height": pack.height,
"barcode": pack.barcode,
"packaging_id": pack.id,
"packaging_type_id": pack_type.id,
}
)
vals_list.append(vals)
return vals_list
def action_reopen_fullscreen(self):
# Action to reopen wizard in fullscreen (e.g. after page refresh)
self.ensure_one()
@@ -87,24 +131,52 @@ class CubiscanWizard(models.TransientModel):
def action_save(self):
self.ensure_one()
actions = []
product_vals = {}
packaging_ids_list = []
for line in self.line_ids:
vals = {
"name": line.name,
"qty": line.qty,
"max_weight": line.max_weight,
"lngth": line.lngth,
"width": line.width,
"height": line.height,
"barcode": line.barcode,
"packaging_type_id": line.packaging_type_id.id,
}
pack = line.packaging_id
if pack:
actions.append((1, pack.id, vals))
packaging_type = line.packaging_type_id
if packaging_type:
# Handle lines with packaging
vals = {
"name": line.name,
"qty": line.qty,
"max_weight": line.max_weight,
"lngth": line.lngth,
"width": line.width,
"height": line.height,
"barcode": line.barcode,
"packaging_type_id": line.packaging_type_id.id,
}
pack = line.packaging_id
if pack:
packaging_ids_list.append((1, pack.id, vals))
else:
packaging_ids_list.append((0, 0, vals))
else:
actions.append((0, 0, vals))
self.product_id.packaging_ids = actions
# Handle unit line
cubiscan_mm_uom = self.env.ref(
"stock_cubiscan.product_uom_mm", raise_if_not_found=False
)
if not cubiscan_mm_uom:
raise exceptions.UserError(
_(
"Cannot find 'mm' Unit of measure, please update "
"`stock_cubiscan` module"
)
)
product_vals.update(
{
"product_length": line.lngth,
"product_width": line.width,
"product_height": line.height,
"dimensional_uom_id": cubiscan_mm_uom.id,
"weight": line.max_weight,
}
)
product_vals.update({"packaging_ids": packaging_ids_list})
self.product_id.write(product_vals)
# Call onchange to update volume on product.product
self.product_id.onchange_calculate_volume()
# reload lines
self.onchange_product_id()
@@ -154,7 +226,7 @@ class CubiscanWizardLine(models.TransientModel):
"product.packaging", string="Packaging (rel)", readonly=True
)
packaging_type_id = fields.Many2one(
"product.packaging.type", readonly=True, required=True
"product.packaging.type", readonly=True,
)
required = fields.Boolean(related="packaging_type_id.required", readonly=True)