diff --git a/odex30_base/os_whatsapp_integration/__init__.py b/odex30_base/os_whatsapp_integration/__init__.py new file mode 100644 index 0000000..9b42961 --- /dev/null +++ b/odex30_base/os_whatsapp_integration/__init__.py @@ -0,0 +1,2 @@ +from . import models +from . import wizard diff --git a/odex30_base/os_whatsapp_integration/__manifest__.py b/odex30_base/os_whatsapp_integration/__manifest__.py new file mode 100644 index 0000000..4141570 --- /dev/null +++ b/odex30_base/os_whatsapp_integration/__manifest__.py @@ -0,0 +1,32 @@ +{ + 'name': 'Odoo Whatsapp Integration', + 'version': '18.0.1.0', + 'summary': 'Odoo Whatsapp Integration', + 'author': 'Odosquare', + 'company': 'Odosquare', + 'maintainer': 'Odosquare', + 'sequence': 4, + 'images': ['static/description/Banner.png'], + 'license': 'LGPL-3', + 'description': """Odoo Whatsapp Integration""", + 'category': 'Connector', + 'depends': [ + 'base', 'contacts', 'sale', 'crm', 'stock', 'sale_management', 'account', 'purchase' + ], + 'data': [ + 'security/ir.model.access.csv', + 'data/whatsapp_template.xml', + 'views/sale_wa.xml', + 'views/crm_wa.xml', + 'views/purchase_wa.xml', + 'views/stock_wa.xml', + 'views/invoice_wa.xml', + 'views/contact_wa.xml', + 'wizard/wizard.xml', + ], + 'demo': [], + 'qweb': [], + 'installable': True, + 'application': False, + 'auto_install': False, +} diff --git a/odex30_base/os_whatsapp_integration/data/whatsapp_template.xml b/odex30_base/os_whatsapp_integration/data/whatsapp_template.xml new file mode 100644 index 0000000..85e7033 --- /dev/null +++ b/odex30_base/os_whatsapp_integration/data/whatsapp_template.xml @@ -0,0 +1,109 @@ + + + + + Sales: Confirm Order + Sales Confirm + + +

Hello *${object.partner_id.name or ''}*,

+ Your order ${object.name} amount *${format_amount(object.amount_total, object.currency_id)}* is Confirmed. +
+ Kindly refer below link for order receipt. +
+ ]]> +
+
+ + + + + + + + + + + + + + + + + Purchase: Confirm Order + Purchase Order + + +

+ Dear ${object.partner_id.name} + % if object.partner_id.parent_id: + (${object.partner_id.parent_id.name}) + % endif +

+ Here is in attachment a purchase order ${object.name} + % if object.partner_ref: + with reference: ${object.partner_ref} + % endif + amounting in ${format_amount(object.amount_total, object.currency_id)} + from ${object.company_id.name}. +

+ If you have any questions, please do not hesitate to contact us. +

+ Best regards, +

+ ]]> + +
+
+ + + Invoice: Send by WhatsApp + + Purchase Order + +

+ Dear + % if object.partner_id.parent_id: + ${object.partner_id.name} (${object.partner_id.parent_id.name}), + % else: + ${object.partner_id.name}, + % endif +

+ Here is your + % if object.name: + invoice ${object.name} + % else: + invoice + %endif + % if object.invoice_origin: + (with reference: ${object.invoice_origin}) + % endif + amounting in ${format_amount(object.amount_total, object.currency_id)} + from ${object.company_id.name}. + % if object.payment_state == 'paid': + This invoice is already paid. + % else: + Please remit payment at your earliest convenience. + % if object.payment_reference: +

+ Please use the following communication for your payment: ${object.payment_reference}. + % endif + % endif +

+ Do not hesitate to contact us if you have any questions. + % if object.invoice_user_id.signature: +
+ ${object.invoice_user_id.signature | safe} + % endif +

