Browse Source

Nov 30: [FIX] Bug Fixed 'sendgrid_email'

pull/195/merge
Cybrosys Technologies 8 months ago
parent
commit
b27dcb4127
  1. 10
      sendgrid_email/README.rst
  2. 3
      sendgrid_email/__init__.py
  3. 12
      sendgrid_email/__manifest__.py
  4. 13
      sendgrid_email/data/resend_error_mails.xml
  5. 4
      sendgrid_email/doc/RELEASE_NOTES.md
  6. 11
      sendgrid_email/models/__init__.py
  7. 122
      sendgrid_email/models/email_api.py
  8. 139
      sendgrid_email/models/email_template.py
  9. 43
      sendgrid_email/models/ir_config_parameter.py
  10. 568
      sendgrid_email/models/mail_mail.py
  11. 271
      sendgrid_email/models/mailing_mailing.py
  12. 139
      sendgrid_email/models/model.py
  13. 19
      sendgrid_email/models/res_config_settings.py
  14. 17
      sendgrid_email/models/sendgrid_email_template.py
  15. 3
      sendgrid_email/security/ir.model.access.csv
  16. BIN
      sendgrid_email/static/description/assets/screenshots/14.png
  17. BIN
      sendgrid_email/static/description/assets/screenshots/3.png
  18. BIN
      sendgrid_email/static/description/assets/screenshots/4.png
  19. BIN
      sendgrid_email/static/description/assets/screenshots/5.png
  20. BIN
      sendgrid_email/static/description/assets/screenshots/6.png
  21. 86
      sendgrid_email/static/description/index.html
  22. 92
      sendgrid_email/views/email_api_view.xml
  23. 18
      sendgrid_email/views/ir_config_view.xml
  24. 98
      sendgrid_email/views/mail_view.xml
  25. 50
      sendgrid_email/views/mailing_mailing_views.xml
  26. 42
      sendgrid_email/views/menuitems.xml
  27. 58
      sendgrid_email/views/res_config_settings_views.xml
  28. 37
      sendgrid_email/views/res_config_view.xml
  29. 35
      sendgrid_email/views/sendgrid_email_template_views.xml
  30. 218
      sendgrid_email/views/view.xml

10
sendgrid_email/README.rst

@ -1,6 +1,5 @@
SendGrid Email API
==================
This module comes under Odoo Email Marketing.
It will Use for Emailing. It could be use for Bulk
Mailing and Single Mailing . Email Template use for
@ -9,23 +8,19 @@ and Bounce Checking Option, here user can Konw the mail status.
Usage
=====
After the installation,in email marketting settings user can see sendgrid api setting field by ticking in check box a new text field will appear here user can set the API key by saving it key will be save in the system ,in email marketting configuration includes a sub menu sendgrid email template details here user can create email templates . in configuration have another menu called sendgrid from emails this menu is used for creating new from emails for using in malling. in mailing menu create a new mail here user can see a new page view called sendgrid emails here we can set the template and another specifications, using sendgrid button on top user can send the mail.
Configuration
=============
For saving the API key configuration have check box field sendgrid api by ticking in check box a new text field will appear here user can set the API key by saving it key will be save in the system.
Company
-------
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__
Credits
-------
* Developer:
Noushid Khan.P
* Developer: (V15) Noushid Khan.P
Contacts
--------
@ -42,11 +37,8 @@ Maintainer
:target: https://cybrosys.com
This module is maintained by Cybrosys Technologies.
For support and more information, please visit `Our Website <https://cybrosys.com/>`__
Further information
===================
HTML Description: `<static/description/index.html>`__

3
sendgrid_email/__init__.py

@ -20,5 +20,4 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
###################################################################################
from . import models
from . import models

12
sendgrid_email/__manifest__.py

@ -23,7 +23,7 @@
{
'name': 'Mass Mailing With SendGrid',
'version': '15.0.1.0.0',
'version': '15.0.1.1.0',
'summary': 'Mass Mailing using SendGrid API',
'description': 'Mass Mailing using SendGrid API',
'category': 'Marketing',
@ -39,11 +39,13 @@
'event'
],
'data': [
'data/resend_error_mails.xml',
'security/ir.model.access.csv',
'views/view.xml',
'views/mail_view.xml',
'views/ir_config_view.xml',
'views/res_config_view.xml'
'views/email_api_view.xml',
'views/mailing_mailing_views.xml',
'views/res_config_settings_views.xml',
'views/sendgrid_email_template_views.xml',
'views/menuitems.xml'
],
'license': 'AGPL-3',
'images': ['static/description/banner.png'],

13
sendgrid_email/data/resend_error_mails.xml

@ -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>

4
sendgrid_email/doc/RELEASE_NOTES.md

