30 changed files with 724 additions and 1384 deletions
@ -0,0 +1,13 @@ |
|||
<odoo> |
|||
<data> |
|||
<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> |
|||
</data> |
|||
</odoo> |
@ -0,0 +1,122 @@ |
|||
# -*- 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 |
|||
import requests |
|||
from odoo import fields, models, _ |
|||
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_check = fields.Boolean() |
|||
to_email_partner = fields.Many2one("res.partner", |
|||
string="Recipient Emails") |
|||
to_email_lead_check = fields.Boolean() |
|||
to_email_lead = fields.Many2one("crm.lead", |
|||
string="Recipient Emails") |
|||
to_email_contact_check = fields.Boolean() |
|||
to_email_contact = fields.Many2one("mailing.contact", |
|||
string="Recipient Emails") |
|||
to_email_applicant_check = fields.Boolean() |
|||
to_email_applicant = fields.Many2one("hr.applicant", |
|||
string="Recipient Emails") |
|||
from_email = fields.Char(string="Sender Email") |
|||
temp_type = fields.Many2one('sendgrid.email.template', |
|||
string="Email Template") |
|||
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.""" |
|||
send_grid_api = self.env['ir.config_parameter'].sudo().get_param( |
|||
'sendgrid_email.send_grid_api_value') |
|||
params = {'email': self.to_email} |
|||
headers = { |
|||
'authorization': "Bearer " + send_grid_api, |
|||
'Content-Type': 'application/json' |
|||
} |
|||
url = "https://api.sendgrid.com/v3/suppression/bounces" |
|||
response = requests.get(url, headers=headers, params=params) |
|||
# Check the response status code |
|||
if response.status_code == 200: |
|||
# Parse the JSON response |
|||
bounce_details = response.json() |
|||
# Check if there are any bounce records for the email |
|||
if 'result' in bounce_details and len(bounce_details['result']) > 0: |
|||
for bounce_record in bounce_details['result']: |
|||
self.bounce_msg = (f"- Reason: {bounce_record['reason']}", |
|||
f" Status: {bounce_record['status']}") |
|||
else: |
|||
self.bounce_msg = f"No bounce records found for {self.to_email}" |
|||
else: |
|||
self.bounce_msg = f"Error retrieving bounce details: {response.status_code} - {response.text}" |
|||
|
|||
def send_error_mails(self): |
|||
"""function is used for Resending Error State mails.""" |
|||
for line in self: |
|||
if line.state == 'error': |
|||
if not line.temp_type: |
|||
raise UserError(_("It Needs A Template ID")) |
|||
if not line.from_email: |
|||
raise UserError(_("It Needs A Sender Email!!")) |
|||
else: |
|||
from_email = line.from_email |
|||
api_key = self.env['ir.config_parameter'].sudo().get_param('sendgrid_email.send_grid_api_value') |
|||
if not api_key and api_key == "": |
|||
raise UserError(_("Your Company Needs an API Key")) |
|||
if line.to_email and line.recipient_name: |
|||
payload = json.dumps({ |
|||
"personalizations": [ |
|||
{"to": [{"email": line.to_email}], |
|||
"subject": line.temp_type.ver_subject} |
|||
], |
|||
"from": {"email": from_email}, |
|||
"content": [ |
|||
{"type": "text/html", |
|||
"value": line.temp_type.temp_cont} |
|||
] |
|||
}) |
|||
headers = { |
|||
'Content-Type': 'application/json', |
|||
'Authorization': f'Bearer {api_key}' |
|||
} |
|||
url = "https://api.sendgrid.com/v3/mail/send" |
|||
response = requests.request("POST", url, |
|||
headers=headers, |
|||
data=payload) |
|||
if response.status_code in [200, 201, 202]: |
|||
line.state = 'send' |
|||
line.error_check = False |
|||
line.error_msg = False |
@ -1,139 +0,0 @@ |
|||
# -*- 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 = "" |
|||
print("testing") |
|||
company_id = self.env.company |
|||
print("company_id", company_id) |
|||
temp_name = self.temp_name |
|||
print("temp_name", temp_name) |
|||
temp_gen = self.generation |
|||
print("temp_gen", temp_gen) |
|||
api_info = self.env['ir.config_parameter'].search( |
|||
[('key', '=', "SendGrid API Key " + company_id.name + "")]) |
|||
print("api_info", api_info) |
|||
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" |
|||
} |
|||
print(payload, headers, "nwerk") |
|||
conn.request("POST", "/v3/templates", payload, headers) |
|||
|
|||
res = conn.getresponse() |
|||
data = res.read() |
|||
print("json", json) |
|||
temp_data = json.loads(data.decode("utf-8")) |
|||
print("temp_data", temp_data) |
|||
self.temp_id = temp_data['id'] |
|||
print("temp_id", self.temp_id) |
|||
|
|||
def create_ver(self): |
|||
""" |
|||
Function is used for creating mail content to the |
|||
Created Template. |
|||
|
|||
""" |
|||
api_key = "" |
|||
if self.temp_cont: |
|||
print(self.temp_cont) |
|||
company_id = self.env.company |
|||
print("cmp", company_id) |
|||
temp_cont = str(self.temp_cont) |
|||
print("cnt", temp_cont) |
|||
temp_id = self.temp_id |
|||
ver_name = self.ver_name |
|||
ver_sub = self.ver_subject |
|||
print("ver_sub", ver_sub, type(ver_sub)) |
|||
api_info = self.env['ir.config_parameter'].search( |
|||
[('key', '=', "SendGrid API Key " + company_id.name + "")]) |
|||
print("api_info", api_info) |
|||
if not api_info: |
|||
raise UserError(_("It Needs API Key")) |
|||
if api_info.company_id.id == self.env.company.id: |
|||
print("x") |
|||
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") |
|||
print("temp_cont", type(temp_cont)) |
|||
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+"\"}" |
|||
# payload = { |
|||
# 'template_id': temp_id, |
|||
# 'active': "1", |
|||
# 'name': ver_name, |
|||
# 'html_content': upt_temp_cnt, |
|||
# 'plain_content': "<%body%>", |
|||
# 'subject': ver_sub |
|||
# |
|||
# } |
|||
print(payload, "fdkngfd") |
|||
headers = { |
|||
'authorization': "Bearer " + api_key + "", |
|||
'content-type': "application/json" |
|||
} |
|||
print("head", headers) |
|||
conn.request("POST", "/v3/templates/" + temp_id + "/versions", payload, headers) |
|||
res = conn.getresponse() |
|||
print("res2", res) |
|||
data = res.read() |
|||
print("data2", data) |
|||
|
@ -1,43 +0,0 @@ |
|||
# -*- 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 |
|||
|
|||
|
@ -1,568 +0,0 @@ |
|||
# -*- 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 |
|||
import markupsafe |
|||
from markupsafe import escape |
|||
|
|||
|
|||
|
|||
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): |
|||
print("action") |
|||
""" |
|||
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") |
|||
print("conn", conn) |
|||
if not self.temp_id: |
|||
raise UserError(_("It Needs A Template ID")) |
|||
if self.from_email: |
|||
from_email = self.from_email.email_id |
|||
print("from_email", from_email) |
|||
from_name = self.from_email.name |
|||
print("from_name", from_name) |
|||
print("to_email_partner", self.to_email_partner) |
|||
else: |
|||
from_email = "noreply@johndoe.com" |
|||
from_name = "JohnDoe" |
|||
if self.to_email_partner: |
|||
print("to_email_partner") |
|||
api_info = self.env['ir.config_parameter'].search( |
|||
[('key', '=', "SendGrid API Key " + company_id.name + "")]) |
|||
print("api_info", api_info) |
|||
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 |
|||
print("to_email", to_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 |
|||
print("subject", type(self.subject)) |
|||
self.temp_id = self.email_temp.temp_id |
|||
print("temp_id", type(self.temp_id)) |
|||
self.body_html = str(self.email_temp.temp_cont) |
|||
print("body_html", self.body_html) |
|||
print("body_html", type(self.body_html)) |
|||
self.body_arch = self.email_temp.temp_cont |
|||
self.body_arch = "str(self.email_temp.temp_cont)" |
|||
print("body_arch", self.body_arch) |
|||
print("body_arch", type(self.body_arch)) |
|||
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(s.sent_datetime) AS sent, |
|||
COUNT(s.trace_status) FILTER (WHERE s.trace_status = 'outgoing') AS scheduled, |
|||
COUNT(s.trace_status) FILTER (WHERE s.trace_status = 'cancel') AS canceled, |
|||
COUNT(s.trace_status) FILTER (WHERE s.trace_status in ('sent', 'open', 'reply')) AS delivered, |
|||
COUNT(s.trace_status) FILTER (WHERE s.trace_status in ('open', 'reply')) AS opened, |
|||
COUNT(s.links_click_datetime) AS clicked, |
|||
COUNT(s.trace_status) FILTER (WHERE s.trace_status = 'reply') AS replied, |
|||
COUNT(s.trace_status) FILTER (WHERE s.trace_status = 'bounce') AS bounced, |
|||
COUNT(s.trace_status) FILTER (WHERE s.trace_status = 'error') 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['canceled']) or 1 |
|||
row['received_ratio'] = 100.0 * row['delivered'] / total |
|||
row['opened_ratio'] = 100.0 * row['opened'] / total |
|||
row['replied_ratio'] = 100.0 * row['replied'] / total |
|||
row['bounced_ratio'] = 100.0 * row['bounced'] / total |
|||
row['clicks_ratio'] = 100.0 * row['clicked'] / 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,271 @@ |
|||
# -*- 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 |
|||
import requests |
|||
from odoo import models, fields, api |
|||
|
|||
|
|||
class SendGridEmail(models.Model): |
|||
_inherit = 'mailing.mailing' |
|||
|
|||
email_temp = fields.Many2one("sendgrid.email.template", |
|||
string="Email Template") |
|||
sender_id = fields.Many2one('mailing.contact', string="Sender") |
|||
to_email_partner_check = fields.Boolean() |
|||
to_email_partner_ids = fields.Many2many("res.partner", |
|||
string="Recipient Emails") |
|||
to_email_lead_check = fields.Boolean() |
|||
to_email_lead = fields.Many2many("crm.lead", |
|||
string="Recipient Emails") |
|||
to_email_contact_check = fields.Boolean() |
|||
to_email_contact = fields.Many2many("mailing.contact", |
|||
string="Recipient Emails") |
|||
to_email_applicant_check = fields.Boolean() |
|||
to_email_applicant = fields.Many2many("hr.applicant", |
|||
string="Recipient Emails") |
|||
email_finder = fields.Integer(string="Email finder") |
|||
sent_count = fields.Integer(string="Send Count") |
|||
temp_check = fields.Boolean() |
|||
|
|||
def action_send_grid(self): |
|||
"""Function for sending emails using the SendGrid API and |
|||
logging the results.""" |
|||
api_key = self.env["ir.config_parameter"].sudo().get_param( |
|||
"sendgrid_email.send_grid_api_value") |
|||
url = "https://api.sendgrid.com/v3/mail/send" |
|||
headers = { |
|||
'Content-Type': 'application/json', |
|||
'Authorization': f'Bearer {api_key}' |
|||
} |
|||
# Helper function to send an individual email |
|||
def send_individual_email(recipient_email): |
|||
if not recipient_email: |
|||
return None |
|||
payload = json.dumps({ |
|||
"personalizations": [ |
|||
{"to": [{"email": recipient_email}], |
|||
"subject": self.subject} |
|||
], |
|||
"from": {"email": self.sender_id.email}, |
|||
"content": [{"type": "text/html", "value": self.body_arch}] |
|||
}) |
|||
try: |
|||
response = requests.post(url, headers=headers, data=payload) |
|||
return response |
|||
except Exception as e: |
|||
return None |
|||
|
|||
# Helper function to handle email responses and log the result |
|||
def log_email_result(recipient, email_field, type_check_field, model_name): |
|||
common_data = { |
|||
'name': self.subject, |
|||
'to_email_partner': recipient.id, |
|||
'to_email': recipient[email_field], |
|||
'recipient_name': recipient.name, |
|||
'company_name': getattr(recipient, 'company_name', |
|||
"") or getattr(recipient.company_id, |
|||
'name', ""), |
|||
'from_email': self.sender_id.email, |
|||
'temp_type': self.email_temp.id, |
|||
'email_finder': self.id, |
|||
type_check_field: True |
|||
} |
|||
response = send_individual_email(recipient[email_field]) |
|||
response.status_code = 201 |
|||
if response.status_code in [200, 201, 202]: |
|||
common_data.update({'state': 'send'}) |
|||
self.env["email.api"].create(common_data) |
|||
else: |
|||
error_data = response.json().get('errors', [{}]) |
|||
error_msg = error_data[0].get('message', |
|||
'Unknown error') if error_data else 'Unknown error' |
|||
common_data.update({'state': 'error', 'error_msg': error_msg, |
|||
'error_check': True}) |
|||
self.env["email.api"].create(common_data) |
|||
# Email recipient mappings |
|||
recipient_mappings = [ |
|||
(self.to_email_partner_ids, 'email', 'to_email_partner_check','res.partner'), |
|||
(self.to_email_lead, 'email_from', 'to_email_lead_check', 'crm.lead'), |
|||
(self.to_email_contact, 'email', 'to_email_contact_check', 'mailing.contact'), |
|||
(self.to_email_applicant, 'email_from', 'to_email_applicant_check', 'hr.applicant'), |
|||
] |
|||
# Process each recipient type |
|||
for recipients, email_field, type_check_field, model_name in recipient_mappings: |
|||
if recipients: |
|||
for recipient in recipients: |
|||
log_email_result(recipient, email_field, type_check_field, model_name) |
|||
|
|||
@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.body_arch = self.email_temp.temp_cont |
|||
self.body_html = self.email_temp.temp_cont |
|||
self.subject = self.email_temp.ver_subject |
|||
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_ids = email_ids.partner_id |
|||
elif self.mailing_model_real == "crm.lead": |
|||
self.to_email_contact = False |
|||
self.to_email_partner_ids = 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_ids = 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_ids = 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_ids = 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_ids = 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_ids = email_ids |
|||
|
|||
@api.onchange('to_email_partner_ids', '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_ids: |
|||
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': |
|||
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) |
@ -1,139 +0,0 @@ |
|||
# -*- 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() |
|||
print("res", res) |
|||
data = res.read() |
|||
print("data1", data) |
|||
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' |
|||
}) |
|
After Width: | Height: | Size: 66 KiB |
After Width: | Height: | Size: 69 KiB |
After Width: | Height: | Size: 35 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 45 KiB |
@ -0,0 +1,92 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<odoo> |
|||
<data> |
|||
<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="from_email"/> |
|||
</group> |
|||
<group> |
|||
<field name="to_email_partner_check" invisible="1"/> |
|||
<field name="to_email_partner" |
|||
attrs="{'invisible': [('to_email_partner_check', '=', False)]}"/> |
|||
<field name="to_email_lead_check" invisible="1"/> |
|||
<field name="to_email_lead" attrs="{'invisible': [('to_email_lead_check', '=',False)]}"/> |
|||
<field name="to_email_contact_check" invisible="1"/> |
|||
<field name="to_email_contact" |
|||
attrs="{'invisible': [('to_email_contact_check', '=',False)]}"/> |
|||
<field name="to_email_applicant_check" invisible="1"/> |
|||
<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"/> |
|||
</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_details_menu"--> |
|||
<!-- parent="mass_mailing.mass_mailing_configuration"--> |
|||
<!-- name="SendGrid From Email"--> |
|||
<!-- action="email_details_action"/>--> |
|||
</data> |
|||
</odoo> |
@ -1,18 +0,0 @@ |
|||
<?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> |
@ -1,98 +0,0 @@ |
|||
<?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_and_opportunities']" position="replace"> |
|||
<button name="action_redirect_to_leads_and_opportunities" type="object" icon="fa-star" class="oe_stat_button" |
|||
groups="sales_team.group_sale_salesman"> |
|||
<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'), ('use_leads', '=', 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,50 @@ |
|||
<?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="sender_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_ids" |
|||
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="email_finder" invisible="1"/> |
|||
<field name="sent_count" invisible="1"/> |
|||
<field name="temp_check" invisible="1"/> |
|||
</group> |
|||
</page> |
|||
</xpath> |
|||
</field> |
|||
</record> |
|||
</data> |
|||
</odoo> |
@ -0,0 +1,42 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<odoo> |
|||
<data> |
|||
<!-- Menuitem for Default Reporting --> |
|||
<menuitem name="Reporting" id="menu_mass_mailing_reporting" |
|||
parent="mass_mailing.menu_mass_mailing_report" |
|||
action="mass_mailing.mailing_trace_report_action_mail" |
|||
groups="mass_mailing.group_mass_mailing_user" sequence="1"/> |
|||
|
|||
<!-- Action for Menuitem --> |
|||
<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': 'state'}</field> |
|||
<field name="help" type="html"> |
|||
<p class="oe_view_nocontent_create">Create contacts</p> |
|||
</field> |
|||
</record> |
|||
<!-- Menuitem for SendGrid Send Emails --> |
|||
<menuitem id="email_sending_menu" |
|||
parent="mass_mailing.menu_mass_mailing_report" |
|||
name="SendGrid Send Emails" |
|||
action="email_sending_action" sequence="2"/> |
|||
|
|||
<!--Windows action of the model sendgrid email template--> |
|||
<record id="sendgrid_email_template_action" model="ir.actions.act_window"> |
|||
<field name="name">Sendgrid Email Template</field> |
|||
<field name="res_model">sendgrid.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> |
|||
<!--Menuitem for the model sendgrid templates--> |
|||
<menuitem id="sendgrid_email_template_menu" |
|||
parent="mass_mailing.mass_mailing_configuration" |
|||
name="SendGrid Templates" |
|||
action="sendgrid_email_template_action"/> |
|||
</data> |
|||
</odoo> |
@ -0,0 +1,58 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<odoo> |
|||
<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[@name='allow_blacklist_setting_container']" |
|||
position="after"> |
|||
<div class="col-md-6 o_setting_box col-xs-12" |
|||
name="sendgrid_details"> |
|||
<div class="o_setting_left_pane" |
|||
title="Sendgrid Details"> |
|||
<field name="send_grid_api_check" modifiers="{}"/> |
|||
</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> |
|||
</xpath> |
|||
<!-- <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> |
|||
</odoo> |
@ -1,37 +0,0 @@ |
|||
<?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,35 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<odoo> |
|||
<!--Tree view of the model sendgrid email template--> |
|||
<record id="sendgrid_email_template_view_tree" model="ir.ui.view"> |
|||
<field name="name">sendgrid.email.template.view.tree</field> |
|||
<field name="model">sendgrid.email.template</field> |
|||
<field name="arch" type="xml"> |
|||
<tree string="Email Template Details"> |
|||
<field name="temp_name"/> |
|||
<field name="ver_subject"/> |
|||
</tree> |
|||
</field> |
|||
</record> |
|||
<!--Form view of the model sendgrid email template--> |
|||
<record id="sendgrid_email_template_view_form" model="ir.ui.view"> |
|||
<field name="name">sendgrid.email.template.view.form</field> |
|||
<field name="model">sendgrid.email.template</field> |
|||
<field name="arch" type="xml"> |
|||
<form string="Email Template Details"> |
|||
<sheet> |
|||
<group> |
|||
<field name="temp_name"/> |
|||
<field name="ver_subject"/> |
|||
</group> |
|||
<notebook> |
|||
<page string="Email Content"> |
|||
<field name="temp_cont" widget="html" |
|||
options="{'style-inline': true}"/> |
|||
</page> |
|||
</notebook> |
|||
</sheet> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
</odoo> |
@ -1,218 +0,0 @@ |
|||
<?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> |
Loading…
Reference in new issue