Skip to content

Commit

Permalink
Merge PR #927 into 14.0
Browse files Browse the repository at this point in the history
Signed-off-by sebalix
  • Loading branch information
OCA-git-bot committed Jan 10, 2025
2 parents 1c6f6a8 + b56cb46 commit 940a40d
Show file tree
Hide file tree
Showing 9 changed files with 537 additions and 19 deletions.
2 changes: 1 addition & 1 deletion stock_reception_screen_measuring_device/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"name": "Stock Measuring Device on Reception Screen",
"summary": "Allow to use a measuring device from a reception screen."
"for packaging measurement",
"version": "14.0.1.0.0",
"version": "14.0.2.0.0",
"category": "Warehouse",
"author": "Camptocamp, Odoo Community Association (OCA)",
"license": "AGPL-3",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Copyright 2024 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)

import logging

from odoo import SUPERUSER_ID, api

_logger = logging.getLogger(__name__)


def populate_new_field(env):
records_to_update = (
env["stock.reception.screen"].search([("current_step", "!=", "done")]).exists()
)
_logger.info(
"Set smaller_package_has_missing_dimensions on ongoing reception screens"
)
records_to_update._compute_smaller_package_has_missing_dimensions()


def migrate(cr, version):
if not version:
return
env = api.Environment(cr, SUPERUSER_ID, {})
populate_new_field(env)
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Copyright 2021 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)

import logging

_logger = logging.getLogger(__name__)


def create_and_populate_new_fields(cr):
cr.execute(
"""
ALTER TABLE stock_reception_screen
ADD COLUMN IF NOT EXISTS smaller_package_has_missing_dimensions BOOLEAN;
"""
)
# Set value to False for done reception screens.
# Otherwise, let the ORM do its job in post migration
_logger.info("Set smaller_package_has_missing_dimensions on done reception screens")
cr.execute(
"""
UPDATE stock_reception_screen
SET smaller_package_has_missing_dimensions = FALSE
WHERE current_step = 'done';
"""
)


def migrate(cr, version):
create_and_populate_new_fields(cr)
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ class StockReceptionScreen(models.Model):
store=True,
help="Indicates if the package have any measurement missing.",
)
smaller_package_has_missing_dimensions = fields.Boolean(
"Smaller Package Requires Measures?",
compute="_compute_smaller_package_has_missing_dimensions",
store=True,
help="Indicates if any smaller package have any measurement missing.",
)
display_package_dimensions = fields.Char(
string="Dimensions (lxhxw)",
compute="_compute_package_dimensions",
Expand All @@ -27,16 +33,19 @@ class StockReceptionScreen(models.Model):
help="A scan from the measuring device was requested",
default=False,
compute="_compute_scan_requested",
store=True,
)

@api.depends("product_packaging_id", "product_packaging_id.measuring_device_id")
@api.depends(
"current_move_product_id.packaging_ids.measuring_device_id",
)
def _compute_scan_requested(self):
for record in self:
record.scan_requested = (
record.product_packaging_id
and record.product_packaging_id.measuring_device_id
)
all_product_packagings = record.current_move_product_id.packaging_ids
record.scan_requested = False
for packaging in all_product_packagings:
if packaging.measuring_device_id:
record.scan_requested = True
break

