@ -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 |
||||
|
|
||||
|
Send POS Receipt and Invoice via WhatsApp |
||||
|
========================================= |
||||
|
This module helps to share POS Receipt and Invoice to customers through WhatsApp. |
||||
|
|
||||
|
Features |
||||
|
======== |
||||
|
* Send POS Receipt and Invoice through Whatsapp |
||||
|
* Capability to set separate WhatsApp authentication for individual POS sessions. |
||||
|
|
||||
|
Configuration |
||||
|
============= |
||||
|
Configure UltraMsg (https://docs.ultramsg.com/) to obtain the API instance and token. |
||||
|
|
||||
|
License |
||||
|
------- |
||||
|
Affero General Public License, v3.0 (AGPL v3). |
||||
|
(https://www.gnu.org/licenses/agpl-3.0-standalone.html) |
||||
|
|
||||
|
Company |
||||
|
------- |
||||
|
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__ |
||||
|
|
||||
|
Credits |
||||
|
------- |
||||
|
* Developers: (V17) Farhana Jahan PT, |
||||
|
Contact: odoo@cybrosys.com |
||||
|
|
||||
|
Contacts |
||||
|
-------- |
||||
|
* Mail Contact : odoo@cybrosys.com |
||||
|
* Website : https://cybrosys.com |
||||
|
|
||||
|
Bug Tracker |
||||
|
----------- |
||||
|
Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. |
||||
|
|
||||
|
Maintainer |
||||
|
========== |
||||
|
.. image:: https://cybrosys.com/images/logo.png |
||||
|
:target: https://cybrosys.com |
||||
|
|
||||
|
This module is maintained by Cybrosys Technologies. |
||||
|
|
||||
|
For support and more information, please visit `Our Website <https://cybrosys.com/>`__ |
||||
|
|
||||
|
Further information |
||||
|
=================== |
||||
|
HTML Description: `<static/description/index.html>`__ |
@ -0,0 +1,23 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions (odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from . import models |
||||
|
from . import wizard |
@ -0,0 +1,62 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions (odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################### |
||||
|
{ |
||||
|
'name': 'Send POS Receipt and Invoice via WhatsApp', |
||||
|
'version': '17.0.1.0.0', |
||||
|
'category': 'Point of Sale', |
||||
|
'summary': 'This module facilitates sending POS receipts and invoices ' |
||||
|
'through WhatsApp during POS sessions.', |
||||
|
'description': 'This module enables seamless integration between ' |
||||
|
'point-of-sale systems and WhatsApp, allowing businesses ' |
||||
|
'to effortlessly send receipts and invoices to customers ' |
||||
|
'during transactions. By streamlining communication channels,' |
||||
|
' it enhances customer engagement and convenience in retail ' |
||||
|
'interactions.', |
||||
|
'author': 'Cybrosys Techno Solutions', |
||||
|
'company': 'Cybrosys Techno Solutions', |
||||
|
'maintainer': 'Cybrosys Techno Solutions', |
||||
|
'website': "https://www.cybrosys.com", |
||||
|
'depends': ['point_of_sale'], |
||||
|
'data': [ |
||||
|
'security/ir_rule.xml', |
||||
|
'security/pos_receipt_invoice_send_whatsapp_groups.xml', |
||||
|
'security/ir.model.access.csv', |
||||
|
'views/configuration_manager_views.xml', |
||||
|
'views/res_partner_views.xml', |
||||
|
'views/res_config_settings_views.xml', |
||||
|
'views/whatsapp_message_views.xml', |
||||
|
'wizard/whatsapp_authenticate_views.xml', |
||||
|
], |
||||
|
'assets': { |
||||
|
'point_of_sale._assets_pos': [ |
||||
|
'pos_receipt_invoice_send_whatsapp/static/src/xml/partner_line_templates.xml', |
||||
|
'pos_receipt_invoice_send_whatsapp/static/src/xml/receipt_screen_templates.xml', |
||||
|
'pos_receipt_invoice_send_whatsapp/static/src/xml/payment_screen_templates.xml', |
||||
|
'pos_receipt_invoice_send_whatsapp/static/src/js/ReceiptScreen.js' |
||||
|
], |
||||
|
}, |
||||
|
'images': ['static/description/banner.jpg'], |
||||
|
'license': 'AGPL-3', |
||||
|
'installable': True, |
||||
|
'auto_install': False, |
||||
|
'application': False, |
||||
|
} |
@ -0,0 +1,5 @@ |
|||||
|
## Module <pos_receipt_invoice_send_whatsapp> |
||||
|
#### 12.06.2024 |
||||
|
#### Version 17.0.1.0.0 |
||||
|
##### ADD |
||||
|
- Initial commit for Send POS Receipt and Invoice via WhatsApp |
@ -0,0 +1,29 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions (odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from . import configuration_manager |
||||
|
from . import pos_config |
||||
|
from . import pos_order |
||||
|
from . import pos_session |
||||
|
from . import res_config_settings |
||||
|
from . import res_partner |
||||
|
from . import res_users |
||||
|
from . import whatsapp_message |
@ -0,0 +1,124 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions (odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################### |
||||
|
import base64 |
||||
|
import io |
||||
|
import json |
||||
|
|
||||
|
import qrcode |
||||
|
import requests |
||||
|
|
||||
|
from odoo import fields, models, _ |
||||
|
from odoo.exceptions import ValidationError |
||||
|
|
||||
|
|
||||
|
class ConfigurationManager(models.Model): |
||||
|
"""A new model is to be created for configuring the API settings |
||||
|
required to connect to WhatsApp.""" |
||||
|
_name = "configuration.manager" |
||||
|
_description = "Configuration Manager" |
||||
|
_rec_name = 'instance' |
||||
|
|
||||
|
instance = fields.Char(string="Instance", required=True, |
||||
|
help="Give instance for whatsapp api") |
||||
|
token = fields.Char(string="Token", required=True, |
||||
|
help="Give token for whatsapp api") |
||||
|
config_id = fields.Many2one("pos.config", string="Point of Sale", |
||||
|
required=True, |
||||
|
help="Give Point of Sale for whatsapp api") |
||||
|
state = fields.Selection( |
||||
|
selection=[('draft', 'Draft'), |
||||
|
('verified', 'Verified')], |
||||
|
default='draft', string="state", |
||||
|
help="State for connection") |
||||
|
|
||||
|
def action_authenticate(self): |
||||
|
""" Opens a wizard for scanning QR code, |
||||
|
After scanning number get active status.""" |
||||
|
url = f"https://api.ultramsg.com/{self.instance}/instance/status" |
||||
|
querystring = { |
||||
|
"token": self.token |
||||
|
} |
||||
|
headers = {'content-type': 'application/x-www-form-urlencoded'} |
||||
|
req = requests.request("GET", url, headers=headers, |
||||
|
params=querystring) |
||||
|
if req.status_code != 200: |
||||
|
raise ValidationError(_("Please provide valid token")) |
||||
|
if req.text == 'Client not found.': |
||||
|
return self.display_notification('danger', |
||||
|
'Please check the field values') |
||||
|
if req.json().get('status', {}).get('accountStatus', {}).get( |
||||
|
'substatus') == 'normal': |
||||
|
self.state = "draft" |
||||
|
qr_code_data = self.get_qr_code() |
||||
|
if qr_code_data: |
||||
|
return self.open_authenticate_wizard(qr_code_data) |
||||
|
if req.json().get('status', {}).get('accountStatus', {}).get( |
||||
|
'substatus') == 'connected': |
||||
|
self.state = "verified" |
||||
|
return self.display_notification('success', |
||||
|
'Already connected') |
||||
|
def get_qr_code(self): |
||||
|
"""Retrieve the QR code from the Ultramsg API.""" |
||||
|
url = f"https://api.ultramsg.com/{self.instance}/instance/qrCode" |
||||
|
querystring = { |
||||
|
"token": self.token |
||||
|
} |
||||
|
headers = {'content-type': 'application/x-www-form-urlencoded'} |
||||
|
response = requests.get(url, headers=headers, params=querystring) |
||||
|
if response.status_code == 200: |
||||
|
qr_code_data = response.text |
||||
|
return qr_code_data |
||||
|
else: |
||||
|
return None |
||||
|
|
||||
|
def display_notification(self, message_type, message): |
||||
|
""" Got connected message""" |
||||
|
return { |
||||
|
'type': 'ir.actions.client', |
||||
|
'tag': 'display_notification', |
||||
|
'params': { |
||||
|
'message': message, |
||||
|
'type': message_type, |
||||
|
'sticky': False, |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
def open_authenticate_wizard(self, qr_code_data): |
||||
|
"""Opens QR code scanning wizard""" |
||||
|
decoded_data = json.loads(qr_code_data) |
||||
|
qr_code_string = decoded_data['qrCode'] |
||||
|
img = qrcode.make(qr_code_string) |
||||
|
result = io.BytesIO() |
||||
|
img.save(result, format='PNG') |
||||
|
result.seek(0) |
||||
|
image_result = base64.b64encode(result.read()) |
||||
|
return { |
||||
|
'type': 'ir.actions.act_window', |
||||
|
'res_model': 'whatsapp.authenticate', |
||||
|
'name': 'WhatsApp Connect', |
||||
|
'views': [(False, 'form')], |
||||
|
'target': 'new', |
||||
|
'context': { |
||||
|
'default_qrcode': image_result, |
||||
|
'default_configuration_manager_id': self.id, |
||||
|
} |
||||
|
} |
@ -0,0 +1,37 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions (odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class PosConfig(models.Model): |
||||
|
"""Inherit the pos_config model to add additional fields |
||||
|
to the configuration settings.""" |
||||
|
_inherit = 'pos.config' |
||||
|
|
||||
|
pos_whatsapp_enabled = fields.Boolean(string='WhatsApp Enabled', |
||||
|
help='Checks WhatsApp Enabled button ' |
||||
|
'active or not') |
||||
|
apply_send_receipt_or_invoice = fields.Selection([ |
||||
|
('send_receipt', 'Send Receipt'), |
||||
|
('send_invoice', 'Send Invoice') |
||||
|
], string="Apply Send Receipt or Invoice", |
||||
|
help='Select either Receipt or Invoice for sending to WhatsApp.') |
@ -0,0 +1,146 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions (odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################### |
||||
|
import base64 |
||||
|
|
||||
|
import requests |
||||
|
|
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class PosOrder(models.Model): |
||||
|
"""Inherit the pos_order model to implement the functionality of sending |
||||
|
invoices and receipts by calling the UltraMsg API.""" |
||||
|
_inherit = 'pos.order' |
||||
|
|
||||
|
def action_send_invoice(self, **kwargs): |
||||
|
"""Sends an invoice to the customer via WhatsApp using |
||||
|
the UltraMsg API.""" |
||||
|
instant = self.env['configuration.manager'].search( |
||||
|
[('state', '=', 'verified'), |
||||
|
('config_id', '=', kwargs.get('config_id'))], limit=1) |
||||
|
order = self.search([('id', '=', kwargs.get('order_id'))]) |
||||
|
if not order.account_move: |
||||
|
order.action_pos_order_invoice() |
||||
|
attachment_id = self.env['ir.attachment'].search([ |
||||
|
('res_model', '=', 'mail.message'), |
||||
|
('res_id', 'in', order.account_move.message_ids.ids)]) |
||||
|
if not attachment_id: |
||||
|
report = self.env['ir.actions.report']._render_qweb_pdf( |
||||
|
"account.account_invoices", order.account_move.ids[0]) |
||||
|
values = { |
||||
|
'name': "Invoice" + order.name, |
||||
|
'type': 'binary', |
||||
|
'datas': base64.b64encode(report[0]), |
||||
|
'store_fname': base64.b64encode(report[0]), |
||||
|
'mimetype': 'application/pdf', |
||||
|
} |
||||
|
attachment_id = self.env['ir.attachment'].create(values) |
||||
|
if instant: |
||||
|
if order.partner_id.whatsapp_number: |
||||
|
url = f"https://api.ultramsg.com/{instant.instance}/messages/document" |
||||
|
payload = { |
||||
|
"token": instant.token, |
||||
|
"to": order.partner_id.whatsapp_number, |
||||
|
"filename": attachment_id.name, |
||||
|
"document": attachment_id.datas.decode('utf-8'), |
||||
|
"caption": "Your Invoice is here", |
||||
|
} |
||||
|
headers = {'content-type': 'application/x-www-form-urlencoded'} |
||||
|
try: |
||||
|
response = requests.post(url, data=payload, headers=headers) |
||||
|
response.raise_for_status() |
||||
|
if response.status_code == 200: |
||||
|
self.env['whatsapp.message'].create({ |
||||
|
'status': 'sent', |
||||
|
'from_user_id': self.env.user.id, |
||||
|
'to_user': order.partner_id.whatsapp_number, |
||||
|
'user_name': order.partner_id.name, |
||||
|
'body': 'Your Invoice is here', |
||||
|
'attachment_id': attachment_id.id, |
||||
|
'date_and_time_sent': fields.datetime.now() |
||||
|
}) |
||||
|
except requests.RequestException as e: |
||||
|
return {'status': 'error', 'message': str(e)} |
||||
|
else: |
||||
|
return {'status': 'error', |
||||
|
'message': 'Partner have not a Whatsapp Number'} |
||||
|
else: |
||||
|
return {'status': 'error', |
||||
|
'message': 'You are not connected with API'} |
||||
|
|
||||
|
def action_send_receipt(self, name, partner, ticket): |
||||
|
""" Sends a receipt on WhatsApp if WhatsApp is enabled and |
||||
|
the partner has a WhatsApp number is provided.""" |
||||
|
self.ensure_one() |
||||
|
filename = 'Receipt-' + name + '.jpg' |
||||
|
receipt = self.env['ir.attachment'].create({ |
||||
|
'name': filename, |
||||
|
'type': 'binary', |
||||
|
'datas': ticket, |
||||
|
'res_model': 'pos.order', |
||||
|
'res_id': self.ids[0], |
||||
|
'mimetype': 'image/jpeg', |
||||
|
}) |
||||
|
instant = self.env['configuration.manager'].search( |
||||
|
[('state', '=', 'verified'), |
||||
|
('config_id', '=', partner['config_id'])], limit=1) |
||||
|
if instant: |
||||
|
if partner['whatsapp']: |
||||
|
url = f"https://api.ultramsg.com/{instant.instance}/messages/document" |
||||
|
payload = { |
||||
|
"token": instant.token, |
||||
|
"to": partner['whatsapp'], |
||||
|
"filename": receipt.name, |
||||
|
"document": receipt.datas.decode('utf-8'), |
||||
|
"caption": "Your Receipt is here", |
||||
|
} |
||||
|
headers = {'content-type': 'application/x-www-form-urlencoded'} |
||||
|
try: |
||||
|
response = requests.post(url, data=payload, headers=headers) |
||||
|
response.raise_for_status() |
||||
|
if response.status_code == 200: |
||||
|
self.env['whatsapp.message'].create({ |
||||
|
'status': 'sent', |
||||
|
'from_user_id': self.env.user.id, |
||||
|
'to_user': partner['whatsapp'], |
||||
|
'user_name': partner['name'], |
||||
|
'body': 'Your Receipt is here', |
||||
|
'attachment_id': receipt.id, |
||||
|
'date_and_time_sent': fields.datetime.now() |
||||
|
}) |
||||
|
except requests.RequestException as e: |
||||
|
return {'status': 'error', 'message': str(e)} |
||||
|
else: |
||||
|
return {'status': 'error', |
||||
|
'message': 'Partner have not a Whatsapp Number'} |
||||
|
else: |
||||
|
return {'status': 'error', |
||||
|
'message': 'You are not connected with API'} |
||||
|
|
||||
|
def get_instance(self, **kwargs): |
||||
|
"""Retrieves the verified configuration instance.""" |
||||
|
instant = self.env['configuration.manager'].search( |
||||
|
[('state', '=', 'verified'), |
||||
|
('config_id', '=', kwargs.get('config_id'))], limit=1) |
||||
|
return { |
||||
|
'instant_id': instant.id |
||||
|
} |
@ -0,0 +1,42 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions (odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from odoo import models |
||||
|
|
||||
|
|
||||
|
class PosSession(models.Model): |
||||
|
"""Inherit the pos_session model to load the WhatsApp number field into |
||||
|
the POS session.""" |
||||
|
_inherit = 'pos.session' |
||||
|
|
||||
|
def _loader_params_res_partner(self): |
||||
|
"""Extends the loader parameters for the res_partner model to include |
||||
|
the 'whatsapp_number' field.""" |
||||
|
result = super()._loader_params_res_partner() |
||||
|
result['search_params']['fields'].extend(['whatsapp_number']) |
||||
|
return result |
||||
|
|
||||
|
def _loader_params_res_users(self): |
||||
|
"""Extends the loader parameters for the res_users model to include |
||||
|
the 'whatsapp_groups_checks' field.""" |
||||
|
result = super()._loader_params_res_users() |
||||
|
result['search_params']['fields'].extend(['whatsapp_groups_checks']) |
||||
|
return result |
@ -0,0 +1,40 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions (odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class ResConfigSettings(models.TransientModel): |
||||
|
"""Inherit the res_config_settings model to add a selection field |
||||
|
and a boolean field for enabling WhatsApp functionality.""" |
||||
|
_inherit = 'res.config.settings' |
||||
|
|
||||
|
pos_whatsapp_enabled = fields.Boolean( |
||||
|
related="pos_config_id.pos_whatsapp_enabled", readonly=False, |
||||
|
help='Checks WhatsApp Enabled button ' |
||||
|
'active or not') |
||||
|
apply_send_receipt_or_invoice = fields.Selection([ |
||||
|
('send_receipt', 'Send Receipt'), |
||||
|
('send_invoice', 'Send Invoice') |
||||
|
], string="Apply Send Receipt or Invoice", |
||||
|
related="pos_config_id.apply_send_receipt_or_invoice", |
||||
|
readonly=False, |
||||
|
help='Select either Receipt or Invoice for sending to WhatsApp.') |
@ -0,0 +1,31 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions (odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class ResPartner(models.Model): |
||||
|
"""Inherit the res_partner model to add a field for the WhatsApp number.""" |
||||
|
_inherit = 'res.partner' |
||||
|
|
||||
|
whatsapp_number = fields.Char(string='WhatsApp Number', |
||||
|
help='A field is needed to add the ' |
||||
|
'WhatsApp number of the partner.') |
@ -0,0 +1,37 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions (odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class ResUsers(models.Model): |
||||
|
"""Inherit the res_user model to add a field for the WhatsApp Groups |
||||
|
Enabled or not.""" |
||||
|
_inherit = 'res.users' |
||||
|
|
||||
|
whatsapp_groups_checks = fields.Boolean( |
||||
|
string='WhatsApp Groups Enabled or not', |
||||
|
compute="_compute_pos_receipt_invoice_send_whatsapp_group_user", |
||||
|
help='A field that checks groups is added or not.') |
||||
|
|
||||
|
def _compute_pos_receipt_invoice_send_whatsapp_group_user(self): |
||||
|
self.whatsapp_groups_checks = self.user_has_groups( |
||||
|
'pos_receipt_invoice_send_whatsapp.pos_receipt_invoice_send_whatsapp_group_user') |
@ -0,0 +1,50 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions (odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class WhatsappMessage(models.Model): |
||||
|
"""Create a new model to capture all messages sent through WhatsApp.""" |
||||
|
_name = "whatsapp.message" |
||||
|
_description = "Whatsapp Message" |
||||
|
_rec_name = 'res_name' |
||||
|
|
||||
|
res_name = fields.Char(related="attachment_id.res_name", |
||||
|
help='The name of the attachment ' |
||||
|
'that is sent to WhatsApp.') |
||||
|
status = fields.Char(string="Status", |
||||
|
help="Status of whatsapp messages") |
||||
|
from_user_id = fields.Many2one('res.users', string="Sent From", |
||||
|
help="From user in whatsapp messages", |
||||
|
required=True) |
||||
|
to_user = fields.Char(string="Sent to", |
||||
|
help="To user in whatsapp messages", required=True) |
||||
|
user_name = fields.Char(string="Partner Name", |
||||
|
help="Name of partner in whatsapp messages", |
||||
|
required=True) |
||||
|
body = fields.Char(string="Message", |
||||
|
help="Message body in whatsapp messages", required=True) |
||||
|
attachment_id = fields.Many2one('ir.attachment', string='Attachments', |
||||
|
help='Added POS attachments') |
||||
|
date_and_time_sent = fields.Datetime(string="Date and Time", |
||||
|
help='The date and time when the ' |
||||
|
'message was sent to WhatsApp.') |
|
@ -0,0 +1,19 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<odoo> |
||||
|
<data> |
||||
|
<!-- Record Rule to Restrict Access for group_survey_user --> |
||||
|
<record id="restrict_whatsapp_user" model="ir.rule"> |
||||
|
<field name="name">Restrict Whatsapp Message for Users</field> |
||||
|
<field ref="model_whatsapp_message" name="model_id"/> |
||||
|
<field name="domain_force">[('from_user_id','=',user.id)]</field> |
||||
|
<field name="groups" eval="[(4, ref('point_of_sale.group_pos_user'))]"/> |
||||
|
</record> |
||||
|
|
||||
|
<!-- Record Rule to Allow Access for group_survey_manager --> |
||||
|
<record id="allow_whatsapp_manager" model="ir.rule"> |
||||
|
<field name="name">Allow Whatsapp Message for Managers</field> |
||||
|
<field ref="model_whatsapp_message" name="model_id"/> |
||||
|
<field name="groups" eval="[(4, ref('point_of_sale.group_pos_manager'))]"/> |
||||
|
</record> |
||||
|
</data> |
||||
|
</odoo> |
@ -0,0 +1,9 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<odoo> |
||||
|
<data noupdate="0"> |
||||
|
<!--Access group for whatsapp configuration and messaging--> |
||||
|
<record id="pos_receipt_invoice_send_whatsapp_group_user" model="res.groups"> |
||||
|
<field name="name">Whatsapp Messaging</field> |
||||
|
</record> |
||||
|
</data> |
||||
|
</odoo> |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 310 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 576 B |
After Width: | Height: | Size: 733 B |
After Width: | Height: | Size: 911 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 673 B |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 878 B |
After Width: | Height: | Size: 653 B |
After Width: | Height: | Size: 905 B |
After Width: | Height: | Size: 839 B |
After Width: | Height: | Size: 427 B |
After Width: | Height: | Size: 627 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 988 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 80 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 565 B |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 43 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 85 KiB |
After Width: | Height: | Size: 71 KiB |
After Width: | Height: | Size: 76 KiB |
After Width: | Height: | Size: 44 KiB |
After Width: | Height: | Size: 82 KiB |
After Width: | Height: | Size: 49 KiB |
After Width: | Height: | Size: 117 KiB |
After Width: | Height: | Size: 44 KiB |
After Width: | Height: | Size: 134 KiB |
After Width: | Height: | Size: 87 KiB |
After Width: | Height: | Size: 121 KiB |
After Width: | Height: | Size: 147 KiB |
After Width: | Height: | Size: 181 KiB |
After Width: | Height: | Size: 56 KiB |
After Width: | Height: | Size: 82 KiB |
After Width: | Height: | Size: 82 KiB |
After Width: | Height: | Size: 86 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 342 KiB |
After Width: | Height: | Size: 128 KiB |
After Width: | Height: | Size: 83 KiB |
After Width: | Height: | Size: 355 KiB |
After Width: | Height: | Size: 95 KiB |
After Width: | Height: | Size: 129 KiB |
After Width: | Height: | Size: 74 KiB |
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 44 KiB |
After Width: | Height: | Size: 48 KiB |
After Width: | Height: | Size: 60 KiB |
After Width: | Height: | Size: 83 KiB |
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 66 KiB |
After Width: | Height: | Size: 413 KiB |
After Width: | Height: | Size: 99 KiB |
After Width: | Height: | Size: 14 KiB |
@ -0,0 +1,92 @@ |
|||||
|
/** @odoo-module */ |
||||
|
// Import dependencies
|
||||
|
import { patch } from "@web/core/utils/patch"; |
||||
|
import { ReceiptScreen } from "@point_of_sale/app/screens/receipt_screen/receipt_screen"; |
||||
|
import { jsonrpc } from "@web/core/network/rpc_service"; |
||||
|
import { _t } from "@web/core/l10n/translation"; |
||||
|
/** |
||||
|
* Patch ReceiptScreen to include functions for sending invoices and receipts via WhatsApp. |
||||
|
*/ |
||||
|
patch(ReceiptScreen.prototype, { |
||||
|
setup() { |
||||
|
super.setup(); |
||||
|
}, |
||||
|
//Function for sending Invoices via Whatsapp
|
||||
|
sendInvoiceOnWhatsapp() { |
||||
|
this.orderUiState.whatsappInvoiceSuccessful = null |
||||
|
this.orderUiState.isInvoiceSending = true; |
||||
|
var self = this; |
||||
|
const order_id = this.currentOrder.server_id |
||||
|
jsonrpc('/web/dataset/call_kw/pos.order/action_send_invoice', { |
||||
|
model: 'pos.order', |
||||
|
method: 'action_send_invoice', |
||||
|
args: [0], |
||||
|
kwargs: { |
||||
|
order_id: order_id, // Pass order_id as a keyword argument
|
||||
|
number: this.currentOrder.get_partner().whatsapp_number, |
||||
|
config_id: this.pos.config.id |
||||
|
} |
||||
|
}).then(function(result) { |
||||
|
if (!result) { |
||||
|
self.orderUiState.isInvoiceSending = false; |
||||
|
self.orderUiState.whatsappInvoiceSuccessful = true; |
||||
|
self.orderUiState.whatsappInvoiceNotice = _t("Message sent to Whatsapp."); |
||||
|
} else { |
||||
|
self.orderUiState.isInvoiceSending = false; |
||||
|
self.orderUiState.whatsappInvoiceSuccessful = false; |
||||
|
self.orderUiState.whatsappInvoiceNotice = _t("Wrong inputs detected. This may be due to incorrect API data entry or selecting the wrong session or whatsapp number is not given."); |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
//Function for sending Receipts via Whatsapp
|
||||
|
sendReceiptOnWhatsapp() { |
||||
|
this.orderUiState.whatsappReceiptSuccessful = null |
||||
|
this.orderUiState.isReceiptSending = true; |
||||
|
setTimeout(async () => { |
||||
|
try { |
||||
|
try { |
||||
|
const res = await jsonrpc('/web/dataset/call_kw/pos.order/get_instance', { |
||||
|
model: 'pos.order', |
||||
|
method: 'get_instance', |
||||
|
args: [0], |
||||
|
kwargs: {config_id: this.pos.config.id} |
||||
|
}); |
||||
|
if (res.instant_id) { |
||||
|
if (this.currentOrder.get_partner().whatsapp_number) { |
||||
|
await this._sendWhatsappReceiptToCustomer(); |
||||
|
this.orderUiState.isReceiptSending =false; |
||||
|
this.orderUiState.whatsappReceiptSuccessful = true; |
||||
|
this.orderUiState.whatsappReceiptNotice = _t("Message sent to Whatsapp."); |
||||
|
} |
||||
|
else{ |
||||
|
this.orderUiState.isReceiptSending = false; |
||||
|
this.orderUiState.whatsappReceiptSuccessful = false; |
||||
|
this.orderUiState.whatsappReceiptNotice = _t("Wrong inputs detected. This may be due to whatsapp number is not given."); |
||||
|
} |
||||
|
} else { |
||||
|
this.orderUiState.isReceiptSending = false; |
||||
|
this.orderUiState.whatsappReceiptSuccessful = false; |
||||
|
this.orderUiState.whatsappReceiptNotice = _t("Wrong inputs detected. This may be due to incorrect API data entry or selecting the wrong session."); |
||||
|
} |
||||
|
} catch (error) { |
||||
|
console.error("Authentication Error:", error); |
||||
|
} |
||||
|
} catch { |
||||
|
this.orderUiState.isReceiptSending = false; |
||||
|
this.orderUiState.whatsappReceiptSuccessful = false; |
||||
|
this.orderUiState.whatsappReceiptNotice = _t("Sending message failed. Please try again."); |
||||
|
} |
||||
|
}, 1000); |
||||
|
}, |
||||
|
async _sendWhatsappReceiptToCustomer() { |
||||
|
var self = this; |
||||
|
const partner = this.currentOrder.get_partner(); |
||||
|
const orderPartner = { |
||||
|
name: partner.name, |
||||
|
whatsapp: partner.whatsapp_number, |
||||
|
config_id: this.pos.config.id |
||||
|
}; |
||||
|
const configId = this.pos.config.id; |
||||
|
const result = await this.sendToCustomer(orderPartner, "action_send_receipt"); |
||||
|
}, |
||||
|
}); |
@ -0,0 +1,14 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<templates xml:space="preserve"> |
||||
|
<t t-name="pos_whatsapp_integration.PartnerLine" |
||||
|
t-inherit="point_of_sale.PartnerLine" t-inherit-mode="extension" owl="1"> |
||||
|
<!--Inherit point_of_sale.PartnerLine to incorporate the partner's |
||||
|
WhatsApp number into the partner line.--> |
||||
|
<xpath expr="//div[hasclass('email-field')]" position="after"> |
||||
|
<div t-if="props.partner.whatsapp_number" class="email-field mb-2"> |
||||
|
<i class="fa fa-whatsapp me-2"/> |
||||
|
<t t-esc="props.partner.whatsapp_number"/> |
||||
|
</div> |
||||
|
</xpath> |
||||
|
</t> |
||||
|
</templates> |
@ -0,0 +1,16 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<templates xml:space="preserve"> |
||||
|
<t t-name="pos_receipt_invoice_send_whatsapp.PaymentScreenButtons" |
||||
|
t-inherit="point_of_sale.PaymentScreenButtons" t-inherit-mode="extension" |
||||
|
owl="1"> |
||||
|
<!--Inherit point_of_sale.PaymentScreenButtons to incorporate the partner's |
||||
|
WhatsApp number into the Payment Screen.--> |
||||
|
<xpath expr="//span[hasclass('partner-name')]" position="after"> |
||||
|
<t t-if="currentOrder.get_partner().whatsapp_number"> |
||||
|
<div> </div> |
||||
|
<i class="fa fa-whatsapp me-2"/> |
||||
|
<t t-esc="currentOrder.get_partner().whatsapp_number"/> |
||||
|
</t> |
||||
|
</xpath> |
||||
|
</t> |
||||
|
</templates> |
@ -0,0 +1,54 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<templates xml:space="preserve"> |
||||
|
<t t-name="pos_receipt_invoice_send_whatsapp.ReceiptScreen" |
||||
|
t-inherit="point_of_sale.ReceiptScreen" t-inherit-mode="extension" |
||||
|
owl="1"> |
||||
|
<!--Inherit point_of_sale.ReceiptScreen to integrate the "Send Invoice" |
||||
|
and "Send Receipt" buttons, along with success and error messages. |
||||
|
Additionally, set conditions for displaying these buttons.--> |
||||
|
<xpath expr="//div[hasclass('buttons')]" position="after"> |
||||
|
<t t-if="pos.user.whatsapp_groups_checks"> |
||||
|
<t t-if="pos.config.pos_whatsapp_enabled"> |
||||
|
<t t-if="pos.config.apply_send_receipt_or_invoice == 'send_invoice' or pos.config.apply_send_receipt_or_invoice == false"> |
||||
|
<div class="buttons my-3"> |
||||
|
<button class="button print btn btn-lg btn-secondary w-100 py-3" |
||||
|
t-on-click="sendInvoiceOnWhatsapp"> |
||||
|
<i class="fa fa-whatsapp me-2" |
||||
|
t-ref="order-print-receipt-button" |
||||
|
t-if="!orderUiState.isInvoiceSending"/> |
||||
|
<i class="fa fa-spinner fa-spin me-2" |
||||
|
t-if="orderUiState.isInvoiceSending"/> |
||||
|
Send Invoice |
||||
|
</button> |
||||
|
<div class="notice mt-2"> |
||||
|
<div t-if="orderUiState.whatsappInvoiceSuccessful !== null" |
||||
|
t-attf-class="{{ orderUiState.whatsappInvoiceSuccessful ? 'successful text-success' : 'failed text-danger' }}"> |
||||
|
<t t-esc="orderUiState.whatsappInvoiceNotice"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</t> |
||||
|
<t t-if="pos.config.apply_send_receipt_or_invoice == 'send_receipt' or pos.config.apply_send_receipt_or_invoice == false"> |
||||
|
<div class="buttons my-3"> |
||||
|
<button class="button print btn btn-lg btn-secondary w-100 py-3" |
||||
|
t-on-click="sendReceiptOnWhatsapp"> |
||||
|
<i class="fa fa-whatsapp ms-2" |
||||
|
t-ref="order-print-receipt-button" |
||||
|
t-if="!orderUiState.isReceiptSending"/> |
||||
|
<i class="fa fa-spinner fa-spin me-2" |
||||
|
t-if="orderUiState.isReceiptSending"/> |
||||
|
Send Receipt |
||||
|
</button> |
||||
|
<div class="notice mt-2"> |
||||
|
<div t-if="orderUiState.whatsappReceiptSuccessful !== null" |
||||
|
t-attf-class="{{ orderUiState.whatsappReceiptSuccessful ? 'successful text-success' : 'failed text-danger' }}"> |
||||
|
<t t-esc="orderUiState.whatsappReceiptNotice"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</t> |
||||
|
</t> |
||||
|
</t> |
||||
|
</xpath> |
||||
|
</t> |
||||
|
</templates> |
@ -0,0 +1,43 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<odoo> |
||||
|
<!--View configuration manager list view--> |
||||
|
<record id="configuration_manager_view_list" model="ir.ui.view"> |
||||
|
<field name="name">configuration.manager.view.tree</field> |
||||
|
<field name="model">configuration.manager</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<tree> |
||||
|
<field name="instance"/> |
||||
|
<field name="token"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!--View configuration manager form view--> |
||||
|
<record id="configuration_manager_view_form" model="ir.ui.view"> |
||||
|
<field name="name">configuration.manager.view.form</field> |
||||
|
<field name="model">configuration.manager</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form> |
||||
|
<sheet> |
||||
|
<group> |
||||
|
<group> |
||||
|
<field name="instance"/> |
||||
|
<field name="token"/> |
||||
|
<field name="config_id"/> |
||||
|
<button name="action_authenticate" type="object" |
||||
|
class="oe_highlight" string="Authenticate"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
</sheet> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!--Action for view configuration manager list and form view--> |
||||
|
<record id="configuration_manager_action" model="ir.actions.act_window"> |
||||
|
<field name="name">Configuration Manager</field> |
||||
|
<field name="res_model">configuration.manager</field> |
||||
|
<field name="view_mode">tree,form</field> |
||||
|
</record> |
||||
|
<!--Menu for Configuration Manager--> |
||||
|
<menuitem name="Whatsapp Configurator" id="menu_qr_whatsapp_messaging_root" |
||||
|
action="configuration_manager_action"/> |
||||
|
</odoo> |
@ -0,0 +1,23 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
<record id="res_config_settings_view_form" model="ir.ui.view"> |
||||
|
<field name="name">res.config.settings.view.form.inherit.pos.receipt.invoice.send.whatsapp |
||||
|
</field> |
||||
|
<field name="model">res.config.settings</field> |
||||
|
<field name="priority" eval="95"/> |
||||
|
<field name="inherit_id" |
||||
|
ref="point_of_sale.res_config_settings_view_form"/> |
||||
|
<!-- Add new fields pos_whatsapp_enabled and |
||||
|
apply_send_receipt_or_invoice in res config settings--> |
||||
|
<field name="arch" type="xml"> |
||||
|
<xpath expr="//block[@id='pos_bills_and_receipts_section']" |
||||
|
position="inside"> |
||||
|
<setting id="pos_whatsapp" help="Send receipts Using WhatsApp"> |
||||
|
<field name="pos_whatsapp_enabled" groups="pos_receipt_invoice_send_whatsapp.pos_receipt_invoice_send_whatsapp_group_user"/> |
||||
|
<field name="apply_send_receipt_or_invoice" |
||||
|
invisible="pos_whatsapp_enabled==False" groups="pos_receipt_invoice_send_whatsapp.pos_receipt_invoice_send_whatsapp_group_user"/> |
||||
|
</setting> |
||||
|
</xpath> |
||||
|
</field> |
||||
|
</record> |
||||
|
</odoo> |
@ -0,0 +1,16 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
<record id="view_partner_form" model="ir.ui.view"> |
||||
|
<field name="name"> |
||||
|
res.partner.view.form.inherit.pos.receipt.invoice.send.whatsapp |
||||
|
</field> |
||||
|
<field name="model">res.partner</field> |
||||
|
<field name="inherit_id" ref="base.view_partner_form"/> |
||||
|
<!-- Add new field WhatsApp Number in res partner--> |
||||
|
<field name="arch" type="xml"> |
||||
|
<field name="vat" position="after"> |
||||
|
<field name="whatsapp_number" string='WhatsApp Number'/> |
||||
|
</field> |
||||
|
</field> |
||||
|
</record> |
||||
|
</odoo> |
@ -0,0 +1,55 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<odoo> |
||||
|
<!--Action for view whatsapp message tree view--> |
||||
|
<record id="pos_whatsapp_message_action" model="ir.actions.act_window"> |
||||
|
<field name="name">Whatsapp Message</field> |
||||
|
<field name="res_model">whatsapp.message</field> |
||||
|
<field name="view_mode">tree,form</field> |
||||
|
</record> |
||||
|
<!--Whatsapp message list view--> |
||||
|
<record id="whatsapp_message_view_list" model="ir.ui.view"> |
||||
|
<field name="name">whatsapp.message.view.list</field> |
||||
|
<field name="model">whatsapp.message</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<tree create="false"> |
||||
|
<field name="from_user_id"/> |
||||
|
<field name="to_user"/> |
||||
|
<field name="user_name"/> |
||||
|
<field name="date_and_time_sent"/> |
||||
|
<field name="attachment_id"/> |
||||
|
<field name="status"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!--Whatsapp message form view--> |
||||
|
<record id="whatsapp_message_view_form" model="ir.ui.view"> |
||||
|
<field name="name">whatsapp.message.view.form</field> |
||||
|
<field name="model">whatsapp.message</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form create="false"> |
||||
|
<sheet> |
||||
|
<h1> |
||||
|
<field name="res_name"/> |
||||
|
</h1> |
||||
|
<group> |
||||
|
<group> |
||||
|
<field name="from_user_id" readonly="1"/> |
||||
|
<field name="to_user" readonly="1"/> |
||||
|
<field name="user_name" readonly="1"/> |
||||
|
</group> |
||||
|
<group> |
||||
|
<field name="body" readonly="1"/> |
||||
|
<field name="attachment_id" readonly="1"/> |
||||
|
<field name="date_and_time_sent" readonly="1"/> |
||||
|
<field name="status" readonly="1"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
</sheet> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!--Menu for Whatsapp Message--> |
||||
|
<menuitem name="Whatsapp Message" id="menu_whatsapp_sent" |
||||
|
action="pos_whatsapp_message_action" |
||||
|
parent="pos_receipt_invoice_send_whatsapp.menu_qr_whatsapp_messaging_root"/> |
||||
|
</odoo> |
@ -0,0 +1,22 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions (odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from . import whatsapp_authenticate |
@ -0,0 +1,39 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions (odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class WhatsappAuthenticate(models.TransientModel): |
||||
|
"""Create a new model""" |
||||
|
_name = 'whatsapp.authenticate' |
||||
|
_description = 'Whatsapp Authentication Wizard' |
||||
|
|
||||
|
qrcode = fields.Binary(attachment=False, string="Qr Code", |
||||
|
help="QR code for scanning") |
||||
|
configuration_manager_id = fields.Many2one("configuration.manager", |
||||
|
string="Configuration Manager", |
||||
|
help="Configuration manager" |
||||
|
"details") |
||||
|
|
||||
|
def action_save(self): |
||||
|
""" Action for Save Button which will check Authentication""" |
||||
|
self.configuration_manager_id.action_authenticate() |
@ -0,0 +1,23 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<odoo> |
||||
|
<!-- Whatsapp authenticate form view --> |
||||
|
<record id="whatsapp_authenticate_view_form" model="ir.ui.view"> |
||||
|
<field name="name">whatsapp.authenticate.view.form</field> |
||||
|
<field name="model">whatsapp.authenticate</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form> |
||||
|
<sheet> |
||||
|
<group> |
||||
|
<group> |
||||
|
<field name="qrcode" readonly="True" widget="image"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
<footer> |
||||
|
<button string="Save" type="object" name="action_save" class="btn-primary"/> |
||||
|
<button string="Cancel" special="cancel" class="btn-secondary"/> |
||||
|
</footer> |
||||
|
</sheet> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
</odoo> |