Browse Source

Merge eb7b53a202 into 7b44ae957c

pull/307/merge
Georg A. G. Notter 5 years ago
committed by GitHub
parent
commit
2a090c05c7
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 83
      mail_store_outgoing/README.rst
  2. 1
      mail_store_outgoing/__init__.py
  3. 21
      mail_store_outgoing/__manifest__.py
  4. 123
      mail_store_outgoing/i18n/de.po
  5. 1
      mail_store_outgoing/models/__init__.py
  6. 128
      mail_store_outgoing/models/ir_mail_server.py
  7. 1
      mail_store_outgoing/readme/CONTRIBUTORS.rst
  8. 2
      mail_store_outgoing/readme/DESCRIPTION.rst
  9. 5
      mail_store_outgoing/readme/USAGE.rst
  10. 2
      mail_store_outgoing/security/ir.model.access.csv
  11. BIN
      mail_store_outgoing/static/description/icon.png
  12. 430
      mail_store_outgoing/static/description/index.html
  13. 1
      mail_store_outgoing/tests/__init__.py
  14. 56
      mail_store_outgoing/tests/test_ir_mail.py
  15. 31
      mail_store_outgoing/views/ir_mail_server_view.xml

83
mail_store_outgoing/README.rst

@ -0,0 +1,83 @@
===================
Mail Store Outgoing
===================
.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--auth-lightgray.png?logo=github
:target: https://github.com/OCA/server-auth/tree/10.0/mail_store_outgoing
:alt: OCA/server-auth
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/server-auth-10-0/server-auth-10-0-mail_store_outgoing
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
:target: https://runbot.odoo-community.org/runbot/251/10.0
:alt: Try me on Runbot
|badge1| |badge2| |badge3| |badge4| |badge5|
This Module enables Odoo to store outgoing Mails via IMAP
into a selected folder.
**Table of contents**
.. contents::
:local:
Usage
=====
To use this module, you need to:
#. Select Store Outgoing
#. Test the IMAP Server Connection
#. Select the Target Folder
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/server-auth/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
`feedback <https://github.com/OCA/server-auth/issues/new?body=module:%20mail_store_outgoing%0Aversion:%2010.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
Authors
~~~~~~~
* Agent ERP GmbH
Contributors
~~~~~~~~~~~~
* Georg A. G. Notter <georg.notter@agenterp.com>
Maintainers
~~~~~~~~~~~
This module is maintained by the OCA.
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
This module is part of the `OCA/server-auth <https://github.com/OCA/server-auth/tree/10.0/mail_store_outgoing>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

1
mail_store_outgoing/__init__.py

@ -0,0 +1 @@
from . import models

21
mail_store_outgoing/__manifest__.py

@ -0,0 +1,21 @@
# Copyright 2017 Georg Notter, Agent ERP GmbH
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
{
"name": "Mail Store Outgoing",
"summary": "Store outgoing Mails via IMAP into a selected folder.",
"version": "12.0.1.0.0",
"category": "mail",
"website": "https://github.com/OCA/social",
"author": "Agent ERP GmbH, "
"Odoo Community Association (OCA)",
"license": "AGPL-3",
"application": False,
"installable": True,
"depends": [
"mail",
],
"data": [
'views/ir_mail_server_view.xml',
'security/ir.model.access.csv',
],
}

123
mail_store_outgoing/i18n/de.po