@api.depends(
"product_packaging_id.packaging_length",
Expand All @@ -54,6 +63,20 @@ def _compute_package_dimensions(self):
else:
record.display_package_dimensions = False

@api.depends(
"product_packaging_id",
"product_packaging_id.qty",
"current_move_product_id.packaging_ids.max_weight",
"current_move_product_id.packaging_ids.packaging_length",
"current_move_product_id.packaging_ids.width",
"current_move_product_id.packaging_ids.height",
)
def _compute_smaller_package_has_missing_dimensions(self):
for record in self:
record.smaller_package_has_missing_dimensions = bool(
record._get_smaller_package_without_dimensions()
)

@api.depends(
"product_packaging_id.max_weight",
"product_packaging_id.packaging_length",
Expand All @@ -71,35 +94,78 @@ def _compute_package_has_missing_dimensions(self):
else:
record.package_has_missing_dimensions = False

def measure_current_packaging(self):
self.ensure_one()
@api.model
def _measure_packaging(self, packaging):
device = self.env["measuring.device"].search(
[("is_default", "=", True)], limit=1
)
if not device:
error_msg = _("No default device set, please configure one.")
_logger.error(error_msg)
self._notify(error_msg)
return UserError(error_msg)
self._notify_warning(error_msg)
raise UserError(error_msg)
if device._is_being_used():
error_msg = _("Measurement machine already in use.")
_logger.error(error_msg)
self._notify(error_msg)
return UserError(error_msg)
self._notify_warning(error_msg)
raise UserError(error_msg)

self.product_packaging_id._measuring_device_assign(device)
packaging._measuring_device_assign(device)
message = "MEASURE {}".format(packaging.packaging_type_id.display_name)
# Letting the info on the screen, so the user knows which packaging to
# needs to be measured
self._notify_info(message, sticky=True)
return True

def measure_current_packaging(self):
self.ensure_one()
return self._measure_packaging(self.product_packaging_id)

def _get_smaller_package_without_dimensions_domain(self):
self.ensure_one()
return [
("product_id", "=", self.current_move_product_id.id),
("qty", "<", self.product_packaging_id.qty),
"|",
"|",
"|",
("packaging_length", "=", 0),
("width", "=", 0),
("height", "=", 0),
("max_weight", "=", 0),
]

def _get_smaller_package_without_dimensions(self):
self.ensure_one()
domain = self._get_smaller_package_without_dimensions_domain()
return self.env["product.packaging"].search(domain, order="qty desc", limit=1)

def measure_smaller_packaging(self):
self.ensure_one()
pack_without_dimensions = self._get_smaller_package_without_dimensions()
if not pack_without_dimensions:
error_msg = _("No available packaging without measurements.")
raise UserError(error_msg)
return self._measure_packaging(pack_without_dimensions)

def cancel_measure_current_packaging(self):
self.ensure_one()
self.product_packaging_id._measuring_device_release()
return True
assigned_packaging = self.current_move_product_id.packaging_ids.filtered(
lambda p: p.measuring_device_id
)
assigned_packaging._measuring_device_release()

def _notify(self, message):
def _notify_warning(self, message):
"""Show a gentle notification on the wizard"""
self.ensure_one()
self.create_uid.with_user(self.create_uid.id).notify_warning(message=message)

def _notify_info(self, message, **kwargs):
self.ensure_one()
self.create_uid.with_user(self.create_uid.id).notify_info(
message=message, **kwargs
)

def reload(self):
self.cancel_measure_current_packaging()
return {
Expand Down
1 change: 1 addition & 0 deletions stock_reception_screen_measuring_device/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import test_reception_screen_measurement
14 changes: 14 additions & 0 deletions stock_reception_screen_measuring_device/tests/fake_components.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright 2024 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)

from odoo.addons.component.core import Component


class FakeDevice(Component):
_name = "device.component.fake"
_inherit = "measuring.device.base"
_usage = "fake"

def post_update_packaging_measures(self, measures, packaging, wizard_line):
# Unassign measuring device when measuring is done
packaging._measuring_device_release()
14 changes: 14 additions & 0 deletions stock_reception_screen_measuring_device/tests/fake_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright 2024 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)

from odoo import fields, models


class FakeMeasuringDevice(models.Model):
_inherit = "measuring.device"

device_type = fields.Selection(selection_add=[("fake", "FAKE")])

def mocked_measure(self, measurements):
self.ensure_one()
self._update_packaging_measures(measurements)
Loading

0 comments on commit 940a40d

Please sign in to comment.