@ -0,0 +1,48 @@ |
|||
.. image:: https://img.shields.io/badge/license-AGPL--3-blue.svg |
|||
:target: https://www.gnu.org/licenses/agpl-3.0-standalone.html |
|||
:alt: License: AGPL-3 |
|||
|
|||
Export Product Images |
|||
===================== |
|||
This module helps to export product images as an excel file along with other details. |
|||
|
|||
Configuration |
|||
============= |
|||
* No additional configuration required. |
|||
|
|||
License |
|||
------- |
|||
Affero General Public License, v3.0 (AGPL v3). |
|||
(https://www.gnu.org/licenses/agpl-3.0-standalone.html) |
|||
|
|||
Company |
|||
------- |
|||
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__ |
|||
|
|||
Credits |
|||
------- |
|||
* Developers: (V16) Ajmunnisa KP, |
|||
(V17) Aysha Shalin, |
|||
(V18) Javid A, Contact: odoo@cybrosys.com |
|||
|
|||
Contacts |
|||
-------- |
|||
* Mail Contact : odoo@cybrosys.com |
|||
* Website : https://cybrosys.com |
|||
|
|||
Bug Tracker |
|||
----------- |
|||
Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. |
|||
|
|||
Maintainer |
|||
========== |
|||
.. image:: https://cybrosys.com/images/logo.png |
|||
:target: https://cybrosys.com |
|||
|
|||
This module is maintained by Cybrosys Technologies. |
|||
|
|||
For support and more information, please visit `Our Website <https://cybrosys.com/>`__ |
|||
|
|||
Further information |
|||
=================== |
|||
HTML Description: `<static/description/index.html>`__ |
@ -0,0 +1,23 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Cybrosys Techno Solutions (odoo@cybrosys.com) |
|||
# |
|||
# You can modify it under the terms of the GNU AFFERO |
|||
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
|||
# |
|||
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
|||
# (AGPL v3) along with this program. |
|||
# If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################### |
|||
from . import controllers |
|||
from . import wizard |
@ -0,0 +1,44 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Cybrosys Techno Solutions (odoo@cybrosys.com) |
|||
# |
|||
# You can modify it under the terms of the GNU AFFERO |
|||
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
|||
# |
|||
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
|||
# (AGPL v3) along with this program. |
|||
# If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################### |
|||
{ |
|||
"name": "Export Product Images", |
|||
"version": "18.0.1.0.0", |
|||
"category": "Warehouse", |
|||
"summary": """To export product details along with the product images.""", |
|||
"description": "The allowed users can download the product details " |
|||
"along with the product images.", |
|||
"author": "Cybrosys Techno Solutions", |
|||
"website": "https://www.cybrosys.com", |
|||
"company": "Cybrosys Techno Solutions", |
|||
"maintainer": "Cybrosys Techno Solutions", |
|||
"depends": ["stock", "product", "web"], |
|||
"data": [ |
|||
"security/product_export_with_images_groups.xml", |
|||
"security/ir.model.access.csv", |
|||
"data/product_export_with_images_data.xml", |
|||
], |
|||
"images": ["static/description/banner.png"], |
|||
"license": "AGPL-3", |
|||
"installable": True, |
|||
"auto_install": False, |
|||
"application": False, |
|||
} |
@ -0,0 +1,22 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Cybrosys Techno Solutions (odoo@cybrosys.com) |
|||
# |
|||
# You can modify it under the terms of the GNU AFFERO |
|||
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
|||
# |
|||
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
|||
# (AGPL v3) along with this program. |
|||
# If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################### |
|||
from . import product_export_with_images |
@ -0,0 +1,126 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Cybrosys Techno Solutions (odoo@cybrosys.com) |
|||
# |
|||
# You can modify it under the terms of the GNU AFFERO |
|||
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
|||
# |
|||
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
|||
# (AGPL v3) along with this program. |
|||
# If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################### |
|||
import base64 |
|||
import io |
|||
import xlsxwriter |
|||
from io import BytesIO |
|||
from odoo import http |
|||
from odoo.http import content_disposition, request |
|||
from odoo.tools import image_process |
|||
|
|||
|
|||
class ExcelReportController(http.Controller): |
|||
""" This class includes the function to downloads excel report """ |
|||
@http.route( |
|||
[ |
|||
'/products_download/excel_report/<model("product.export"):wizards>', |
|||
], |
|||
type="http", |
|||
auth="public", |
|||
csrf=False, |
|||
) |
|||
def get_product_excel_report(self, wizards=None): |
|||
""" Downloads the Excel document with the details of products """ |
|||
response = request.make_response( |
|||
None, |
|||
headers=[ |
|||
("Content-Type", "application/vnd.ms-excel"), |
|||
("Content-Disposition", content_disposition("Products" + ".xlsx")), |
|||
], |
|||
) |
|||
# Create workbook object from xlsxwriter library |
|||
output = io.BytesIO() |
|||
workbook = xlsxwriter.Workbook(output, {"in_memory": True}) |
|||
# Create styles to set up the font type, the font size, the border, |
|||
# and the alignment |
|||
header_style = workbook.add_format( |
|||
{ |
|||
"text_wrap": True, |
|||
"font_name": "Times", |
|||
"bold": True, |
|||
"left": 1, |
|||
"bottom": 1, |
|||
"right": 1, |
|||
"top": 1, |
|||
"align": "center", |
|||
} |
|||
) |
|||
text_style = workbook.add_format( |
|||
{ |
|||
"text_wrap": True, |
|||
"font_name": "Times", |
|||
"left": 1, |
|||
"bottom": 1, |
|||
"right": 1, |
|||
"top": 1, |
|||
"align": "left", |
|||
} |
|||
) |
|||
product_lines = wizards.get_product_lines() |
|||
sheet = workbook.add_worksheet("Products") |
|||
sheet.set_landscape() |
|||
sheet.set_paper(9) |
|||
sheet.merge_range("A1:G1", "PRODUCTS", header_style) |
|||
sheet.set_margins(0.5, 0.5, 0.5, 0.5) |
|||
sheet.set_column("A:A", 5) |
|||
sheet.set_column("B:F", 15) |
|||
sheet.set_column("G:G", 20) |
|||
sheet.set_row(1, 30) |
|||
sheet.set_row(0, 30) |
|||
# table title |
|||
sheet.write(2, 0, "ID", header_style) |
|||
sheet.write(2, 1, "Internal Reference", header_style) |
|||
sheet.write(2, 2, "Name", header_style) |
|||
sheet.write(2, 3, "Cost", header_style) |
|||
sheet.write(2, 4, "Sales Price", header_style) |
|||
sheet.write(2, 5, "Product Category", header_style) |
|||
sheet.write(2, 6, "Image", header_style) |
|||
row = 3 |
|||
number = 1 |
|||
count = 0 |
|||
for line in product_lines: |
|||
sheet.set_row(row, 128) |
|||
# the report content |
|||
count += 1 |
|||
sheet.write(row, 0, count, text_style) |
|||
if line["internal_reference"]: |
|||
sheet.write(row, 1, line["internal_reference"], text_style) |
|||
elif not line["internal_reference"]: |
|||
sheet.write(row, 1, "", text_style) |
|||
sheet.write(row, 2, line["name"], text_style) |
|||
sheet.write(row, 3, str(line["currency"]) + str(line["cost"]), text_style) |
|||
sheet.write( |
|||
row, 4, str(line["currency"]) + str(line["sales_price"]), text_style |
|||
) |
|||
sheet.write(row, 5, line["category"], text_style) |
|||
if line["image"]: |
|||
source = base64.b64decode(line["image"]) |
|||
image_data = BytesIO(image_process(source, size=(300, 300))) |
|||
sheet.write(row, 6, "", text_style) |
|||
sheet.insert_image(row, 6, "product.png", {"image_data": image_data}) |
|||
row += 1 |
|||
number += 1 |
|||
workbook.close() |
|||
output.seek(0) |
|||
response.stream.write(output.read()) |
|||
output.close() |
|||
return response |
@ -0,0 +1,35 @@ |
|||
<?xml version="1.0" encoding="UTF-8" ?> |
|||
<odoo> |
|||
<data noupdate="1"> |
|||
<!-- Record for server action button to export product images in product template --> |
|||
<record id="action_export_product_template_images" |
|||
model="ir.actions.server"> |
|||
<field name="name">Export Product Images</field> |
|||
<field name="model_id" ref="model_product_export"/> |
|||
<field name="binding_model_id" |
|||
ref="product.model_product_template"/> |
|||
<field name="binding_view_types">form,list</field> |
|||
<field name="state">code</field> |
|||
<field name="code"> |
|||
action = model.action_export_products() |
|||
</field> |
|||
<field name="groups_id" |
|||
eval="[(4, ref('product_export_with_images.group_product_export_with_images'))]"/> |
|||
</record> |
|||
|
|||
<!-- Record for server action button to export product images in product --> |
|||
<record id="action_export_product_images" model="ir.actions.server"> |
|||
<field name="name">Export Product Images</field> |
|||
<field name="model_id" ref="model_product_export"/> |
|||
<field name="binding_model_id" |
|||
ref="product.model_product_product"/> |
|||
<field name="binding_view_types">form,list</field> |
|||
<field name="state">code</field> |
|||
<field name="code"> |
|||
action = model.action_export_products() |
|||
</field> |
|||
<field name="groups_id" |
|||
eval="[(4, ref('product_export_with_images.group_product_export_with_images'))]"/> |
|||
</record> |
|||
</data> |
|||
</odoo> |
@ -0,0 +1,6 @@ |
|||
## Module <product_export_with_images> |
|||
|
|||
#### 19.10.2024 |
|||
#### Version 18.0.1.0.0 |
|||
##### ADD |
|||
- Initial commit for Export Product Images |
|
@ -0,0 +1,8 @@ |
|||
<?xml version="1.0" encoding="UTF-8" ?> |
|||
<odoo> |
|||
<!-- Only users in this group are allowed to export product images --> |
|||
<record id="group_product_export_with_images" model="res.groups"> |
|||
<field name="name">Export products Images</field> |
|||
<field name="category_id" ref="base.module_category_hidden"/> |
|||
</record> |
|||
</odoo> |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 628 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 210 KiB |
After Width: | Height: | Size: 209 KiB |
After Width: | Height: | Size: 109 KiB |
After Width: | Height: | Size: 495 B |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 624 B |
After Width: | Height: | Size: 136 KiB |
After Width: | Height: | Size: 214 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 310 B |
After Width: | Height: | Size: 929 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 542 B |
After Width: | Height: | Size: 576 B |
After Width: | Height: | Size: 733 B |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 738 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 911 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 600 B |
After Width: | Height: | Size: 673 B |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 462 B |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 926 B |
After Width: | Height: | Size: 9.0 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 7.0 KiB |
After Width: | Height: | Size: 878 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 653 B |
After Width: | Height: | Size: 800 B |
After Width: | Height: | Size: 905 B |
After Width: | Height: | Size: 189 KiB |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 839 B |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 5.9 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 427 B |
After Width: | Height: | Size: 627 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 988 B |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 875 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 912 KiB |
After Width: | Height: | Size: 1.3 MiB |
After Width: | Height: | Size: 46 KiB |
After Width: | Height: | Size: 44 KiB |
After Width: | Height: | Size: 46 KiB |
After Width: | Height: | Size: 85 KiB |
After Width: | Height: | Size: 96 KiB |
After Width: | Height: | Size: 138 KiB |
After Width: | Height: | Size: 112 KiB |
After Width: | Height: | Size: 112 KiB |
After Width: | Height: | Size: 144 KiB |
After Width: | Height: | Size: 219 KiB |
After Width: | Height: | Size: 880 KiB |
After Width: | Height: | Size: 89 KiB |
After Width: | Height: | Size: 8.9 KiB |
@ -0,0 +1,22 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Cybrosys Techno Solutions (odoo@cybrosys.com) |
|||
# |
|||
# You can modify it under the terms of the GNU AFFERO |
|||
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
|||
# |
|||
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
|||
# (AGPL v3) along with this program. |
|||
# If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################### |
|||
from . import product_export |
@ -0,0 +1,80 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Cybrosys Techno Solutions (odoo@cybrosys.com) |
|||
# |
|||
# You can modify it under the terms of the GNU AFFERO |
|||
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
|||
# |
|||
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
|||
# (AGPL v3) along with this program. |
|||
# If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################### |
|||
from odoo import fields, models |
|||
|
|||
|
|||
class ExportWizard(models.TransientModel): |
|||
""" This class contains the functions to get selected product ids and |
|||
redirect to excel download URL. """ |
|||
|
|||
_name = "product.export" |
|||
_description = "Export Products and Make an Excel Download URL." |
|||
|
|||
name = fields.Char(string="Name", help="Name of the record") |
|||
product_tmp_ids = fields.Many2many( |
|||
"product.template", string="Products", |
|||
help="Products for exporting") |
|||
product_ids = fields.Many2many( |
|||
"product.product", string="Products Variants", |
|||
help="Product variants for exporting") |
|||
|
|||
def action_export_products(self): |
|||
""" Select the active product/ product template ids. Return URL action |
|||
to download excel report. """ |
|||
active_products = self.env.context["active_ids"] |
|||
active_model = self.env.context["active_model"] |
|||
if active_model == "product.template": |
|||
export_wizard = self.env["product.export"].create( |
|||
{"product_tmp_ids": [(6, 0, active_products)]} |
|||
) |
|||
if active_model == "product.product": |
|||
export_wizard = self.env["product.export"].create( |
|||
{"product_ids": [(6, 0, active_products)]} |
|||
) |
|||
if export_wizard: |
|||
return { |
|||
"type": "ir.actions.act_url", |
|||
"url": "/products_download/excel_report/%s" % export_wizard.id, |
|||
"target": "new", |
|||
"context": {"active_ids": active_products}, |
|||
} |
|||
|
|||
def get_product_lines(self): |
|||
""" Returns the product details like name, default code, category, |
|||
image etc. """ |
|||
rec_list = [] |
|||
if self.product_ids: |
|||
active_records = self.product_ids |
|||
elif self.product_tmp_ids: |
|||
active_records = self.product_tmp_ids |
|||
for rec in active_records: |
|||
vals = { |
|||
"name": rec.name, |
|||
"internal_reference": rec.default_code, |
|||
"category": rec.categ_id.display_name, |
|||
"currency": self.env.company.currency_id.symbol, |
|||
"cost": rec.standard_price, |
|||
"sales_price": rec.list_price, |
|||
"image": rec.image_128, |
|||
} |
|||
rec_list.append(vals) |
|||
return rec_list |