Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
20cc674
[REF] shopfloor_reception_mobile: relocate date-picker-input for bett…
nicolas-delbovier-acsone Jan 28, 2026
36d804a
[REF] shopfloor_reception: better lot handling.
nicolas-delbovier-acsone Feb 3, 2026
9387a8f
[REF] shopfloor_reception: adapt test suite to "set_lot" refactoring
nicolas-delbovier-acsone Feb 3, 2026
41a9dd1
[IMP] shopfloor_reception: pass product.use_expiration_date value to …
nicolas-delbovier-acsone Feb 6, 2026
3e68d44
[REF] shopfloor_reception_mobile: buffer lot inputs in UI
nicolas-delbovier-acsone Feb 3, 2026
b24f16f
[FIX] shopfloor: decouple unit tests from product serialization
nicolas-delbovier-acsone Feb 11, 2026
f15172d
[IMP] shopfloor_reception: add scan_lot_name endpoint.
nicolas-delbovier-acsone Feb 11, 2026
15310cd
[IMP] shopfloor_reception_mobile: call "scan_lot_name" endpoint on lo…
nicolas-delbovier-acsone Feb 9, 2026
eff17da
[IMP] shopfloor_reception: extract expiration date from barcode on lo…
nicolas-delbovier-acsone Feb 12, 2026
f199ad1
[FIX] shopfloor_reception: persist lot_name on validation error
nicolas-delbovier-acsone Feb 11, 2026
1f96ac1
[IMP] shopfloor_reception: add missing unit test
nicolas-delbovier-acsone Feb 12, 2026
d7214f6
[FIX] shopfloor_reception_mobile: normalize lot expiration dates to UTC
nicolas-delbovier-acsone Feb 12, 2026
a28efe1
[IMP] shopfloor_reception_mobile: hide time from lot expiration date …
nicolas-delbovier-acsone Feb 12, 2026
7baaa99
[IMP] shopfloor_reception_mobile: add red color for past lot expirati…
nicolas-delbovier-acsone Feb 12, 2026
931e86f
[REF] shopfloor_reception_mobile: use refactored/improved date-picker…
nicolas-delbovier-acsone Apr 9, 2026
5c75d82
[FIX] shopfloor_reception: align component method naming and fix docs…
nicolas-delbovier-acsone Feb 18, 2026
27cc2cb
[IMP] shopfloor_reception: use ISO format for lot expiration date
nicolas-delbovier-acsone Feb 23, 2026
08408e5
[IMP] shopfloor_reception_mobile: use ISO format for lot expiration date
nicolas-delbovier-acsone Feb 23, 2026
cd71745
[IMP] shopfloor_reception: prevent user from changing an existing exp…
nicolas-delbovier-acsone Feb 23, 2026
cb6389d
[FIX] shopfloor_reception: fix Python 3.10 compatibility
nicolas-delbovier-acsone Feb 24, 2026
809b1fb
[FIX] shopfloor_reception: enforce lot creation restriction
nicolas-delbovier-acsone Feb 24, 2026
dfb9947
[IMP] shopfloor_reception: prioritize lot_id over lot_name for state …
nicolas-delbovier-acsone Feb 24, 2026
ffb1b95
[IMP] shopfloor_reception: resolve lot record from name for UI pre-fill
nicolas-delbovier-acsone Feb 24, 2026
2f48960
[IMP] shopfloor_reception: auto-confirm lot when data is found in scan
nicolas-delbovier-acsone Feb 24, 2026
83ceb30
[IMP] shopfloor_reception: remove dead code
nicolas-delbovier-acsone Apr 17, 2026
9f759f2
[REF] shopfloor_reception: improve code clarity of `set_lot_confirm_a…
nicolas-delbovier-acsone Apr 17, 2026
78376aa
[FIX] shopfloor_reception: make sure "set_lot" is skipped on existing…
nicolas-delbovier-acsone Apr 17, 2026
58530e1
[FIX] shopfloor_reception: fix incorrect lot_name parse when scanning…
nicolas-delbovier-acsone Apr 29, 2026
b20c3d0
[REF] shopfloor_reception: rename endpoint 'scan_lot_name' to 'scan_lot'
nicolas-delbovier-acsone May 4, 2026
f613034
[REF] shopfloor_reception_mobile: use renammed endpoint 'scan_lot_nam…
nicolas-delbovier-acsone May 4, 2026
2fabdd3
[FIX] shopfloor_reception: restore expiration date clearing on new lot
nicolas-delbovier-acsone Apr 29, 2026
f264545
Merge PR #1128 into 16.0
OCA-git-bot May 4, 2026
77fd545
[UPD] Update shopfloor_reception.pot
May 4, 2026
867eb2c
[BOT] post-merge updates
OCA-git-bot May 4, 2026
f687d7a
Update translation files
weblate May 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ addon | version | maintainers | summary
[sale_stock_release_channel_delivery_date](sale_stock_release_channel_delivery_date/) | 16.0.1.1.2 | <a href='https://github.com/jbaudoux'><img src='https://github.com/jbaudoux.png' width='32' height='32' style='border-radius:50%;' alt='jbaudoux'/></a> | Compute expected date based on available release channels
[sale_stock_release_channel_partner_by_date](sale_stock_release_channel_partner_by_date/) | 16.0.1.1.0 | <a href='https://github.com/sebalix'><img src='https://github.com/sebalix.png' width='32' height='32' style='border-radius:50%;' alt='sebalix'/></a> | Release channels integration with Sales
[sale_stock_release_channel_partner_by_date_delivery](sale_stock_release_channel_partner_by_date_delivery/) | 16.0.1.1.1 | <a href='https://github.com/sebalix'><img src='https://github.com/sebalix.png' width='32' height='32' style='border-radius:50%;' alt='sebalix'/></a> | Filters channels on sales based on selected carrier.
[shopfloor](shopfloor/) | 16.0.2.16.3 | <a href='https://github.com/guewen'><img src='https://github.com/guewen.png' width='32' height='32' style='border-radius:50%;' alt='guewen'/></a> <a href='https://github.com/simahawk'><img src='https://github.com/simahawk.png' width='32' height='32' style='border-radius:50%;' alt='simahawk'/></a> <a href='https://github.com/sebalix'><img src='https://github.com/sebalix.png' width='32' height='32' style='border-radius:50%;' alt='sebalix'/></a> | manage warehouse operations with barcode scanners
[shopfloor](shopfloor/) | 16.0.2.17.0 | <a href='https://github.com/guewen'><img src='https://github.com/guewen.png' width='32' height='32' style='border-radius:50%;' alt='guewen'/></a> <a href='https://github.com/simahawk'><img src='https://github.com/simahawk.png' width='32' height='32' style='border-radius:50%;' alt='simahawk'/></a> <a href='https://github.com/sebalix'><img src='https://github.com/sebalix.png' width='32' height='32' style='border-radius:50%;' alt='sebalix'/></a> | manage warehouse operations with barcode scanners
[shopfloor_base](shopfloor_base/) | 16.0.1.2.1 | <a href='https://github.com/guewen'><img src='https://github.com/guewen.png' width='32' height='32' style='border-radius:50%;' alt='guewen'/></a> <a href='https://github.com/simahawk'><img src='https://github.com/simahawk.png' width='32' height='32' style='border-radius:50%;' alt='simahawk'/></a> <a href='https://github.com/sebalix'><img src='https://github.com/sebalix.png' width='32' height='32' style='border-radius:50%;' alt='sebalix'/></a> | Core module for creating mobile apps
[shopfloor_batch_automatic_creation](shopfloor_batch_automatic_creation/) | 16.0.1.1.0 | <a href='https://github.com/guewen'><img src='https://github.com/guewen.png' width='32' height='32' style='border-radius:50%;' alt='guewen'/></a> | Create batch transfers for Cluster Picking
[shopfloor_mobile](shopfloor_mobile/) | 16.0.1.4.1 | <a href='https://github.com/simahawk'><img src='https://github.com/simahawk.png' width='32' height='32' style='border-radius:50%;' alt='simahawk'/></a> | Mobile frontend for WMS Shopfloor app
[shopfloor_mobile_base](shopfloor_mobile_base/) | 16.0.1.2.0 | <a href='https://github.com/simahawk'><img src='https://github.com/simahawk.png' width='32' height='32' style='border-radius:50%;' alt='simahawk'/></a> | Mobile frontend for WMS Shopfloor app
[shopfloor_mobile_base_auth_api_key](shopfloor_mobile_base_auth_api_key/) | 16.0.1.0.0 | | Provides authentication via API key to Shopfloor base mobile app
[shopfloor_reception](shopfloor_reception/) | 16.0.1.6.8 | <a href='https://github.com/mmequignon'><img src='https://github.com/mmequignon.png' width='32' height='32' style='border-radius:50%;' alt='mmequignon'/></a> <a href='https://github.com/JuMiSanAr'><img src='https://github.com/JuMiSanAr.png' width='32' height='32' style='border-radius:50%;' alt='JuMiSanAr'/></a> | Reception scenario for shopfloor
[shopfloor_reception_mobile](shopfloor_reception_mobile/) | 16.0.1.1.3 | <a href='https://github.com/JuMiSanAr'><img src='https://github.com/JuMiSanAr.png' width='32' height='32' style='border-radius:50%;' alt='JuMiSanAr'/></a> | Scenario for receiving products
[shopfloor_reception](shopfloor_reception/) | 16.0.1.7.0 | <a href='https://github.com/mmequignon'><img src='https://github.com/mmequignon.png' width='32' height='32' style='border-radius:50%;' alt='mmequignon'/></a> <a href='https://github.com/JuMiSanAr'><img src='https://github.com/JuMiSanAr.png' width='32' height='32' style='border-radius:50%;' alt='JuMiSanAr'/></a> | Reception scenario for shopfloor
[shopfloor_reception_mobile](shopfloor_reception_mobile/) | 16.0.1.2.0 | <a href='https://github.com/JuMiSanAr'><img src='https://github.com/JuMiSanAr.png' width='32' height='32' style='border-radius:50%;' alt='JuMiSanAr'/></a> | Scenario for receiving products
[shopfloor_reception_packaging_dimension](shopfloor_reception_packaging_dimension/) | 16.0.1.0.0 | <a href='https://github.com/TDu'><img src='https://github.com/TDu.png' width='32' height='32' style='border-radius:50%;' alt='TDu'/></a> | Collect Packaging Dimension from the Reception scenario
[shopfloor_reception_packaging_dimension_mobile](shopfloor_reception_packaging_dimension_mobile/) | 16.0.1.0.0 | <a href='https://github.com/TDu'><img src='https://github.com/TDu.png' width='32' height='32' style='border-radius:50%;' alt='TDu'/></a> | Frontend for the packaging dimension on reception scenario
[shopfloor_reception_refund_return](shopfloor_reception_refund_return/) | 16.0.1.0.0 | <a href='https://github.com/mmequignon'><img src='https://github.com/mmequignon.png' width='32' height='32' style='border-radius:50%;' alt='mmequignon'/></a> | Mark created return as to refund
Expand Down
2 changes: 1 addition & 1 deletion shopfloor/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Shopfloor
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:22f8e5b0353c5637d5aea9d6f6ae884fd29d5d25e456451b5d76e0926b14b45c
!! source digest: sha256:c15d6753dddf755436a53b85c4d516370700a548b898688c65362447fac692a6
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
Expand Down
2 changes: 1 addition & 1 deletion shopfloor/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
{
"name": "Shopfloor",
"summary": "manage warehouse operations with barcode scanners",
"version": "16.0.2.16.3",
"version": "16.0.2.17.0",
"development_status": "Beta",
"category": "Inventory",
"website": "https://github.com/OCA/wms",
Expand Down
2 changes: 1 addition & 1 deletion shopfloor/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ <h1>Shopfloor</h1>
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:22f8e5b0353c5637d5aea9d6f6ae884fd29d5d25e456451b5d76e0926b14b45c
!! source digest: sha256:c15d6753dddf755436a53b85c4d516370700a548b898688c65362447fac692a6
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<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/license-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/wms/tree/16.0/shopfloor"><img alt="OCA/wms" src="https://img.shields.io/badge/github-OCA%2Fwms-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-shopfloor"><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/wms&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>Shopfloor is a barcode scanner application for internal warehouse operations.</p>
Expand Down
18 changes: 1 addition & 17 deletions shopfloor/tests/test_actions_data_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,23 +120,7 @@ def _expected_location(self, record, **kw):
return data

def _expected_product(self, record, **kw):
data = {
"id": record.id,
"name": record.name,
"display_name": record.display_name,
"default_code": record.default_code,
"barcode": record.barcode,
"packaging": [
self._expected_packaging(x) for x in record.packaging_ids if x.qty
],
"uom": {
"factor": record.uom_id.factor,
"id": record.uom_id.id,
"name": record.uom_id.name,
"rounding": record.uom_id.rounding,
},
"supplier_code": self._expected_supplier_code(record),
}
data = self.data._jsonify(record, self.data._product_parser)
data.update(kw)
return data

Expand Down
2 changes: 1 addition & 1 deletion shopfloor_reception/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Shopfloor Reception
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:4a5cae1dea64b85f2f987a26658f70b634462808055727f8e4475218e37783a8
!! source digest: sha256:cfdee049f8d54795db4bbfe84208e158c79747d001200a55167286239b20231b
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
Expand Down
2 changes: 1 addition & 1 deletion shopfloor_reception/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
from . import services, models
from . import services, models, actions
from .hooks import post_init_hook, uninstall_hook
2 changes: 1 addition & 1 deletion shopfloor_reception/__manifest__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "Shopfloor Reception",
"summary": "Reception scenario for shopfloor",
"version": "16.0.1.6.8",
"version": "16.0.1.7.0",
"development_status": "Beta",
"category": "Inventory",
"website": "https://github.com/OCA/wms",
Expand Down
3 changes: 3 additions & 0 deletions shopfloor_reception/actions/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from . import data
from . import schema
from . import message
56 changes: 56 additions & 0 deletions shopfloor_reception/actions/data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Copyright 2026 ACSONE SA/NV
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo.addons.component.core import Component
from odoo.addons.shopfloor_base.utils import ensure_model


class DataAction(Component):
_inherit = "shopfloor.data.action"

@property
def _product_parser(self):
"""
The jsonifier engine passes (record, field_name) when calling
parser functions. We use *args to capture them.
"""
res = super(DataAction, self)._product_parser
return res + ["use_expiration_date"]

@property
def _lot_parser_reception(self):
return self._simple_record_parser() + [
"ref",
(
"expiration_date",
lambda rec, fname:
# Odoo Datetime fields are stored as naive UTC in the DB.
rec.expiration_date.isoformat() + "+00:00"
if rec.expiration_date
else None,
),
]

@ensure_model("stock.move.line")
def move_line(self, record, with_picking=False, **kw):
data = super().move_line(record, with_picking, **kw)

lot_data = {}
if lot := kw.get("lot"):
lot_data = self._jsonify(lot, self._lot_parser_reception)
# add expiration_date from scan if not defined on existing lot
if not lot_data.get("expiration_date") and (
lot_expiration_date := kw.get("lot_expiration_date")
):
lot_data["expiration_date"] = lot_expiration_date.isoformat()
else:
if lot_name := kw.get("lot_name"):
lot_data["name"] = lot_name
if lot_expiration_date := kw.get("lot_expiration_date"):
lot_data["expiration_date"] = lot_expiration_date.isoformat()

if lot_data:
data["lot"] = data.get("lot") or {}
data["lot"].update(lot_data)

return data
41 changes: 41 additions & 0 deletions shopfloor_reception/actions/message.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Copyright 2025 ACSONE SA/NV (https://www.acsone.eu)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import logging

from odoo import _

from odoo.addons.component.core import Component

_logger = logging.getLogger(__name__)


class MessageAction(Component):
_inherit = "shopfloor.message.action"

def lot_already_exists_different_expiration_date(self, lot, expiration_date):
formatted_lot_expiration_date = self.work.env[
"ir.qweb.field.date"
].value_to_html(lot.expiration_date, {})
formatted_provided_expiration_date = self.work.env[
"ir.qweb.field.date"
].value_to_html(expiration_date, {})
return {
"message_type": "warning",
"body": _(
"This lot already exists with a different expiration date.\n\n"
"Lot: '%(lot_name)s'\nStored expiration date: %(current)s"
"\nProvided expiration date: %(provided)s",
lot_name=lot.name,
current=formatted_lot_expiration_date,
provided=formatted_provided_expiration_date,
),
}

def lot_creation_disabled(self, picking_type):
return {
"message_type": "error",
"body": _(
"The operation type '%(picking_type)s' does not allow to create new lots.",
picking_type=picking_type.display_name,
),
}
32 changes: 32 additions & 0 deletions shopfloor_reception/actions/schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Copyright 2026 ACSONE SA/NV
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo.addons.component.core import Component


class ShopfloorSchemaAction(Component):
_inherit = "shopfloor.schema.action"

def product(self):
res = super().product()
res.update(
{
"use_expiration_date": {
"type": "boolean",
"nullable": True,
"required": False,
},
}
)
return res

def lot(self):
res = super().lot()

# We need to be able to send lot name and expiration date info
# for "virtual lot" not yet created -> not yet an id
res.update(
{
"id": {"required": False, "type": "integer"},
}
)
return res
20 changes: 20 additions & 0 deletions shopfloor_reception/i18n/it.po
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,26 @@ msgstr "Movimenti prodotto (riga movimento di magazzino)"
msgid "Reception"
msgstr "Ricezione"

#. module: shopfloor_reception
#. odoo-python
#: code:addons/shopfloor_reception/actions/message.py:0
#, python-format
msgid ""
"The operation type '%(picking_type)s' does not allow to create new lots."
msgstr ""

#. module: shopfloor_reception
#. odoo-python
#: code:addons/shopfloor_reception/actions/message.py:0
#, python-format
msgid ""
"This lot already exists with a different expiration date.\n"
"\n"
"Lot: '%(lot_name)s'\n"
"Stored expiration date: %(current)s\n"
"Provided expiration date: %(provided)s"
msgstr ""

#~ msgid "Is Shopfloor Created"
#~ msgstr "Il reparto è crato"

Expand Down
20 changes: 20 additions & 0 deletions shopfloor_reception/i18n/shopfloor_reception.pot
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,23 @@ msgstr ""
#: model:stock.picking.type,name:shopfloor_reception.picking_type_reception_demo
msgid "Reception"
msgstr ""

#. module: shopfloor_reception
#. odoo-python
#: code:addons/shopfloor_reception/actions/message.py:0
#, python-format
msgid ""
"The operation type '%(picking_type)s' does not allow to create new lots."
msgstr ""

#. module: shopfloor_reception
#. odoo-python
#: code:addons/shopfloor_reception/actions/message.py:0
#, python-format
msgid ""
"This lot already exists with a different expiration date.\n"
"\n"
"Lot: '%(lot_name)s'\n"
"Stored expiration date: %(current)s\n"
"Provided expiration date: %(provided)s"
msgstr ""
Loading
Loading