Skip to content

Commit

Permalink
[MIG] sale_stock_line_customer_ref: Migration to 18.0
Browse files Browse the repository at this point in the history
  • Loading branch information
xaviedoanhduy committed Jan 2, 2025
1 parent df5ef09 commit 85dcb73
Show file tree
Hide file tree
Showing 18 changed files with 92 additions and 71 deletions.
17 changes: 17 additions & 0 deletions sale_stock_line_customer_ref/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,16 @@ Usage
By default the customer reference field is not displayed on the sale
order form, you have to enable it in the list of optional fields.

We want the customer ref on the package because the label should be
printed from there (like all other kind of existing labels). As we can't
get the right stock.move.line/stock.move easily from the package it is
easier to store the Customer Ref. of the move/move_line on the package
when this one is assigned to the move line. Also, a (destination)
package could contain different products (so different moves), and these
moves could have different Customer Ref., all of them will be concatened
in the package => ",
".join(customer_ref_of_all_moves_link_to_this_package)

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

Expand All @@ -66,6 +76,13 @@ Contributors

- Sébastien Alix <[email protected]>
- Simone Orsi <[email protected]>
- Do Anh Duy <[email protected]>

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

The migration of this module from 14.0 to 18.0 was financially supported
by Camptocamp.

Maintainers
-----------
Expand Down
2 changes: 1 addition & 1 deletion sale_stock_line_customer_ref/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"Allow you to add a customer reference on order lines "
"propagaged to move operations."
),
"version": "14.0.1.0.0",
"version": "18.0.1.0.0",
"author": "Camptocamp, Odoo Community Association (OCA)",
"maintainers": ["sebalix"],
"website": "https://github.com/OCA/sale-workflow",
Expand Down
8 changes: 4 additions & 4 deletions sale_stock_line_customer_ref/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,32 @@

import logging

from odoo import fields
from odoo.tools import sql

logger = logging.getLogger(__name__)


def pre_init_hook(cr):
def pre_init_hook(env):
"""Create table columns for computed fields to not get them computed by Odoo.
This is done to avoid MemoryError when installing the module on big databases.
Also it is useless to compute these fields which should be empty when installing
the module because no SO lines have a customer reference set.
"""
# Create columns
cr = env.cr
if not sql.column_exists(cr, "stock_move", "customer_ref_sale_line_id"):
sql.create_column(
cr,
"stock_move",
"customer_ref_sale_line_id",
fields.Many2one.column_type[1],
"int4",
comment="Sale Line With Customer Ref",
)
if not sql.column_exists(cr, "stock_move", "customer_ref"):
sql.create_column(
cr,
"stock_move",
"customer_ref",
sql.pg_varchar(),
"VARCHAR",
)
9 changes: 2 additions & 7 deletions sale_stock_line_customer_ref/models/stock_move.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ def _get_customer_ref_sale_line(self):
self.ensure_one()
if self.sale_line_id.customer_ref:
return self.sale_line_id
if not self.move_dest_ids:
return self.sale_line_id.browse()

Check warning on line 36 in sale_stock_line_customer_ref/models/stock_move.py

View check run for this annotation

Codecov / codecov/patch

sale_stock_line_customer_ref/models/stock_move.py#L36

Added line #L36 was not covered by tests
# Search in the destination moves recursively until we find a SO line
moves_dest = self.move_dest_ids
move_seen_ids = set(moves_dest.ids)
Expand All @@ -58,10 +60,3 @@ def _prepare_merge_moves_distinct_fields(self):
# pick+pack based on the customer reference.
distinct_fields.append("customer_ref")
return distinct_fields

@api.model
def _prepare_merge_move_sort_method(self, move):
move.ensure_one()
keys_sorted = super()._prepare_merge_move_sort_method(move)
keys_sorted.append(move.customer_ref)
return keys_sorted
5 changes: 3 additions & 2 deletions sale_stock_line_customer_ref/models/stock_move_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
class StockMoveLine(models.Model):
_inherit = "stock.move.line"

customer_ref = fields.Char(related="move_id.customer_ref", readonly=True)
customer_ref = fields.Char(related="move_id.customer_ref")