+ ]]> +
+ + + + + + + +
+
\ No newline at end of file diff --git a/odex30_base/os_whatsapp_integration/models/__init__.py b/odex30_base/os_whatsapp_integration/models/__init__.py new file mode 100644 index 0000000..1332c92 --- /dev/null +++ b/odex30_base/os_whatsapp_integration/models/__init__.py @@ -0,0 +1,6 @@ +from . import contacts_wa +from . import crm_wa +from . import invoice_wa +from . import purchase_wa +from . import sale_wa +from . import stock_wa diff --git a/odex30_base/os_whatsapp_integration/models/contacts_wa.py b/odex30_base/os_whatsapp_integration/models/contacts_wa.py new file mode 100644 index 0000000..390dfae --- /dev/null +++ b/odex30_base/os_whatsapp_integration/models/contacts_wa.py @@ -0,0 +1,15 @@ +from odoo import _, models + + +class ResPartner(models.Model): + _inherit = 'res.partner' + + def contacts_whatsapp(self): + return {'type': 'ir.actions.act_window', + 'name': _('Whatsapp Message'), + 'res_model': 'whatsapp.message.wizard', + 'target': 'new', + 'view_mode': 'form', + 'view_type': 'form', + 'context': {'default_user_id': self.id}, + } diff --git a/odex30_base/os_whatsapp_integration/models/crm_wa.py b/odex30_base/os_whatsapp_integration/models/crm_wa.py new file mode 100644 index 0000000..baedffd --- /dev/null +++ b/odex30_base/os_whatsapp_integration/models/crm_wa.py @@ -0,0 +1,15 @@ +from odoo import _, models + + +class WhatsappCrm(models.Model): + _inherit = 'crm.lead' + + def crm_whatsapp(self): + return {'type': 'ir.actions.act_window', + 'name': _('Whatsapp Message'), + 'res_model': 'whatsapp.message.wizard', + 'target': 'new', + 'view_mode': 'form', + 'view_type': 'form', + 'context': {'default_user_id': self.partner_id.id}, + } diff --git a/odex30_base/os_whatsapp_integration/models/invoice_wa.py b/odex30_base/os_whatsapp_integration/models/invoice_wa.py new file mode 100644 index 0000000..54c362a --- /dev/null +++ b/odex30_base/os_whatsapp_integration/models/invoice_wa.py @@ -0,0 +1,15 @@ +from odoo import _, models + + +class WhatsappInvoice(models.Model): + _inherit = 'account.move' + + def invoice_whatsapp(self): + return {'type': 'ir.actions.act_window', + 'name': _('Whatsapp Message'), + 'res_model': 'whatsapp.message.wizard', + 'target': 'new', + 'view_mode': 'form', + 'view_type': 'form', + 'context': {'default_template_id': self.env.ref('os_whatsapp_integration.invoice_whatsapp_template').id}, + } diff --git a/odex30_base/os_whatsapp_integration/models/purchase_wa.py b/odex30_base/os_whatsapp_integration/models/purchase_wa.py new file mode 100644 index 0000000..3252a66 --- /dev/null +++ b/odex30_base/os_whatsapp_integration/models/purchase_wa.py @@ -0,0 +1,15 @@ +from odoo import _, models + + +class WhatsappPurchase(models.Model): + _inherit = 'purchase.order' + + def purchase_whatsapp(self): + return {'type': 'ir.actions.act_window', + 'name': _('Whatsapp Message'), + 'res_model': 'whatsapp.message.wizard', + 'target': 'new', + 'view_mode': 'form', + 'view_type': 'form', + 'context': {'default_template_id': self.env.ref('os_whatsapp_integration.purchase_whatsapp_template').id}, + } diff --git a/odex30_base/os_whatsapp_integration/models/sale_wa.py b/odex30_base/os_whatsapp_integration/models/sale_wa.py new file mode 100644 index 0000000..f3ee857 --- /dev/null +++ b/odex30_base/os_whatsapp_integration/models/sale_wa.py @@ -0,0 +1,15 @@ +from odoo import _, models + + +class WhatsappSale(models.Model): + _inherit = 'sale.order' + + def sale_whatsapp(self): + return {'type': 'ir.actions.act_window', + 'name': _('Whatsapp Message'), + 'res_model': 'whatsapp.message.wizard', + 'target': 'new', + 'view_mode': 'form', + 'view_type': 'form', + 'context': {'default_template_id': self.env.ref('os_whatsapp_integration.sales_whatsapp_template').id}, + } diff --git a/odex30_base/os_whatsapp_integration/models/stock_wa.py b/odex30_base/os_whatsapp_integration/models/stock_wa.py new file mode 100644 index 0000000..8a8c586 --- /dev/null +++ b/odex30_base/os_whatsapp_integration/models/stock_wa.py @@ -0,0 +1,15 @@ +from odoo import _, models + + +class WhatsappPurchase(models.Model): + _inherit = 'stock.picking' + + def stock_whatsapp(self): + return {'type': 'ir.actions.act_window', + 'name': _('Whatsapp Message'), + 'res_model': 'whatsapp.message.wizard', + 'target': 'new', + 'view_mode': 'form', + 'view_type': 'form', + 'context': {'default_user_id': self.partner_id.id}, + } diff --git a/odex30_base/os_whatsapp_integration/security/ir.model.access.csv b/odex30_base/os_whatsapp_integration/security/ir.model.access.csv new file mode 100644 index 0000000..ace71c3 --- /dev/null +++ b/odex30_base/os_whatsapp_integration/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_group_user,Access User,model_whatsapp_message_wizard,base.group_user,1,1,1,1 \ No newline at end of file diff --git a/odex30_base/os_whatsapp_integration/static/description/Banner.png b/odex30_base/os_whatsapp_integration/static/description/Banner.png new file mode 100644 index 0000000..576d326 Binary files /dev/null and b/odex30_base/os_whatsapp_integration/static/description/Banner.png differ diff --git a/odex30_base/os_whatsapp_integration/static/description/feature/account.png b/odex30_base/os_whatsapp_integration/static/description/feature/account.png new file mode 100644 index 0000000..e3a38a7 Binary files /dev/null and b/odex30_base/os_whatsapp_integration/static/description/feature/account.png differ diff --git a/odex30_base/os_whatsapp_integration/static/description/feature/contacts.png b/odex30_base/os_whatsapp_integration/static/description/feature/contacts.png new file mode 100644 index 0000000..4d179a9 Binary files /dev/null and b/odex30_base/os_whatsapp_integration/static/description/feature/contacts.png differ diff --git a/odex30_base/os_whatsapp_integration/static/description/feature/crm.png b/odex30_base/os_whatsapp_integration/static/description/feature/crm.png new file mode 100644 index 0000000..65ebc4f Binary files /dev/null and b/odex30_base/os_whatsapp_integration/static/description/feature/crm.png differ diff --git a/odex30_base/os_whatsapp_integration/static/description/feature/purchase.png b/odex30_base/os_whatsapp_integration/static/description/feature/purchase.png new file mode 100644 index 0000000..02b7321 Binary files /dev/null and b/odex30_base/os_whatsapp_integration/static/description/feature/purchase.png differ diff --git a/odex30_base/os_whatsapp_integration/static/description/feature/sale.png b/odex30_base/os_whatsapp_integration/static/description/feature/sale.png new file mode 100644 index 0000000..343c9f7 Binary files /dev/null and b/odex30_base/os_whatsapp_integration/static/description/feature/sale.png differ diff --git a/odex30_base/os_whatsapp_integration/static/description/feature/stock.png b/odex30_base/os_whatsapp_integration/static/description/feature/stock.png new file mode 100644 index 0000000..692e762 Binary files /dev/null and b/odex30_base/os_whatsapp_integration/static/description/feature/stock.png differ diff --git a/odex30_base/os_whatsapp_integration/static/description/icon.png b/odex30_base/os_whatsapp_integration/static/description/icon.png new file mode 100644 index 0000000..bf312cd Binary files /dev/null and b/odex30_base/os_whatsapp_integration/static/description/icon.png differ diff --git a/odex30_base/os_whatsapp_integration/static/description/index.html b/odex30_base/os_whatsapp_integration/static/description/index.html new file mode 100644 index 0000000..6388933 --- /dev/null +++ b/odex30_base/os_whatsapp_integration/static/description/index.html @@ -0,0 +1,172 @@ +
+
+

