Browse Source

Jun 14: [ADD] Initial Commit 'chatgpt_odoo_connector'

pull/320/head
RisvanaCybro 11 months ago
parent
commit
7c8bc35b6a
  1. 52
      chatgpt_odoo_connector/README.rst
  2. 23
      chatgpt_odoo_connector/__init__.py
  3. 63
      chatgpt_odoo_connector/__manifest__.py
  4. 22
      chatgpt_odoo_connector/controllers/__init__.py
  5. 43
      chatgpt_odoo_connector/controllers/chatgpt_odoo_connector.py
  6. 8
      chatgpt_odoo_connector/doc/RELEASE_NOTES.md
  7. 25
      chatgpt_odoo_connector/models/__init__.py
  8. 91
      chatgpt_odoo_connector/models/open_chatgpt.py
  9. 91
      chatgpt_odoo_connector/models/product_product.py
  10. 88
      chatgpt_odoo_connector/models/product_template.py
  11. 30
      chatgpt_odoo_connector/models/res_config_settings.py
  12. 2
      chatgpt_odoo_connector/security/ir.model.access.csv
  13. BIN
      chatgpt_odoo_connector/static/description/assets/icons/chatgpt.png
  14. BIN
      chatgpt_odoo_connector/static/description/assets/icons/check.png
  15. BIN
      chatgpt_odoo_connector/static/description/assets/icons/chevron.png
  16. BIN
      chatgpt_odoo_connector/static/description/assets/icons/close.png
  17. BIN
      chatgpt_odoo_connector/static/description/assets/icons/cogs.png
  18. BIN
      chatgpt_odoo_connector/static/description/assets/icons/consultation.png
  19. BIN
      chatgpt_odoo_connector/static/description/assets/icons/ecom-black.png
  20. BIN
      chatgpt_odoo_connector/static/description/assets/icons/education-black.png
  21. BIN
      chatgpt_odoo_connector/static/description/assets/icons/hotel-black.png
  22. BIN
      chatgpt_odoo_connector/static/description/assets/icons/license.png
  23. BIN
      chatgpt_odoo_connector/static/description/assets/icons/lifebuoy.png
  24. BIN
      chatgpt_odoo_connector/static/description/assets/icons/manufacturing-black.png
  25. BIN
      chatgpt_odoo_connector/static/description/assets/icons/pos-black.png
  26. BIN
      chatgpt_odoo_connector/static/description/assets/icons/puzzle.png
  27. BIN
      chatgpt_odoo_connector/static/description/assets/icons/restaurant-black.png
  28. BIN
      chatgpt_odoo_connector/static/description/assets/icons/service-black.png
  29. BIN
      chatgpt_odoo_connector/static/description/assets/icons/trading-black.png
  30. BIN
      chatgpt_odoo_connector/static/description/assets/icons/training.png
  31. BIN
      chatgpt_odoo_connector/static/description/assets/icons/update.png
  32. BIN
      chatgpt_odoo_connector/static/description/assets/icons/user.png
  33. BIN
      chatgpt_odoo_connector/static/description/assets/icons/wrench.png
  34. BIN
      chatgpt_odoo_connector/static/description/assets/misc/categories.png
  35. BIN
      chatgpt_odoo_connector/static/description/assets/misc/check-box.png
  36. BIN
      chatgpt_odoo_connector/static/description/assets/misc/compass.png
  37. BIN
      chatgpt_odoo_connector/static/description/assets/misc/corporate.png
  38. BIN
      chatgpt_odoo_connector/static/description/assets/misc/customer-support.png
  39. BIN
      chatgpt_odoo_connector/static/description/assets/misc/cybrosys-logo.png
  40. BIN
      chatgpt_odoo_connector/static/description/assets/misc/features.png
  41. BIN
      chatgpt_odoo_connector/static/description/assets/misc/logo.png
  42. BIN
      chatgpt_odoo_connector/static/description/assets/misc/pictures.png
  43. BIN
      chatgpt_odoo_connector/static/description/assets/misc/pie-chart.png
  44. BIN
      chatgpt_odoo_connector/static/description/assets/misc/right-arrow.png
  45. BIN
      chatgpt_odoo_connector/static/description/assets/misc/star.png
  46. BIN
      chatgpt_odoo_connector/static/description/assets/misc/support.png
  47. BIN
      chatgpt_odoo_connector/static/description/assets/misc/whatsapp.png
  48. BIN
      chatgpt_odoo_connector/static/description/assets/modules/1.png
  49. BIN
      chatgpt_odoo_connector/static/description/assets/modules/2.png
  50. BIN
      chatgpt_odoo_connector/static/description/assets/modules/3.png
  51. BIN
      chatgpt_odoo_connector/static/description/assets/modules/4.png
  52. BIN
      chatgpt_odoo_connector/static/description/assets/modules/5.png
  53. BIN
      chatgpt_odoo_connector/static/description/assets/modules/6.png
  54. BIN
      chatgpt_odoo_connector/static/description/assets/screenshots/1.png
  55. BIN
      chatgpt_odoo_connector/static/description/assets/screenshots/10.png
  56. BIN
      chatgpt_odoo_connector/static/description/assets/screenshots/11.png
  57. BIN
      chatgpt_odoo_connector/static/description/assets/screenshots/12.png
  58. BIN
      chatgpt_odoo_connector/static/description/assets/screenshots/13.png
  59. BIN
      chatgpt_odoo_connector/static/description/assets/screenshots/14.png
  60. BIN
      chatgpt_odoo_connector/static/description/assets/screenshots/15.png
  61. BIN
      chatgpt_odoo_connector/static/description/assets/screenshots/16.png
  62. BIN
      chatgpt_odoo_connector/static/description/assets/screenshots/17.png
  63. BIN
      chatgpt_odoo_connector/static/description/assets/screenshots/18.png
  64. BIN
      chatgpt_odoo_connector/static/description/assets/screenshots/19.png
  65. BIN
      chatgpt_odoo_connector/static/description/assets/screenshots/2.png
  66. BIN
      chatgpt_odoo_connector/static/description/assets/screenshots/20.png
  67. BIN
      chatgpt_odoo_connector/static/description/assets/screenshots/21.png
  68. BIN
      chatgpt_odoo_connector/static/description/assets/screenshots/3.png
  69. BIN
      chatgpt_odoo_connector/static/description/assets/screenshots/4.png
  70. BIN
      chatgpt_odoo_connector/static/description/assets/screenshots/5.png
  71. BIN
      chatgpt_odoo_connector/static/description/assets/screenshots/6.png
  72. BIN
      chatgpt_odoo_connector/static/description/assets/screenshots/7.png
  73. BIN
      chatgpt_odoo_connector/static/description/assets/screenshots/8.png
  74. BIN
      chatgpt_odoo_connector/static/description/assets/screenshots/9.png
  75. BIN
      chatgpt_odoo_connector/static/description/assets/screenshots/hero.gif
  76. BIN
      chatgpt_odoo_connector/static/description/banner.png
  77. BIN
      chatgpt_odoo_connector/static/description/icon.png
  78. 752
      chatgpt_odoo_connector/static/description/index.html
  79. BIN
      chatgpt_odoo_connector/static/src/Icons/icon.png
  80. 94
      chatgpt_odoo_connector/static/src/css/chatgpt_odoo.css
  81. 56
      chatgpt_odoo_connector/static/src/js/alternative_chatgpt.js
  82. 21
      chatgpt_odoo_connector/static/src/js/custom_toolbar.js
  83. 93
      chatgpt_odoo_connector/static/src/js/open_chatgpt.js
  84. 128
      chatgpt_odoo_connector/static/src/js/recordAudio.js
  85. 62
      chatgpt_odoo_connector/static/src/js/wysiwyg.js
  86. 33
      chatgpt_odoo_connector/static/src/xml/alternative_chatgpt.xml
  87. 13
      chatgpt_odoo_connector/static/src/xml/web_editor_toolbar.xml
  88. 15
      chatgpt_odoo_connector/views/product_product.xml
  89. 16
      chatgpt_odoo_connector/views/product_template.xml
  90. 26
      chatgpt_odoo_connector/views/res_config_settings_views.xml

