Skip to content

Commit

Permalink
[MIG] sale_order_weight: Migration to 16.0 (from 12.0)
Browse files Browse the repository at this point in the history
[FIX] change weight on product now change automatically the weight of the sale orders.
So it is not necessary to 'recompute' the weight of the orders, and the value is always correct.
(Also the column 'Unit Weight' is removed at sale.order.line level)

[FIX] Now handle correctly conversion. Use Case :
- product.product (weight : 50kg ; Uom : Unit)
- sale.order.line (Qty : 10 ; UoM : dozen)
-> Before, the weight was 50 * 10 = 500 and was wrong.
-> Now the weight is 50 * 10 * 12 = 6000

[ADD] migration script to recompute correctly values that can be incorrect and obsolete (due to conversion errors)

[IMP] Display weight on sale order report.
Note: this code comes from the other OCA modules name sale_order_weight,
present in the OCA repo sale-reporting, in V14:
See: https://github.com/OCA/sale-reporting/tree/14.0/sale_order_weight

[IMP] add configuration to display the weight or not on the sale order report.
(configuration for the total order, and the order on each lines)

[REM] remove 'delivered' weight for the following reasons:
- The delivered quantity on sale order lines is a non stored field.
  So, the recompute of the field fails, and the field total_delivered_weight is not updated correctly.
- It is legit to want to have only Ordered weight and not Delivered Weight, and the addition of the delivered weight
  make the database bigger, and the process slower.
Better to create a dedicated module for delivered weight
  • Loading branch information
legalsylvain committed Nov 19, 2024
1 parent ee705d1 commit 09b050c
Show file tree
Hide file tree
Showing 20 changed files with 320 additions and 133 deletions.
29 changes: 28 additions & 1 deletion sale_order_weight/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,38 @@ Sale Order Weight

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

This module is used to calculate the weight in a sale order.
This module is used to calculate the weight (Ordered Products) in a sale order.

The weight can be displayed on the sale order report.


**Table of contents**

.. contents::
:local:

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

* Go to "Sales > Configuration > Settings"

.. figure:: https://raw.githubusercontent.com/OCA/sale-workflow/16.0/sale_order_weight/static/description/configuration.png

Display Order weight is checked by default.

The weight display at line level is hidden by default, to avoid burdening the PDF report.

Usage
=====

* Go to a sale order.

* the ordered weights are displayed on each order lines and at order level.

.. figure:: https://raw.githubusercontent.com/OCA/sale-workflow/16.0/sale_order_weight/static/description/sale_order_form.png

Note: The weight are also available on the order tree view. (hidden by default)

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

Expand All @@ -51,12 +76,14 @@ Credits
Authors
~~~~~~~

* GRAP
* Xtendoo

Contributors
~~~~~~~~~~~~

* Manuel Calero - https://xtendoo.es <[email protected]>
* Sylvain LE GAL

Maintainers
~~~~~~~~~~~
Expand Down
15 changes: 7 additions & 8 deletions sale_order_weight/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,19 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "Sale Order Weight",
"version": "12.0.1.1.0",
"category": "Accounting & Finance",
"author": "Xtendoo, Odoo Community Association (OCA)",
"summary": "Add Ordered weights on sale order and sale order line levels",
"version": "16.0.1.0.0",
"category": "Sales",
"author": "GRAP, Xtendoo, Odoo Community Association (OCA)",
"maintainers": ["legalsylvain"],
"website": "https://github.com/OCA/sale-workflow",
"license": "AGPL-3",
"summary": "Sale Order Weight",
"installable": True,
"depends": [
"sale",
"sale_stock",
],
"depends": ["sale"],
"data": [
"views/sale_order_view.xml",
"views/res_config_settings_view.xml",
"reports/report_sale_order.xml",
],
"pre_init_hook": "pre_init_hook",
}
17 changes: 17 additions & 0 deletions sale_order_weight/migrations/16.0.1.0.0/pre-migration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright (C) 2024 - Today: GRAP (http://www.grap.coop)
# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from openupgradelib import openupgrade

# pylint: disable=W8150
from odoo.addons.sale_order_weight import pre_init_hook


@openupgrade.migrate()
def migrate(env, version):
# we recompute the weights because in previous implementation,
# 1) the UoM conversion was not done, so the value could be incorrect
# 2) the recompute was not done when the weight of the product has changed
# so the value could be obsolete.
pre_init_hook(env.cr)
5 changes: 2 additions & 3 deletions sale_order_weight/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# Copyright 2021 Manuel Calero Solís (https://xtendoo.es)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from . import res_company
from . import res_config_settings
from . import sale_order
from . import sale_order_line
11 changes: 11 additions & 0 deletions sale_order_weight/models/res_company.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html)