@ -0,0 +1,123 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * mail_store_outgoing
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 10.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-10-15 14:53+0000\n"
"PO-Revision-Date: 2017-10-15 16:57+0100\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: \n"
"X-Generator: Poedit 1.5.4\n"
#. module: mail_store_outgoing
#: code:addons/mail_store_outgoing/models/ir_mail_server.py:48
#, python-format
msgid "Connection Test Failed!"
msgstr "Verbindung fehlgeschlagen!"
#. module: mail_store_outgoing
#: model:ir.model.fields,field_description:mail_store_outgoing.field_ir_mail_imap_folder_create_uid
msgid "Created by"
msgstr "Erstellt von"
#. module: mail_store_outgoing
#: model:ir.model.fields,field_description:mail_store_outgoing.field_ir_mail_imap_folder_create_date
msgid "Created on"
msgstr "Angelegt am"
#. module: mail_store_outgoing
#: model:ir.model.fields,field_description:mail_store_outgoing.field_ir_mail_imap_folder_display_name
msgid "Display Name"
msgstr "Anzeigename"
#. module: mail_store_outgoing
#: model:ir.model.fields,field_description:mail_store_outgoing.field_ir_mail_imap_folder_name
msgid "Foldername"
msgstr "Verzeichnisname"
#. module: mail_store_outgoing
#: code:addons/mail_store_outgoing/models/ir_mail_server.py:48
#, python-format
msgid ""
"Here is what we got instead:\n"
" %s"
msgstr ""
"Fehlermeldung:\n"
" %s"
#. module: mail_store_outgoing
#: model:ir.model.fields,field_description:mail_store_outgoing.field_ir_mail_imap_folder_id
msgid "ID"
msgstr "ID"
#. module: mail_store_outgoing
#: model:ir.model.fields,field_description:mail_store_outgoing.field_ir_mail_server_imap_mailbox_verified
msgid "IMAP Connection Verified"
msgstr "IMAP Verbindung verifiziert"
#. module: mail_store_outgoing
#: model:ir.model,name:mail_store_outgoing.model_ir_mail_imap_folder
msgid "Imap Folder"
msgstr "Imap Verzeichnis"
#. module: mail_store_outgoing
#: model:ir.model.fields,field_description:mail_store_outgoing.field_ir_mail_server_imap_mailbox_folder
msgid "Imap Folders"
msgstr "Imap Verzeichnisse"
#. module: mail_store_outgoing
#: model:ir.model.fields,field_description:mail_store_outgoing.field_ir_mail_imap_folder___last_update
msgid "Last Modified on"
msgstr "Zuletzt geändert am"
#. module: mail_store_outgoing
#: model:ir.model.fields,field_description:mail_store_outgoing.field_ir_mail_imap_folder_write_uid
msgid "Last Updated by"
msgstr "Zuletzt aktualisiert durch"
#. module: mail_store_outgoing
#: model:ir.model.fields,field_description:mail_store_outgoing.field_ir_mail_imap_folder_write_date
msgid "Last Updated on"
msgstr "Zuletzt aktualisiert am"
#. module: mail_store_outgoing
#: model:ir.model.fields,field_description:mail_store_outgoing.field_ir_mail_imap_folder_server_id
msgid "Mail Server"
msgstr "Mailserver"
#. module: mail_store_outgoing
#: model:ir.ui.view,arch_db:mail_store_outgoing.ir_mail_server_form
msgid "Outgoing Mail Settings"
msgstr "Maileinstellungen"
#. module: mail_store_outgoing
#: model:ir.model.fields,field_description:mail_store_outgoing.field_ir_mail_server_separate_imap_server
msgid "Separate Imap Server"
msgstr "Alternativer Imapserver"
#. module: mail_store_outgoing
#: model:ir.model.fields,field_description:mail_store_outgoing.field_ir_mail_server_store_outgoing_mail
msgid "Store Outgoing Mail"
msgstr "Ausgehende Mails speichern"
#. module: mail_store_outgoing
#: model:ir.ui.view,arch_db:mail_store_outgoing.ir_mail_server_form
msgid "Test Imap Connection"
msgstr "Verbindung testen "
#. module: mail_store_outgoing
#: model:ir.model.fields,field_description:mail_store_outgoing.field_ir_mail_server_has_separate_imap_server
msgid "Use Separate Imap Server"
msgstr "Verwende alternativen IMAP Server"
#. module: mail_store_outgoing
#: model:ir.model,name:mail_store_outgoing.model_ir_mail_server
msgid "ir.mail_server"
msgstr "ir.mail_server"

1
mail_store_outgoing/models/__init__.py

@ -0,0 +1 @@
from . import ir_mail_server

128
mail_store_outgoing/models/ir_mail_server.py