def write(self, vals):
# Overridden to update related result packages
Expand All @@ -20,7 +20,8 @@ def write(self, vals):
@contextmanager
def update_related_packages(self, vals):
"""Keep packages in sync."""
# FIXME: is not granted that all the lines involved by the pkg will be updated here.
# FIXME: is not granted that all the lines involved
# by the pkg will be updated here.
# We should look for all lines linked to the same picking and update them all.
result_package_updated = "result_package_id" in vals
if result_package_updated:
Expand Down
9 changes: 8 additions & 1 deletion sale_stock_line_customer_ref/models/stock_picking.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class StockPicking(models.Model):
help="Technical field to display 'Customer Ref' column on moves.",
)

@api.depends("move_lines.customer_ref")
@api.depends("move_ids.customer_ref")
def _compute_has_customer_ref(self):
for picking in self:
# Break on the first move having a customer ref
Expand All @@ -24,3 +24,10 @@ def _compute_has_customer_ref(self):
),
False,
)

def action_detailed_operations(self):
res = super().action_detailed_operations()
ctx = dict(res.get("context", {}))
ctx["has_customer_ref"] = self.has_customer_ref
res["context"] = ctx
return res

Check warning on line 33 in sale_stock_line_customer_ref/models/stock_picking.py

View check run for this annotation

Codecov / codecov/patch

sale_stock_line_customer_ref/models/stock_picking.py#L29-L33

Added lines #L29 - L33 were not covered by tests
9 changes: 0 additions & 9 deletions sale_stock_line_customer_ref/models/stock_quant_package.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,6 @@
class StockQuantPackage(models.Model):
_inherit = "stock.quant.package"

