Skip to content

Commit bdc9c55

Browse files
[ADD] product_catalog_download: New module
1 parent 37fb901 commit bdc9c55

File tree

12 files changed

+714
-0
lines changed

12 files changed

+714
-0
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
==========================
2+
Product Catalog CSV Export
3+
==========================
4+
5+
..
6+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
7+
!! This file is generated by oca-gen-addon-readme !!
8+
!! changes will be overwritten. !!
9+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
10+
!! source digest: sha256:f91fff29b8eb65573173388815219b940ca8c6e4f17c6e90226074816057b3c1
11+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
12+
13+
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
14+
:target: https://odoo-community.org/page/development-status
15+
:alt: Beta
16+
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
17+
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
18+
:alt: License: AGPL-3
19+
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fproduct--attribute-lightgray.png?logo=github
20+
:target: https://github.com/OCA/product-attribute/tree/18.0/product_catalog_download
21+
:alt: OCA/product-attribute
22+
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
23+
:target: https://translation.odoo-community.org/projects/product-attribute-18-0/product-attribute-18-0-product_catalog_download
24+
:alt: Translate me on Weblate
25+
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
26+
:target: https://runboat.odoo-community.org/builds?repo=OCA/product-attribute&target_branch=18.0
27+
:alt: Try me on Runboat
28+
29+
|badge1| |badge2| |badge3| |badge4| |badge5|
30+
31+
| This module provides an **HTTP endpoint** that allows authenticated
32+
Odoo users to export the product catalog as a **CSV file**.
33+
| It automatically applies the user's assigned **pricelist**, so the
34+
exported prices match what the user would see in sales quotations or
35+
the portal.
36+
37+
**Table of contents**
38+
39+
.. contents::
40+
:local:
41+
42+
Bug Tracker
43+
===========
44+
45+
Bugs are tracked on `GitHub Issues <https://github.com/OCA/product-attribute/issues>`_.
46+
In case of trouble, please check there if your issue has already been reported.
47+
If you spotted it first, help us to smash it by providing a detailed and welcomed
48+
`feedback <https://github.com/OCA/product-attribute/issues/new?body=module:%20product_catalog_download%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
49+
50+
Do not contact contributors directly about support or help with technical issues.
51+
52+
Credits
53+
=======
54+
55+
Authors
56+
-------
57+
58+
* Odoo S.A.
59+
* Tecnativa
60+
61+
Contributors
62+
------------
63+
64+
- [Tecnativa](https://www.tecnativa.com):
65+
66+
- Eduardo Ezerouali
67+
68+
Maintainers
69+
-----------
70+
71+
This module is maintained by the OCA.
72+
73+
.. image:: https://odoo-community.org/logo.png
74+
:alt: Odoo Community Association
75+
:target: https://odoo-community.org
76+
77+
OCA, or the Odoo Community Association, is a nonprofit organization whose
78+
mission is to support the collaborative development of Odoo features and
79+
promote its widespread use.
80+
81+
This module is part of the `OCA/product-attribute <https://github.com/OCA/product-attribute/tree/18.0/product_catalog_download>`_ project on GitHub.
82+
83+
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Copyright 2025 Tecnativa - Eduardo Ezerouali
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
3+
from . import controllers
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Copyright 2025 Tecnativa - Eduardo Ezerouali
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
3+
{
4+
"name": "Product Catalog CSV Export",
5+
"version": "18.0.1.0.0",
6+
"summary": "Download CSV with product catalog from a pricelist using controller",
7+
"category": "Product",
8+
"license": "AGPL-3",
9+
"website": "https://github.com/OCA/product-attribute",
10+
"author": "Odoo S.A., Tecnativa, Odoo Community Association (OCA)",
11+
"depends": ["product"],
12+
"data": [],
13+
"installable": True,
14+
"application": False,
15+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Copyright 2025 Tecnativa - Eduardo Ezerouali
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
3+
from . import main
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Copyright 2025 Tecnativa - Eduardo Ezerouali
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
3+
import csv
4+
import io
5+
from datetime import datetime
6+
7+
from odoo import http
8+
from odoo.http import request
9+
10+
11+
class CatalogExportController(http.Controller):
12+
@http.route(
13+
["/catalog/export/products.csv"],
14+
type="http",
15+
auth="user",
16+
methods=["GET"],
17+
csrf=False,
18+
)
19+
def export_products_csv(self, **kwargs):
20+
"""
21+
Export product catalog to CSV applying pricelist.
22+
Params:
23+
pricelist_id: ID of the pricelist (or user default pricelist)
24+
fields: comma-separated list of fields
25+
active: true/false
26+
"""
27+
fields_param = (
28+
kwargs.get("fields") or "name,default_code,barcode,list_price,qty_available"
29+
)
30+
fields = [f.strip() for f in fields_param.split(",") if f.strip()]
31+
active = kwargs.get("active", "true").lower() != "false"
32+
pricelist_id = kwargs.get("pricelist_id")
33+
pricelist = None
34+
if pricelist_id:
35+
pricelist = (
36+
request.env["product.pricelist"].browse(int(pricelist_id)).exists()
37+
)
38+
if not pricelist:
39+
partner = request.env.user.partner_id
40+
pricelist = partner.property_product_pricelist
41+
domain = [("active", "=", active), ("sale_ok", "=", True)]
42+
products = request.env["product.product"].search(domain)
43+
buf = io.StringIO()
44+
writer = csv.writer(buf, quoting=csv.QUOTE_MINIMAL)
45+
writer.writerow(fields)
46+
47+
def get_val(rec, field):
48+
if field == "list_price":
49+
return (
50+
pricelist._get_product_price(rec, 1.0)
51+
if pricelist
52+
else rec.list_price
53+
)
54+
val = rec[field] if field in rec._fields else ""
55+
if hasattr(val, "name") and val._name != "ir.attachment":
56+
return val.name
57+
if hasattr(val, "ids"):
58+
return ",".join(str(x) for x in val.ids)
59+
if isinstance(val, datetime):
60+
return val.isoformat()
61+
return val if val is not False else ""
62+
63+
for rec in products:
64+
writer.writerow([get_val(rec, f) for f in fields])
65+
66+
csv_bytes = buf.getvalue().encode("utf-8-sig")
67+
headers = [
68+
("Content-Type", "text/csv; charset=utf-8"),
69+
("Content-Disposition", 'attachment; filename="products.csv"'),
70+
]
71+
return request.make_response(csv_bytes, headers=headers)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[build-system]
2+
requires = ["whool"]
3+
build-backend = "whool.buildapi"
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- \[Tecnativa\](<https://www.tecnativa.com>):
2+
- Eduardo Ezerouali
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
This module provides an **HTTP endpoint** that allows authenticated Odoo users to export the product catalog as a **CSV file**.
2+
It automatically applies the user's assigned **pricelist**, so the exported prices match what the user would see in sales quotations or the portal.
9.23 KB
Loading

0 commit comments

Comments
 (0)