from odoo import fields, models


class ResCompany(models.Model):
_inherit = "res.company"

display_line_weight_on_sale_report = fields.Boolean(default=False)

display_order_weight_on_sale_report = fields.Boolean(default=True)
13 changes: 13 additions & 0 deletions sale_order_weight/models/res_config_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html)
from odoo import fields, models


class ResConfigSettings(models.TransientModel):
_inherit = "res.config.settings"

display_line_weight_on_sale_report = fields.Boolean(
related="company_id.display_line_weight_on_sale_report", readonly=False
)
display_order_weight_on_sale_report = fields.Boolean(
related="company_id.display_order_weight_on_sale_report", readonly=False
)
18 changes: 1 addition & 17 deletions sale_order_weight/models/sale_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,7 @@ class SaleOrder(models.Model):

total_ordered_weight = fields.Float(
compute="_compute_total_ordered_weight",
string="Total Ordered Weight",
store=True,
)
total_delivered_weight = fields.Float(
compute="_compute_total_delivered_weight",
string="Total Delivered Weight",
string="Ordered Weight",
store=True,
)

Expand All @@ -24,14 +19,3 @@ def _compute_total_ordered_weight(self):
order.total_ordered_weight = sum(
order.mapped("order_line.total_ordered_weight")
)

@api.depends("order_line.total_delivered_weight")
def _compute_total_delivered_weight(self):
for order in self:
order.total_delivered_weight = sum(
order.mapped("order_line.total_delivered_weight")
)

@api.multi
def recalculate_weight(self):
self.mapped("order_line")._onchange_weight()
36 changes: 11 additions & 25 deletions sale_order_weight/models/sale_order_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,24 @@

from odoo import api, fields, models

from odoo.addons import decimal_precision as dp


class SaleOrderLine(models.Model):
_inherit = "sale.order.line"

unit_weight = fields.Float(
string="Unit Weight",
digits=dp.get_precision("Stock Weight"),
)
total_ordered_weight = fields.Float(
compute="_compute_total_ordered_weight",
string="Total Ordered Weight",
store=True,
)
total_delivered_weight = fields.Float(
compute="_compute_total_delivered_weight",
string="Total Delivered Weight",
string="Ordered Weight",
store=True,
)

@api.onchange("product_id")
def _onchange_weight(self):
for line in self:
line.unit_weight = line.product_id.weight

@api.depends("unit_weight", "product_uom_qty")
@api.depends(
"product_id.weight", "product_id.uom_id", "product_uom", "product_uom_qty"
)
def _compute_total_ordered_weight(self):
for line in self:
line.total_ordered_weight = line.unit_weight * line.product_uom_qty

@api.depends("unit_weight", "qty_delivered")
def _compute_total_delivered_weight(self):
for line in self:
line.total_delivered_weight = line.unit_weight * line.qty_delivered
for line in self.filtered(lambda x: x.product_id):
line.total_ordered_weight = line.product_uom._compute_quantity(
line.product_id.weight * line.product_uom_qty,
line.product_id.uom_id,
round=False,
raise_if_failure=False,
)
33 changes: 24 additions & 9 deletions sale_order_weight/pre_init_hook.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,46 @@

