mirror of
https://github.com/OCA/stock-logistics-warehouse.git
synced 2025-01-21 14:27:28 +02:00
211 lines
7.9 KiB
Python
211 lines
7.9 KiB
Python
# Copyright 2021 Camptocamp SA
|
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
|
|
from odoo import api, fields, models
|
|
|
|
|
|
class MeasuringWizard(models.TransientModel):
|
|
_name = "measuring.wizard"
|
|
_inherit = "barcodes.barcode_events_mixin"
|
|
_description = "measuring Wizard"
|
|
_rec_name = "device_id"
|
|
|
|
product_id = fields.Many2one("product.product", domain=[("type", "=", "product")])
|
|
line_ids = fields.One2many("measuring.wizard.line", "wizard_id")
|
|
device_id = fields.Many2one("measuring.device", readonly=True)
|
|
|
|
@api.onchange("product_id")
|
|
def onchange_product_id(self):
|
|
if self.product_id:
|
|
to_create = []
|
|
to_create += self._prepare_unit_line()
|
|
to_create += self._prepare_packaging_lines()
|
|
recs = self.env["measuring.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,
|
|
"packaging_length": self.product_id.product_length,
|
|
"width": self.product_id.product_width,
|
|
"height": self.product_id.product_height,
|
|
"is_unit_line": True,
|
|
}
|
|
product_dimension_uom = self.product_id.dimensional_uom_id
|
|
mm_uom = self.env.ref("stock_measuring_device.product_uom_mm")
|
|
if mm_uom != product_dimension_uom:
|
|
vals.update(
|
|
{
|
|
"packaging_length": product_dimension_uom._compute_quantity(
|
|
self.product_id.product_length, mm_uom
|
|
),
|
|
"width": product_dimension_uom._compute_quantity(
|
|
self.product_id.product_width, mm_uom
|
|
),
|
|
"height": product_dimension_uom._compute_quantity(
|
|
self.product_id.product_height, mm_uom
|
|
),
|
|
}
|
|
)
|
|
return [vals]
|
|
|
|
def _prepare_packaging_lines(self):
|
|
vals_list = []
|
|
product_packaging = self.env["product.packaging"]
|
|
packaging_types = self.env["product.packaging.type"].search([])
|
|
for seq, pack_type in enumerate(packaging_types):
|
|
pack = 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,
|
|
"packaging_length": 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,
|
|
"packaging_length": pack.packaging_length,
|
|
"width": pack.width,
|
|
"height": pack.height,
|
|
"barcode": pack.barcode,
|
|
"packaging_id": pack.id,
|
|
"packaging_type_id": pack_type.id,
|
|
"scan_requested": bool(pack.measuring_device_id),
|
|
}
|
|
)
|
|
vals_list.append(vals)
|
|
return vals_list
|
|
|
|
def action_reopen_fullscreen(self):
|
|
self.ensure_one()
|
|
res = self.device_id.open_wizard()
|
|
res["res_id"] = self.id
|
|
return res
|
|
|
|
def on_barcode_scanned(self, barcode):
|
|
self.ensure_one()
|
|
prod = self.env["product.product"].search([("barcode", "=", barcode)], limit=1)
|
|
self.product_id = prod
|
|
|
|
def action_save(self):
|
|
self.ensure_one()
|
|
mm_uom = self.env.ref("stock_measuring_device.product_uom_mm")
|
|
product_vals = {}
|
|
packaging_ids_list = []
|
|
for line in self.line_ids:
|
|
packaging_type = line.packaging_type_id
|
|
if not line.is_measured:
|
|
continue
|
|
if packaging_type:
|
|
# Handle lines with packaging
|
|
vals = {
|
|
"name": line.name,
|
|
"qty": line.qty,
|
|
"max_weight": line.max_weight,
|
|
"packaging_length": line.packaging_length,
|
|
"width": line.width,
|
|
"height": line.height,
|
|
"length_uom_id": mm_uom.id,
|
|
"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:
|
|
# Handle unit line
|
|
product_vals.update(
|
|
{
|
|
"product_length": line.packaging_length,
|
|
"product_width": line.width,
|
|
"product_height": line.height,
|
|
"dimensional_uom_id": 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()
|
|
|
|
def action_close(self):
|
|
for line in self.line_ids:
|
|
if not line.scan_requested:
|
|
continue
|
|
line.packaging_id._measuring_device_release()
|
|
line.scan_requested = False
|
|
return {
|
|
"type": "ir.actions.act_window",
|
|
"res_model": self.device_id._name,
|
|
"res_id": self.device_id.id,
|
|
"view_mode": "form",
|
|
"target": "main",
|
|
"flags": {"headless": False, "clear_breadcrumbs": True},
|
|
}
|
|
|
|
def retrieve_product(self):
|
|
"""Assigns product that locks the device if a scan is already requested."""
|
|
if self.device_id._is_being_used():
|
|
pack = self.env["product.packaging"]._measuring_device_find_assigned(
|
|
self.device_id
|
|
)
|
|
self.product_id = pack.product_id
|
|
self.onchange_product_id()
|
|
|
|
def reload(self):
|
|
return {
|
|
"type": "ir.actions.act_view_reload",
|
|
}
|
|
|
|
def _send_notification_refresh(self):
|
|
"""Send a refresh notification on the wizard.
|
|
|
|
Other notifications can be implemented, they have to be
|
|
added in static/src/js/measuring_wizard.js and the message
|
|
must contain an "action" and "params".
|
|
"""
|
|
self.ensure_one()
|
|
channel = "notify_measuring_wizard_screen"
|
|
bus_message = {
|
|
"action": "refresh",
|
|
"params": {"model": self._name, "id": self.id},
|
|
}
|
|
self.env["bus.bus"].sendone(channel, bus_message)
|
|
|
|
def _notify(self, message):
|
|
"""Show a gentle notification on the wizard
|
|
|
|
We can't use the user set in the current environment because the user
|
|
that attends the screen (that opened the wizard, thus created it) may
|
|
be not the same than the one (artificial user) that scans and submits
|
|
the data, e.g. by using an api call via a controller. We have to send
|
|
this original user in the environment because notify_warning checks
|
|
that you only notify a user which is the same than the one set in
|
|
the environment.
|
|
"""
|
|
self.ensure_one()
|
|
self.create_uid.with_user(self.create_uid.id).notify_warning(message=message)
|