@ -1,46 +0,0 @@ |
|||
.. 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 |
|||
|
|||
Product Data Feed Generation |
|||
============================ |
|||
Generating a Product Catalog Feeds Sharing Link |
|||
|
|||
Configuration |
|||
============= |
|||
* No additional configurations needed |
|||
|
|||
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 |
|||
------- |
|||
* Developer: (V17) Subina P, 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>`__ |
@ -1,22 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Subina P (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, models |
@ -1,54 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Subina P (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': 'Product Data Feed Generation', |
|||
'version': '17.0.1.0.0', |
|||
'category': 'eCommerce', |
|||
'summary': 'Help to create the catalog for promoting your sale', |
|||
'description': 'Using this module we have to promote and market our sales' |
|||
' through facebook and instagram for using the catalog of ' |
|||
'our product. Many of the businesses sell or advertise ' |
|||
'their product through facebook and instagram. So they' |
|||
' need a catalog that contains the information about your ' |
|||
'products. In this module generate the product data feed ' |
|||
'file for the facebook commerce manager in automatic ' |
|||
'mode(by URL). After adding the data feed URL on facebook ' |
|||
'you will be able to promote your product in sale channels ,' |
|||
' on facebook shops, instagram shopping, with dynamic ads,' |
|||
' and more.', |
|||
'author': 'Cybrosys Techno Solutions', |
|||
'company': 'Cybrosys Techno Solutions', |
|||
'maintainer': 'Cybrosys Techno Solutions', |
|||
'website': 'https://www.cybrosys.com', |
|||
'depends': ['website_sale', 'product', 'mail', 'stock'], |
|||
'data': [ |
|||
'security/ir.model.access.csv', |
|||
'views/product_data_feed_views.xml', |
|||
'views/product_data_feed_columns_views.xml', |
|||
'views/field_column_value_views.xml', |
|||
], |
|||
'images': ['static/description/banner.jpg'], |
|||
'license': 'AGPL-3', |
|||
'installable': True, |
|||
'application': False, |
|||
'auto_install': False |
|||
} |
@ -1,22 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Subina P (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 odoo_fb_insta_product_data_feed |
@ -1,95 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Subina P (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 csv |
|||
from six import StringIO |
|||
from odoo import http |
|||
from odoo.http import request |
|||
|
|||
|
|||
class ProductData(http.Controller): |
|||
"""This controller handle for downloading the catalog csv file""" |
|||
def generate_formatted_file_content(self, columns, item_filter, record): |
|||
"""Generating the file content""" |
|||
# Apply the filter criteria and fetch the relevant items |
|||
filtered_items = request.env[record.used_model].search(item_filter) |
|||
formatted_rows = [] |
|||
# Iterate over each item and generate a row of values |
|||
for item in filtered_items: |
|||
row = [] |
|||
for column in columns: |
|||
if column.type == 'Model Field': |
|||
# Access the field value directly |
|||
value = getattr(item, column.value_id.name, '') |
|||
elif column.type == 'Special': |
|||
if column.special_type == 'product_availability': |
|||
# Access the product's on-hand quantity |
|||
on_hand_qty = item.qty_available |
|||
# Set value based on on-hand quantity |
|||
if on_hand_qty == 0: |
|||
value = 'out of stock' |
|||
else: |
|||
value = 'in stock' |
|||
elif column.special_type == 'qty': |
|||
value = item.qty_available |
|||
elif column.special_type == 'product_price': |
|||
value = item.standard_price |
|||
elif column.special_type == 'disc_price': |
|||
value = item.list_price |
|||
elif column.special_type == 'price_without_tax': |
|||
value = item.list_price |
|||
elif column.special_type == 'price_currency': |
|||
value = self.currency_id.name |
|||
elif column.type == 'Text': |
|||
value = column.value |
|||
elif column.type == 'Value': |
|||
value = column.field_value_id.column_name |
|||
else: |
|||
value = column.value |
|||
row.append(value) |
|||
formatted_rows.append(row) |
|||
return formatted_rows |
|||
|
|||
@http.route(['/product_data/<int:id>/<name>', |
|||
'/product_data/<name>' |
|||
], type="http", |
|||
auth='public') |
|||
def product_data(self, id, name): |
|||
"""Making the product data into a CSV formate.""" |
|||
record = request.env['product.data.feed'].sudo().browse(id) |
|||
column_ids = record.feed_columns_line_ids |
|||
item_filter = eval(record.item_filter) if record.item_filter else [] |
|||
formatted_file_content = self.generate_formatted_file_content( |
|||
column_ids, item_filter, record) |
|||
csv_content = StringIO() |
|||
csv_writer = csv.writer(csv_content) |
|||
column_header = [column.name for column in column_ids] |
|||
csv_writer.writerow(column_header) |
|||
for row in formatted_file_content: |
|||
csv_writer.writerow(row) |
|||
# Get CSV content as a string |
|||
csv_string = csv_content.getvalue() |
|||
csv_content.close() |
|||
headers = [ |
|||
('Content-Type', 'text/csv'), |
|||
('Content-Disposition', http.content_disposition(name + '.csv')), |
|||
] |
|||
return request.make_response(csv_string, headers=headers) |
@ -1,6 +0,0 @@ |
|||
## Module <odoo_fb_insta_product_data_feed> |
|||
|
|||
#### 20.04.2024 |
|||
#### Version 17.0.1.0.0 |
|||
#### ADD |
|||
- Initial Commit for Product Data Feed Generation |
@ -1,24 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Subina P (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 field_column_value |
|||
from . import product_data_feed |
|||
from . import product_data_feed_columns |
@ -1,40 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Subina P (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 FieldColumnValue(models.Model): |
|||
"""Model for storing field column values. |
|||
|
|||
This class represents field column values used in a product data feed. |
|||
It is used to define the mapping of column names to their corresponding |
|||
values. |
|||
""" |
|||
_name = 'field.column.value' |
|||
_description = 'Field Column Value' |
|||
_rec_name = 'value' |
|||
|
|||
feed_id = fields.Many2one('product.data.feed', |
|||
string='Feed Name', help='Feed Name') |
|||
column_name = fields.Char(string='Column Name', |
|||
help='Enter the column name.') |
|||
value = fields.Char(string='Value', help='Value of the column name.') |
@ -1,246 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Subina P (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 secrets |
|||
import string |
|||
import csv |
|||
from io import StringIO |
|||
from odoo import api, fields, models |
|||
|
|||
|
|||
class ProductDataFeed(models.Model): |
|||
"""Data feed model for managing and generating product data feeds. |
|||
This class represents a product data feed, which can be used to export |
|||
product information in a specific format. It inherits from 'mail.thread' |
|||
and 'mail.activity.mixin' to provide messaging and activity tracking |
|||
capabilities.""" |
|||
_name = 'product.data.feed' |
|||
_description = 'Product Data Feed' |
|||
_inherit = ['mail.thread', 'mail.activity.mixin'] |
|||
|
|||
name = fields.Char(string='Name', help='Name of the feed', copy=False, |
|||
required=True) |
|||
url_link = fields.Char(string='Link', help='Data feed download link', |
|||
compute='_compute_url_link') |
|||
is_token = fields.Boolean(string='Use Token', |
|||
help='Use token or Not for the ' |
|||
'security') |
|||
access_token = fields.Char(string='Access Token', |
|||
help='Access Token of the feed', |
|||
compute='_compute_access_token') |
|||
website_id = fields.Many2one('website', string='Websites', |
|||
help='Allow this data feed for the selected ' |
|||
'websites.Allow for all if not set ') |
|||
format = fields.Char(string='File Formate', |
|||
help='The file formate of the data feed.', |
|||
default='CSV', readonly=True) |
|||
is_file_name = fields.Boolean(string='File Name', |
|||
help='Enabled the file name') |
|||
name_show = fields.Char(string='File Name', help='Show the file name', |
|||
compute='_compute_name_show') |
|||
use_model = fields.Selection( |
|||
[('Product', 'Product'), ('Product Variant', 'Product Variant')], |
|||
string='Use Model', help='Used model of the product feed', |
|||
default='Product', required=True) |
|||
used_model = fields.Char(string='Used Model', help='Model') |
|||
item_filter = fields.Char(string='Item Filter', help='The model domain to' |
|||
' filter for the feed') |
|||
feed_columns_line_ids = fields.One2many('product.data.feed.columns', |
|||
'data_feed_columns_id', |
|||
string='Columns', |
|||
help='Feed column line', |
|||
readonly=True,) |
|||
columns_count = fields.Integer(string='Columns Count', |
|||
help='Total number of columns used this ' |
|||
'feed', |
|||
compute='_compute_columns_count') |
|||
|
|||
def generate_formatted_file_content(self, columns, item_filter): |
|||
"""Generate formatted content for a file based on specified columns |
|||
and an item filter.This method applies the provided filter criteria to |
|||
fetch relevant items from the environment, and then generates formatted |
|||
rows of values for the specified columns for each item.""" |
|||
# Apply the filter criteria and fetch the relevant items |
|||
filtered_items = self.env[self.used_model].search(item_filter) |
|||
formatted_rows = [] |
|||
# Iterate over each item and generate a row of values |
|||
for item in filtered_items: |
|||
row = [] |
|||
value = '' |
|||
for column in columns: |
|||
if column.type == 'Model Field': |
|||
# Access the field value directly |
|||
model_value = getattr(item, column.value_id.name, '') |
|||
if model_value: |
|||
value = model_value |
|||
else: |
|||
value = '' |
|||
|
|||
elif column.type == 'Special': |
|||
if column.special_type == 'product_availability': |
|||
# Access the product's on-hand quantity |
|||
on_hand_qty = item.qty_available |
|||
# Set value based on on-hand quantity |
|||
if on_hand_qty == 0: |
|||
value = 'out of stock' |
|||
else: |
|||
value = 'in stock' |
|||
elif column.special_type == 'qty': |
|||
value = item.qty_available |
|||
elif column.special_type == 'product_price': |
|||
value = item.standard_price |
|||
elif column.special_type == 'disc_price': |
|||
value = item.list_price |
|||
elif column.special_type == 'price_without_tax': |
|||
value = item.list_price |
|||
elif column.special_type == 'price_currency': |
|||
value = self.currency_id.name |
|||
elif column.special_type == 'image_link': |
|||
value = item.image_1920 |
|||
elif column.special_type == 'price_tax': |
|||
if item.taxes_id: |
|||
value = (item.list_price * ( |
|||
item.taxes_id.amount / 100) + |
|||
item.list_price) |
|||
else: |
|||
value = 0.0 |
|||
elif column.type == 'Text': |
|||
value = column.value |
|||
elif column.type == 'Value': |
|||
value = column.field_value_id.value |
|||
else: |
|||
value = column.value |
|||
if value: |
|||
row.append(value) |
|||
formatted_rows.append(row) |
|||
return formatted_rows |
|||
|
|||
def action_download_doc(self): |
|||
"""Download the catalog""" |
|||
columns = self.feed_columns_line_ids |
|||
item_filter = eval(self.item_filter) if self.item_filter else [] |
|||
formatted_file_content = self.generate_formatted_file_content( |
|||
columns, item_filter) |
|||
# Create a CSV content string |
|||
csv_content = StringIO() |
|||
csv_writer = csv.writer(csv_content) |
|||
column_header = [column.name for column in columns] |
|||
csv_writer.writerow(column_header) |
|||
for row in formatted_file_content: |
|||
csv_writer.writerow(row) |
|||
encoded_content = csv_content.getvalue().encode('utf-8') |
|||
# Close the StringIO buffer |
|||
csv_content.close() |
|||
attachment = self.env['ir.attachment'].create({ |
|||
'name': self.name_show if self.name_show else 'feed', |
|||
'type': 'binary', |
|||
'datas': base64.b64encode(encoded_content), |
|||
'res_model': self.used_model, |
|||
'res_id': self.id, |
|||
'mimetype': 'text/csv' |
|||
}) |
|||
return { |
|||
'type': 'ir.actions.act_url', |
|||
'target': 'new', |
|||
'url': f"/web/content/{attachment.id}?download=true" |
|||
} |
|||
|
|||
def action_product_items(self): |
|||
"""Open the product item list""" |
|||
return { |
|||
'type': 'ir.actions.act_window', |
|||
'name': 'Feed Items', |
|||
'view_mode': 'tree,form', |
|||
'res_model': self.used_model, |
|||
'domain': self.item_filter, |
|||
'context': self.env.context, |
|||
} |
|||
|
|||
def action_columns_creation(self): |
|||
"""Create the columns for feed.""" |
|||
return { |
|||
'type': 'ir.actions.act_window', |
|||
'name': 'Columns', |
|||
'view_mode': 'tree,form', |
|||
'res_model': 'product.data.feed.columns', |
|||
'context': { |
|||
'default_feed_id': self.id, |
|||
'default_data_feed_columns_id': self.id, |
|||
}, |
|||
'domain': [('feed_id', '=', self.id)] |
|||
} |
|||
|
|||
@api.depends('access_token') |
|||
def _compute_access_token(self): |
|||
"""Update the access token when enabling the token boolean field""" |
|||
access_tokens = secrets.token_urlsafe(27) |
|||
self.write({'access_token': access_tokens}) |
|||
|
|||
def action_refresh_token(self): |
|||
"""Refresh and generate new token""" |
|||
access_tokens = secrets.token_urlsafe( |
|||
27) # 27 bytes gives you 36 characters |
|||
self.write({'access_token': access_tokens}) |
|||
|
|||
@api.depends('name_show') |
|||
def _compute_name_show(self): |
|||
"""Generate the random name when enabling the file_name""" |
|||
prefix = "feed-" |
|||
random_length = 4 |
|||
random_chars = ''.join( |
|||
secrets.choice(string.ascii_letters + string.digits) for _ in |
|||
range(random_length)) |
|||
random_name = prefix + random_chars |
|||
self.write({'name_show': random_name}) |
|||
|
|||
@api.onchange('use_model') |
|||
def _onchange_use_model(self): |
|||
"""When changing the use_model it update the model into used_model""" |
|||
if self.use_model == 'Product': |
|||
self.write({'used_model': 'product.template'}) |
|||
else: |
|||
self.write({'used_model': 'product.product'}) |
|||
|
|||
@api.depends('format', 'name_show', 'is_token') |
|||
def _compute_url_link(self): |
|||
"""Compute the downloading link""" |
|||
for feed in self: |
|||
base_url = self.env['ir.config_parameter'].get_param( |
|||
'web.base.url') + '/product_data' |
|||
if feed.is_token and feed.is_file_name: |
|||
feed.url_link = f'{base_url}/{self.id}/{feed.name_show}.{feed.format}?access_token={feed.access_token}' |
|||
elif feed.is_file_name: |
|||
feed.url_link = f'{base_url}/{self.id}/{feed.name_show}.{feed.format}' |
|||
elif feed.is_token: |
|||
feed.url_link = f'{base_url}/{self.id}/feed.{feed.format}?access_token={feed.access_token}' |
|||
else: |
|||
feed.url_link = f'{base_url}/{self.id}/feed.{feed.format}' |
|||
|
|||
def _compute_columns_count(self): |
|||
"""Calculate the total number of column count of the current feed""" |
|||
for rec in self: |
|||
if rec.ids: |
|||
rec.columns_count = self.env[ |
|||
'product.data.feed.columns'].search_count( |
|||
[('feed_id', '=', rec.id)]) |
|||
else: |
|||
rec.columns_count = 0 |
@ -1,60 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Subina P (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 ProductDataFeedColumns(models.Model): |
|||
"""Model for defining columns in a product data feed. |
|||
|
|||
This class represents the columns used in a product data feed. These columns |
|||
define the structure of the data to be included in the feed, including |
|||
various types such as text, model fields, values, and special types.""" |
|||
_name = 'product.data.feed.columns' |
|||
_description = 'Product Data Feed Columns' |
|||
_inherit = ['mail.thread', 'mail.activity.mixin'] |
|||
|
|||
name = fields.Char(string='Name', help='Columns name') |
|||
feed_id = fields.Many2one('product.data.feed', |
|||
string='Feed', help='Feed Name') |
|||
type = fields.Selection( |
|||
[('Text', 'Text'), ('Model Field', 'Model Field'), |
|||
('Value', 'Value'), ('Special', 'Special')], |
|||
string='Type', help='Choose the type of the columns') |
|||
value = fields.Char(string="Value", help='Enter the column value') |
|||
value_id = fields.Many2one('ir.model.fields', |
|||
string="Value", help='Choose the column value', |
|||
) |
|||
field_value_id = fields.Many2one('field.column.value', |
|||
string="Value", |
|||
help='Choose the column value') |
|||
data_feed_columns_id = fields.Many2one('product.data.feed', |
|||
string='Data Columns', |
|||
help='Data columns inverse field') |
|||
special_type = fields.Selection( |
|||
[('product_price', 'Product Price'), |
|||
('disc_price', 'Discounted Price'), |
|||
('price_currency', 'Price Currency'), |
|||
('product_availability', 'Product Availability'), |
|||
('qty', 'Qty in Stock'), |
|||
('price_tax', 'Product Price(with Taxes)'), |
|||
('price_without_tax', 'Product Price(without Taxes)')], |
|||
string='Special Type', help='Choose the special type') |
|
Before Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 310 B |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 576 B |
Before Width: | Height: | Size: 733 B |
Before Width: | Height: | Size: 911 B |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 673 B |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 878 B |
Before Width: | Height: | Size: 653 B |
Before Width: | Height: | Size: 905 B |
Before Width: | Height: | Size: 839 B |
Before Width: | Height: | Size: 427 B |
Before Width: | Height: | Size: 627 B |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 988 B |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 80 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 589 B |
Before Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 565 B |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 967 B |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 5.0 KiB |
Before Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 284 KiB |
Before Width: | Height: | Size: 118 KiB |
Before Width: | Height: | Size: 108 KiB |
Before Width: | Height: | Size: 87 KiB |
Before Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 92 KiB |
Before Width: | Height: | Size: 85 KiB |
Before Width: | Height: | Size: 71 KiB |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 76 KiB |
Before Width: | Height: | Size: 180 KiB |
Before Width: | Height: | Size: 77 KiB |
Before Width: | Height: | Size: 85 KiB |
Before Width: | Height: | Size: 116 KiB |
Before Width: | Height: | Size: 91 KiB |
Before Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 167 KiB |
Before Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 162 KiB |
Before Width: | Height: | Size: 161 KiB |
Before Width: | Height: | Size: 161 KiB |
Before Width: | Height: | Size: 71 KiB |
Before Width: | Height: | Size: 95 KiB |
Before Width: | Height: | Size: 156 KiB |
Before Width: | Height: | Size: 197 KiB |
Before Width: | Height: | Size: 161 KiB |
Before Width: | Height: | Size: 474 KiB |
Before Width: | Height: | Size: 81 KiB |
Before Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 173 KiB |
Before Width: | Height: | Size: 87 KiB |
Before Width: | Height: | Size: 9.8 KiB |
@ -1,19 +0,0 @@ |
|||
<?xml version="1.0" encoding="UTF-8" ?> |
|||
<odoo> |
|||
<!-- Values creation form--> |
|||
<record id="field_column_value_view_form" model="ir.ui.view"> |
|||
<field name="name">field.column.value.view.form</field> |
|||
<field name="model">field.column.value</field> |
|||
<field name="arch" type="xml"> |
|||
<form> |
|||
<sheet> |
|||
<group> |
|||
<field name="feed_id"/> |
|||
<field name="column_name"/> |
|||
<field name="value"/> |
|||
</group> |
|||
</sheet> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
</odoo> |
@ -1,49 +0,0 @@ |
|||
<?xml version="1.0" encoding="UTF-8" ?> |
|||
<odoo> |
|||
<!-- Product data feed columns form view--> |
|||
<record id="product_data_feed_columns_view_form" model="ir.ui.view"> |
|||
<field name="name">product.data.feed.columns.view.form</field> |
|||
<field name="model">product.data.feed.columns</field> |
|||
<field name="arch" type="xml"> |
|||
<form name="product_data_feed_columns"> |
|||
<sheet> |
|||
<label for="name"/> |
|||
<div class="oe_title"> |
|||
<h3> |
|||
<field name="name" required="1"/> |
|||
</h3> |
|||
</div> |
|||
<group name="main"> |
|||
<group> |
|||
<field name="feed_id" default="context.get('default_feed_id')"/> |
|||
<field name="type"/> |
|||
<field name="value" invisible="type != 'Text'"/> |
|||
<field name="value_id" invisible="type != 'Model Field'"/> |
|||
<field name="field_value_id" invisible="type != 'Value'" context="{'default_feed_id': feed_id, 'default_column_name': name, 'default_value': field_value_id}"/> |
|||
<field name="special_type" invisible="type != 'Special'"/> |
|||
<field name="data_feed_columns_id" invisible="1" default="context.get('default_data_feed_columns_id')"/> |
|||
</group> |
|||
</group> |
|||
</sheet> |
|||
<div class="oe_chatter"> |
|||
<field name="message_follower_ids"/> |
|||
<field name="activity_ids"/> |
|||
<field name="message_ids"/> |
|||
</div> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
<!-- Product data feed column tree view--> |
|||
<record id="product_data_feed_columns_view_tree" model="ir.ui.view"> |
|||
<field name="name">product.data.feed.columns.view.tree</field> |
|||
<field name="model">product.data.feed.columns</field> |
|||
<field name="arch" type="xml"> |
|||
<tree> |
|||
<field name="name"/> |
|||
<field name="type"/> |
|||
<field name="value" string="Text Value"/> |
|||
<field name="field_value_id"/> |
|||
</tree> |
|||
</field> |
|||
</record> |
|||
</odoo> |
@ -1,111 +0,0 @@ |
|||
<?xml version="1.0" encoding="UTF-8" ?> |
|||
<odoo> |
|||
<!-- product data feed action--> |
|||
<record id="product_data_feed_action" model="ir.actions.act_window"> |
|||
<field name="name">Data Feed</field> |
|||
<field name="type">ir.actions.act_window</field> |
|||
<field name="res_model">product.data.feed</field> |
|||
<field name="view_mode">tree,form</field> |
|||
<field name="help" type="html"> |
|||
<p class="oe_view_nocontent_create"> |
|||
Click to add the data feed details. |
|||
</p> |
|||
</field> |
|||
</record> |
|||
<!-- Product data feed form view--> |
|||
<record id="product_data_feed_view_form" model="ir.ui.view"> |
|||
<field name="name">product.data.feed.view.form</field> |
|||
<field name="model">product.data.feed</field> |
|||
<field name="arch" type="xml"> |
|||
<form name="product_data_feed"> |
|||
<header> |
|||
<button name="action_download_doc" type="object" |
|||
string="Download" class="btn-secondary" |
|||
invisible="feed_columns_line_ids == []" |
|||
widget="statusbar"/> |
|||
</header> |
|||
<sheet name="product_data_feed"> |
|||
<!--smart button action--> |
|||
<div name="button_box" class="oe_button_box"> |
|||
<button name="action_product_items" string="Items" |
|||
class="oe_stat_button" |
|||
icon="fa-cubes" type="object"/> |
|||
<button name="action_columns_creation" type="object" |
|||
class="oe_stat_button" string="Columns" |
|||
icon="fa-list"> |
|||
<field name="columns_count" readonly="True"/> |
|||
<span class="o_stat_text">Columns</span> |
|||
</button> |
|||
</div> |
|||
<div class="oe_title"> |
|||
<h1> |
|||
<field name="name" required="1" |
|||
placeholder="Feed Name...."/> |
|||
</h1> |
|||
</div> |
|||
<field name="url_link" |
|||
widget="CopyClipboardChar" |
|||
class="w-100 pb-2"/> |
|||
<group> |
|||
<group> |
|||
<field name="is_token" widget="boolean_toggle"/> |
|||
<label for="access_token" invisible="is_token == False"/> |
|||
<div class="o_row" invisible="is_token == False"> |
|||
<field name="access_token"/> |
|||
<button class="btn-secondary" name="action_refresh_token" icon="fa-refresh" type="object" title="Refresh Token"/> |
|||
</div> |
|||
<field name="website_id"/> |
|||
<label for="name_show"/> |
|||
<div class="o_row"> |
|||
<field name="is_file_name" widget="boolean_toggle"/> |
|||
<field name="name_show" invisible="is_file_name == False" nolabel="1"/> |
|||
</div> |
|||
</group> |
|||
<group> |
|||
<field name="use_model" widget="radio"/> |
|||
<field name="used_model" invisible="1"/> |
|||
<field name="item_filter" widget="domain" options="{'model': 'product.template', 'in_dialog': true}" |
|||
invisible="use_model != 'Product'"/> |
|||
<field name="item_filter" widget="domain" options="{'model': 'product.product', 'in_dialog': true}" |
|||
invisible="use_model != 'Product Variant'"/> |
|||
<field name="format"/> |
|||
</group> |
|||
<notebook> |
|||
<page string="Columns" name="Columns"> |
|||
<field name="feed_columns_line_ids" readonly="1"> |
|||
<tree> |
|||
<field name="name"/> |
|||
</tree> |
|||
</field> |
|||
</page> |
|||
</notebook> |
|||
</group> |
|||
</sheet> |
|||
<div class="oe_chatter"> |
|||
<field name="message_follower_ids"/> |
|||
<field name="activity_ids"/> |
|||
<field name="message_ids"/> |
|||
</div> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
<!-- Product data feed tree view--> |
|||
<record id="product_data_feed_view_tree" model="ir.ui.view"> |
|||
<field name="name">product.data.feed.view.tree</field> |
|||
<field name="model">product.data.feed</field> |
|||
<field name="arch" type="xml"> |
|||
<tree> |
|||
<field name="name"/> |
|||
<field name="used_model"/> |
|||
<field name="is_token"/> |
|||
<field name="columns_count"/> |
|||
</tree> |
|||
</field> |
|||
</record> |
|||
<!-- product data feed menu--> |
|||
<menuitem id="product_data_feed_menu" |
|||
name="Product Data Feed" |
|||
parent="website_sale.menu_catalog" |
|||
action="product_data_feed_action" |
|||
sequence="6"/> |
|||
</odoo> |