@ -0,0 +1,128 @@
import logging
import re
import imaplib
import threading
from odoo import tools
from odoo.exceptions import ValidationError
from odoo import fields
from odoo import models
from odoo import api
from odoo.tools.translate import _
_logger = logging.getLogger(__name__)
_test_logger = logging.getLogger('odoo.tests')
class IrMailServer(models.Model):
_inherit = 'ir.mail_server'
imap_mailbox_folder = fields.Many2one('ir.mail.imap.folder',
'Imap Folders',)
imap_mailbox_verified = fields.Boolean('IMAP Connection Verified', )
store_outgoing_mail = fields.Boolean()
has_separate_imap_server = fields.Boolean('Use Separate Imap Server', )
separate_imap_server = fields.Char()
active = fields.Boolean()
@api.model
def parse_list_response(self, line):
line = line.decode('utf-8')
list_response_pattern = re.compile(
r'\((?P<flags>.*?)\) "(?P<delimiter>.*)" (?P<name>.*)'
)
flags, delimiter, mailbox_name = \
list_response_pattern.match(line).groups()
mailbox_name = mailbox_name.strip('"')
return (flags, delimiter, mailbox_name)
@api.multi
def test_imap_connection(self):
self.ensure_one()
imap_pool = self.env['ir.mail.imap.folder']
maillib = None
if self.has_separate_imap_server:
smtp_server = self.separate_imap_server
else:
smtp_server = self.smtp_host
try:
if getattr(threading.currentThread(), 'testing', False) or \
self.env.registry.in_test_mode():
_test_logger.info("skip sending email in test mode")
return True
maillib = imaplib.IMAP4_SSL(smtp_server)
maillib.login(self.smtp_user, self.smtp_pass)
typ, mBoxes = maillib.list()
folder_ids = imap_pool.search([('server_id', '=', self.id)])
for folder in folder_ids:
folder.unlink()
for line in mBoxes:
flags, delimiter, \
mailbox_name = self.parse_list_response(line)
res = {'server_id': self.id, 'name': mailbox_name, }
imap_pool.create(res)
self.write({'imap_mailbox_verified': True})
except Exception as e:
raise ValidationError(
_("Connection Test Failed! "
"Here is what we got instead:\n %s") % tools.ustr(e))
finally:
if maillib:
maillib.logout()
@api.model
def send_email(self, message, mail_server_id=None,
smtp_server=None, smtp_port=None, smtp_user=None,
smtp_password=None, smtp_encryption=None,
smtp_debug=False, smtp_session=None):
res = super(IrMailServer, self).send_email(
message, mail_server_id, smtp_server, smtp_port,
smtp_user, smtp_password, smtp_encryption, smtp_debug,
smtp_session)
self._save_sent_message_to_sentbox(message, mail_server_id)
return res
@api.model
def _save_sent_message_to_sentbox(self, msg, mail_server_id=None):
mail_server = None
smtp_server = None
maillib = None
if mail_server_id:
mail_server = self.sudo().browse(mail_server_id)
else:
mail_server = self.sudo().search([], order='sequence', limit=1)
if mail_server:
if not mail_server.store_outgoing_mail:
return True
if mail_server.has_separate_imap_server:
smtp_server = mail_server.separate_imap_server
else:
smtp_server = mail_server.smtp_host
smtp_user = mail_server.smtp_user
smtp_password = mail_server.smtp_pass
try:
if getattr(threading.currentThread(), 'testing', False) or \
self.env.registry.in_test_mode():
_test_logger.info("skip sending email in test mode")
return True
maillib = imaplib.IMAP4_SSL(smtp_server)
maillib.login(smtp_user, smtp_password)
folder = mail_server.imap_mailbox_folder.name.join('""')
maillib.append(str.encode(folder),
r'\Seen', None, str(msg).encode())
except Exception as ex:
_logger.error(_(
'Failed attaching mail via imap to server %s %s')
% (ex, msg))
finally:
if maillib:
maillib.logout()
return True
class IrMailImapFolder(models.Model):
_name = 'ir.mail.imap.folder'
_description = 'Imap Folder'
server_id = fields.Many2one('ir.mail_server', 'Mail Server', )
name = fields.Char('Foldername',)

1
mail_store_outgoing/readme/CONTRIBUTORS.rst

@ -0,0 +1 @@
* Georg A. G. Notter <georg.notter@agenterp.com>

2
mail_store_outgoing/readme/DESCRIPTION.rst

@ -0,0 +1,2 @@
This Module enables Odoo to store outgoing Mails via IMAP
into a selected folder.

5
mail_store_outgoing/readme/USAGE.rst

@ -0,0 +1,5 @@
To use this module, you need to:
#. Select Store Outgoing
#. Test the IMAP Server Connection
#. Select the Target Folder

2
mail_store_outgoing/security/ir.model.access.csv

@ -0,0 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_ir_mail_imap_folder,access_ir_mail_imap_folder,model_ir_mail_imap_folder,,1,0,1,0

BIN
mail_store_outgoing/static/description/icon.png

After

Width: 64  |  Height: 64  |  Size: 1005 B

430
mail_store_outgoing/static/description/index.html

