diff --git a/odex25_base/os_whatsapp_integration/__init__.py b/odex25_base/os_whatsapp_integration/__init__.py new file mode 100644 index 000000000..9b4296142 --- /dev/null +++ b/odex25_base/os_whatsapp_integration/__init__.py @@ -0,0 +1,2 @@ +from . import models +from . import wizard diff --git a/odex25_base/os_whatsapp_integration/__manifest__.py b/odex25_base/os_whatsapp_integration/__manifest__.py new file mode 100644 index 000000000..d713df562 --- /dev/null +++ b/odex25_base/os_whatsapp_integration/__manifest__.py @@ -0,0 +1,32 @@ +{ + 'name': 'Odoo Whatsapp Integration', + 'version': '14.0.0.1', + '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/odex25_base/os_whatsapp_integration/data/whatsapp_template.xml b/odex25_base/os_whatsapp_integration/data/whatsapp_template.xml new file mode 100644 index 000000000..3a880a022 --- /dev/null +++ b/odex25_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/odex25_base/os_whatsapp_integration/models/__init__.py b/odex25_base/os_whatsapp_integration/models/__init__.py new file mode 100644 index 000000000..1332c92d1 --- /dev/null +++ b/odex25_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/odex25_base/os_whatsapp_integration/models/contacts_wa.py b/odex25_base/os_whatsapp_integration/models/contacts_wa.py new file mode 100644 index 000000000..390dfae29 --- /dev/null +++ b/odex25_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/odex25_base/os_whatsapp_integration/models/crm_wa.py b/odex25_base/os_whatsapp_integration/models/crm_wa.py new file mode 100644 index 000000000..baedffdde --- /dev/null +++ b/odex25_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/odex25_base/os_whatsapp_integration/models/invoice_wa.py b/odex25_base/os_whatsapp_integration/models/invoice_wa.py new file mode 100644 index 000000000..54c362a87 --- /dev/null +++ b/odex25_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/odex25_base/os_whatsapp_integration/models/purchase_wa.py b/odex25_base/os_whatsapp_integration/models/purchase_wa.py new file mode 100644 index 000000000..3252a667e --- /dev/null +++ b/odex25_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/odex25_base/os_whatsapp_integration/models/sale_wa.py b/odex25_base/os_whatsapp_integration/models/sale_wa.py new file mode 100644 index 000000000..f3ee857c7 --- /dev/null +++ b/odex25_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/odex25_base/os_whatsapp_integration/models/stock_wa.py b/odex25_base/os_whatsapp_integration/models/stock_wa.py new file mode 100644 index 000000000..8a8c586bc --- /dev/null +++ b/odex25_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/odex25_base/os_whatsapp_integration/security/ir.model.access.csv b/odex25_base/os_whatsapp_integration/security/ir.model.access.csv new file mode 100644 index 000000000..ace71c3df --- /dev/null +++ b/odex25_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/odex25_base/os_whatsapp_integration/static/description/Banner.png b/odex25_base/os_whatsapp_integration/static/description/Banner.png new file mode 100644 index 000000000..576d326b5 Binary files /dev/null and b/odex25_base/os_whatsapp_integration/static/description/Banner.png differ diff --git a/odex25_base/os_whatsapp_integration/static/description/feature/account.png b/odex25_base/os_whatsapp_integration/static/description/feature/account.png new file mode 100644 index 000000000..e3a38a766 Binary files /dev/null and b/odex25_base/os_whatsapp_integration/static/description/feature/account.png differ diff --git a/odex25_base/os_whatsapp_integration/static/description/feature/contacts.png b/odex25_base/os_whatsapp_integration/static/description/feature/contacts.png new file mode 100644 index 000000000..4d179a954 Binary files /dev/null and b/odex25_base/os_whatsapp_integration/static/description/feature/contacts.png differ diff --git a/odex25_base/os_whatsapp_integration/static/description/feature/crm.png b/odex25_base/os_whatsapp_integration/static/description/feature/crm.png new file mode 100644 index 000000000..65ebc4f24 Binary files /dev/null and b/odex25_base/os_whatsapp_integration/static/description/feature/crm.png differ diff --git a/odex25_base/os_whatsapp_integration/static/description/feature/purchase.png b/odex25_base/os_whatsapp_integration/static/description/feature/purchase.png new file mode 100644 index 000000000..02b732165 Binary files /dev/null and b/odex25_base/os_whatsapp_integration/static/description/feature/purchase.png differ diff --git a/odex25_base/os_whatsapp_integration/static/description/feature/sale.png b/odex25_base/os_whatsapp_integration/static/description/feature/sale.png new file mode 100644 index 000000000..343c9f7e0 Binary files /dev/null and b/odex25_base/os_whatsapp_integration/static/description/feature/sale.png differ diff --git a/odex25_base/os_whatsapp_integration/static/description/feature/stock.png b/odex25_base/os_whatsapp_integration/static/description/feature/stock.png new file mode 100644 index 000000000..692e76244 Binary files /dev/null and b/odex25_base/os_whatsapp_integration/static/description/feature/stock.png differ diff --git a/odex25_base/os_whatsapp_integration/static/description/icon.png b/odex25_base/os_whatsapp_integration/static/description/icon.png new file mode 100644 index 000000000..bf312cd1c Binary files /dev/null and b/odex25_base/os_whatsapp_integration/static/description/icon.png differ diff --git a/odex25_base/os_whatsapp_integration/static/description/index.html b/odex25_base/os_whatsapp_integration/static/description/index.html new file mode 100644 index 000000000..6388933cc --- /dev/null +++ b/odex25_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/odex25_base/os_whatsapp_integration/static/description/what_index/contact1.jpg b/odex25_base/os_whatsapp_integration/static/description/what_index/contact1.jpg new file mode 100755 index 000000000..9da2d9e09 Binary files /dev/null and b/odex25_base/os_whatsapp_integration/static/description/what_index/contact1.jpg differ diff --git a/odex25_base/os_whatsapp_integration/static/description/what_index/contact2.jpg b/odex25_base/os_whatsapp_integration/static/description/what_index/contact2.jpg new file mode 100644 index 000000000..b37c6180a Binary files /dev/null and b/odex25_base/os_whatsapp_integration/static/description/what_index/contact2.jpg differ diff --git a/odex25_base/os_whatsapp_integration/static/description/what_index/crm1.jpg b/odex25_base/os_whatsapp_integration/static/description/what_index/crm1.jpg new file mode 100755 index 000000000..143f89005 Binary files /dev/null and b/odex25_base/os_whatsapp_integration/static/description/what_index/crm1.jpg differ diff --git a/odex25_base/os_whatsapp_integration/static/description/what_index/invoice1.jpg b/odex25_base/os_whatsapp_integration/static/description/what_index/invoice1.jpg new file mode 100755 index 000000000..383f1cb51 Binary files /dev/null and b/odex25_base/os_whatsapp_integration/static/description/what_index/invoice1.jpg differ diff --git a/odex25_base/os_whatsapp_integration/static/description/what_index/invoice2.jpg b/odex25_base/os_whatsapp_integration/static/description/what_index/invoice2.jpg new file mode 100644 index 000000000..1f9f9d2c9 Binary files /dev/null and b/odex25_base/os_whatsapp_integration/static/description/what_index/invoice2.jpg differ diff --git a/odex25_base/os_whatsapp_integration/static/description/what_index/purchase1.jpg b/odex25_base/os_whatsapp_integration/static/description/what_index/purchase1.jpg new file mode 100755 index 000000000..380c9deff Binary files /dev/null and b/odex25_base/os_whatsapp_integration/static/description/what_index/purchase1.jpg differ diff --git a/odex25_base/os_whatsapp_integration/static/description/what_index/purchase2.jpg b/odex25_base/os_whatsapp_integration/static/description/what_index/purchase2.jpg new file mode 100644 index 000000000..e02e21508 Binary files /dev/null and b/odex25_base/os_whatsapp_integration/static/description/what_index/purchase2.jpg differ diff --git a/odex25_base/os_whatsapp_integration/static/description/what_index/sale1.jpg b/odex25_base/os_whatsapp_integration/static/description/what_index/sale1.jpg new file mode 100755 index 000000000..f278db665 Binary files /dev/null and b/odex25_base/os_whatsapp_integration/static/description/what_index/sale1.jpg differ diff --git a/odex25_base/os_whatsapp_integration/static/description/what_index/sale2.jpg b/odex25_base/os_whatsapp_integration/static/description/what_index/sale2.jpg new file mode 100644 index 000000000..8158fb71c Binary files /dev/null and b/odex25_base/os_whatsapp_integration/static/description/what_index/sale2.jpg differ diff --git a/odex25_base/os_whatsapp_integration/static/description/what_index/sale3.jpg b/odex25_base/os_whatsapp_integration/static/description/what_index/sale3.jpg new file mode 100755 index 000000000..2e1995b6a Binary files /dev/null and b/odex25_base/os_whatsapp_integration/static/description/what_index/sale3.jpg differ diff --git a/odex25_base/os_whatsapp_integration/static/description/what_index/stock1.jpg b/odex25_base/os_whatsapp_integration/static/description/what_index/stock1.jpg new file mode 100755 index 000000000..a0086f561 Binary files /dev/null and b/odex25_base/os_whatsapp_integration/static/description/what_index/stock1.jpg differ diff --git a/odex25_base/os_whatsapp_integration/views/contact_wa.xml b/odex25_base/os_whatsapp_integration/views/contact_wa.xml new file mode 100644 index 000000000..d279c07f7 --- /dev/null +++ b/odex25_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/odex25_base/os_whatsapp_integration/views/crm_wa.xml b/odex25_base/os_whatsapp_integration/views/crm_wa.xml new file mode 100644 index 000000000..8926f41cf --- /dev/null +++ b/odex25_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/odex25_base/os_whatsapp_integration/views/invoice_wa.xml b/odex25_base/os_whatsapp_integration/views/invoice_wa.xml new file mode 100644 index 000000000..7e7ef4063 --- /dev/null +++ b/odex25_base/os_whatsapp_integration/views/invoice_wa.xml @@ -0,0 +1,16 @@ + + + + + whatsapp.view.form.inherit.account + account.move + + +
+
+
+
+
+
\ No newline at end of file diff --git a/odex25_base/os_whatsapp_integration/views/purchase_wa.xml b/odex25_base/os_whatsapp_integration/views/purchase_wa.xml new file mode 100644 index 000000000..2f62241d6 --- /dev/null +++ b/odex25_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/odex25_base/os_whatsapp_integration/views/sale_wa.xml b/odex25_base/os_whatsapp_integration/views/sale_wa.xml new file mode 100644 index 000000000..de070156f --- /dev/null +++ b/odex25_base/os_whatsapp_integration/views/sale_wa.xml @@ -0,0 +1,17 @@ + + + + + whatsapp.view.form.inherit.sale + sale.order + + +
+
+
+
+
+
+ diff --git a/odex25_base/os_whatsapp_integration/views/stock_wa.xml b/odex25_base/os_whatsapp_integration/views/stock_wa.xml new file mode 100644 index 000000000..bccbed30b --- /dev/null +++ b/odex25_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/odex25_base/os_whatsapp_integration/wizard/__init__.py b/odex25_base/os_whatsapp_integration/wizard/__init__.py new file mode 100644 index 000000000..40272379f --- /dev/null +++ b/odex25_base/os_whatsapp_integration/wizard/__init__.py @@ -0,0 +1 @@ +from . import wizard diff --git a/odex25_base/os_whatsapp_integration/wizard/wizard.py b/odex25_base/os_whatsapp_integration/wizard/wizard.py new file mode 100644 index 000000000..748cb7e33 --- /dev/null +++ b/odex25_base/os_whatsapp_integration/wizard/wizard.py @@ -0,0 +1,72 @@ +from odoo import api, fields, models + +import html2text + + +class WhatsappSendMessage(models.TransientModel): + _name = 'whatsapp.message.wizard' + + user_id = fields.Many2one('res.partner', string="Recipient") + mobile = fields.Char(related='user_id.mobile', required=True) + message = fields.Text(string="Message") + model = fields.Char('mail.template.model_id') + template_id = fields.Many2one( + 'mail.template', 'Use template', index=True, ) + + @api.onchange('template_id') + def onchange_template_id_wrapper(self): + self.ensure_one() + res_id = self._context.get('active_id') or 1 + values = self.onchange_template_id(self.template_id.id, self.model, res_id)['value'] + for fname, value in values.items(): + setattr(self, fname, value) + + def onchange_template_id(self, template_id, model, res_id): + if template_id: + values = self.generate_email_for_composer(template_id, [res_id])[res_id] + else: + default_values = self.with_context(default_model=model, default_res_id=res_id).default_get( + ['model', 'res_id', 'partner_ids', 'message']) + values = dict((key, default_values[key]) for key in + ['body', 'partner_ids'] + if key in default_values) + values = self._convert_to_write(values) + return {'value': values} + + def generate_email_for_composer(self, template_id, res_ids, fields=None): + multi_mode = True + if isinstance(res_ids, int): + multi_mode = False + res_ids = [res_ids] + if fields is None: + fields = ['body_html'] + returned_fields = fields + ['partner_ids'] + values = dict.fromkeys(res_ids, False) + template_values = self.env['mail.template'].with_context(tpl_partners_only=True).browse( + template_id).generate_email(res_ids, fields=fields) + for res_id in res_ids: + res_id_values = dict((field, template_values[res_id][field]) for field in returned_fields if + template_values[res_id].get(field)) + res_id_values['message'] = html2text.html2text(res_id_values.pop('body_html', '')) + values[res_id] = res_id_values + + return multi_mode and values or values[res_ids[0]] + + def send_message(self): + if self.message and self.mobile: + message_string = '' + message = self.message.split(' ') + for msg in message: + message_string = message_string + msg + '%20' + message_string = message_string[:(len(message_string) - 3)] + number = self.user_id.mobile + link = "https://web.whatsapp.com/send?phone=" + number + send_msg = { + 'type': 'ir.actions.act_url', + 'url': link + "&text=" + message_string, + 'target': 'new', + 'res_id': self.id, + } + + return send_msg + diff --git a/odex25_base/os_whatsapp_integration/wizard/wizard.xml b/odex25_base/os_whatsapp_integration/wizard/wizard.xml new file mode 100644 index 000000000..8d0ba3b0c --- /dev/null +++ b/odex25_base/os_whatsapp_integration/wizard/wizard.xml @@ -0,0 +1,32 @@ + + + + + whatsapp.message.wizard.form + whatsapp.message.wizard + + +
+ + + + + + + + + + + + + +
+
+
+
+
\ No newline at end of file