Odoo WhatsApp Integration

+
+
+
+
+

Now Send Messages to the customers and partners + through WhatsApp. The WhatsApp feature is available in the modules Sales, CRM, Purchase, Invoice, Inventory and + Contacts. With this feature, the communication between the partners become more easier as the new technologies. +

+
+
+
+
+
+

+ Available in +

+
+
+
+
+
+ +
+
+

Using WhatsApp For Customer Communication

+ Direct chat with the contacts in the contacts module through WhatsApp +
+
+
+
+
+
+ +
+
+

Creative Usage Of WhatsApp For Business

+ Grow your business profitably and creatively. Use WhatsApp as an extra sales channel. Easy to send the Quotation, Sale Order, etc... related files to the corresponding partners +
+
+
+
+
+
+
+
+ +
+
+

Using WhatsApp For Marketing & Promotion

+ WhatsApp can be a very solid marketing tool. It is a good individual platform for direct communication. You can use WhatsApp to send images, audio files, short videos of your products and more. +
+
+
+
+
+
+ +
+
+

Using WhatsApp For payment reminder

+ Whatsapp will help you bill more, faster and control and speed up your collection process. +
+
+
+
+
+
+
+
+ +
+
+

Quick collection of accounts receivable, payment reminder

+ Your collection team will have an additional communication channel to streamline your accounts receivable process. +
+
+
+
+
+
+ +
+
+

