@ -0,0 +1,52 @@ |
|||
SendGrid Email API |
|||
================== |
|||
|
|||
This module comes under Odoo Email Marketing. |
|||
It will Use for Emailing. It could be use for Bulk |
|||
Mailing and Single Mailing . Email Template use for |
|||
constructing Email Content.It includes Mail reports |
|||
and Bounce Checking Option, here user can Konw the mail status. |
|||
|
|||
Usage |
|||
===== |
|||
|
|||
After the installation,in email marketting settings user can see sendgrid api setting field by ticking in check box a new text field will appear here user can set the API key by saving it key will be save in the system ,in email marketting configuration includes a sub menu sendgrid email template details here user can create email templates . in configuration have another menu called sendgrid from emails this menu is used for creating new from emails for using in malling. in mailing menu create a new mail here user can see a new page view called sendgrid emails here we can set the template and another specifications, using sendgrid button on top user can send the mail. |
|||
|
|||
Configuration |
|||
============= |
|||
|
|||
For saving the API key configuration have check box field sendgrid api by ticking in check box a new text field will appear here user can set the API key by saving it key will be save in the system. |
|||
|
|||
|
|||
Company |
|||
------- |
|||
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__ |
|||
|
|||
Credits |
|||
------- |
|||
* Developer: |
|||
Noushid Khan.P |
|||
|
|||
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,24 @@ |
|||
# -*- coding: utf-8 -*- |
|||
################################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2019-TODAY Cybrosys Technologies (<https://www.cybrosys.com>). |
|||
# Author: Noushid Khan.P (<https://www.cybrosys.com>) |
|||
# |
|||
# This program is free software: you can modify |
|||
# it under the terms of the GNU Affero General Public License (AGPL) as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# |
|||
# 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 for more details. |
|||
# |
|||
# You should have received a copy of the GNU Affero General Public License |
|||
# along with this program. If not, see <https://www.gnu.org/licenses/>. |
|||
# |
|||
################################################################################### |
|||
|
|||
from . import models |
@ -0,0 +1,53 @@ |
|||
# -*- coding: utf-8 -*- |
|||
################################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2019-TODAY Cybrosys Technologies (<https://www.cybrosys.com>). |
|||
# Author: Noushid Khan.P (<https://www.cybrosys.com>) |
|||
# |
|||
# This program is free software: you can modify |
|||
# it under the terms of the GNU Affero General Public License (AGPL) as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# |
|||
# 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 for more details. |
|||
# |
|||
# You should have received a copy of the GNU Affero General Public License |
|||
# along with this program. If not, see <https://www.gnu.org/licenses/>. |
|||
# |
|||
################################################################################### |
|||
|
|||
{ |
|||
'name': 'Mass Mailing With SendGrid', |
|||
'version': '13.0.1.0.0', |
|||
'summary': 'Mass Mailing using SendGrid API', |
|||
'description': 'Mass Mailing using SendGrid API', |
|||
'category': 'Marketing', |
|||
'author': 'Cybrosys Techno Solutions', |
|||
'maintainer': 'Cybrosys Techno Solutions', |
|||
'company': 'Cybrosys Techno Solutions', |
|||
'website': 'https://www.cybrosys.com', |
|||
'depends': [ |
|||
'crm', |
|||
'mass_mailing', |
|||
'base', |
|||
'hr_recruitment', |
|||
'event' |
|||
], |
|||
'data': [ |
|||
'security/ir.model.access.csv', |
|||
'views/view.xml', |
|||
'views/mail_view.xml', |
|||
'views/ir_config_view.xml', |
|||
'views/res_config_view.xml' |
|||
], |
|||
'license': 'AGPL-3', |
|||
'images': ['static/description/banner.png'], |
|||
'installable': True, |
|||
'application': False, |
|||
'auto_install': False, |
|||
} |
@ -0,0 +1,7 @@ |
|||
## Module <sendgrid_email> |
|||
|
|||
#### 30.01.2020 |
|||
#### Version 13.0.1.0.0 |
|||
##### ADD |
|||
- Initial commit for sendgrid_email. |
|||
|
@ -0,0 +1,29 @@ |
|||
# -*- coding: utf-8 -*- |
|||
################################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2019-TODAY Cybrosys Technologies (<https://www.cybrosys.com>). |
|||
# Author: Noushid Khan.P (<https://www.cybrosys.com>) |
|||
# |
|||
# This program is free software: you can modify |
|||
# it under the terms of the GNU Affero General Public License (AGPL) as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# |
|||
# 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 for more details. |
|||
# |
|||
# You should have received a copy of the GNU Affero General Public License |
|||
# along with this program. If not, see <https://www.gnu.org/licenses/>. |
|||
# |
|||
################################################################################### |
|||
|
|||
from . import model |
|||
from . import email_send |
|||
from . import email_template |
|||
from . import mail_mail |
|||
from . import ir_config_parameter |
|||
from . import res_config_settings |
@ -0,0 +1,32 @@ |
|||
# -*- coding: utf-8 -*- |
|||
################################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2019-TODAY Cybrosys Technologies (<https://www.cybrosys.com>). |
|||
# Author: Noushid Khan.P (<https://www.cybrosys.com>) |
|||
# |
|||
# This program is free software: you can modify |
|||
# it under the terms of the GNU Affero General Public License (AGPL) as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# |
|||
# 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 for more details. |
|||
# |
|||
# You should have received a copy of the GNU Affero General Public License |
|||
# along with this program. If not, see <https://www.gnu.org/licenses/>. |
|||
# |
|||
################################################################################### |
|||
|
|||
from odoo import models, fields |
|||
|
|||
|
|||
class EmailDetails(models.Model): |
|||
_name = "email.sent" |
|||
_description = 'Email From Mails' |
|||
|
|||
name = fields.Char(string="Name", required=True) |
|||
email_id = fields.Char(string="Email ID", required=True) |
@ -0,0 +1,117 @@ |
|||
# -*- coding: utf-8 -*- |
|||
################################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2019-TODAY Cybrosys Technologies (<https://www.cybrosys.com>). |
|||
# Author: Noushid Khan.P (<https://www.cybrosys.com>) |
|||
# |
|||
# This program is free software: you can modify |
|||
# it under the terms of the GNU Affero General Public License (AGPL) as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# |
|||
# 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 for more details. |
|||
# |
|||
# You should have received a copy of the GNU Affero General Public License |
|||
# along with this program. If not, see <https://www.gnu.org/licenses/>. |
|||
# |
|||
################################################################################### |
|||
|
|||
import json |
|||
|
|||
from odoo import models, fields, _ |
|||
import http.client |
|||
|
|||
from odoo.exceptions import UserError |
|||
|
|||
|
|||
class EmailTemplateDetails(models.Model): |
|||
_name = "email.template" |
|||
_rec_name = "temp_name" |
|||
_description = "Template Creation" |
|||
|
|||
temp_name = fields.Char(string="Template Name", required=True) |
|||
generation = fields.Char(string="Template Generation", default="Dynamic", readonly=True) |
|||
ver_name = fields.Char(string="Version Name") |
|||
ver_subject = fields.Char(string="Version Subject", required=True) |
|||
ver_editor = fields.Selection([('design', "Design"), ('code', "Code")], string="Version Editor", default="design") |
|||
temp_cont = fields.Html(string="Template Content", help="content convert to html code", translate=True, sanitize=False) |
|||
temp_id = fields.Char(string="Template ID") |
|||
|
|||
def create_temp(self): |
|||
""" |
|||
function is used for creating Mail Template |
|||
|
|||
""" |
|||
api_key = "" |
|||
company_id = self.env.company |
|||
temp_name = self.temp_name |
|||
temp_gen = self.generation |
|||
api_info = self.env['ir.config_parameter'].search( |
|||
[('key', '=', "SendGrid API Key " + company_id.name + "")]) |
|||
if not api_info: |
|||
raise UserError(_("It Needs API Key")) |
|||
if api_info.company_id.id == self.env.company.id: |
|||
api_key = api_info.value |
|||
if not api_key and api_key == "": |
|||
raise UserError(_("Your Company Needs an API Key")) |
|||
conn = http.client.HTTPSConnection("api.sendgrid.com") |
|||
|
|||
payload = "{\"name\":\""+temp_name+"\",\"generation\":\"dynamic\"}" |
|||
|
|||
headers = { |
|||
'authorization': "Bearer "+api_key+"", |
|||
'content-type': "application/json" |
|||
} |
|||
|
|||
conn.request("POST", "/v3/templates", payload, headers) |
|||
|
|||
res = conn.getresponse() |
|||
data = res.read() |
|||
|
|||
temp_data = json.loads(data.decode("utf-8")) |
|||
self.temp_id = temp_data['id'] |
|||
|
|||
def create_ver(self): |
|||
""" |
|||
Function is used for creating mail content to the |
|||
Created Template. |
|||
|
|||
""" |
|||
api_key = "" |
|||
if self.temp_cont: |
|||
company_id = self.env.company |
|||
temp_cont = self.temp_cont |
|||
temp_id = self.temp_id |
|||
ver_name = self.ver_name |
|||
ver_sub = self.ver_subject |
|||
api_info = self.env['ir.config_parameter'].search( |
|||
[('key', '=', "SendGrid API Key " + company_id.name + "")]) |
|||
if not api_info: |
|||
raise UserError(_("It Needs API Key")) |
|||
if api_info.company_id.id == self.env.company.id: |
|||
api_key = api_info.value |
|||
if not api_key and api_key == "": |
|||
raise UserError(_("Your Company Needs an API Key")) |
|||
conn = http.client.HTTPSConnection("api.sendgrid.com") |
|||
upt_temp_cnt = (temp_cont.replace('"','')) |
|||
|
|||
payload = "{\"template_id\":\""+temp_id+"\",\"active\":1,\"name\":\""+ver_name+"\",\"html_content\":\""+upt_temp_cnt+"\",\"plain_content\":\"<%body%>\",\"subject\":\""+ver_sub+"\"}" |
|||
|
|||
headers = { |
|||
'authorization': "Bearer "+api_key+"", |
|||
'content-type': "application/json" |
|||
} |
|||
|
|||
conn.request("POST", "/v3/templates/"+temp_id+"/versions", payload, headers) |
|||
|
|||
# res = conn.getresponse() |
|||
# data = res.read() |
|||
|
|||
|
|||
|
|||
|
@ -0,0 +1,43 @@ |
|||
# -*- coding: utf-8 -*- |
|||
################################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2019-TODAY Cybrosys Technologies (<https://www.cybrosys.com>). |
|||
# Author: Noushid Khan.P (<https://www.cybrosys.com>) |
|||
# |
|||
# This program is free software: you can modify |
|||
# it under the terms of the GNU Affero General Public License (AGPL) as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# |
|||
# 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 for more details. |
|||
# |
|||
# You should have received a copy of the GNU Affero General Public License |
|||
# along with this program. If not, see <https://www.gnu.org/licenses/>. |
|||
# |
|||
################################################################################### |
|||
|
|||
from odoo import models, fields, api |
|||
|
|||
|
|||
class SendGridAPI(models.Model): |
|||
_inherit = "ir.config_parameter" |
|||
|
|||
company_id = fields.Many2one('res.company', string="Company ID") |
|||
|
|||
@api.model |
|||
def create(self, vals_list): |
|||
""" |
|||
function is used for auto filling company |
|||
details to company_id |
|||
|
|||
""" |
|||
res = super(SendGridAPI, self).create(vals_list) |
|||
res.company_id = self.env.company.id |
|||
return res |
|||
|
|||
|
@ -0,0 +1,549 @@ |
|||
# -*- coding: utf-8 -*- |
|||
################################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2019-TODAY Cybrosys Technologies (<https://www.cybrosys.com>). |
|||
# Author: Noushid Khan.P (<https://www.cybrosys.com>) |
|||
# |
|||
# This program is free software: you can modify |
|||
# it under the terms of the GNU Affero General Public License (AGPL) as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# |
|||
# 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 for more details. |
|||
# |
|||
# You should have received a copy of the GNU Affero General Public License |
|||
# along with this program. If not, see <https://www.gnu.org/licenses/>. |
|||
# |
|||
################################################################################### |
|||
|
|||
import json |
|||
|
|||
from odoo import models, fields, api, _ |
|||
from odoo.exceptions import UserError |
|||
import http.client |
|||
|
|||
|
|||
class SendGridEmail(models.Model): |
|||
_inherit = 'mailing.mailing' |
|||
|
|||
email_temp = fields.Many2one("email.template", string="Email Template") |
|||
temp_id = fields.Char(string="Template ID") |
|||
from_email = fields.Many2one("email.sent", string="Sender Email") |
|||
to_email_partner = fields.Many2many("res.partner", string="Recipient Emails") |
|||
to_email_partner_check = fields.Boolean() |
|||
to_email_lead = fields.Many2many("crm.lead", string="Recipient Emails") |
|||
to_email_lead_check = fields.Boolean() |
|||
to_email_contact = fields.Many2many("mailing.contact", string="Recipient Emails") |
|||
to_email_contact_check = fields.Boolean() |
|||
to_email_applicant = fields.Many2many("hr.applicant", string="Recipient Emails") |
|||
to_email_applicant_check = fields.Boolean() |
|||
email_finder = fields.Integer(string="Email finder") |
|||
sent_count = fields.Integer(string="Send Count") |
|||
send_grid_check = fields.Boolean() |
|||
temp_check = fields.Boolean() |
|||
|
|||
def action_send_grid(self): |
|||
""" |
|||
function used for Sending emails using |
|||
SendGrid API using "sendgrid" Button |
|||
and creating report based on states. |
|||
|
|||
""" |
|||
company_id = self.env.company |
|||
api_key = "" |
|||
conn = http.client.HTTPSConnection("api.sendgrid.com") |
|||
if not self.temp_id: |
|||
raise UserError(_("It Needs A Template ID")) |
|||
if self.from_email: |
|||
from_email = self.from_email.email_id |
|||
from_name = self.from_email.name |
|||
else: |
|||
from_email = "noreply@johndoe.com" |
|||
from_name = "JohnDoe" |
|||
if self.to_email_partner: |
|||
api_info = self.env['ir.config_parameter'].search( |
|||
[('key', '=', "SendGrid API Key " + company_id.name + "")]) |
|||
if not api_info: |
|||
raise UserError(_("It Needs API Key")) |
|||
if api_info.company_id.id == self.env.company.id: |
|||
api_key = api_info.value |
|||
if not api_key and api_key == "": |
|||
raise UserError(_("Your Company Needs an API Key")) |
|||
for data in self.to_email_partner: |
|||
to_email = data.email |
|||
to_name = data.name |
|||
to_company = data.company_name |
|||
if not to_company: |
|||
to_company = "" |
|||
temp_id = self.temp_id |
|||
if to_email: |
|||
payload = "{\"personalizations\":[{\"to\":[{\"email\":\"" + to_email + "\"}],\"dynamic_template_data\":{\"firstname\":\"" + to_name + "\",\"english\":\"true\",\"company\":\"" + to_company + "\"},\"subject\":\"Official Mail\"}],\"from\":{\"email\":\"" + from_email + "\",\"name\":\"" + from_name + "\"},\"template_id\":\"" + temp_id + "\"}" |
|||
|
|||
headers = { |
|||
'authorization': "Bearer " + api_key + "", |
|||
'content-type': "application/json" |
|||
} |
|||
|
|||
conn.request("POST", "/v3/mail/send", payload, headers) |
|||
|
|||
res = conn.getresponse() |
|||
data_msg = res.read() |
|||
error_msg = '' |
|||
if data_msg.decode("utf-8"): |
|||
error_data = json.loads(data_msg.decode("utf-8")) |
|||
error_msg = error_data['errors'][0]['message'] |
|||
if not data_msg.decode("utf-8"): |
|||
self.sent_count += 1 |
|||
self.write({ |
|||
'state': 'done' |
|||
}) |
|||
self.env['email.api'].create({ |
|||
'name': self.subject, |
|||
'to_email_partner': data.id, |
|||
'to_email': to_email, |
|||
'recipient_name': to_name, |
|||
'company_name': to_company, |
|||
'from_email': self.from_email.id, |
|||
'temp_type': self.email_temp.id, |
|||
'temp_id': self.temp_id, |
|||
'to_email_partner_check': True, |
|||
'email_finder': self.id |
|||
}) |
|||
|
|||
elif error_msg: |
|||
self.env['email.api'].create({ |
|||
'name': self.subject, |
|||
'to_email_partner': data.id, |
|||
'to_email': to_email, |
|||
'recipient_name': to_name, |
|||
'company_name': to_company, |
|||
'from_email': self.from_email.id, |
|||
'temp_type': self.email_temp.id, |
|||
'temp_id': self.temp_id, |
|||
'error_msg': error_msg, |
|||
'state': 'error', |
|||
'to_email_partner_check': True, |
|||
'error_check': True, |
|||
'email_finder': self.id |
|||
}) |
|||
self.email_finder = self.id |
|||
self.send_grid_check = True |
|||
elif self.to_email_lead: |
|||
api_info = self.env['ir.config_parameter'].search( |
|||
[('key', '=', "SendGrid API Key " + company_id.name + "")]) |
|||
if not api_info: |
|||
raise UserError(_("It Needs API Key")) |
|||
if api_info.company_id.id == self.env.company.id: |
|||
api_key = api_info.value |
|||
if not api_key and api_key == "": |
|||
raise UserError(_("Your Company Needs an API Key")) |
|||
for data in self.to_email_lead: |
|||
to_email = data.email_from |
|||
to_name = data.contact_name |
|||
if not to_name: |
|||
raise UserError(_("Your Lead Needs A Contact Name")) |
|||
to_company = data.partner_name |
|||
if not to_company: |
|||
to_company = "" |
|||
temp_id = self.temp_id |
|||
payload = "" |
|||
if to_email: |
|||
payload = "{\"personalizations\":[{\"to\":[{\"email\":\"" + to_email + "\"}],\"dynamic_template_data\":{\"firstname\":\"" + to_name + "\",\"english\":\"true\",\"company\":\"" + to_company + "\"},\"subject\":\"Official Mail\"}],\"from\":{\"email\":\"" + from_email + "\",\"name\":\"" + from_name + "\"},\"template_id\":\"" + temp_id + "\"}" |
|||
|
|||
headers = { |
|||
'authorization': "Bearer " + api_key + "", |
|||
'content-type': "application/json" |
|||
} |
|||
|
|||
conn.request("POST", "/v3/mail/send", payload, headers) |
|||
|
|||
res = conn.getresponse() |
|||
data_msg = res.read() |
|||
|
|||
error_msg = '' |
|||
if data_msg.decode("utf-8"): |
|||
error_data = json.loads(data_msg.decode("utf-8")) |
|||
error_msg = error_data['errors'][0]['message'] |
|||
if not data_msg.decode("utf-8"): |
|||
self.sent_count += 1 |
|||
self.write({ |
|||
'state': 'done' |
|||
}) |
|||
self.env['email.api'].create({ |
|||
'name': self.subject, |
|||
'to_email_lead': data.id, |
|||
'to_email': to_email, |
|||
'recipient_name': to_name, |
|||
'company_name': to_company, |
|||
'from_email': self.from_email.id, |
|||
'temp_type': self.email_temp.id, |
|||
'temp_id': self.temp_id, |
|||
'to_email_lead_check': True, |
|||
'email_finder': self.id |
|||
}) |
|||
|
|||
elif error_msg: |
|||
self.env['email.api'].create({ |
|||
'name': self.subject, |
|||
'to_email_lead': data.id, |
|||
'to_email': to_email, |
|||
'recipient_name': to_name, |
|||
'company_name': to_company, |
|||
'from_email': self.from_email.id, |
|||
'temp_type': self.email_temp.id, |
|||
'temp_id': self.temp_id, |
|||
'error_msg': error_msg, |
|||
'state': 'error', |
|||
'to_email_lead_check': True, |
|||
'error_check': True, |
|||
'email_finder': self.id |
|||
}) |
|||
self.email_finder = self.id |
|||
self.send_grid_check = True |
|||
elif self.to_email_contact: |
|||
api_info = self.env['ir.config_parameter'].search( |
|||
[('key', '=', "SendGrid API Key " + company_id.name + "")]) |
|||
if not api_info: |
|||
raise UserError(_("It Needs API Key")) |
|||
if api_info.company_id.id == self.env.company.id: |
|||
api_key = api_info.value |
|||
if not api_key and api_key == "": |
|||
raise UserError(_("Your Company Needs an API Key")) |
|||
for data in self.to_email_contact: |
|||
to_email = data.email |
|||
to_name = data.name |
|||
to_company = data.company_name |
|||
if not to_company: |
|||
to_company = "" |
|||
temp_id = self.temp_id |
|||
payload = "" |
|||
if to_email: |
|||
payload = "{\"personalizations\":[{\"to\":[{\"email\":\"" + to_email + "\"}],\"dynamic_template_data\":{\"firstname\":\"" + to_name + "\",\"english\":\"true\",\"company\":\"" + to_company + "\"},\"subject\":\"Official Mail\"}],\"from\":{\"email\":\"" + from_email + "\",\"name\":\"" + from_name + "\"},\"template_id\":\"" + temp_id + "\"}" |
|||
|
|||
headers = { |
|||
'authorization': "Bearer " + api_key + "", |
|||
'content-type': "application/json" |
|||
} |
|||
|
|||
conn.request("POST", "/v3/mail/send", payload, headers) |
|||
|
|||
res = conn.getresponse() |
|||
data_msg = res.read() |
|||
|
|||
error_msg = '' |
|||
if data_msg.decode("utf-8"): |
|||
error_data = json.loads(data_msg.decode("utf-8")) |
|||
error_msg = error_data['errors'][0]['message'] |
|||
if not data_msg.decode("utf-8"): |
|||
self.sent_count += 1 |
|||
self.write({ |
|||
'state': 'done' |
|||
}) |
|||
self.env['email.api'].create({ |
|||
'name': self.subject, |
|||
'to_email_contact': data.id, |
|||
'to_email': to_email, |
|||
'recipient_name': to_name, |
|||
'company_name': to_company, |
|||
'from_email': self.from_email.id, |
|||
'temp_type': self.email_temp.id, |
|||
'temp_id': self.temp_id, |
|||
'to_email_contact_check': True, |
|||
'email_finder': self.id |
|||
}) |
|||
|
|||
elif error_msg: |
|||
self.env['email.api'].create({ |
|||
'name': self.subject, |
|||
'to_email_contact': data.id, |
|||
'to_email': to_email, |
|||
'recipient_name': to_name, |
|||
'company_name': to_company, |
|||
'from_email': self.from_email.id, |
|||
'temp_type': self.email_temp.id, |
|||
'temp_id': self.temp_id, |
|||
'error_msg': error_msg, |
|||
'state': 'error', |
|||
'to_email_contact_check': True, |
|||
'error_check': True, |
|||
'email_finder': self.id |
|||
}) |
|||
self.email_finder = self.id |
|||
self.send_grid_check = True |
|||
elif self.to_email_applicant: |
|||
api_info = self.env['ir.config_parameter'].search( |
|||
[('key', '=', "SendGrid API Key " + company_id.name + "")]) |
|||
if not api_info: |
|||
raise UserError(_("It Needs API Key")) |
|||
if api_info.company_id.id == self.env.company.id: |
|||
api_key = api_info.value |
|||
if not api_key and api_key == "": |
|||
raise UserError(_("Your Company Needs an API Key")) |
|||
for data in self.to_email_applicant: |
|||
to_email = data.email_from |
|||
to_name = data.partner_name |
|||
to_company = data.company_id.name |
|||
if not to_company: |
|||
to_company = "" |
|||
temp_id = self.temp_id |
|||
payload = "" |
|||
if to_email: |
|||
payload = "{\"personalizations\":[{\"to\":[{\"email\":\"" + to_email + "\"}],\"dynamic_template_data\":{\"firstname\":\"" + to_name + "\",\"english\":\"true\",\"company\":\"" + to_company + "\"},\"subject\":\"Official Mail\"}],\"from\":{\"email\":\"" + from_email + "\",\"name\":\"" + from_name + "\"},\"template_id\":\"" + temp_id + "\"}" |
|||
|
|||
headers = { |
|||
'authorization': "Bearer " + api_key + "", |
|||
'content-type': "application/json" |
|||
} |
|||
|
|||
conn.request("POST", "/v3/mail/send", payload, headers) |
|||
|
|||
res = conn.getresponse() |
|||
data_msg = res.read() |
|||
|
|||
error_msg = '' |
|||
if data_msg.decode("utf-8"): |
|||
error_data = json.loads(data_msg.decode("utf-8")) |
|||
error_msg = error_data['errors'][0]['message'] |
|||
if not data_msg.decode("utf-8"): |
|||
self.sent_count += 1 |
|||
self.write({ |
|||
'state': 'done' |
|||
}) |
|||
self.env['email.api'].create({ |
|||
'name': self.subject, |
|||
'to_email_applicant': data.id, |
|||
'to_email': to_email, |
|||
'recipient_name': to_name, |
|||
'company_name': to_company, |
|||
'from_email': self.from_email.id, |
|||
'temp_type': self.email_temp.id, |
|||
'temp_id': self.temp_id, |
|||
'to_email_applicant_check': True, |
|||
'email_finder': self.id |
|||
}) |
|||
|
|||
elif error_msg: |
|||
self.env['email.api'].create({ |
|||
'name': self.subject, |
|||
'to_email_applicant': data.id, |
|||
'to_email': to_email, |
|||
'recipient_name': to_name, |
|||
'company_name': to_company, |
|||
'from_email': self.from_email.id, |
|||
'temp_type': self.email_temp.id, |
|||
'temp_id': self.temp_id, |
|||
'error_msg': error_msg, |
|||
'state': 'error', |
|||
'email_finder': self.id, |
|||
'to_email_applicant_check': True, |
|||
'error_check': True |
|||
}) |
|||
self.email_finder = self.id |
|||
self.send_grid_check = True |
|||
|
|||
@api.onchange('email_temp', 'mailing_model_id', 'contact_list_ids') |
|||
def temp_details(self): |
|||
""" |
|||
function used for filling subject and recipients emails |
|||
based on template and recipient emails |
|||
|
|||
""" |
|||
if self.email_temp: |
|||
self.temp_check = True |
|||
self.subject = self.email_temp.ver_subject |
|||
self.temp_id = self.email_temp.temp_id |
|||
self.body_html = self.email_temp.temp_cont |
|||
self.body_arch = self.email_temp.temp_cont |
|||
else: |
|||
self.temp_check = False |
|||
|
|||
if self.mailing_model_real == "sale.order" or self.mailing_model_real == "event.registration" or self.mailing_model_real == "event.track": |
|||
self.to_email_contact = False |
|||
self.to_email_lead = False |
|||
self.to_email_applicant = False |
|||
self.mailing_domain = "[]" |
|||
for mass_mailing in self: |
|||
mai_data = mass_mailing.sudo()._get_recipients() |
|||
email_ids = self.env[self.mailing_model_real].search([('id', '=', mai_data)]) |
|||
if email_ids: |
|||
self.to_email_partner = email_ids.partner_id |
|||
elif self.mailing_model_real == "crm.lead": |
|||
self.to_email_contact = False |
|||
self.to_email_partner = False |
|||
self.to_email_applicant = False |
|||
self.mailing_domain = "[]" |
|||
for mass_mailing in self: |
|||
mai_data = mass_mailing.sudo()._get_recipients() |
|||
email_ids = self.env[self.mailing_model_real].search([('id', '=', mai_data)]) |
|||
if email_ids: |
|||
self.to_email_lead = email_ids |
|||
elif self.mailing_model_real == "mailing.contact": |
|||
self.to_email_partner = False |
|||
self.to_email_lead = False |
|||
self.to_email_applicant = False |
|||
self.mailing_domain = "[]" |
|||
for mass_mailing in self: |
|||
mai_data = mass_mailing.sudo()._get_recipients() |
|||
email_ids = self.env[self.mailing_model_real].search([('id', '=', mai_data)]) |
|||
if email_ids: |
|||
self.to_email_contact = email_ids |
|||
if self.contact_list_ids: |
|||
email_ids = self.env[self.mailing_model_real].search( |
|||
[('id', '=', mai_data), ('list_ids', '=', self.contact_list_ids.ids)]) |
|||
self.to_email_contact = email_ids |
|||
|
|||
elif self.mailing_model_real == "hr.applicant": |
|||
self.to_email_contact = False |
|||
self.to_email_lead = False |
|||
self.to_email_partner = False |
|||
self.mailing_domain = "[]" |
|||
for mass_mailing in self: |
|||
mai_data = mass_mailing.sudo()._get_recipients() |
|||
email_ids = self.env[self.mailing_model_real].search([('id', '=', mai_data)]) |
|||
if email_ids: |
|||
self.to_email_applicant = email_ids |
|||
|
|||
else: |
|||
self.to_email_contact = False |
|||
self.to_email_lead = False |
|||
self.to_email_applicant = False |
|||
self.mailing_domain = "[]" |
|||
for mass_mailing in self: |
|||
mai_data = mass_mailing.sudo()._get_recipients() |
|||
email_ids = self.env[self.mailing_model_real].search([('id', '=', mai_data)]) |
|||
if email_ids: |
|||
self.to_email_partner = email_ids |
|||
|
|||
@api.onchange('mailing_domain') |
|||
def get_mails_recipients(self): |
|||
""" |
|||
function used for filtering based on domain |
|||
filter |
|||
|
|||
""" |
|||
if self.mailing_model_real == "sale.order" or self.mailing_model_real == "event.registration" or self.mailing_model_real == "event.track": |
|||
for mass_mailing in self: |
|||
mai_data = mass_mailing.sudo()._get_recipients() |
|||
email_ids = self.env[self.mailing_model_real].search([('id', '=', mai_data)]) |
|||
if email_ids: |
|||
self.to_email_partner = email_ids.partner_id |
|||
elif self.mailing_model_real == "crm.lead": |
|||
for mass_mailing in self: |
|||
mai_data = mass_mailing.sudo()._get_recipients() |
|||
email_ids = self.env[self.mailing_model_real].search([('id', '=', mai_data)]) |
|||
if email_ids: |
|||
self.to_email_lead = email_ids |
|||
elif self.mailing_model_real == "mailing.contact": |
|||
for mass_mailing in self: |
|||
mai_data = mass_mailing.sudo()._get_recipients() |
|||
email_ids = self.env[self.mailing_model_real].search([('id', '=', mai_data)]) |
|||
if email_ids: |
|||
self.to_email_contact = email_ids |
|||
elif self.mailing_model_real == "hr.applicant": |
|||
for mass_mailing in self: |
|||
mai_data = mass_mailing.sudo()._get_recipients() |
|||
email_ids = self.env[self.mailing_model_real].search([('id', '=', mai_data)]) |
|||
if email_ids: |
|||
self.to_email_applicant = email_ids |
|||
else: |
|||
for mass_mailing in self: |
|||
mai_data = mass_mailing.sudo()._get_recipients() |
|||
email_ids = self.env[self.mailing_model_real].search([('id', '=', mai_data)]) |
|||
if email_ids: |
|||
self.to_email_partner = email_ids |
|||
|
|||
@api.onchange('to_email_partner', 'to_email_lead', 'to_email_contact', 'to_email_applicant') |
|||
def show_hide_fields(self): |
|||
""" |
|||
function is used for Enabling Needed |
|||
recipient mail fields by changing check box |
|||
values. |
|||
|
|||
""" |
|||
if self.to_email_partner: |
|||
self.to_email_partner_check = True |
|||
else: |
|||
self.to_email_partner_check = False |
|||
if self.to_email_lead: |
|||
self.to_email_lead_check = True |
|||
else: |
|||
self.to_email_lead_check = False |
|||
if self.to_email_contact: |
|||
self.to_email_contact_check = True |
|||
else: |
|||
self.to_email_contact_check = False |
|||
if self.to_email_applicant: |
|||
self.to_email_applicant_check = True |
|||
else: |
|||
self.to_email_applicant_check = False |
|||
|
|||
def _action_view_documents_filtered(self, view_filter): |
|||
""" |
|||
function is used for returning send view in |
|||
needed recipient tree view |
|||
|
|||
""" |
|||
if view_filter == 'sent' and self.temp_id: |
|||
res_ids = [] |
|||
for mass_mailing in self: |
|||
mai_data = mass_mailing.sudo()._get_recipients() |
|||
res_ids = self.env[self.mailing_model_real].search([('id', '=', mai_data)]) |
|||
model_name = self.env['ir.model']._get(self.mailing_model_real).display_name |
|||
return { |
|||
'name': model_name, |
|||
'type': 'ir.actions.act_window', |
|||
'view_mode': 'tree', |
|||
'res_model': self.mailing_model_real, |
|||
'domain': [('id', 'in', res_ids.ids)], |
|||
'context': dict(self._context, create=False) |
|||
} |
|||
else: |
|||
return super(SendGridEmail, self)._action_view_documents_filtered(view_filter) |
|||
|
|||
def _compute_statistics(self): |
|||
""" |
|||
function is used for computing Send mails Smart button |
|||
count |
|||
|
|||
""" |
|||
self.env.cr.execute(""" |
|||
SELECT |
|||
m.id as mailing_id, |
|||
COUNT(s.id) AS expected, |
|||
COUNT(CASE WHEN s.sent is not null THEN 1 ELSE null END) AS sent, |
|||
COUNT(CASE WHEN s.scheduled is not null AND s.sent is null AND s.exception is null AND s.ignored is null AND s.bounced is null THEN 1 ELSE null END) AS scheduled, |
|||
COUNT(CASE WHEN s.scheduled is not null AND s.sent is null AND s.exception is null AND s.ignored is not null THEN 1 ELSE null END) AS ignored, |
|||
COUNT(CASE WHEN s.sent is not null AND s.exception is null AND s.bounced is null THEN 1 ELSE null END) AS delivered, |
|||
COUNT(CASE WHEN s.opened is not null THEN 1 ELSE null END) AS opened, |
|||
COUNT(CASE WHEN s.clicked is not null THEN 1 ELSE null END) AS clicked, |
|||
COUNT(CASE WHEN s.replied is not null THEN 1 ELSE null END) AS replied, |
|||
COUNT(CASE WHEN s.bounced is not null THEN 1 ELSE null END) AS bounced, |
|||
COUNT(CASE WHEN s.exception is not null THEN 1 ELSE null END) AS failed |
|||
FROM |
|||
mailing_trace s |
|||
RIGHT JOIN |
|||
mailing_mailing m |
|||
ON (m.id = s.mass_mailing_id) |
|||
WHERE |
|||
m.id IN %s |
|||
GROUP BY |
|||
m.id |
|||
""", (tuple(self.ids),)) |
|||
for row in self.env.cr.dictfetchall(): |
|||
total = row['expected'] = (row['expected'] - row['ignored']) or 1 |
|||
row['received_ratio'] = 100.0 * row['delivered'] / total |
|||
row['opened_ratio'] = 100.0 * row['opened'] / total |
|||
row['clicks_ratio'] = 100.0 * row['clicked'] / total |
|||
row['replied_ratio'] = 100.0 * row['replied'] / total |
|||
row['bounced_ratio'] = 100.0 * row['bounced'] / total |
|||
self.browse(row.pop('mailing_id')).update(row) |
|||
for mail in self: |
|||
if mail.temp_id: |
|||
mail.sent = mail.sent_count |
|||
else: |
|||
return super(SendGridEmail, self)._compute_statistics() |
@ -0,0 +1,137 @@ |
|||
# -*- coding: utf-8 -*- |
|||
################################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2019-TODAY Cybrosys Technologies (<https://www.cybrosys.com>). |
|||
# Author: Noushid Khan.P (<https://www.cybrosys.com>) |
|||
# |
|||
# This program is free software: you can modify |
|||
# it under the terms of the GNU Affero General Public License (AGPL) as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# |
|||
# 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 for more details. |
|||
# |
|||
# You should have received a copy of the GNU Affero General Public License |
|||
# along with this program. If not, see <https://www.gnu.org/licenses/>. |
|||
# |
|||
################################################################################### |
|||
|
|||
import json |
|||
|
|||
from odoo import models, fields, _ |
|||
import http.client |
|||
|
|||
from odoo.exceptions import UserError |
|||
|
|||
|
|||
class SendGridSendEmails(models.Model): |
|||
_name = "email.api" |
|||
_description = "Email Reports" |
|||
|
|||
name = fields.Char(string="Name") |
|||
company_name = fields.Char(string="Company Name") |
|||
recipient_name = fields.Char(string="Recipient Name") |
|||
to_email = fields.Char(string="Recipient Email ID") |
|||
to_email_partner = fields.Many2one("res.partner", string="Recipient Emails") |
|||
to_email_partner_check = fields.Boolean() |
|||
to_email_lead = fields.Many2one("crm.lead", string="Recipient Emails") |
|||
to_email_lead_check = fields.Boolean() |
|||
to_email_contact = fields.Many2one("mailing.contact", string="Recipient Emails") |
|||
to_email_contact_check = fields.Boolean() |
|||
to_email_applicant = fields.Many2one("hr.applicant", string="Recipient Emails") |
|||
to_email_applicant_check = fields.Boolean() |
|||
from_email = fields.Many2one("email.sent", string="Sender Email") |
|||
temp_type = fields.Many2one('email.template', string="Email Template") |
|||
temp_id = fields.Char(string="Template_id") |
|||
send_date = fields.Datetime(string="Send Date", readonly=True, default=fields.Datetime.now) |
|||
error_msg = fields.Text(string="Error Content", readonly=True) |
|||
error_check = fields.Boolean() |
|||
state = fields.Selection([('send', "Send"), ('error', "Error")], readonly=True, string="State", default='send') |
|||
bounce_msg = fields.Text(string="Bounce Message") |
|||
email_finder = fields.Integer(string="Email finder") |
|||
|
|||
def bounce_check(self): |
|||
""" |
|||
function is used for Checking Email Bounce |
|||
Status. |
|||
|
|||
""" |
|||
|
|||
conn = http.client.HTTPSConnection("api.sendgrid.com") |
|||
|
|||
payload = "{}" |
|||
|
|||
headers = {'authorization': "Bearer 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"} |
|||
|
|||
conn.request("GET", "/v3/suppression/bounces/" + self.to_email + "", payload, headers) |
|||
|
|||
res = conn.getresponse() |
|||
data = res.read() |
|||
|
|||
bounce_msg = json.loads(data.decode("utf-8")) |
|||
if bounce_msg: |
|||
self.bounce_msg = bounce_msg[0]['reason'] |
|||
|
|||
else: |
|||
self.bounce_msg = "This Email Is Not Bounced" |
|||
|
|||
def send_error_mails(self): |
|||
""" |
|||
function is used for Resending Error State |
|||
mails. |
|||
|
|||
""" |
|||
company_id = self.env.company |
|||
api_key = "" |
|||
for line in self: |
|||
if line.state == 'error': |
|||
if not line.temp_id: |
|||
raise UserError(_("It Needs A Template ID")) |
|||
if line.from_email: |
|||
from_email = line.from_email.email_id |
|||
else: |
|||
from_email = "noreply@johndoe.com" |
|||
api_info = self.env['ir.config_parameter'].search( |
|||
[('key', '=', "SendGrid API Key " + company_id.name + "")]) |
|||
if not api_info: |
|||
raise UserError(_("It Needs API Key")) |
|||
if api_info.company_id.id == self.env.company.id: |
|||
api_key = api_info.value |
|||
if not api_key and api_key == "": |
|||
raise UserError(_("Your Company Needs an API Key")) |
|||
conn = http.client.HTTPSConnection("api.sendgrid.com") |
|||
to_company = line.company_name |
|||
if not to_company: |
|||
to_company = "" |
|||
temp_id = line.temp_id |
|||
payload = "" |
|||
if line.to_email and line.recipient_name: |
|||
payload = "{\"personalizations\":[{\"to\":[{\"email\":\"" + line.to_email + "\"}],\"dynamic_template_data\":{\"firstname\":\"" + line.recipient_name + "\",\"english\":\"true\",\"company\":\"" + to_company + "\"},\"subject\":\"Official Mail\"}],\"from\":{\"email\":\"" + from_email + "\",},\"template_id\":\"" + temp_id + "\"}" |
|||
headers = { |
|||
'authorization': "Bearer " + api_key + "", |
|||
'content-type': "application/json" |
|||
} |
|||
|
|||
conn.request("POST", "/v3/mail/send", payload, headers) |
|||
|
|||
res = conn.getresponse() |
|||
data_msg = res.read() |
|||
|
|||
if data_msg.decode("utf-8"): |
|||
error_data = json.loads(data_msg.decode("utf-8")) |
|||
line.error_msg = error_data['errors'][0]['message'] |
|||
if not data_msg.decode("utf-8"): |
|||
line.state = 'send' |
|||
line.error_msg = "" |
|||
line.error_check = False |
|||
email_id_use = self.env['mailing.mailing'].search([('id', '=', line.email_finder)]) |
|||
email_id_use.send_grid_check = True |
|||
email_id_use.sent_count += 1 |
|||
email_id_use.write({ |
|||
'state': 'done' |
|||
}) |
@ -0,0 +1,39 @@ |
|||
# -*- coding: utf-8 -*- |
|||
################################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2019-TODAY Cybrosys Technologies (<https://www.cybrosys.com>). |
|||
# Author: Noushid Khan.P (<https://www.cybrosys.com>) |
|||
# |
|||
# This program is free software: you can modify |
|||
# it under the terms of the GNU Affero General Public License (AGPL) as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# |
|||
# 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 for more details. |
|||
# |
|||
# You should have received a copy of the GNU Affero General Public License |
|||
# along with this program. If not, see <https://www.gnu.org/licenses/>. |
|||
# |
|||
################################################################################### |
|||
|
|||
from odoo import models, fields, api, _ |
|||
|
|||
|
|||
class SendGridApiConfig(models.TransientModel): |
|||
_inherit = 'res.config.settings' |
|||
|
|||
send_grid_api_check = fields.Boolean(string="SendGrid API") |
|||
send_grid_api_value = fields.Char(string='API key') |
|||
|
|||
def set_values(self): |
|||
""" save values in the settings fields """ |
|||
|
|||
super(SendGridApiConfig, self).set_values() |
|||
company_id = self.env.company |
|||
self.env['ir.config_parameter'].sudo().set_param("SendGrid API Key "+company_id.name+"", |
|||
self.send_grid_api_value) |
|
After Width: | Height: | Size: 54 KiB |
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 76 KiB |
After Width: | Height: | Size: 69 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 72 KiB |
After Width: | Height: | Size: 63 KiB |
After Width: | Height: | Size: 77 KiB |
After Width: | Height: | Size: 51 KiB |
After Width: | Height: | Size: 74 KiB |
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 68 KiB |
After Width: | Height: | Size: 63 KiB |
After Width: | Height: | Size: 50 KiB |
After Width: | Height: | Size: 74 KiB |
After Width: | Height: | Size: 73 KiB |
After Width: | Height: | Size: 85 KiB |
After Width: | Height: | Size: 89 KiB |
After Width: | Height: | Size: 81 KiB |
After Width: | Height: | Size: 87 KiB |
After Width: | Height: | Size: 88 KiB |
After Width: | Height: | Size: 92 KiB |
After Width: | Height: | Size: 92 KiB |
After Width: | Height: | Size: 86 KiB |
After Width: | Height: | Size: 89 KiB |
After Width: | Height: | Size: 89 KiB |
After Width: | Height: | Size: 124 KiB |
After Width: | Height: | Size: 123 KiB |
After Width: | Height: | Size: 106 KiB |
After Width: | Height: | Size: 112 KiB |
After Width: | Height: | Size: 124 KiB |
After Width: | Height: | Size: 122 KiB |
After Width: | Height: | Size: 66 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 66 KiB |
After Width: | Height: | Size: 75 KiB |
After Width: | Height: | Size: 54 KiB |
After Width: | Height: | Size: 66 KiB |
After Width: | Height: | Size: 47 KiB |
@ -0,0 +1,18 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<odoo> |
|||
<data> |
|||
|
|||
<record id="ir_config_inherit_view" model="ir.ui.view"> |
|||
<field name="name">company config</field> |
|||
<field name="model">ir.config_parameter</field> |
|||
<field name="inherit_id" ref="base.view_ir_config_form"/> |
|||
<field name="arch" type="xml"> |
|||
<xpath expr="//field[@name='value']" |
|||
position="after"> |
|||
<field name="company_id" invisible="1"/> |
|||
</xpath> |
|||
</field> |
|||
</record> |
|||
|
|||
</data> |
|||
</odoo> |
@ -0,0 +1,99 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<odoo> |
|||
<data> |
|||
|
|||
<record id="send_mass_mailing_view" model="ir.ui.view"> |
|||
<field name="name">SendGrid Mass MAil</field> |
|||
<field name="model">mailing.mailing</field> |
|||
<field name="inherit_id" ref="mass_mailing.view_mail_mass_mailing_form"/> |
|||
<field name="arch" type="xml"> |
|||
<xpath expr="/form/header" position="inside"> |
|||
<button name="action_send_grid" type="object" |
|||
attrs="{'invisible': [('state', 'in', ('in_queue', 'done'))]}" class="oe_highlight" |
|||
string="SendGrid" |
|||
confirm="This will send the email to all recipients. Do you still want to proceed ?"/> |
|||
</xpath> |
|||
<xpath expr="/form/sheet/notebook/page[@name='mail_body']" |
|||
position="after"> |
|||
<page string="SendGrid Email" name="send_grid"> |
|||
<group> |
|||
<field name="email_temp"/> |
|||
<field name="temp_id"/> |
|||
</group> |
|||
<group> |
|||
<field name="to_email_partner_check" invisible="1"/> |
|||
<field name="to_email_lead_check" invisible="1"/> |
|||
<field name="to_email_contact_check" invisible="1"/> |
|||
<field name="to_email_applicant_check" invisible="1"/> |
|||
<field name="to_email_partner" widget="many2many_tags" |
|||
attrs="{'invisible': [('to_email_partner_check', '=', False)]}"/> |
|||
<field name="to_email_lead" widget="many2many_tags" |
|||
attrs="{'invisible': [('to_email_lead_check', '=',False)]}"/> |
|||
<field name="to_email_contact" widget="many2many_tags" |
|||
attrs="{'invisible': [('to_email_contact_check', '=',False)]}"/> |
|||
<field name="to_email_applicant" widget="many2many_tags" |
|||
attrs="{'invisible': [('to_email_applicant_check', '=',False)]}"/> |
|||
<field name="from_email"/> |
|||
<field name="email_finder" invisible="1"/> |
|||
<field name="sent_count" invisible="1"/> |
|||
<field name="send_grid_check" invisible="1"/> |
|||
<field name="temp_check" invisible="1"/> |
|||
</group> |
|||
</page> |
|||
</xpath> |
|||
<xpath expr="//button[@name='action_view_delivered']" position="replace"> |
|||
<button name="action_view_delivered" type="object" |
|||
context="{'search_default_filter_delivered': True}" |
|||
attrs="{'invisible': ['|',('state', 'in', ('draft','test')),('send_grid_check','=',True)]}" |
|||
class="oe_stat_button"> |
|||
<field name="received_ratio" string="Received" widget="percentpie"/> |
|||
</button> |
|||
</xpath> |
|||
<xpath expr="//button[@name='action_redirect_to_leads']" position="replace"> |
|||
<button name="action_redirect_to_leads" type="object" icon="fa-star" class="oe_stat_button" |
|||
groups="sales_team.group_sale_salesman" |
|||
attrs="{'invisible': ['|','|',('state', '=', 'draft'), ('crm_lead_activated', '=', False), ('send_grid_check','=',True)]}"> |
|||
<field name="crm_lead_count" string="Leads" widget="statinfo"/> |
|||
</button> |
|||
</xpath> |
|||
<xpath expr="//button[@name='action_redirect_to_opportunities']" position="replace"> |
|||
<button name="action_redirect_to_opportunities" type="object" icon="fa-star" class="oe_stat_button" |
|||
groups="sales_team.group_sale_salesman" |
|||
attrs="{'invisible': ['|','|',('state', '=', 'draft'), ('crm_lead_activated', '=', True), ('send_grid_check','=',True)]}"> |
|||
<field name="crm_opportunities_count" string="Opportunities" widget="statinfo"/> |
|||
</button> |
|||
</xpath> |
|||
<xpath expr="//button[@name='action_view_opened']" position="replace"> |
|||
<button name="action_view_opened" type="object" context="{'search_default_filter_opened': True}" |
|||
attrs="{'invisible': ['|',('state', 'in', ('draft','test')),('send_grid_check','=',True)]}" |
|||
class="oe_stat_button"> |
|||
<field name="opened_ratio" string="Opened" widget="percentpie"/> |
|||
</button> |
|||
</xpath> |
|||
<xpath expr="//button[@name='action_view_replied']" position="replace"> |
|||
<button name="action_view_replied" type="object" context="{'search_default_filter_replied': True}" |
|||
attrs="{'invisible': ['|',('state', 'in', ('draft','test')),('send_grid_check','=',True)]}" |
|||
class="oe_stat_button"> |
|||
<field name="replied_ratio" string="Replied" widget="percentpie"/> |
|||
</button> |
|||
</xpath> |
|||
<xpath expr="//button[@name='action_view_bounced']" position="replace"> |
|||
<button name="action_view_bounced" type="object" context="{'search_default_filter_bounced': True}" |
|||
attrs="{'invisible': ['|',('state', 'in', ('draft','test')),('send_grid_check','=',True)]}" |
|||
class="oe_stat_button"> |
|||
<field name="bounced_ratio" string="Bounced" widget="percentpie"/> |
|||
</button> |
|||
</xpath> |
|||
<xpath expr="//field[@name='body_arch']" position="replace"> |
|||
<field name="body_arch" class="o_mail_body oe_edit_only" widget="mass_mailing_html" |
|||
options="{ |
|||
'snippets': 'mass_mailing.email_designer_snippets', |
|||
'cssEdit': 'mass_mailing.iframe_css_assets_edit', |
|||
'inline-field': 'body_html' |
|||
}" attrs="{'readonly': ['|',('state', 'in', ('sending', 'done')),('temp_check','=', True)]}"/> |
|||
</xpath> |
|||
</field> |
|||
</record> |
|||
|
|||
</data> |
|||
</odoo> |
@ -0,0 +1,37 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<odoo> |
|||
<data> |
|||
<record id="res_config_settings_send_grid_view_form" model="ir.ui.view"> |
|||
<field name="name">res.config.settings.view.form.inherit.send.grid</field> |
|||
<field name="model">res.config.settings</field> |
|||
<field name="priority" eval="70"/> |
|||
<field name="inherit_id" ref="base.res_config_settings_view_form"/> |
|||
<field name="arch" type="xml"> |
|||
<xpath expr="//div[hasclass('settings')]" |
|||
position="inside"> |
|||
<div class="app_settings_block"> |
|||
<div class="row mt16 o_settings_container"> |
|||
<div class="col-lg-6 o_setting_box col-12"> |
|||
<div class="o_setting_left_pane"> |
|||
<field name="send_grid_api_check"/> |
|||
</div> |
|||
<div class="o_setting_right_pane"> |
|||
<label for="send_grid_api_check"/> |
|||
<div class="text-muted"> |
|||
Use API key For SendGrid Service |
|||
</div> |
|||
<div class="content-group" |
|||
attrs="{'invisible': [('send_grid_api_check', '=', False)]}"> |
|||
<div class="mt16"> |
|||
<field name="send_grid_api_value"/> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</xpath> |
|||
</field> |
|||
</record> |
|||
</data> |
|||
</odoo> |
@ -0,0 +1,218 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<odoo> |
|||
<data> |
|||
|
|||
<record id="email_sending_action" model="ir.actions.act_window"> |
|||
<field name="name">Send Emails</field> |
|||
<field name="res_model">email.api</field> |
|||
<field name="view_mode">tree,form</field> |
|||
<field name="context">{'group_by': 'name'}</field> |
|||
<field name="help" type="html"> |
|||
<p class="oe_view_nocontent_create">Create contacts |
|||
</p> |
|||
</field> |
|||
</record> |
|||
|
|||
<record id="send_emails_tree_view" model="ir.ui.view"> |
|||
<field name="name">Send Emails tree</field> |
|||
<field name="model">email.api</field> |
|||
<field name="arch" type="xml"> |
|||
<tree string="Send Emails" delete="0" create="0"> |
|||
<field name="name"/> |
|||
<field name="to_email"/> |
|||
<field name="send_date"/> |
|||
<field name="state"/> |
|||
</tree> |
|||
</field> |
|||
</record> |
|||
|
|||
<record id="send_emails_free_view" model="ir.ui.view"> |
|||
<field name="name">Send Emails Form</field> |
|||
<field name="model">email.api</field> |
|||
<field name="arch" type="xml"> |
|||
<form string="Email Details" delete="0" create="0" edit="0"> |
|||
<header> |
|||
<field name="state" widget="statusbar"/> |
|||
</header> |
|||
<sheet> |
|||
<group> |
|||
<field name="name"/> |
|||
<field name="send_date"/> |
|||
</group> |
|||
<group> |
|||
<field name="temp_type"/> |
|||
<field name="temp_id"/> |
|||
</group> |
|||
<group> |
|||
<field name="to_email_partner_check" invisible="1"/> |
|||
<field name="to_email_lead_check" invisible="1"/> |
|||
<field name="to_email_contact_check" invisible="1"/> |
|||
<field name="to_email_applicant_check" invisible="1"/> |
|||
<field name="to_email_partner" |
|||
attrs="{'invisible': [('to_email_partner_check', '=', False)]}"/> |
|||
<field name="to_email_lead" attrs="{'invisible': [('to_email_lead_check', '=',False)]}"/> |
|||
<field name="to_email_contact" |
|||
attrs="{'invisible': [('to_email_contact_check', '=',False)]}"/> |
|||
<field name="to_email_applicant" |
|||
attrs="{'invisible': [('to_email_applicant_check', '=',False)]}"/> |
|||
<field name="to_email" invisible="1"/> |
|||
<field name="company_name" invisible="1"/> |
|||
<field name="recipient_name" invisible="1"/> |
|||
<field name="email_finder" invisible="1"/> |
|||
<field name="from_email"/> |
|||
</group> |
|||
<group> |
|||
<field name="error_check" invisible="1"/> |
|||
</group> |
|||
<group> |
|||
<button string="Bounce Check" name="bounce_check" type="object" |
|||
attrs="{'invisible': [('error_check', '=',True)]}"/> |
|||
</group> |
|||
</sheet> |
|||
<notebook> |
|||
<page string="Messages"> |
|||
<field name="bounce_msg" widget="text" attrs="{'invisible': [('error_check', '=',True)]}"/> |
|||
<field name="error_msg" widget="text" attrs="{'invisible': [('error_check', '=',False)]}"/> |
|||
</page> |
|||
</notebook> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
|
|||
<record id='send_emails_search' model='ir.ui.view'> |
|||
<field name="name">send.emails.search</field> |
|||
<field name="model">email.api</field> |
|||
<field name="arch" type="xml"> |
|||
<search string="Send Emails"> |
|||
<field name="name"/> |
|||
<field name="to_email"/> |
|||
<field name="send_date"/> |
|||
<field name="state"/> |
|||
<group expand="1" string="Group By"> |
|||
<filter name="groupby_name" context="{'group_by': 'name'}" string="Name"/> |
|||
<filter name="groupby_state" context="{'group_by': 'state'}" |
|||
string="Email State"/> |
|||
</group> |
|||
</search> |
|||
</field> |
|||
</record> |
|||
|
|||
<menuitem id="email_sending_menu" |
|||
parent="mass_mailing.menu_mass_mailing_report" |
|||
name="SendGrid Send Emails" |
|||
action="email_sending_action"/> |
|||
|
|||
<record id="email_details_action" model="ir.actions.act_window"> |
|||
<field name="name">Email Details</field> |
|||
<field name="res_model">email.sent</field> |
|||
<field name="view_mode">tree,form</field> |
|||
<field name="help" type="html"> |
|||
<p class="oe_view_nocontent_create">Create Email Details |
|||
</p> |
|||
</field> |
|||
</record> |
|||
|
|||
<record id="email_details_tree_view" model="ir.ui.view"> |
|||
<field name="name">Email Details tree</field> |
|||
<field name="model">email.sent</field> |
|||
<field name="arch" type="xml"> |
|||
<tree string="Email Details"> |
|||
<field name="name"/> |
|||
<field name="email_id"/> |
|||
</tree> |
|||
</field> |
|||
</record> |
|||
|
|||
<record id="email_details_from_view" model="ir.ui.view"> |
|||
<field name="name">Email Details Form</field> |
|||
<field name="model">email.sent</field> |
|||
<field name="arch" type="xml"> |
|||
<form string="Email Details"> |
|||
<sheet> |
|||
<group> |
|||
<field name="name"/> |
|||
<field name="email_id"/> |
|||
</group> |
|||
</sheet> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
|
|||
<menuitem id="email_details_menu" |
|||
parent="mass_mailing.mass_mailing_configuration" |
|||
name="SendGrid From Email" |
|||
action="email_details_action"/> |
|||
|
|||
<record id="email_template_action" model="ir.actions.act_window"> |
|||
<field name="name">Email Template Details</field> |
|||
<field name="res_model">email.template</field> |
|||
<field name="view_mode">tree,form</field> |
|||
<field name="help" type="html"> |
|||
<p class="oe_view_nocontent_create">Create Email Template Details |
|||
</p> |
|||
</field> |
|||
</record> |
|||
|
|||
<record id="email_template_details_tree_view" model="ir.ui.view"> |
|||
<field name="name">Email Template Details tree</field> |
|||
<field name="model">email.template</field> |
|||
<field name="arch" type="xml"> |
|||
<tree string="Email Template Details"> |
|||
<field name="temp_name"/> |
|||
<field name="generation"/> |
|||
</tree> |
|||
</field> |
|||
</record> |
|||
|
|||
<record id="email_template_details_from_view" model="ir.ui.view"> |
|||
<field name="name">Email Template Details Form</field> |
|||
<field name="model">email.template</field> |
|||
<field name="arch" type="xml"> |
|||
<form string="Email Template Details"> |
|||
<sheet> |
|||
<group> |
|||
<field name="temp_name"/> |
|||
<field name="generation"/> |
|||
</group> |
|||
<group> |
|||
<field name="ver_name"/> |
|||
<field name="ver_editor"/> |
|||
</group> |
|||
<notebook> |
|||
<page string="Email Content"> |
|||
<label for="ver_subject"/> |
|||
<h2 style="display: inline-block;"> |
|||
<field name="ver_subject" placeholder="Subject (placeholders may be used here)"/> |
|||
</h2> |
|||
<field name="temp_cont" widget="html" options="{'style-inline': true}"/> |
|||
<button string="Create Template" name="create_temp" type="object"/> |
|||
<group> |
|||
<field name="temp_id"/> |
|||
</group> |
|||
<button string="Create Version" name="create_ver" type="object"/> |
|||
</page> |
|||
</notebook> |
|||
</sheet> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
|
|||
<record id="action_auto_sent_error_emails" model="ir.actions.server"> |
|||
<field name="name">Resend Error Mails</field> |
|||
<field name="type">ir.actions.server</field> |
|||
<field name="state">code</field> |
|||
<field name="model_id" ref="model_email_api"/> |
|||
<field name="binding_model_id" ref="model_email_api"/> |
|||
<field name="binding_view_types">list</field> |
|||
<field name="code"> |
|||
records.send_error_mails() |
|||
</field> |
|||
</record> |
|||
|
|||
<menuitem id="email_template_details_menu" |
|||
parent="mass_mailing.mass_mailing_configuration" |
|||
name="SendGrid Template Details" |
|||
action="email_template_action"/> |
|||
|
|||
</data> |
|||
</odoo> |