52
chatgpt_odoo_connector/README.rst

@ -0,0 +1,52 @@
.. 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
ChatGPT Odoo Connector
======================
This module simplifies content creation and editing by integrating ChatGPT.
It also facilitates the generation of images for newly created products and
when modifying product names. Additionally, it includes a Speech-to-Text feature
that allows users to convert spoken language into written text, making hands-free
interaction possible and further streamlining the content creation process.
Configuration
=============
The user should install 'openai' for Python by running:
'sudo pip install openai' for authorization code flow.
Company
-------
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__
License
-------
Affero General Public License, Version 3 (AGPL v3).
(https://www.gnu.org/licenses/agpl-3.0-standalone.html)
Credits
-------
Developer: (V16) Ashwin 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>`__

23
chatgpt_odoo_connector/__init__.py

@ -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(<https://www.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 models

63
chatgpt_odoo_connector/__manifest__.py

@ -0,0 +1,63 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.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": "ChatGPT Odoo Connector",
"version": "16.0.1.0.0",
"category": "Productivity, Extra Tools ",
"summary": "User can create content, Generate product image and Convert spoken language into written text using AI.",
"description": """ This module simplifies content creation and editing by integrating ChatGPT.
It also facilitates the generation of images for newly created products and
when modifying product names. Additionally, it includes a Speech-to-Text feature
that allows users to convert spoken language into written text, making hands-free
interaction possible and further streamlining the content creation process.""",
'author': 'Cybrosys Techno Solutions',
'company': 'Cybrosys Techno Solutions',
'maintainer': 'Cybrosys Techno Solutions',
'website': "https://www.cybrosys.com",
'depends': ['mail', 'product', 'web_editor'],
'data': [
'security/ir.model.access.csv',
'views/res_config_settings_views.xml',
'views/product_template.xml',
'views/product_product.xml',
],
'assets': {
'web_editor.assets_wysiwyg': [
'chatgpt_odoo_connector/static/src/xml/web_editor_toolbar.xml',
'chatgpt_odoo_connector/static/src/xml/alternative_chatgpt.xml',
],
'web.assets_backend': [
'chatgpt_odoo_connector/static/src/css/chatgpt_odoo.css',
'chatgpt_odoo_connector/static/src/js/wysiwyg.js',
'chatgpt_odoo_connector/static/src/js/open_chatgpt.js',
'chatgpt_odoo_connector/static/src/js/recordAudio.js',
'chatgpt_odoo_connector/static/src/js/custom_toolbar.js',
'chatgpt_odoo_connector/static/src/js/alternative_chatgpt.js',
],
},
'external_dependencies': {'python': ['openai']},
'images': ['static/description/banner.png'],
'license': 'AGPL-3',
'installable': True,
'auto_install': False,
'application': False,
}

22
chatgpt_odoo_connector/controllers/__init__.py

@ -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(<https://www.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 chatgpt_odoo_connector

43
chatgpt_odoo_connector/controllers/chatgpt_odoo_connector.py

@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.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 http
from pathlib import Path
from odoo.http import request
import os
from odoo.tools import json
class SpeechToText(http.Controller):
@http.route('/upload_audio', type='http', auth='public', methods=['POST'], csrf=False)
def upload_audio(self, **kwargs):
"""
Function for uploading audio file into a file and
returns the path of the file as json format
"""
upload_dir = Path(__file__).parent
file = kwargs.get('file')
if file:
file_path = os.path.join(upload_dir, file.filename)
with open(file_path, 'wb') as f:
f.write(file.read())
return request.make_response(json.dumps({'filePath': file_path}), headers={'Content-Type': 'application/json'})
return request.make_response(json.dumps({'error': 'No file uploaded'}), headers={'Content-Type': 'application/json'})

8
chatgpt_odoo_connector/doc/RELEASE_NOTES.md

@ -0,0 +1,8 @@
## Module <chatgpt_odoo_connector>
#### 27.05.2024
#### Version 16.0.1.0.0
#### ADD
- Initial commit for ChatGPT Odoo Connector

25
chatgpt_odoo_connector/models/__init__.py

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.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 open_chatgpt
from . import product_product
from . import product_template
from . import res_config_settings

91
chatgpt_odoo_connector/models/open_chatgpt.py

@ -0,0 +1,91 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.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 os import remove
from openai import OpenAI
from odoo import api, models
class ChatGPTOdoo(models.Model):
_name = 'open.chatgpt'
_description = 'Open ChatGPT'
@api.model
def get_response(self, message):
"""Function for getting response based on the message."""
api_key = self.env['ir.config_parameter'].sudo().get_param('chatgpt_odoo_connector.api_key')
client = OpenAI(api_key=api_key)
try:
chat_completion = client.chat.completions.create(
messages=[
{
"role": "user",
"content": message,
}
],
model="gpt-3.5-turbo",
)
except Exception as e:
message = str(e).split("'message':")[1]
error_message = message.split(", 'type':")[0]
return error_message
return chat_completion.choices[0].message.content
@api.model
def edit_content(self, message, message_type):
"""Function for editing(shortening, lengthening, and rephrasing) the description """
api_key = self.env['ir.config_parameter'].sudo().get_param(
'chatgpt_odoo_connector.api_key')
client = OpenAI(api_key=api_key)
try:
chat_completion = client.chat.completions.create(
messages=[
{
"role": "user",
"content": f"{message_type}: {message}",
}
],
model="gpt-3.5-turbo",
)
except Exception as e:
message = str(e).split("'message':")[1]
error_message = message.split(", 'type':")[0]
return error_message
return chat_completion.choices[0].message.content
@api.model
def convert_to_text(self, audio_path):
""" Function for converting the audio from the file into text using AI.
It returns the text.
"""
api_key = self.env['ir.config_parameter'].sudo().get_param(
'chatgpt_odoo_connector.api_key')
client = OpenAI(api_key=api_key)
try:
audio_file = open(audio_path, "rb")
transcription = client.audio.transcriptions.create(
model="whisper-1",
file=audio_file
)
remove(audio_path)
except Exception as e:
return f'Error: {str(e)}'
return transcription.text

91
chatgpt_odoo_connector/models/product_product.py

@ -0,0 +1,91 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.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 requests
from openai import OpenAI
from odoo import api, fields, models
class ProductProduct(models.Model):
_inherit = 'product.product'
is_create_image = fields.Boolean(related='product_tmpl_id.is_create_image',
string='Generate Image',
readonly=False,
help='Check this box if you want to automatically generate an image for this product')
is_update_image = fields.Boolean(related='product_tmpl_id.is_update_image',
string='Update Image',
readonly=False,
help='Check this box if you want to automatically update an image for this product while changing the name.')
@api.model
def create(self, vals):
""" Method for generating images for product """
res = super(ProductProduct, self).create(vals)
if not res.image_1920 and res.is_create_image:
image_base64 = self.generate_image(res.name)
if image_base64:
res.write({
'image_1920': image_base64,
})
else:
res.message_post(
body="Failed to generate image for product: '%s' due to 'Incorrect API key provided or Other issues. You can find your API key at https://platform.openai.com/account/api-keys." % res.name,
message_type='notification')
return res
def write(self, vals):
""" Method for updating image if name of the product updates"""
if 'name' in vals and 'image_1920' not in vals:
is_update_image = vals.get('is_update_image', self.is_update_image)
if is_update_image:
image_base64 = self.generate_image(vals['name'])
if image_base64:
vals['image_1920'] = image_base64
else:
self.message_post(
body="Failed to update image for product: '%s' due to 'Incorrect API key provided or Other issues. You can find your API key at https://platform.openai.com/account/api-keys." %
vals['name'],
message_type='notification')
return super(ProductProduct, self).write(vals)
def generate_image(self, name):
""" Function for generating images with the help of AI based on the name
of the product"""
api_key = self.env['ir.config_parameter'].sudo().get_param(
'chatgpt_odoo_connector.api_key')
client = OpenAI(api_key=api_key)
try:
response = client.images.generate(
model="dall-e-3",
prompt=name,
size="1024x1024",
quality="standard",
n=1,
)
image_url = response.data[0].url
response = requests.get(image_url)
image_base64 = base64.b64encode(response.content)
except:
return None
return image_base64

88
chatgpt_odoo_connector/models/product_template.py

@ -0,0 +1,88 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.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 requests
from openai import OpenAI
from odoo import api, fields, models
class ProductTemplate(models.Model):
_inherit = 'product.template'
is_create_image = fields.Boolean(string='Generate Image',
default=True,
help='Check this box if you want to automatically generate an image for this product')
is_update_image = fields.Boolean(string='Update Image',
help='Check this box if you want to automatically update an image for this product while changing the name.')
@api.model
def create(self, vals):
""" Method for generating images for product """
res = super(ProductTemplate, self).create(vals)
if not res.image_1920 and res.is_create_image:
image_base64 = self.generate_image(res.name)
if image_base64:
res.write({
'image_1920': image_base64,
})
else:
res.message_post(
body="Failed to generate image for product: '%s' due to 'Incorrect API key provided or Other issues. You can find your API key at https://platform.openai.com/account/api-keys." % res.name,
message_type='notification')
return res
def write(self, vals):
""" Method for updating image if name of the product updates"""
if 'name' in vals and 'image_1920' not in vals:
is_update_image = vals.get('is_update_image', self.is_update_image)
if is_update_image:
image_base64 = self.generate_image(vals['name'])
if image_base64:
vals['image_1920'] = image_base64
else:
self.message_post(
body="Failed to update image for product: '%s' due to 'Incorrect API key provided or Other issues. You can find your API key at https://platform.openai.com/account/api-keys." %
vals['name'],
message_type='notification')
return super(ProductTemplate, self).write(vals)
def generate_image(self, name):
""" Function for generating images with the help of AI based on the name
of the product"""
api_key = self.env['ir.config_parameter'].sudo().get_param(
'chatgpt_odoo_connector.api_key')
client = OpenAI(api_key=api_key)
try:
response = client.images.generate(
model="dall-e-3",
prompt=name,
size="1024x1024",
quality="standard",
n=1,
)
image_url = response.data[0].url
response = requests.get(image_url)
image_base64 = base64.b64encode(response.content)
except:
return None
return image_base64

30
chatgpt_odoo_connector/models/res_config_settings.py

@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.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 ResConfigSettings(models.TransientModel):
"""Add field to configuration settings"""
_inherit = "res.config.settings"
api_key = fields.Char(string="API Key", help="Provide the API Key here",
config_parameter="chatgpt_odoo_connector.api_key")

2
chatgpt_odoo_connector/security/ir.model.access.csv

@ -0,0 +1,2 @@
id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
access_open_chatgpt,access.open.chatgpt,model_open_chatgpt,base.group_user,1,1,1,1
1 id name model_id/id group_id/id perm_read perm_write perm_create perm_unlink
2 access_open_chatgpt access.open.chatgpt model_open_chatgpt base.group_user 1 1 1 1

BIN
chatgpt_odoo_connector/static/description/assets/icons/chatgpt.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

BIN
chatgpt_odoo_connector/static/description/assets/icons/check.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
chatgpt_odoo_connector/static/description/assets/icons/chevron.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 B

BIN
chatgpt_odoo_connector/static/description/assets/icons/close.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

BIN
chatgpt_odoo_connector/static/description/assets/icons/cogs.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
chatgpt_odoo_connector/static/description/assets/icons/consultation.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
chatgpt_odoo_connector/static/description/assets/icons/ecom-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 B

BIN
chatgpt_odoo_connector/static/description/assets/icons/education-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

BIN
chatgpt_odoo_connector/static/description/assets/icons/hotel-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 911 B

BIN
chatgpt_odoo_connector/static/description/assets/icons/license.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
chatgpt_odoo_connector/static/description/assets/icons/lifebuoy.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
chatgpt_odoo_connector/static/description/assets/icons/manufacturing-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

BIN
chatgpt_odoo_connector/static/description/assets/icons/pos-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 878 B

BIN
chatgpt_odoo_connector/static/description/assets/icons/puzzle.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

BIN
chatgpt_odoo_connector/static/description/assets/icons/restaurant-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 B

BIN
chatgpt_odoo_connector/static/description/assets/icons/service-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 839 B

BIN
chatgpt_odoo_connector/static/description/assets/icons/trading-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

BIN
chatgpt_odoo_connector/static/description/assets/icons/training.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

BIN
chatgpt_odoo_connector/static/description/assets/icons/update.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
chatgpt_odoo_connector/static/description/assets/icons/user.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 988 B

BIN
chatgpt_odoo_connector/static/description/assets/icons/wrench.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
chatgpt_odoo_connector/static/description/assets/misc/categories.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
chatgpt_odoo_connector/static/description/assets/misc/check-box.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
chatgpt_odoo_connector/static/description/assets/misc/compass.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
chatgpt_odoo_connector/static/description/assets/misc/corporate.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
chatgpt_odoo_connector/static/description/assets/misc/customer-support.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
chatgpt_odoo_connector/static/description/assets/misc/cybrosys-logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
chatgpt_odoo_connector/static/description/assets/misc/features.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 589 B

BIN
chatgpt_odoo_connector/static/description/assets/misc/logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
chatgpt_odoo_connector/static/description/assets/misc/pictures.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
chatgpt_odoo_connector/static/description/assets/misc/pie-chart.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
chatgpt_odoo_connector/static/description/assets/misc/right-arrow.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 967 B

BIN
chatgpt_odoo_connector/static/description/assets/misc/star.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
chatgpt_odoo_connector/static/description/assets/misc/support.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

BIN
chatgpt_odoo_connector/static/description/assets/misc/whatsapp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
chatgpt_odoo_connector/static/description/assets/modules/1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

BIN
chatgpt_odoo_connector/static/description/assets/modules/2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

BIN
chatgpt_odoo_connector/static/description/assets/modules/3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

BIN
chatgpt_odoo_connector/static/description/assets/modules/4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

BIN
chatgpt_odoo_connector/static/description/assets/modules/5.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
chatgpt_odoo_connector/static/description/assets/modules/6.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

BIN
chatgpt_odoo_connector/static/description/assets/screenshots/1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

BIN
chatgpt_odoo_connector/static/description/assets/screenshots/10.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

BIN
chatgpt_odoo_connector/static/description/assets/screenshots/11.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

BIN
chatgpt_odoo_connector/static/description/assets/screenshots/12.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

BIN
chatgpt_odoo_connector/static/description/assets/screenshots/13.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

BIN
chatgpt_odoo_connector/static/description/assets/screenshots/14.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

BIN
chatgpt_odoo_connector/static/description/assets/screenshots/15.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

BIN
chatgpt_odoo_connector/static/description/assets/screenshots/16.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

BIN
chatgpt_odoo_connector/static/description/assets/screenshots/17.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

BIN
chatgpt_odoo_connector/static/description/assets/screenshots/18.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

BIN
chatgpt_odoo_connector/static/description/assets/screenshots/19.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

BIN
chatgpt_odoo_connector/static/description/assets/screenshots/2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

BIN
chatgpt_odoo_connector/static/description/assets/screenshots/20.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

BIN
chatgpt_odoo_connector/static/description/assets/screenshots/21.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

BIN
chatgpt_odoo_connector/static/description/assets/screenshots/3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

BIN
chatgpt_odoo_connector/static/description/assets/screenshots/4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

BIN
chatgpt_odoo_connector/static/description/assets/screenshots/5.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

BIN
chatgpt_odoo_connector/static/description/assets/screenshots/6.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

BIN
chatgpt_odoo_connector/static/description/assets/screenshots/7.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

BIN
chatgpt_odoo_connector/static/description/assets/screenshots/8.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

BIN
chatgpt_odoo_connector/static/description/assets/screenshots/9.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

BIN
chatgpt_odoo_connector/static/description/assets/screenshots/hero.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 KiB

BIN
chatgpt_odoo_connector/static/description/banner.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

BIN
chatgpt_odoo_connector/static/description/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

752
chatgpt_odoo_connector/static/description/index.html

@ -0,0 +1,752 @@
<div style="background-color: #714B67; height: 810px; width: 100%; padding: 15px; position: relative;">
<!-- TITLE BAR -->
<div class="d-flex align-items-center justify-content-between"
style="border-bottom: 1px solid #875A7B; padding: 15px; display: flex; justify-content: space-between; align-items: center;">
<img src="assets/misc/cybrosys-logo.png" width="42" height="42"
style="width: 42px; height: 42px;"/>
<div>
<div style="color: #7C7BAD; font-size: 14px; font-family: 'Montserrat', sans-serif; font-weight: bold; background-color: white; display: inline-block; padding: 3px 10px; border-radius: 50px;"
class="mr-2">
<i class="fa fa-check mr-1"></i>Community
</div>
<div style="color: #7C7BAD; font-size: 14px; font-family: 'Montserrat', sans-serif; font-weight: bold; background-color: white; display: inline-block; padding: 3px 10px; border-radius: 50px;"
class="mr-2">
<i class="fa fa-check mr-1"></i>Enterprise
</div>
</div>
</div>
<!-- END OF TITLE BAR -->
<div class="container">
<div class="row">
<div class="col-sm-12 col-md-12 col-lg-12">
<h1 style="color: #FFFFFF; font-weight: bolder; font-size: 50px; text-align: center; margin-top: 50px;">
ChatGPT Odoo Connector
</h1>
<p style="color:#FFFFFF; padding: 8px 15px; text-align: center; font-size: 24px;">
User can create content, Generate product image and Convert
spoken language into written text using AI
</p>
<!-- END OF APP HERO -->
<img src="assets/screenshots/hero.gif" class="img-responsive"
style="width: 100%; margin-left: auto; margin-right: auto;" />
</div>
</div>
</div>
</div>
<!-- NAVIGATION SECTION -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px; margin-top: 300px;">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/compass.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Explore This
Module</h2>
</div>
<div class="row my-4" style="font-family: 'Montserrat', sans-serif;">
<div class="col-sm-12 col-md-6 my-3">
<a href="#overview">
<div class="d-flex justify-content-between align-items-center"
style="background-color: #f5f5f5; padding: 30px; width: 100%;">
<div>
<span style="color: #714B67; font-size: 24px; font-weight: 500; display: block;">Overview</span>
<span style="color: #714B67; font-size: 16px; font-weight: 400; color:#282F33; display: block;">Learn more about this module</span>
</div>
<img src="assets/misc/right-arrow.png" width="36" height="36"/>
</div>
</a>
</div>
<div class="col-sm-12 col-md-6 my-3">
<a href="#features">
<div class="d-flex justify-content-between align-items-center"
style="background-color: #f5f5f5; padding: 30px; width: 100%;">
<div>
<span style="color: #714B67; font-size: 24px; font-weight: 500; display: block;">Features</span>
<span style="color: #714B67; font-size: 16px; font-weight: 400; color:#282F33; display: block;">View features of this module</span>
</div>
<img src="assets/misc/right-arrow.png" width="36" height="36"/>
</div>
</a>
</div>
<div class="col-sm-12 col-md-6 my-3">
<a href="#screenshots">
<div class="d-flex justify-content-between align-items-center"
style="background-color: #f5f5f5; padding: 30px; width: 100%;">
<div>
<span style="color: #714B67; font-size: 24px; font-weight: 500; display: block;">Screenshots</span>
<span style="color: #714B67; font-size: 16px; font-weight: 400; color:#282F33; display: block;">View screenshots for this module</span>
</div>
<img src="assets/misc/right-arrow.png" width="36" height="36"/>
</div>
</a>
</div>
</div>
<!-- END OF NAVIGATION SECTION -->
<!-- OVERVIEW SECTION -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px;"
id="overview">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/pie-chart.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Overview
</h2>
</div>
<div class="row"
style="font-family: 'Montserrat', sans-serif; font-weight: 400; font-size: 14px; line-height: 200%;">
<div class="col-sm-12 py-4">
This module simplifies content creation and editing by integrating ChatGPT.
It also facilitates the generation of images for newly created products and
when modifying product names. Additionally, it includes a Speech-to-Text feature
that allows users to convert spoken language into written text, making hands-free
interaction possible and further streamlining the content creation process.
</div>
</div>
<!-- END OF OVERVIEW SECTION -->
<!-- FEATURES SECTION -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px;"
id="features">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/features.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Features
</h2>
</div>
<div class="row"
style="font-family: 'Montserrat', sans-serif; font-weight: 400; font-size: 14px; line-height: 200%;">
<div class="col-sm-12 col-md-6">
<div class="d-flex align-items-center"
style="margin-top: 30px; margin-bottom: 30px">
<img src="assets/misc/check-box.png" class="mr-2"/>
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Available in Odoo 16.0 Community & Enterprise</span>
</div>
<div class="d-flex align-items-center"
style="margin-top: 30px; margin-bottom: 30px">
<img src="assets/misc/check-box.png" class="mr-2"/>
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Easy to Set Up API Key of the ChatGPT</span>
</div>
<div class="d-flex align-items-center"
style="margin-top: 30px; margin-bottom: 30px">
<img src="assets/misc/check-box.png" class="mr-2"/>
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Accessing questions and answers directly from the Odoo interface is as easy as interacting with ChatGPT</span>
</div>
<div class="d-flex align-items-center"
style="margin-top: 30px; margin-bottom: 30px">
<img src="assets/misc/check-box.png" class="mr-2"/>
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Image generation for products using AI</span>
</div>
<div class="d-flex align-items-center"
style="margin-top: 30px; margin-bottom: 30px">
<img src="assets/misc/check-box.png" class="mr-2"/>
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Speech to Text feature for hands-free interaction</span>
</div>
<div class="d-flex align-items-center"
style="margin-top: 30px; margin-bottom: 30px">
<img src="assets/misc/check-box.png" class="mr-2"/>
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Speech to Text feature supports 57 languages</span>
</div>
</div>
</div>
<!-- END OF FEATURES SECTION -->
<!-- SCREENSHOTS SECTION -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px;"
id="screenshots">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/pictures.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Screenshots
</h2>
</div>
<div class="row">
<div class="col-sm-12">
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Setting API Key
</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
Simply set chatGPT API Key inside Settings. You can find your API key at
<a href="https://platform.openai.com/account/api-keys">https://platform.openai.com/account/api-keys</a>
</p>
<img src="assets/screenshots/1.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
We can access ChatGPT from Text field section by typing '/'.
</p>
<img src="assets/screenshots/2.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
When we're selecting the ChatGPT option, we can have an interface for entering the question and click Send Icon.
</p>
<img src="assets/screenshots/3.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
We can see the generated response and also an 'INSERT' button.
</p>
<img src="assets/screenshots/4.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
While clicking the 'INSERT' button the generated response from AI will be added to the Notes field.
</p>
<img src="assets/screenshots/5.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
We can use the ChatGPT option for generating mail content also.
</p>
<img src="assets/screenshots/6.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Additional Feature
</h3>
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Edit Content
</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
We can perform various process on the content
such as shortening , lengthening or rephrasing the content.
Access these features by selecting the content.
</p>
<img src="assets/screenshots/7.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
Upon clicking the icon, a popup window emerges, presenting users
with various buttons for content processing options: shortening,
lengthening, or rephrasing. This interface allows users to select
their preferred method for modifying the content according to
their specific needs or objectives.
</p>
<img src="assets/screenshots/8.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
By clicking any of the button it will generate response and shows
in the specified field, and we can replace the content by clicking
the 'REPLACE' button.
</p>
<img src="assets/screenshots/9.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
If any errors while generating response it will return the response as error as shown in the image below.
</p>
<img src="assets/screenshots/10.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Generate Image
</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
Generate product image using AI while creating a new product or Updating name of a product.
To use the feature while creating a product, enable "Generate Image," enter a name for the product, and save.
</p>
<img src="assets/screenshots/11.png" class="img-thumbnail">
<img src="assets/screenshots/12.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
For updating the product image while changing the product name, enable "Update Image".
By turning on it will automatically generate an image and update it.
</p>
<img src="assets/screenshots/13.png" class="img-thumbnail">
<img src="assets/screenshots/14.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
If any errors encounter while generating or updating image using AI it will create a message in Log note.
</p>
<img src="assets/screenshots/15.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Speech-to-text
</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
Speech-to-Text using AI allows users to convert spoken language
into written text seamlessly. This feature leverages advanced artificial
intelligence to accurately transcribe voice inputs, enabling hands-free
interaction and improving efficiency in tasks such as note-taking, and content creation.
</p>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
We can access Speech-to-text from Text field section by typing '/'.
</p>
<img src="assets/screenshots/16.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
When we're selecting the Speech-to-text option, we can have an interface for recoding audio.
Start the recording by clicking the button.
</p>
<img src="assets/screenshots/17.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
After recording audio stop the recording by clicking the button.
</p>
<img src="assets/screenshots/18.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
By stopping the recording, the system will process the audio and
provide the transcribed text in the response.
</p>
<img src="assets/screenshots/19.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
While clicking the 'INSERT' button the generated Text form audio using AI will be added to the Notes field.
</p>
<img src="assets/screenshots/20.png" class="img-thumbnail">
<img src="assets/screenshots/21.png" class="img-thumbnail">
</div>
</div>
</div>
<!-- END OF SCREENSHOTS SECTION -->
<!-- RELATED PRODUCTS -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px;">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/categories.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Related
Products
</h2>
</div>
<div class="row">
<div class="col-sm-12">
<div id="demo1" class="row carousel slide" data-ride="carousel">
<!-- The slideshow -->
<div class="carousel-inner" style="padding: 30px;">
<div class="carousel-item" style="min-height: 198.656px;">
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16"
style="float:left">
<a href="https://apps.odoo.com/apps/modules/16.0/hide_menu_user/"
target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-radius: 0px;"
src="assets/modules/1.png">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16"
style="float:left">
<a href="https://apps.odoo.com/apps/modules/16.0/odoo_dynamic_dashboard/"
target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-radius: 0px;"
src="assets/modules/2.png">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16"
style="float:left">
<a href="https://apps.odoo.com/apps/modules/16.0/whatsapp_mail_messaging/"
target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-radius: 0px;"
src="assets/modules/3.png">
</div>
</a>
</div>
</div>
<div class="carousel-item active"
style="min-height: 198.656px;">
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16"
style="float:left">
<a href="https://apps.odoo.com/apps/modules/16.0/login_user_detail/"
target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-radius: 0px;"
src="assets/modules/4.png">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16"
style="float:left">
<a href="https://apps.odoo.com/apps/modules/16.0/all_in_one_dynamic_custom_fields/"
target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-radius: 0px;"
src="assets/modules/5.png">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16"
style="float:left">
<a href="https://apps.odoo.com/apps/modules/16.0/rest_api_odoo/"
target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-radius: 0px;"
src="assets/modules/6.png">
</div>
</a>
</div>
</div>
</div>
<!-- Left and right controls -->
<a class="carousel-control-prev" href="#demo1" data-slide="prev"
style="width:35px; color:#000"> <span
class="carousel-control-prev-icon"><i
class="fa fa-chevron-left"
style="font-size:24px"></i></span>
</a> <a class="carousel-control-next" href="#demo1"
data-slide="next" style="width:35px; color:#000">
<span class="carousel-control-next-icon"><i
class="fa fa-chevron-right"
style="font-size:24px"></i></span>
</a>
</div>
</div>
</div>
<!-- END OF RELATED PRODUCTS -->
<!-- OUR SERVICES -->
<section class="container" style="margin-top: 6rem !important;">
<div class="row">
<div class="col-lg-12 d-flex flex-column justify-content-center align-items-center">
<h2 style="color: #212529 !important;">Our Services</h2>
<hr style="border: 3px solid #714B67 !important; background-color: #714B67 !important; width: 80px !important; margin-bottom: 2rem !important;"/>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #1dd1a1 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/cogs.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Customization</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #ff6b6b !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/wrench.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Implementation</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #6462CD !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/lifebuoy.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Support</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #ffa801 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/user.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Hire
Odoo
Developer</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #54a0ff !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/puzzle.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Integration</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #6d7680 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/update.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Migration</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #786fa6 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/consultation.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Consultancy</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #f8a5c2 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/training.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo Implementation</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #e6be26 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/license.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo Licensing Consultancy</h6>
</div>
</div>
</section>
<!-- END OF OUR SERVICES -->
<!-- OUR INDUSTRIES -->
<section class="container" style="margin-top: 6rem !important;">
<div class="row">
<div class="col-lg-12 d-flex flex-column justify-content-center align-items-center">
<h2 style="color: #212529 !important;">Our Industries</h2>
<hr
style="border: 3px solid #714B67 !important; background-color: #714B67 !important; width: 80px !important; margin-bottom: 2rem !important;"/>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;">
<img src="./assets/icons/trading-black.png"
class="img-responsive mb-3" height="48px" width="48px">
<h5
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Trading
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Easily procure and sell your products</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;">
<img src="./assets/icons/pos-black.png"
class="img-responsive mb-3" height="48px" width="48px">
<h5
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
POS
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Easy
configuration
and convivial experience</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;">
<img src="./assets/icons/education-black.png"
class="img-responsive mb-3" height="48px"
width="48px">
<h5
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Education
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
A platform for
educational management</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;">
<img src="./assets/icons/manufacturing-black.png"
class="img-responsive mb-3" height="48px"
width="48px">
<h5
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Manufacturing
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Plan, track and
schedule your operations</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;">
<img src="./assets/icons/ecom-black.png"
class="img-responsive mb-3" height="48px" width="48px">
<h5
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
E-commerce &amp; Website
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Mobile
friendly,
awe-inspiring product pages</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;">
<img src="./assets/icons/service-black.png"
class="img-responsive mb-3" height="48px" width="48px">
<h5
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Service Management
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Keep track of
services and invoice</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;">
<img src="./assets/icons/restaurant-black.png"
class="img-responsive mb-3" height="48px"
width="48px">
<h5
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Restaurant
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Run your bar or
restaurant methodically</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;">
<img src="./assets/icons/hotel-black.png"
class="img-responsive mb-3" height="48px" width="48px">
<h5
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Hotel Management
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
An
all-inclusive
hotel management application</p>
</div>
</div>
</div>
</section>
<!-- END OF OUR INDUSTRIES -->
<!-- FOOTER -->
<!-- Footer Section -->
<section class="container" style="margin: 5rem auto 2rem;">
<div class="row" style="max-width:1540px;">
<div class="col-lg-12 d-flex flex-column justify-content-center align-items-center">
<h2 style="color: #212529 !important;">Need Help?</h2>
<hr
style="border: 3px solid #714B67 !important; background-color: #714B67 !important; width: 80px !important; margin-bottom: 2rem !important;"/>
</div>
</div>
<!-- Contact Cards -->
<div class="row d-flex justify-content-center align-items-center"
style="max-width:1540px; margin: 0 auto 2rem auto;">
<div class="col-lg-12"
style="padding: 0rem 3rem 2rem; border-radius: 10px; margin-right: 3rem; ">
<div class="row mt-4">
<div class="col-lg-6">
<a href="mailto:odoo@cybrosys.com" target="_blank"
class="btn btn-block mb-2 deep_hover"
style="text-decoration: none; background-color: #4d4d4d; color: #FFF; border-radius: 4px;"><i
class="fa fa-envelope mr-2"></i>odoo@cybrosys.com</a>
</div>
<div class="col-lg-6">
<a href="https://api.whatsapp.com/send?phone=918606827707"
target="_blank"
class="btn btn-block mb-2 deep_hover"
style="text-decoration: none; background-color: #25D366; color: #FFF; border-radius: 4px;"><i
class="fa fa-whatsapp mr-2"></i>+91 86068 27707</a>
</div>
</div>
</div>
</div>
<!-- End of Contact Cards -->
</section>
<!-- Footer -->
<section class="oe_container" style="padding: 2rem 3rem 1rem;">
<div class="row"
style="max-width:1540px; margin: 0 auto; margin-right: 3rem; ">
<!-- Logo -->
<div class="col-lg-12 d-flex justify-content-center align-items-center"
style="margin-top: 3rem;">
<img src="https://www.cybrosys.com/images/logo.png" width="200px"
height="auto"/>
</div>
<!-- End of Logo -->
<div class="col-lg-12">
<hr
style="margin-top: 3rem;background: linear-gradient(90deg, rgba(2,0,36,0) 0%, rgba(229,229,229,1) 33%, rgba(229,229,229,1) 58%, rgba(0,212,255,0) 100%); height: 2px; border-style: none;">
<!-- End of Footer Section -->
</div>
</div>
</section>
<!-- END OF FOOTER -->

BIN
chatgpt_odoo_connector/static/src/Icons/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

94
chatgpt_odoo_connector/static/src/css/chatgpt_odoo.css

@ -0,0 +1,94 @@
.popChatGPT{
background-color: #2d2d2d;
width: 600px;
height: 360px;
position: fixed;
left: 28%;
top: 28%;
padding: 50px;
z-index: 9999;
border-radius: 25px;
}
.popChatGPTAlter{
background-color: #2d2d2d;
width: 600px;
height: 360px;
position: fixed;
left: 28%;
top: 28%;
padding: 50px;
z-index: 9999;
border-radius: 25px;
}
.heading{
color: white;
margin-left: 10px;
}
.custom{
width:48%;
border-radius:10px;
}
.custom-input{
padding: 0.375rem 0.75rem;
font-size: 1.08333333rem;
font-weight: 400;
line-height: 1.5;
color: #ffffff;
background-color: #353535;
background-clip: padding-box;
border: 1px solid #353535;
height:40px;
border-radius: 12px 0px 0px 12px;
}
.custom-text{
padding: 0.375rem 0.75rem;
font-size: 1.08333333rem;
font-weight: 400;
line-height: 1.5;
color: #ffffff;
background-color: #353535;
background-clip: padding-box;
border: 1px solid #353535;
resize:none;
border-radius: 12px;
}
.alterButton{
border-radius:10px;
width: 120px;
}
#response::-webkit-scrollbar {
width: 5px;
}
/* Track */
#response::-webkit-scrollbar-track {
box-shadow: inset 0 0 5px grey;
border-radius: 10px;
}
#response::-webkit-scrollbar-thumb {
background: white;
border-radius: 10px;
}
#response::-webkit-scrollbar-thumb:hover {
background: #818281;
}
.audio-record{
display: flex;
justify-content: center
}
.button-mic{
border-radius: 13px;
height: 65px;
width: 55px;
}

56
chatgpt_odoo_connector/static/src/js/alternative_chatgpt.js

@ -0,0 +1,56 @@
odoo.define('chatgpt_odoo_connector.alternative_chatgpt', function (require) {
'use strict';
var Widget = require('web.Widget');
var rpc = require('web.rpc');
/* Extending the widget */
var AlternativeChatGPT = Widget.extend({
template: 'alternativeChatGPT',
events: {
'click .alterButton': '_onClick',
'click .Replace': '_onClickReplace',
'click .Cancel': '_onClickCancel',
},
init: function(parent, options) {
this._super(parent);
$(document).on('click', this._onOutSideClick.bind(this));
},
start: function() {
var self = this;
this._super.apply(this, arguments);
},
/* Function for clicking the buttons for shortening, lengthening and rephrasing the content */
_onClick: function(event){
var dataValue = event.target.getAttribute('data-value');
var message = this.__parentedParent.__parentedParent.el.innerText
this.response = rpc.query({
model: 'open.chatgpt',
method: 'edit_content',
args: [message,dataValue],
}).then((response) => {
document.getElementById('response').value = response;
})
},
/* Function for inserting the created response into the description field */
_onClickReplace: function(){
var new_content = document.getElementById('response').value;
if (new_content.trim()){
this.__parentedParent.__parentedParent.el.innerText = new_content
this._onClickCancel();
}
},
/* Function for closing the widget while clicking outside */
_onOutSideClick: function(ev){
var element = document.querySelector('.popChatGPTAlter');
var element_button = document.getElementsByClassName('chatgpt');
var isClickInsideElementButton = Array.from(element_button).some(button => button.contains(ev.target));
if (element && !element.contains(ev.target) && !isClickInsideElementButton){
this._onClickCancel();
}
},
/* Function for closing */
_onClickCancel: function(){
this.destroy()
}
});
return AlternativeChatGPT;
});

21
chatgpt_odoo_connector/static/src/js/custom_toolbar.js

@ -0,0 +1,21 @@
odoo.define('chatgpt_odoo_connector.custom_toolbar', function (require) {
'use strict';
var web_editor = require('web_editor.toolbar');
var Dialog = require('web.Dialog');
var AlternativeChatGPT = require('chatgpt_odoo_connector.alternative_chatgpt');
/* Adding a new button to the toolbar */
var toolbar = web_editor.include({
start: function () {
var res = this._super.apply(this, arguments);
this.$el.on('click', '#open-chatgpt', this._onButtonClick.bind(this));
return res;
},
/* Function for showing the widget while clicking the button. */
_onButtonClick: function () {
if (!this.alternativeChatGPT || this.alternativeChatGPT.isDestroyed()) {
this.alternativeChatGPT = new AlternativeChatGPT(this);
}
this.alternativeChatGPT.appendTo(this.el.offsetParent);
},
});
});

93
chatgpt_odoo_connector/static/src/js/open_chatgpt.js

@ -0,0 +1,93 @@
/** @odoo-module **/
const { Component, useState, useExternalListener, xml } = owl;
import { registry } from "@web/core/registry";
/* Extending the component and creating class OpenChatGPT */
export class OpenChatGPT extends Component {
constructor() {
super(...arguments);
this.state = useState({
message: '',
response: ''
});
this.Send = this.Send.bind(this);
this.Cancel = this.Cancel.bind(this);
this.onWindowEnter = this.onWindowEnter.bind(this);
useExternalListener(window, "click", this.onWindowClick);
useExternalListener(window, "keydown", this.onWindowEnter);
}
/* Getting the response based on the message provided */
async Send(ev){
if (ev.state.message.trim()){
this.state.response = await this.props.rpc.query({
model: 'open.chatgpt',
method: 'get_response',
args: [ev.state.message],
})
}
}
/* Function for inserting the response to the description field */
insert(){
var content = this.state.response
const lines = content.split('\n').filter(line => line.trim().length);
const fragment = document.createDocumentFragment();
for (const line of lines) {
const block = document.createElement(line.startsWith('Title: ') ? 'h2' : 'p');
block.innerText = line;
fragment.appendChild(block);
}
this.props.self.el.appendChild(fragment);
this.Cancel()
}
/* Function for cancelling */
Cancel(){
var element = document.querySelector('.popChatGPT');
element.remove();
}
/* Function for closing the widget while clicking outside */
onWindowClick(ev) {
var element = document.querySelector('.popChatGPT');
if (element && !element.contains(ev.target)){
element.remove();
}
}
/* Function for calling the function Send */
onWindowEnter(ev){
var element = document.querySelector('.popChatGPT');
if (element && ev.key == 'Enter'){
this.Send(this)
}
}
}
OpenChatGPT.template = xml`
<div class="popChatGPT">
<div style="display: flex; align-items: end;margin-top:-20px;">
<img src="chatgpt_odoo_connector/static/src/Icons/icon.png" height="35px"/>
<div class="h2 heading">ChatGPT</div>
</div>
<hr/>
<div class="mb-3">
<label for="message" class="form-label" style="color:white;">Message</label>
<div style="display: flex;">
<input type="text" class="custom-input" id="message" placeholder="Enter message"
t-model="state.message"/>
<button class="btn btn-success" style="border-radius:0px 12px 12px 0px;" t-on-click="() => Send(this)">
<i class="fa fa-paper-plane"></i>
</button>
</div>
</div>
<label for="response" class="form-label" style="color:white;" t-if="state.response">Response</label>
<div t-if="state.response">
<div class="mb-3">
<textarea id="response" class="custom-text" rows="4" t-model="state.response"></textarea>
</div>
</div>
<div style="display: flex;justify-content: space-around;">
<button class="btn btn-primary custom" t-if="state.response" t-on-click="insert">Insert</button>
<button class="btn btn-secondary custom" t-on-click="Cancel">Cancel</button>
</div>
</div>`;
registry.category("actions").add("chatGPT", OpenChatGPT);

128
chatgpt_odoo_connector/static/src/js/recordAudio.js

@ -0,0 +1,128 @@
/** @odoo-module **/
const { Component, useState, useRef, useExternalListener, xml } = owl;
import { registry } from "@web/core/registry";
import { browser } from '@web/core/browser/browser';
import {_t} from 'web.core';
/* Extending the component and creating class recordAudio */
export class recordAudio extends Component {
constructor() {
super(...arguments);
this.state = useState({
startedRecording: '',
transcriptedText: '',
audioChunks: [],
});
this.recordAudio = this.recordAudio.bind(this);
this.stopRecord = this.stopRecord.bind(this);
this.onWindowClick = this.onWindowClick.bind(this);
useExternalListener(window, "click", this.onWindowClick);
}
/* Function for recording audio and save the recording in a file. */
async recordAudio(ev){
this.state.startedRecording = true
this.state.audioChunks = [];
try {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
this.mediaRecorder = new MediaRecorder(stream);
this.mediaRecorder.ondataavailable = (e) => {
if (e.data.size > 0) {
this.state.audioChunks.push(e.data);
}
};
this.mediaRecorder.onstop = async () => {
if (this.state.audioChunks.length > 0) {
const audioBlob = new Blob(this.state.audioChunks, { type: 'audio/wav' });
const file = new File([audioBlob], 'recorded_audio.wav', { type: 'audio/wav' });
const formData = new FormData();
formData.append('file', file);
const response = await fetch('/upload_audio', {
method: 'POST',
body: formData,
});
const { filePath } = await response.json();
this.state.transcriptedText = await this.props.rpc.query({
model: 'open.chatgpt',
method: 'convert_to_text',
args: [filePath],
})
}
};
this.audioStream = stream;
this.mediaRecorder.start();
} catch (error) {
this.props.self.displayNotification({
title: _t('Warning'),
message: "Recording Error: Error accessing Microphone"
});
}
}
/* Function for stop audio recording */
async stopRecord() {
this.state.startedRecording = false;
if (this.mediaRecorder && this.mediaRecorder.state !== 'inactive') {
this.mediaRecorder.stop();
if (this.audioStream) {
this.audioStream.getTracks().forEach(track => track.stop());
}
}
}
/* Function for inserting the converted text from the audio file. */
Insert(){
var content = this.state.transcriptedText
const lines = content.split('\n').filter(line => line.trim().length);
const fragment = document.createDocumentFragment();
for (const line of lines) {
const block = document.createElement(line.startsWith('Title: ') ? 'h2' : 'p');
block.innerText = line;
fragment.appendChild(block);
}
this.props.self.el.appendChild(fragment);
this.Cancel()
}
/* Function for cancelling it will remove the element popChatGPT*/
Cancel(){
var element = document.querySelector('.popChatGPT');
element.remove();
}
/* Function for closing the widget while clicking outside */
onWindowClick(ev) {
var element = document.querySelector('.popChatGPT');
if (element && !element.contains(ev.target)){
this.Cancel()
}
}
}
recordAudio.template = xml`
<div class="popChatGPT">
<div style="display: flex; align-items: end;margin-top:-20px;">
<img src="chatgpt_odoo_connector/static/src/Icons/icon.png" height="35px"/>
<div class="h2 heading">Speech-to-text</div>
</div>
<hr/>
<div class="mb-3 audio-record">
<button class="btn btn-success button-mic" t-if="!state.startedRecording" t-on-click="() => recordAudio(this)">
<i class="fa fa-microphone" style="font-size: 24px;color:black;"/>
</button>
<button class="btn btn-danger button-mic" t-if="state.startedRecording" style="border-radius:13px;" t-on-click="() => stopRecord(this)">
<i class="fa fa-microphone-slash" style="font-size: 24px;color:black;"></i>
</button>
</div>
<label for="response" class="form-label" t-if="state.transcriptedText"
style="color:white;">Response</label>
<div t-if="state.transcriptedText">
<div class="mb-3">
<textarea id="response" class="custom-text" rows="4" t-model="state.transcriptedText"></textarea>
</div>
</div>
<div style="display: flex;justify-content: space-around;">
<button class="btn btn-primary custom" t-if="state.transcriptedText" t-on-click="Insert">Insert</button>
<button class="btn btn-secondary custom" t-on-click="Cancel">Cancel</button>
</div>
</div>`;
registry.category("actions").add("recordAudio", recordAudio);

62
chatgpt_odoo_connector/static/src/js/wysiwyg.js

@ -0,0 +1,62 @@
/** @odoo-module **/
import Wysiwyg from 'web_editor.wysiwyg';
import { browser } from '@web/core/browser/browser';
import { _t } from 'web.core';
var Dialog = require('web.Dialog');
var core = require('web.core');
var QWeb = core.qweb;
var rpc = require('web.rpc');
import { OpenChatGPT } from "./open_chatgpt";
import { recordAudio } from "./recordAudio";
const { mount } = owl;
/* Appending new Category AI Tools, Chatgpt tool, and Speech-to-text tool in the powerbox options */
Wysiwyg.include({
init: function (parent, options) {
this._super.apply(this, arguments);
},
/* Function for adding new category and tool */
_getPowerboxOptions: function (){
const options = this._super();
const { commands, categories } = options;
const Category = {
name: _t('AI Tools'),
priority: 40
};
const itemSectionCommand = {
category: _t('AI Tools'),
name: _t('ChatGPT'),
priority: 40,
description: _t('Generate content with AI'),
fontawesome: 'fa-magic',
callback: this._openChatGPT.bind(this)
};
const itemSpeechToAudio = {
category: _t('AI Tools'),
name: _t('Speech-To-Text'),
priority: 40,
description: _t('Speech to text'),
fontawesome: 'fa-microphone',
callback: this._recordVoice.bind(this)
};
categories.push(Category);
commands.push(itemSectionCommand);
commands.push(itemSpeechToAudio);
return options;
},
/* Function for mounting the element of chatgpt in the view */
_openChatGPT: function () {
var element = $('.o_web_client')[0];
if (element) {
const props = {rpc: rpc, self: this};
mount(OpenChatGPT, element, {props: props});
}
},
/* Function for mounting the element speech-to-text in the view */
_recordVoice: function () {
var element = $('.o_web_client')[0];
if (element) {
const props = {rpc: rpc, self: this};
mount(recordAudio, element, {props: props});
}
},
});

33
chatgpt_odoo_connector/static/src/xml/alternative_chatgpt.xml

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<!-- Template for alternative chatgpt -->
<t t-name="alternativeChatGPT" id="chatGPTdialog">
<div class="popChatGPTAlter">
<div style="display: flex; align-items: end;margin-top:-20px;">
<img src="chatgpt_odoo_connector/static/src/Icons/icon.png" height="35px"/>
<div class="h2 heading">ChatGPT</div>
</div>
<hr/>
<div style="display:flex;justify-content: space-evenly;">
<div>
<button class="alterButton btn btn-outline-light" data-value="shorten">Shorten</button>
</div>
<div>
<button class="alterButton btn btn-outline-light" data-value="lengthen">Lengthen</button>
</div>
<div>
<button class="alterButton btn btn-outline-light" data-value="rephrase">Rephrase</button>
</div>
</div>
<br/>
<div class="mb-3">
<label for="response" style="color:white;" class="form-label">Response</label>
<textarea class="custom-text" id="response" rows="4"/>
</div>
<div style="display: flex;justify-content: space-around;">
<button class="Replace custom btn btn-primary">Replace</button>
<button class="Cancel custom btn btn-secondary">Cancel</button>
</div>
</div>
</t>
</templates>

13
chatgpt_odoo_connector/static/src/xml/web_editor_toolbar.xml

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<!-- Adding new icon in the web_editor toolbar-->
<t t-name="toolbarCustom" t-inherit="web_editor.toolbar" t-inherit-mode="extension" owl="1">
<xpath expr="//div[@id='link']" position="after">
<div id="chatgpt" class="btn-group">
<div id="open-chatgpt" title="Generate or transform content with AI" class="btn editor-ignore chatgpt">
<span class="fa fa-magic fa-fw"/>
</div>
</div>
</xpath>
</t>
</templates>

15
chatgpt_odoo_connector/views/product_product.xml

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<!-- Inheriting product_product view -->
<record id="product_normal_form_view" model="ir.ui.view">
<field name="name">product.product.view.form</field>
<field name="model">product.product</field>
<field name="inherit_id" ref="product.product_normal_form_view"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='product_tag_ids']" position="after">
<field name="is_create_image"/>
<field name="is_update_image"/>
</xpath>
</field>
</record>
</odoo>

16
chatgpt_odoo_connector/views/product_template.xml

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<!-- Inheriting product template view -->
<record id="product_template_only_form_view" model="ir.ui.view">
<field name="name">product.template.view.form</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_only_form_view"/>
<field name="arch" type="xml">
<xpath expr="//group[@name='group_standard_price']" position="inside">
<field name="is_create_image"/>
<field name="is_update_image"/>
</xpath>
</field>
</record>
</odoo>

26
chatgpt_odoo_connector/views/res_config_settings_views.xml

@ -0,0 +1,26 @@
<?xml version="1.0"?>
<odoo>
<!-- Inheriting res config settings view-->
<record id="res_config_settings_view_form" model="ir.ui.view">
<field name="name">
res.config.settings.view.form.inherit.odoo.ai
</field>
<field name="model">res.config.settings</field>
<field name="priority" eval="20"/>
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
<field name="arch" type="xml">
<xpath expr="//div[@name='integration']" position="inside">
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane" id="chatgpt">
</div>
<div class="o_setting_right_pane">
<label string="ChatGPT" for="api_key"/>
<div class="text-muted">
<field name="api_key"/>
</div>
</div>
</div>
</xpath>
</field>
</record>
</odoo>
Loading…
Cancel
Save