Using WhatsApp For Customer Support

+ Our customers would always prefer to send you a message over WhatsApp rather than calling a helpdesk number or raising a ticket. +
+
+
+
+
+
+ +
+
+
+

Contacts

+
+ + +
+
+
+
+
+
+

Sales

+
+ + + +
+
+
+
+
+
+

Invoice

+
+ + +
+
+
+
+
+
+

Purchase

+
+ + +
+
+
+
+
+
+

Inventory

+
+ +
+
+
+
+
+
+

CRM

+
+ +
+
+
+ +
+
+
+
+
+
+

If you have any queries or doubt just contact us:


+

Email: support@odosquare.com

+

Website: www.odosquare.com

+
+
+
+
+
+
+ \ No newline at end of file diff --git a/odex30_base/os_whatsapp_integration/static/description/what_index/contact1.jpg b/odex30_base/os_whatsapp_integration/static/description/what_index/contact1.jpg new file mode 100755 index 0000000..9da2d9e Binary files /dev/null and b/odex30_base/os_whatsapp_integration/static/description/what_index/contact1.jpg differ diff --git a/odex30_base/os_whatsapp_integration/static/description/what_index/contact2.jpg b/odex30_base/os_whatsapp_integration/static/description/what_index/contact2.jpg new file mode 100644 index 0000000..b37c618 Binary files /dev/null and b/odex30_base/os_whatsapp_integration/static/description/what_index/contact2.jpg differ diff --git a/odex30_base/os_whatsapp_integration/static/description/what_index/crm1.jpg b/odex30_base/os_whatsapp_integration/static/description/what_index/crm1.jpg new file mode 100755 index 0000000..143f890 Binary files /dev/null and b/odex30_base/os_whatsapp_integration/static/description/what_index/crm1.jpg differ diff --git a/odex30_base/os_whatsapp_integration/static/description/what_index/invoice1.jpg b/odex30_base/os_whatsapp_integration/static/description/what_index/invoice1.jpg new file mode 100755 index 0000000..383f1cb Binary files /dev/null and b/odex30_base/os_whatsapp_integration/static/description/what_index/invoice1.jpg differ diff --git a/odex30_base/os_whatsapp_integration/static/description/what_index/invoice2.jpg b/odex30_base/os_whatsapp_integration/static/description/what_index/invoice2.jpg new file mode 100644 index 0000000..1f9f9d2 Binary files /dev/null and b/odex30_base/os_whatsapp_integration/static/description/what_index/invoice2.jpg differ diff --git a/odex30_base/os_whatsapp_integration/static/description/what_index/purchase1.jpg b/odex30_base/os_whatsapp_integration/static/description/what_index/purchase1.jpg new file mode 100755 index 0000000..380c9de Binary files /dev/null and b/odex30_base/os_whatsapp_integration/static/description/what_index/purchase1.jpg differ diff --git a/odex30_base/os_whatsapp_integration/static/description/what_index/purchase2.jpg b/odex30_base/os_whatsapp_integration/static/description/what_index/purchase2.jpg new file mode 100644 index 0000000..e02e215 Binary files /dev/null and b/odex30_base/os_whatsapp_integration/static/description/what_index/purchase2.jpg differ diff --git a/odex30_base/os_whatsapp_integration/static/description/what_index/sale1.jpg b/odex30_base/os_whatsapp_integration/static/description/what_index/sale1.jpg new file mode 100755 index 0000000..f278db6 Binary files /dev/null and b/odex30_base/os_whatsapp_integration/static/description/what_index/sale1.jpg differ diff --git a/odex30_base/os_whatsapp_integration/static/description/what_index/sale2.jpg b/odex30_base/os_whatsapp_integration/static/description/what_index/sale2.jpg new file mode 100644 index 0000000..8158fb7 Binary files /dev/null and b/odex30_base/os_whatsapp_integration/static/description/what_index/sale2.jpg differ diff --git a/odex30_base/os_whatsapp_integration/static/description/what_index/sale3.jpg b/odex30_base/os_whatsapp_integration/static/description/what_index/sale3.jpg new file mode 100755 index 0000000..2e1995b Binary files /dev/null and b/odex30_base/os_whatsapp_integration/static/description/what_index/sale3.jpg differ diff --git a/odex30_base/os_whatsapp_integration/static/description/what_index/stock1.jpg b/odex30_base/os_whatsapp_integration/static/description/what_index/stock1.jpg new file mode 100755 index 0000000..a0086f5 Binary files /dev/null and b/odex30_base/os_whatsapp_integration/static/description/what_index/stock1.jpg differ diff --git a/odex30_base/os_whatsapp_integration/views/contact_wa.xml b/odex30_base/os_whatsapp_integration/views/contact_wa.xml new file mode 100644 index 0000000..d279c07 --- /dev/null +++ b/odex30_base/os_whatsapp_integration/views/contact_wa.xml @@ -0,0 +1,18 @@ + + + + + whatsapp.view.form.inherit.res + res.partner + + + +
+
+
+
+
+
+
\ No newline at end of file diff --git a/odex30_base/os_whatsapp_integration/views/crm_wa.xml b/odex30_base/os_whatsapp_integration/views/crm_wa.xml new file mode 100644 index 0000000..8926f41 --- /dev/null +++ b/odex30_base/os_whatsapp_integration/views/crm_wa.xml @@ -0,0 +1,16 @@ + + + + + whatsapp.view.form.inherit.crm + crm.lead + + +
+
+
+
+
+
\ No newline at end of file diff --git a/odex30_base/os_whatsapp_integration/views/invoice_wa.xml b/odex30_base/os_whatsapp_integration/views/invoice_wa.xml new file mode 100644 index 0000000..125c3db --- /dev/null +++ b/odex30_base/os_whatsapp_integration/views/invoice_wa.xml @@ -0,0 +1,17 @@ + + + + + whatsapp.view.form.inherit.account + account.move + + +
+
+
+
+
+
diff --git a/odex30_base/os_whatsapp_integration/views/purchase_wa.xml b/odex30_base/os_whatsapp_integration/views/purchase_wa.xml new file mode 100644 index 0000000..2f62241 --- /dev/null +++ b/odex30_base/os_whatsapp_integration/views/purchase_wa.xml @@ -0,0 +1,16 @@ + + + + + whatsapp.view.form.inherit.purchase + purchase.order + + +
+
+
+
+
+
\ No newline at end of file diff --git a/odex30_base/os_whatsapp_integration/views/sale_wa.xml b/odex30_base/os_whatsapp_integration/views/sale_wa.xml new file mode 100644 index 0000000..897abfd --- /dev/null +++ b/odex30_base/os_whatsapp_integration/views/sale_wa.xml @@ -0,0 +1,17 @@ + + + + + whatsapp.view.form.inherit.sale + sale.order + + +
+
+
+
+
+
diff --git a/odex30_base/os_whatsapp_integration/views/stock_wa.xml b/odex30_base/os_whatsapp_integration/views/stock_wa.xml new file mode 100644 index 0000000..bccbed3 --- /dev/null +++ b/odex30_base/os_whatsapp_integration/views/stock_wa.xml @@ -0,0 +1,16 @@ + + + + + whatsapp.view.form.inherit.stock + stock.picking + + +
+
+
+
+
+
\ No newline at end of file diff --git a/odex30_base/os_whatsapp_integration/wizard/__init__.py b/odex30_base/os_whatsapp_integration/wizard/__init__.py new file mode 100644 index 0000000..4027237 --- /dev/null +++ b/odex30_base/os_whatsapp_integration/wizard/__init__.py @@ -0,0 +1 @@ +from . import wizard diff --git a/odex30_base/os_whatsapp_integration/wizard/wizard.py b/odex30_base/os_whatsapp_integration/wizard/wizard.py new file mode 100644 index 0000000..720eb48 --- /dev/null +++ b/odex30_base/os_whatsapp_integration/wizard/wizard.py @@ -0,0 +1,51 @@ +from odoo import api, fields, models +import html2text + + +class WhatsappSendMessage(models.TransientModel): + _name = 'whatsapp.message.wizard' + _description = 'Whatsapp Message Wizard' + + user_id = fields.Many2one('res.partner', string="Recipient") + mobile = fields.Char(related='user_id.mobile', required=True, readonly=False) + message = fields.Text(string="Message") + model = fields.Char('Related Document Model') + template_id = fields.Many2one( + 'mail.template', 'Use template', index=True, + domain="[('model', '=', model)]" + ) + + @api.onchange('template_id') + def _onchange_template_id(self): + """ + Renders the selected template and populates the message field. + This is the correct method for Odoo 17/18. + """ + if self.template_id: + res_id = self._context.get('active_id') + # Render the template's body_html field for the active record + rendered_html = self.template_id._render_field('body_html', [res_id], compute_lang=True)[res_id] + # Convert the rendered HTML to plain text suitable for WhatsApp + self.message = html2text.html2text(rendered_html) + + def send_message(self): + """ + Generates the WhatsApp Web URL and opens it in a new tab. + """ + self.ensure_one() + if self.message and self.mobile: + # Properly encode the message for a URL, handling spaces and new lines + message_string = self.message.replace(' ', '%20').replace('\n', '%0A') + + # Sanitize the mobile number for the URL + number = self.mobile.replace('+', '').replace(' ', '') + + link = f"https://web.whatsapp.com/send?phone={number}&text={message_string}" + + return { + 'type': 'ir.actions.act_url', + 'url': link, + 'target': 'new', + } + return True + diff --git a/odex30_base/os_whatsapp_integration/wizard/wizard.xml b/odex30_base/os_whatsapp_integration/wizard/wizard.xml new file mode 100644 index 0000000..8d0ba3b --- /dev/null +++ b/odex30_base/os_whatsapp_integration/wizard/wizard.xml @@ -0,0 +1,32 @@ + + + + + whatsapp.message.wizard.form + whatsapp.message.wizard + + +
+ + + + + + + + + + + + + +
+
+
+
+
\ No newline at end of file