@ -0,0 +1,430 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.14: http://docutils.sourceforge.net/" />
<title>Mail Store Outgoing</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: grey; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document" id="mail-store-outgoing">
<h1 class="title">Mail Store Outgoing</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/server-auth/tree/10.0/mail_store_outgoing"><img alt="OCA/server-auth" src="https://img.shields.io/badge/github-OCA%2Fserver--auth-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/server-auth-10-0/server-auth-10-0-mail_store_outgoing"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/251/10.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p>
<p>This Module enables Odoo to store outgoing Mails via IMAP
into a selected folder.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#usage" id="id1">Usage</a></li>
<li><a class="reference internal" href="#bug-tracker" id="id2">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="id3">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="id4">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="id5">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="id6">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="usage">
<h1><a class="toc-backref" href="#id1">Usage</a></h1>
<p>To use this module, you need to:</p>
<ol class="arabic simple">
<li>Select Store Outgoing</li>
<li>Test the IMAP Server Connection</li>
<li>Select the Target Folder</li>
</ol>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#id2">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/server-auth/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/server-auth/issues/new?body=module:%20mail_store_outgoing%0Aversion:%2010.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1><a class="toc-backref" href="#id3">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#id4">Authors</a></h2>
<ul class="simple">
<li>Agent ERP GmbH</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#id5">Contributors</a></h2>
<ul class="simple">
<li>Georg A. G. Notter &lt;<a class="reference external" href="mailto:georg.notter&#64;agenterp.com">georg.notter&#64;agenterp.com</a>&gt;</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#id6">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.</p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/server-auth/tree/10.0/mail_store_outgoing">OCA/server-auth</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>
</div>
</body>
</html>

1
mail_store_outgoing/tests/__init__.py

@ -0,0 +1 @@
from . import test_ir_mail

56
mail_store_outgoing/tests/test_ir_mail.py

@ -0,0 +1,56 @@
# Copyright 2018 AGENTERP GMBH
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo.exceptions import ValidationError
from openerp.tests import common
class TestIrMail(common.TransactionCase):
def setUp(self):
super(TestIrMail, self).setUp()
self.mail_server = self.env['ir.mail_server'].create({
'smtp_port': '25',
'smtp_host': 'localhost',
'smtp_encryption': 'none',
'name': 'test',
'has_separate_imap_server': True,
'store_outgoing_mail': True,
})
def test_parse_list_response(self):
imap_mailbox = \
b'(\\HasNoChildren \\UnMarked) "." "INBOX.Deleted Messages"'
flags, delimiter, mailbox_name = \
self.env['ir.mail_server'].parse_list_response(imap_mailbox)
self.assertEqual(flags, '\\HasNoChildren \\UnMarked')
self.assertEqual(delimiter, '.')
self.assertEqual(mailbox_name, 'INBOX.Deleted Messages')
def test_imap_connection(self):
try:
self.mail_server.test_imap_connection()
except ValidationError as e:
pass
def test_send_mail(self):
msg = self.env['ir.mail_server'].build_email(
email_from='test.from@example.com',
reply_to='test.reply@example.com',
email_to=["test.to@example.com"],
subject="Test Subject",
body="test Bosy",
)
self.env['ir.mail_server'].send_email(
msg, mail_server_id=self.mail_server.id)
def test_save_sent_message_to_sentbox(self):
msg = self.env['ir.mail_server'].build_email(
email_from='test.from@example.com',
reply_to='test.reply@example.com',
email_to=["test.to@example.com"],
subject="Test Subject",
body="test Bosy",
)
msg = self.env['ir.mail_server']._save_sent_message_to_sentbox(
msg, self.mail_server.id)

31
mail_store_outgoing/views/ir_mail_server_view.xml

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record model="ir.ui.view" id="ir_mail_server_form_save_outgoing">
<field name="model">ir.mail_server</field>
<field name="name">ir_mail_server_form_save_outgoing</field>
<field name="inherit_id" ref="base.ir_mail_server_form" />
<field name="arch" type="xml">
<field name="sequence" position="after">
<field name="active"/>
</field>
<xpath expr="//form/sheet/group" position="after">
<group string="Outgoing Mail Settings" colspan="4">
<field name="store_outgoing_mail"/>
</group>
<group colspan="4" attrs="{'invisible': [('store_outgoing_mail','=', False)]}">
<field name="has_separate_imap_server"/>
<field name="separate_imap_server" attrs="{'invisible': [('has_separate_imap_server','=', False)]}"/>
</group>
<group colspan="4" attrs="{'invisible': [('store_outgoing_mail','=', False)]}">
<button name="test_imap_connection" type="object" string="Test Imap Connection" icon="gtk-network"/>
</group>
<group colspan="4" attrs="{'invisible': [('store_outgoing_mail','=', False)]}">
<field name="imap_mailbox_verified" readonly="1"/>
</group>
<group colspan="4" attrs="{'invisible': [('store_outgoing_mail','=', False),('imap_mailbox_verified','=', False)]}">
<field name="imap_mailbox_folder" attrs="{'required': [('imap_mailbox_verified','=', True),('store_outgoing_mail','=',True)]}"/>
</group>
</xpath>
</field>
</record>
</odoo>
Loading…
Cancel
Save