# TODO: to put in the readme
# We want the customer ref on the package because the label should be printed
# from there (like all other kind of existing labels).
# As we can't get the right stock.move.line/stock.move easily from the package
# it is easier to store the Customer Ref. of the move/move_line on the package when
# this one is assigned to the move line.
# Also, a (destination) package could contain different products (so different moves),
# and these moves could have different Customer Ref., all of them will be concatened
# in the package => ", ".join(customer_ref_of_all_moves_link_to_this_package)
customer_ref = fields.Char(
string="Customer Ref.",
help="Customer reference coming from the sale order line.",
Expand Down
1 change: 1 addition & 0 deletions sale_stock_line_customer_ref/readme/CONTRIBUTORS.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
- Sébastien Alix \<<[email protected]>\>
- Simone Orsi \<<[email protected]>\>
- Do Anh Duy \<<[email protected]>\>
1 change: 1 addition & 0 deletions sale_stock_line_customer_ref/readme/CREDITS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The migration of this module from 14.0 to 18.0 was financially supported by Camptocamp.
4 changes: 4 additions & 0 deletions sale_stock_line_customer_ref/readme/USAGE.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
By default the customer reference field is not displayed on the sale
order form, you have to enable it in the list of optional fields.

We want the customer ref on the package because the label should be printed from there (like all other kind of existing labels).
As we can't get the right stock.move.line/stock.move easily from the package it is easier to store the Customer Ref. of the move/move_line on the package when this one is assigned to the move line.
Also, a (destination) package could contain different products (so different moves), and these moves could have different Customer Ref., all of them will be concatened in the package => ", ".join(customer_ref_of_all_moves_link_to_this_package)
20 changes: 18 additions & 2 deletions sale_stock_line_customer_ref/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,8 @@ <h1 class="title">Sale Stock Line Customer Reference</h1>
<li><a class="reference internal" href="#credits" id="toc-entry-3">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-4">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-5">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-6">Maintainers</a></li>
<li><a class="reference internal" href="#other-credits" id="toc-entry-6">Other credits</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-7">Maintainers</a></li>
</ul>
</li>
</ul>
Expand All @@ -390,6 +391,15 @@ <h1 class="title">Sale Stock Line Customer Reference</h1>
<h1><a class="toc-backref" href="#toc-entry-1">Usage</a></h1>
<p>By default the customer reference field is not displayed on the sale
order form, you have to enable it in the list of optional fields.</p>
<p>We want the customer ref on the package because the label should be
printed from there (like all other kind of existing labels). As we can’t
get the right stock.move.line/stock.move easily from the package it is
easier to store the Customer Ref. of the move/move_line on the package
when this one is assigned to the move line. Also, a (destination)
package could contain different products (so different moves), and these
moves could have different Customer Ref., all of them will be concatened
in the package =&gt; “,
“.join(customer_ref_of_all_moves_link_to_this_package)</p>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#toc-entry-2">Bug Tracker</a></h1>
Expand All @@ -412,10 +422,16 @@ <h2><a class="toc-backref" href="#toc-entry-5">Contributors</a></h2>
<ul class="simple">
<li>Sébastien Alix &lt;<a class="reference external" href="mailto:sebastien.alix&#64;camptocamp.com">sebastien.alix&#64;camptocamp.com</a>&gt;</li>
<li>Simone Orsi &lt;<a class="reference external" href="mailto:simone.orsi&#64;camptocamp.com">simone.orsi&#64;camptocamp.com</a>&gt;</li>
<li>Do Anh Duy &lt;<a class="reference external" href="mailto:duyda&#64;trobz.com">duyda&#64;trobz.com</a>&gt;</li>
</ul>
</div>
<div class="section" id="other-credits">
<h2><a class="toc-backref" href="#toc-entry-6">Other credits</a></h2>
<p>The migration of this module from 14.0 to 18.0 was financially supported
by Camptocamp.</p>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-6">Maintainers</a></h2>
<h2><a class="toc-backref" href="#toc-entry-7">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org">
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
Expand Down
26 changes: 16 additions & 10 deletions sale_stock_line_customer_ref/tests/test_customer_ref.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
# Copyright 2022 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
from odoo.tests.common import Form, SavepointCase

from odoo.tests import Form

class TestSaleLineCustomerRef(SavepointCase):
from odoo.addons.base.tests.common import BaseCommon


class TestSaleLineCustomerRef(BaseCommon):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True))
cls.wh = cls.env.ref("stock.warehouse0")
cls.wh.delivery_steps = "pick_pack_ship"
cls.product = cls.env.ref("product.consu_delivery_01")
cls.stock_loc = cls.env.ref("stock.stock_location_stock")
delivery_route = cls.wh.delivery_route_id
rule_id1 = delivery_route.rule_ids[1]
delivery_route.rule_ids[0].location_dest_id = rule_id1.location_src_id.id
delivery_route.rule_ids.write({"action": "pull"})
cls.stock_loc = cls.wh.lot_stock_id
cls.order = cls._create_order()
cls.order.action_confirm()
cls.pkg_model = cls.env["stock.quant.package"]
Expand Down Expand Up @@ -46,11 +52,11 @@ def _update_qty_in_location(

@classmethod
def _get_pick(cls, order):
return order.picking_ids.filtered(lambda x: not x.move_lines.move_orig_ids)
return order.picking_ids.filtered(lambda x: not x.move_ids.move_orig_ids)

@classmethod
def _get_pack(cls, order):
return cls._get_pick(order).move_lines.move_dest_ids.picking_id
return cls._get_pick(order).move_ids.move_dest_ids.picking_id

Check warning on line 59 in sale_stock_line_customer_ref/tests/test_customer_ref.py

View check run for this annotation

Codecov / codecov/patch

sale_stock_line_customer_ref/tests/test_customer_ref.py#L59

Added line #L59 was not covered by tests

def test_customer_ref(self):
# Ship moves can't be merged anyway in std Odoo as they belong to
Expand Down Expand Up @@ -100,13 +106,13 @@ def test_package_ref(self):
picking.move_line_ids[0].result_package_id = pkg1
picking.move_line_ids[1].result_package_id = pkg2
packages = picking.move_line_ids.result_package_id.sorted("name")
packages.invalidate_cache()
packages.invalidate_recordset()

self.assertEqual(packages.mapped("customer_ref"), ["TEST_0", "TEST_1"])
picking.move_line_ids.filtered(
lambda x: x.result_package_id == pkg2
).result_package_id = False
packages.invalidate_cache()
packages.invalidate_recordset()
self.assertEqual(packages.mapped("customer_ref"), ["TEST_0", False])

def test_package_ref_concat(self):
Expand All @@ -119,9 +125,9 @@ def test_package_ref_concat(self):
self.pkg_model.create({"name": "TEST-REF-2"})
picking.move_line_ids.result_package_id = pkg1
packages = picking.move_line_ids.result_package_id.sorted("name")
packages.invalidate_cache()
packages.invalidate_recordset()

self.assertEqual(packages.mapped("customer_ref"), ["TEST_0, TEST_1"])
picking.move_line_ids.result_package_id = False
packages.invalidate_cache()
packages.invalidate_recordset()
self.assertEqual(packages.mapped("customer_ref"), [False])
4 changes: 2 additions & 2 deletions sale_stock_line_customer_ref/views/sale_order.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
<field name="inherit_id" ref="sale.view_order_form" />
<field name="arch" type="xml">
<xpath
expr="//field[@name='order_line']/tree/field[@name='name']"
expr="//field[@name='order_line']/list/field[@name='name']"
position="after"
>
<field name="customer_ref" optional="hide" />
</xpath>
<xpath
expr="//field[@name='order_line']/form//field[@name='analytic_tag_ids']"
expr="//field[@name='order_line']/form//field[@name='analytic_distribution']"
position="after"
>
<field name="customer_ref" />
Expand Down
5 changes: 1 addition & 4 deletions sale_stock_line_customer_ref/views/stock_move.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@
<field name="inherit_id" ref="stock.view_stock_move_operations" />
<field name="arch" type="xml">
<field name="product_id" position="after">
<field
name="customer_ref"
attrs="{'invisible': [('customer_ref', '=', False)]}"
/>
<field name="customer_ref" invisible="not customer_ref" />
</field>
</field>
</record>
Expand Down
9 changes: 3 additions & 6 deletions sale_stock_line_customer_ref/views/stock_move_line.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,13 @@
<field name="inherit_id" ref="stock.view_move_line_form" />
<field name="arch" type="xml">
<field name="product_id" position="after">
<field
name="customer_ref"
attrs="{'invisible': [('customer_ref', '=', False)]}"
/>
<field name="customer_ref" invisible="not customer_ref" />
</field>
</field>
</record>

<record id="view_stock_move_line_detailed_operation_tree" model="ir.ui.view">
<field name="name">stock.move.line.operations.tree.inherit</field>
<field name="name">stock.move.line.operations.list.inherit</field>
<field name="model">stock.move.line</field>
<field
name="inherit_id"
Expand All @@ -27,7 +24,7 @@
<field name="product_id" position="after">
<field
name="customer_ref"
attrs="{'column_invisible': [('parent.has_customer_ref', '=', False)]}"
column_invisible="not context.get('has_customer_ref')"
/>
</field>
</field>
Expand Down
11 changes: 4 additions & 7 deletions sale_stock_line_customer_ref/views/stock_package_level.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,22 @@
<field name="model">stock.package_level</field>
<field name="inherit_id" ref="stock.package_level_form_view" />
<field name="arch" type="xml">
<field name="picking_type_code" position="after">
<field name="has_customer_ref" invisible="1" />
</field>
<xpath
expr="//field[@name='move_ids']/tree//field[@name='product_id']"
expr="//field[@name='move_ids']/list/field[@name='product_id']"
position="after"
>
<field
name="customer_ref"
attrs="{'column_invisible': [('parent.has_customer_ref', '=', False)]}"
column_invisible="not parent.has_customer_ref"
/>
</xpath>
<xpath
expr="//field[@name='move_line_ids']/tree//field[@name='product_id']"
expr="//field[@name='move_line_ids']/list/field[@name='product_id']"
position="after"
>
<field
name="customer_ref"
attrs="{'column_invisible': [('parent.has_customer_ref', '=', False)]}"
column_invisible="not parent.has_customer_ref"
/>
</xpath>
</field>
Expand Down
16 changes: 2 additions & 14 deletions sale_stock_line_customer_ref/views/stock_picking.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,13 @@
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.view_picking_form" />
<field name="arch" type="xml">
<field name="use_create_lots" position="after">
<field name="has_customer_ref" invisible="1" />
</field>
<xpath
expr="//field[@name='move_ids_without_package']/tree/field[@name='product_id']"
expr="//field[@name='move_ids_without_package']/list/field[@name='product_id']"
position="after"
>
<field
name="customer_ref"
attrs="{'column_invisible': [('parent.has_customer_ref', '=', False)]}"
/>
</xpath>
<xpath
expr="//field[@name='move_ids_without_package']/form//field[@name='product_id']"
position="after"
>
<field
name="customer_ref"
attrs="{'invisible': [('customer_ref', '=', False)]}"
column_invisible="not parent.has_customer_ref"
/>
</xpath>
</field>
Expand Down
Loading

0 comments on commit 85dcb73

Please sign in to comment.