def pre_init_hook(cr):
_logger.info(
"sale.order.line: Create 'weight', 'total_ordered_weight' and"
"sale.order.line: Create 'total_ordered_weight' and"
" 'total_delivered_weight' to be fast initialized."
)
cr.execute(
"""
ALTER TABLE sale_order_line
ADD COLUMN IF NOT EXISTS unit_weight NUMERIC,
ADD COLUMN IF NOT EXISTS total_ordered_weight DOUBLE PRECISION,
ADD COLUMN IF NOT EXISTS total_delivered_weight DOUBLE PRECISION;
"""
)
_logger.info(
"sale.order.line model :"
" Initialize 'unit weight';"
" precompute 'total_ordered_weight' and 'total_delivered_weight'"
)
cr.execute(
"""
UPDATE sale_order_line
SET unit_weight = product_product.weight,
total_ordered_weight = product_product.weight * product_uom_qty,
total_delivered_weight = product_product.weight * qty_delivered
FROM product_product
WHERE product_product.id = sale_order_line.product_id
AND product_product.weight != 0;
SET
total_ordered_weight = (
product.weight
* sale_order_line.product_uom_qty
/ line_uom.factor
* template_uom.factor
),
total_delivered_weight = (
product.weight
* sale_order_line.qty_delivered
/ line_uom.factor
* template_uom.factor
)
FROM
product_product product,
product_template template,
uom_uom as template_uom,
uom_uom as line_uom
WHERE product.id = sale_order_line.product_id
AND template.id = product.product_tmpl_id
AND template.uom_id = template_uom.id
AND sale_order_line.product_uom = line_uom.id
AND product.weight != 0;
"""
)

Expand Down
7 changes: 7 additions & 0 deletions sale_order_weight/readme/CONFIGURE.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
* Go to "Sales > Configuration > Settings"

.. figure:: ../static/description/configuration.png

Display Order weight is checked by default.

The weight display at line level is hidden by default, to avoid burdening the PDF report.
1 change: 1 addition & 0 deletions sale_order_weight/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
* Manuel Calero - https://xtendoo.es <[email protected]>
* Sylvain LE GAL
5 changes: 4 additions & 1 deletion sale_order_weight/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
This module is used to calculate the weight in a sale order.
This module is used to calculate the weight (Ordered Products) in a sale order.

The weight can be displayed on the sale order report.

7 changes: 7 additions & 0 deletions sale_order_weight/readme/USAGE.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
* Go to a sale order.

* the ordered weights are displayed on each order lines and at order level.

.. figure:: ../static/description/sale_order_form.png

Note: The weight are also available on the order tree view. (hidden by default)
78 changes: 78 additions & 0 deletions sale_order_weight/reports/report_sale_order.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
Copyright 2016 Andrea Cometa - Apulia Software
License AGPL-3.0 or later (http://www.gnu.org/licenses/gpl.html).
-->
<odoo>

<template
id="report_saleorder_document"
inherit_id="sale.report_saleorder_document"
>

<xpath expr="//t[@t-set='address']" position="after">
<t
t-set="weight_uom_name"
t-value="doc.env['product.template']._get_weight_uom_name_from_ir_config_parameter()"
/>
<t
t-set="weight_precision"
t-value="(doc.env['product.template']._fields['weight'].get_digits(doc.env) or (None, None))[1]"
/>
<t
t-set="display_line_weight_on_sale_report"
t-value="doc.company_id.display_line_weight_on_sale_report"
/>
<t
t-set="display_order_weight_on_sale_report"
t-value="doc.company_id.display_order_weight_on_sale_report"
/>
</xpath>


<xpath
expr="//table[hasclass('o_main_table')]/thead/tr/th[@name='th_priceunit']"
position="after"
>
<t t-if="display_line_weight_on_sale_report">
<th class="text-right">Weight</th>
</t>
</xpath>

<xpath
expr="//table[hasclass('o_main_table')]/tbody//tr//td[@name='td_priceunit']"
position="after"
>
<t t-if="display_line_weight_on_sale_report">
<td class="text-right">
<t t-set="line_weight" t-value="line.total_ordered_weight" />
<t t-if="line_weight">
<span
t-esc="line_weight"
t-options="{'widget': 'float', 'precision': weight_precision}"
/>
<span t-esc="weight_uom_name" />
</t>
</td>
</t>
</xpath>

<xpath expr="//t[@t-call='account.document_tax_totals']" position="after">
<t t-if="display_order_weight_on_sale_report">
<tr class="border-black o_total">
<td><strong>Total Weight</strong></td>
<td class="text-end">
<t t-set="order_weight" t-value="doc.total_ordered_weight" />
<span
t-esc="order_weight"
t-options="{'widget': 'float', 'precision': weight_precision}"
/>
<span t-esc="weight_uom_name" />
</td>
</tr>
</t>
</xpath>

</template>

</odoo>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 09b050c

Please sign in to comment.