@ -5,3 +5,7 @@
##### ADD
- Initial commit for sendgrid_email.
#### 29.11.2024
#### Version 15.0.1.1.0
##### UPDT
- Update the module by changing the workflow.

11
sendgrid_email/models/__init__.py

@ -20,10 +20,7 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
###################################################################################
from . import model
from . import email_send
from . import email_template
from . import mail_mail
from . import ir_config_parameter
from . import res_config_settings
from . import email_api
from . import mailing_mailing
from . import res_config_settings
from . import sendgrid_email_template

122
sendgrid_email/models/email_api.py

@ -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

139
sendgrid_email/models/email_template.py

@ -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)

43
sendgrid_email/models/ir_config_parameter.py

@ -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

568
sendgrid_email/models/mail_mail.py

@ -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()

271
sendgrid_email/models/mailing_mailing.py

@ -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)

139
sendgrid_email/models/model.py

@ -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'
})

19
sendgrid_email/models/res_config_settings.py

@ -21,19 +21,14 @@
#
###################################################################################
from odoo import models, fields, api, _
from odoo import models, fields
class SendGridApiConfig(models.TransientModel):
class ResConfigSettings(models.TransientModel):
"""Inherits the model res.config.settings to add extra fields"""
_inherit = 'res.config.settings'
send_grid_api_check = fields.Boolean(string="SendGrid API")
send_grid_api_value = fields.Char(string='API key')
def set_values(self):
""" save values in the settings fields """
super(SendGridApiConfig, self).set_values()
company_id = self.env.company
self.env['ir.config_parameter'].sudo().set_param("SendGrid API Key "+company_id.name+"",
self.send_grid_api_value)
send_grid_api_check = fields.Boolean(string="SendGrid API",
config_parameter="sendgrid_email.send_grid_api_check")
send_grid_api_value = fields.Char(string='API key',
config_parameter="sendgrid_email.send_grid_api_value")

17
sendgrid_email/models/email_send.py → sendgrid_email/models/sendgrid_email_template.py

@ -20,13 +20,18 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
###################################################################################
from odoo import models, fields
class EmailDetails(models.Model):
_name = "email.sent"
_description = 'Email From Mails'
class SendgridEmailTemplate(models.Model):
"""Creates the model sendgrid.email.template to create the email templates
that needs to be sent through the send grid"""
_name = "sendgrid.email.template"
_rec_name = "temp_name"
_description = "Sendgrid Email Template"
name = fields.Char(string="Name", required=True)
email_id = fields.Char(string="Email ID", required=True)
temp_name = fields.Char(string="Template Name", required=True)
ver_subject = fields.Char(string="Template Subject", required=True)
temp_cont = fields.Html(string="Template Content",
help="content convert to html code", translate=True,
sanitize=False)

3
sendgrid_email/security/ir.model.access.csv

@ -1,4 +1,3 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_sendgrid_email_template_admin,access.sendgrid.email.template.admin,model_sendgrid_email_template,base.group_system,1,1,1,1
access_email_api,access.email.api,model_email_api,base.group_system,1,1,1,1
access_email_sent,access.email.sent,model_email_sent,base.group_system,1,1,1,1
access_email_template,access.email.template,model_email_template,base.group_system,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_sendgrid_email_template_admin access.sendgrid.email.template.admin model_sendgrid_email_template base.group_system 1 1 1 1
3 access_email_api access.email.api model_email_api base.group_system 1 1 1 1
access_email_sent access.email.sent model_email_sent base.group_system 1 1 1 1
access_email_template access.email.template model_email_template base.group_system 1 1 1 1

BIN
sendgrid_email/static/description/assets/screenshots/14.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

BIN
sendgrid_email/static/description/assets/screenshots/3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

BIN
sendgrid_email/static/description/assets/screenshots/4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
sendgrid_email/static/description/assets/screenshots/5.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

BIN
sendgrid_email/static/description/assets/screenshots/6.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

86
sendgrid_email/static/description/index.html

