Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
e4a481f
Add module product_logistics_uom
hparfr Apr 28, 2020
997cfa8
Added translation using Weblate (Spanish)
claudiagn Oct 13, 2020
7b1c299
Translated using Weblate (Spanish)
claudiagn Oct 13, 2020
f82f84c
[IMP] product_logistics_uom: black, isort, prettier
hparfr Jan 11, 2021
c8d7195
[MIG] product_logistics_uom: Migration to 14.0
hparfr Jan 11, 2021
d8243cf
[MIG] product_logistics_uom: 15.0
flachica Sep 29, 2022
3431494
[MIG] product_logistics_uom: Migration to 16.0
marielejeune Oct 7, 2022
5f2643c
Added translation using Weblate (German)
marylla Nov 4, 2022
53c20e5
Translated using Weblate (German)
marylla Nov 4, 2022
eef8f7a
Added translation using Weblate (Italian)
PicchiSeba Apr 27, 2023
f615481
Translated using Weblate (Italian)
PicchiSeba Apr 27, 2023
e715cc9
Translated using Weblate (Italian)
mymage May 9, 2023
cb0f667
[FIX] product_logistics_uom: Store value in system UOM
lmignon Mar 31, 2023
e4145db
Translated using Weblate (Spanish)
Ivorra78 Aug 22, 2023
022ed0e
Added translation using Weblate (Portuguese (Brazil))
adrianojprado Oct 4, 2023
2e791de
Translated using Weblate (Italian)
mymage Oct 29, 2023
a17d86c
Translated using Weblate (Italian)
mymage Nov 1, 2023
af3026a
[IMP] product_logistics_uom: pre-commit auto fixes
bizzappdev May 6, 2024
7ce7230
[MIG] product_logistics_uom: Migration to 17.0
bizzappdev May 6, 2024
e9938e7
Translated using Weblate (Italian)
mymage Jul 22, 2024
dac522a
[IMP] product_logistics_uom: pre-commit auto fixes
LucasTran380381 Oct 23, 2024
9ae094d
[MIG] partner_logistics_uom: Migration to 18.0
LucasTran380381 Oct 23, 2024
d6f7ef1
[UPD] Update product_logistics_uom.pot
Dec 20, 2024
b8d581b
[BOT] post-merge updates
OCA-git-bot Dec 20, 2024
31bdfad
Update translation files
weblate Dec 20, 2024
32e42b2
[UPD] Update product_logistics_uom.pot
Dec 28, 2024
7438903
Update translation files
weblate Dec 28, 2024
c5ab13b
Translated using Weblate (Italian)
mymage Dec 28, 2024
581027b
[FIX] volume_uom_id is ambiguous
rdualsam Mar 11, 2025
5c13ba5
[BOT] post-merge updates
OCA-git-bot Mar 12, 2025
a5d0611
[19.0][MIG] product_logistics_uom
eugenios73 Oct 24, 2025
172a04b
[DON'T MERGE] test-requirements.txt
eugenios73 Nov 6, 2025
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
158 changes: 158 additions & 0 deletions product_logistics_uom/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
.. image:: https://odoo-community.org/readme-banner-image
:target: https://odoo-community.org/get-involved?utm_source=readme
:alt: Odoo Community Association

=====================
Product logistics UoM
=====================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:326d9bbcf8543523257fb6237f3387b9f67e4e3c781935665691ac2055f58ab2
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fproduct--attribute-lightgray.png?logo=github
:target: https://github.com/OCA/product-attribute/tree/19.0/product_logistics_uom
:alt: OCA/product-attribute
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/product-attribute-19-0/product-attribute-19-0-product_logistics_uom
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/product-attribute&target_branch=19.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This module allows to choose an Unit Of Measure (UoM) for products
weight and volume. It can be set product per product for users in
group_uom.

Without this module, you only have the choice between Kg or Lb(s) and m³
for all the products.

For some business cases, you need to express in more precise UoM than
default ones like Liters instead of M³.

Even if you choose another UoM for the weight or volume, the system will
still store the value for these fields in the Odoo default UoM (Kg or
Lb(s) and m³). This ensures that the arithmetic operations on these
fields are correct and consistent with the rest of the addons.

Once this addon is installed values stored into the initial Volume and
Weight fields on the product and product template models are no more
rounded to the decimal precision defined for these fields. This could
lead to some side effects into reportss where these fields are used. You
can replace the fields by the new ones provided by this addon to avoid
this problem (product_volume and product_weight). In any cases, since
you use different UoM by product, you should most probably modify your
reportss to display the right UoM.

**Table of contents**

.. contents::
:local:

Installation
============

Be aware, that this module only change the UoM but not the value.

It's the same behavior as base Odoo when you change from Metric System
to Imperial System.

Configuration
=============

To change the default UoM

1. Go "General Settings", then in "Products"
2. you have to select a default unit of measure for weights and volumes.

To change on a specific product

1. Go the product form you can change the UoM directly.

Usage
=====

Once installed and the 'Sell and purchase products in different units of
measure' option is enabled, the 'Unit of Measure' field will become
updatable on the 'Product' form for users with the permission 'Manage
Multiple Units of Measure'.

If the displayed value is 0.00 and a warning icon is displayed in front
of the unit of measure, it means that the value is too small to be
displayed in the current unit of measure. You should change the unit of
measure to a larger one to see the value.

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/product-attribute/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/product-attribute/issues/new?body=module:%20product_logistics_uom%0Aversion:%2019.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
-------

* Akretion
* ACSONE SA/NV

Contributors
------------

- Raphaël Reverdy <raphael.reverdy@akretion.com>
- Fernando La Chica <fernandolachica@gmail.com>
- Laurent Mignon <laurent.mignon@acsone.eu>
- Nhan Tran <nhant@trobz.com>
- `Studio73 <https://www.studio73.es/>`__:

- Eugenio Micó <eugenio@studio73.es>

Other credits
-------------

The development of this module has been financially supported by:

- Akretion <https://akretion.com>
- La Base <https://labase.coop>

Maintainers
-----------

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

.. |maintainer-hparfr| image:: https://github.com/hparfr.png?size=40px
:target: https://github.com/hparfr
:alt: hparfr

Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:

|maintainer-hparfr|

This module is part of the `OCA/product-attribute <https://github.com/OCA/product-attribute/tree/19.0/product_logistics_uom>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
2 changes: 2 additions & 0 deletions product_logistics_uom/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import models
from .hooks import pre_init_hook
22 changes: 22 additions & 0 deletions product_logistics_uom/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright 2020 Akretion (https://www.akretion.com).
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
{
"name": "Product logistics UoM",
"summary": "Configure product weights and volume UoM",
"version": "19.0.1.0.0",
"development_status": "Beta",
"category": "Product",
"website": "https://github.com/OCA/product-attribute",
"author": " Akretion, ACSONE SA/NV, Odoo Community Association (OCA)",
"maintainers": ["hparfr"],
"license": "AGPL-3",
"installable": True,
"depends": [
"product",
],
"data": [
"views/res_config_settings.xml",
"views/product.xml",
],
"pre_init_hook": "pre_init_hook",
}
133 changes: 133 additions & 0 deletions product_logistics_uom/hooks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# Copyright 2023 ACSONE SA
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)

import logging

from odoo.tools import SQL, sql

_logger = logging.getLogger(__name__)


def pre_init_hook(env): # pragma: nocover
"""Recompute the volume and weight column on product and template
by converting the value from the uom defined on the product to the default uom
"""
if sql.column_exists(env.cr, "product_template", "volume_uom_id"):
_logger.info("Recompute volume on product.product")
# get default m3 uom
env.cr.execute(
SQL("""
SELECT res_id
FROM ir_model_data
WHERE module = 'uom' AND name = 'product_uom_cubic_meter'
""")
)
m3_uom_id = env.cr.fetchone()[0]
# get uom factor
env.cr.execute(
SQL(
"""
SELECT factor
FROM uom_uom
WHERE id = %s
""",
m3_uom_id,
)
)
m3_uom_factor = env.cr.fetchone()[0]
# update volume where volume_uom_id is not null and not m3
env.cr.execute(
SQL(
"""
UPDATE product_product
SET volume = product_product.volume / product_uom.factor * %s
FROM uom_uom product_uom,
product_template pt
WHERE product_uom.id = pt.volume_uom_id
AND pt.id = product_product.product_tmpl_id
AND pt.volume_uom_id IS NOT NULL AND pt.volume_uom_id != %s
""",
m3_uom_factor,
m3_uom_id,
)
)
_logger.info(f"{env.cr.rowcount} product_product rows updated")
# update product_template with 1 product_product
env.cr.execute(
SQL(
"""
UPDATE product_template
SET Volume = unique_product.volume
FROM (
SELECT product_tmpl_id, volume
FROM product_product
WHERE volume is not null
GROUP BY product_tmpl_id, volume
HAVING COUNT(*) = 1
) unique_product
WHERE product_template.id = unique_product.product_tmpl_id
AND product_template.volume_uom_id != %s
""",
m3_uom_id,
)
)
_logger.info(f"{env.cr.rowcount} product_template rows updated")
if sql.column_exists(env.cr, "product_template", "weight_uom_id"):
_logger.info("Recompute weight on product.product")
# get default kg uom
env.cr.execute(
SQL("""
SELECT res_id
FROM ir_model_data
WHERE module = 'uom' AND name = 'product_uom_kgm'
""")
)
kg_uom_id = env.cr.fetchone()[0]
# get uom factor
env.cr.execute(
SQL(
"""
SELECT factor
FROM uom_uom
WHERE id = %s
""",
kg_uom_id,
)
)
kg_uom_factor = env.cr.fetchone()[0]
# update weight where weight_uom_id is not null and not kg
env.cr.execute(
SQL(
"""
UPDATE product_product
SET weight = product_product.weight / product_uom.factor * %s
FROM uom_uom product_uom, product_template pt
WHERE product_uom.id = pt.weight_uom_id
AND pt.id = product_product.product_tmpl_id
AND pt.weight_uom_id IS NOT NULL AND pt.weight_uom_id != %s
""",
kg_uom_factor,
kg_uom_id,
)
)
_logger.info(f"{env.cr.rowcount} product_product rows updated")
# update product_template with 1 product_product
env.cr.execute(
SQL(
"""
UPDATE product_template
SET weight = unique_product.weight
FROM (
SELECT product_tmpl_id, weight
FROM product_product
WHERE volume is not null
GROUP BY product_tmpl_id, weight
HAVING COUNT(*) = 1
) unique_product
WHERE product_template.id = unique_product.product_tmpl_id
AND product_template.weight_uom_id != %s
""",
kg_uom_id,
)
)
_logger.info(f"{env.cr.rowcount} product_template rows updated")
Loading
Loading