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