@ -15,7 +15,6 @@
style="background-color: #875A7B !important; color: #fff !important; font-weight: 600 !important; padding: 5px 15px 8px !important; margin: 0 5px !important;">
<i class="fa fa-check mr-1"></i>Enterprise
</div>
</div>
</div>
</div>
@ -337,7 +336,7 @@ In Email Marketing Configuration have a checkbox field SendGrid API by checking
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
In Email Marketing Configuration have a sub menu SendGrid Template Details
</p>
<img src="assets/screenshots/configuration-template-menu.png" class="img-responsive img-thumbnail border"
<img src="assets/screenshots/3.png" class="img-responsive img-thumbnail border"
width="100%" height="auto" />
</div>
@ -350,7 +349,7 @@ In Email Marketing Configuration have a checkbox field SendGrid API by checking
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
In Email Template Details show a tree view like below create new template by clicking Create button
</p>
<img src="assets/screenshots/template-page-tree.png" class="img-responsive img-thumbnail border"
<img src="assets/screenshots/4.png" class="img-responsive img-thumbnail border"
width="100%" height="auto" />
</div>
@ -363,7 +362,7 @@ In Email Marketing Configuration have a checkbox field SendGrid API by checking
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
Email template form view is shown in below here you can fill all the fields. You can fill the Email subject and content in the subject field and content box and click the save button.
</p>
<img src="assets/screenshots/template-page-form.png" class="img-responsive img-thumbnail border"
<img src="assets/screenshots/5.png" class="img-responsive img-thumbnail border"
width="100%" height="auto" />
</div>
@ -376,30 +375,7 @@ In Email Marketing Configuration have a checkbox field SendGrid API by checking
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
This Form view will be fill like below.
</p>
<img src="assets/screenshots/template-from-filled.png" class="img-responsive img-thumbnail border"
width="100%" height="auto" />
</div>
<div class="col-lg-12 my-3">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Template create button</h4>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
Template create button in using for creating the template.
</p>
<img src="assets/screenshots/template-create-template.png" class="img-responsive img-thumbnail border"
width="100%" height="auto" />
</div>
<div class="col-lg-12 my-3">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">Create Version button</h4>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
After clicking template create button Template ID will be fill. Using Template ID We can Write the template content by clicking Create Version button.
</p>
<img src="assets/screenshots/template-create-version.png" class="img-responsive img-thumbnail border"
<img src="assets/screenshots/6.png" class="img-responsive img-thumbnail border"
width="100%" height="auto" />
</div>
@ -481,18 +457,6 @@ In Email Marketing Configuration have a checkbox field SendGrid API by checking
width="100%" height="auto" />
</div>
<div class="col-lg-12 my-3">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Draft State to Send State</h4>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
If the mail send to the recipient then the draft state is change to send state. User can see which recipient have send the mails in sent smart button on the mailing form
</p>
<img src="assets/screenshots/mailing-state-send.png" class="img-responsive img-thumbnail border"
width="100%" height="auto" />
</div>
<div class="col-lg-12 my-3">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
@ -505,18 +469,6 @@ In Email Marketing Configuration have a checkbox field SendGrid API by checking
width="100%" height="auto" />
</div>
<div class="col-lg-12 my-3">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Recipient Details</h4>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
By clicking Send smart button it will show a tree view like below, here we can see mailing completed recipient details.
</p>
<img src="assets/screenshots/smart-button-send.png" class="img-responsive img-thumbnail border"
width="100%" height="auto" />
</div>
<div class="col-lg-12 my-3">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
@ -525,7 +477,7 @@ In Email Marketing Configuration have a checkbox field SendGrid API by checking
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
In Email Marketing Reporting menu have sub menu SendGrid Send Emails, Here user can get the mailing details done by SendGrid Service.
</p>
<img src="assets/screenshots/mailing-report.png" class="img-responsive img-thumbnail border"
<img src="assets/screenshots/14.png" class="img-responsive img-thumbnail border"
width="100%" height="auto" />
</div>
@ -588,36 +540,8 @@ In Email Marketing Configuration have a checkbox field SendGrid API by checking
<img src="assets/screenshots/error-resent.png" class="img-responsive img-thumbnail border"
width="100%" height="auto" />
</div>
<div class="col-lg-12 my-3">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Storing from Email Records</h4>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">Mailing configuration menu have submenu SendGrid From Email it used form storing from email Records. User can use this from emails on mailing page.
</p>
<img src="assets/screenshots/from-email-menu.png" class="img-responsive img-thumbnail border"
width="100%" height="auto" />
</div>
<div class="col-lg-12 my-3">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Create New</h4>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
User can create new from email record by clicking on create button on the view.
</p>
<img src="assets/screenshots/from-email-page.png" class="img-responsive img-thumbnail border"
width="100%" height="auto" />
</div>
</div>
<!-- SUGGESTED PRODUCTS -->
<div class="row">
<div class="col-lg-12 d-flex flex-column justify-content-center"

92
sendgrid_email/views/email_api_view.xml

@ -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>

18
sendgrid_email/views/ir_config_view.xml

@ -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>

98
sendgrid_email/views/mail_view.xml

@ -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>

50
sendgrid_email/views/mailing_mailing_views.xml

@ -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>

42
sendgrid_email/views/menuitems.xml

@ -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>

58
sendgrid_email/views/res_config_settings_views.xml

@ -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>

37
sendgrid_email/views/res_config_view.xml

@ -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>

35
sendgrid_email/views/sendgrid_email_template_views.xml

@ -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>

218
sendgrid_email/views/view.xml

@ -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…
Cancel
Save