Skip to content

Commit b3a62ce

Browse files
carlosdaudenCarlosRoca13
authored andcommitted
[IMP] sale_product_catalog_extended: Add catalog_origin_data option to select products from last sales
1 parent 79401b0 commit b3a62ce

File tree

6 files changed

+108
-4
lines changed

6 files changed

+108
-4
lines changed

sale_product_catalog_extended/README.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,10 @@ Authors
5757
Contributors
5858
------------
5959

60-
- `Tecnativa <https://www.tecnativa.com>`__:
60+
- `Tecnativa <https://www.tecnativa.com>`__:
6161

62-
- Carlos Dauden
63-
- Carlos Roca
62+
- Carlos Dauden
63+
- Carlos Roca
6464

6565
Maintainers
6666
-----------

sale_product_catalog_extended/__manifest__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@
99
"version": "18.0.1.0.0",
1010
"website": "https://github.com/OCA/sale-workflow",
1111
"depends": ["sale"],
12-
"data": ["views/sale_order_line_views.xml"],
12+
"data": [
13+
"views/product_views.xml",
14+
"views/sale_order_line_views.xml",
15+
],
1316
"assets": {
1417
"web.assets_backend": ["sale_product_catalog_extended/static/src/**/*"],
1518
},
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
from . import product_product
12
from . import sale_order
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Copyright 2025 Tecnativa - Carlos Dauden
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3+
from datetime import timedelta
4+
5+
from odoo import api, fields, models
6+
7+
8+
class ProductProduct(models.Model):
9+
_inherit = "product.product"
10+
11+
catalog_origin_data = fields.Selection(
12+
selection=[("sale_order", "Last sales")],
13+
store=False,
14+
search="_search_catalog_origin_data",
15+
)
16+
17+
@api.model
18+
def search_fetch(self, domain, field_names, offset=0, limit=None, order=None):
19+
catalog_orig_data_bool_list = [
20+
"catalog_origin_data" in subdomain for subdomain in domain
21+
]
22+
if any(catalog_orig_data_bool_list):
23+
# Get value of catalog_origin_data from domain to know which method throw.
24+
# Then browse the ids to respect the order.
25+
product_ids = getattr(
26+
self,
27+
f"_get_product_picker_data_{domain[catalog_orig_data_bool_list.index(True)][2]}",
28+
)()
29+
return self.browse(product_ids)
30+
return super().search_fetch(
31+
domain, field_names, offset=offset, limit=limit, order=order
32+
)
33+
34+
@api.model
35+
def _search_catalog_origin_data(self, operator, value):
36+
# Hack to be able to filter by catalog_origin_data
37+
return []
38+
39+
@api.model
40+
def _product_picker_data_sale_order_domain(self):
41+
"""Domain to find recent SO lines."""
42+
months = 6
43+
start = fields.Datetime.now() - timedelta(days=months * 30)
44+
start = fields.Datetime.to_string(start)
45+
catalog_partner_id = self.env.context.get("product_catalog_partner_id", False)
46+
catalog_order_id = self.env.context.get("product_catalog_order_id", False)
47+
# Search with sudo for get sale order from other commercials users
48+
other_sales = (
49+
self.env["sale.order"]
50+
# .sudo()
51+
._search(
52+
[
53+
("id", "!=", catalog_order_id),
54+
("company_id", "=", self.env.company.id),
55+
("partner_shipping_id", "=", catalog_partner_id),
56+
("date_order", ">=", start),
57+
]
58+
)
59+
)
60+
domain = [
61+
("order_id", "in", other_sales),
62+
("qty_delivered", "!=", 0.0),
63+
]
64+
return domain
65+
66+
@api.model
67+
def _get_product_picker_data_sale_order(self):
68+
# Specific limit to allow show all products sold in recent orders
69+
limit = int(
70+
self.env["ir.config_parameter"]
71+
.sudo()
72+
.get_param("sale_order_product_picker.product_picker_last_order_limit", "0")
73+
)
74+
sol_groups = self.env["sale.order.line"]._read_group(
75+
self._product_picker_data_sale_order_domain(),
76+
groupby=["product_id"],
77+
aggregates=["__count", "qty_delivered:sum"],
78+
limit=limit,
79+
order="__count desc, qty_delivered:sum desc",
80+
)
81+
return [g[0].id for g in sol_groups]

sale_product_catalog_extended/models/sale_order.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@ def _get_catalog_order_line(self, product_id, **kwargs):
2020
self._get_catalog_order_line_filter_domain(product_id, **kwargs)
2121
).ids
2222

23+
def _get_action_add_from_catalog_extra_context(self):
24+
# TODO: partner_id or shipping_partner_id?
25+
return {
26+
**super()._get_action_add_from_catalog_extra_context(),
27+
"product_catalog_partner_id": self.partner_shipping_id.id,
28+
}
29+
2330

2431
class SaleOrderLine(models.Model):
2532
_inherit = "sale.order.line"
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<odoo>
3+
<record id="product_view_search_catalog" model="ir.ui.view">
4+
<field name="model">product.product</field>
5+
<field name="inherit_id" ref="product.product_view_search_catalog" />
6+
<field name="arch" type="xml">
7+
<xpath expr="//searchpanel/field[@name='categ_id']" position="before">
8+
<field name="catalog_origin_data" string="Origin" expand="1" />
9+
</xpath>
10+
</field>
11+
</record>
12+
</odoo>

0 commit comments

Comments
 (0)