all models, need to check everything
This commit is contained in:
parent
3080254b8c
commit
093418ec59
19 changed files with 804 additions and 0 deletions
3
bemade_mailcow_blacklist/__init__.py
Normal file
3
bemade_mailcow_blacklist/__init__.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import models
|
||||
38
bemade_mailcow_blacklist/__manifest__.py
Normal file
38
bemade_mailcow_blacklist/__manifest__.py
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
{
|
||||
'name': 'Mailcow Integration',
|
||||
'version': '1.0.0',
|
||||
'category': 'Extra Tools',
|
||||
'summary': 'Module for integrating Mailcow email server with Odoo.',
|
||||
'description': """
|
||||
Mailcow Integration
|
||||
===================
|
||||
|
||||
This module integrates the Mailcow email server with Odoo, providing a seamless email communication solution for your Odoo instance. It allows for syncing of mailboxes and email aliases from Mailcow to Odoo and vice versa.
|
||||
|
||||
Main Features:
|
||||
--------------
|
||||
* Synchronize Mailcow mailboxes with Odoo users.
|
||||
* Synchronize Mailcow email aliases with Odoo.
|
||||
* Configuration of Mailcow API credentials in Odoo settings.
|
||||
* Automatically create and manage mailboxes and aliases in Mailcow when they are created in Odoo.
|
||||
""",
|
||||
'sequence': 10,
|
||||
'license': 'OPL-1',
|
||||
'author': 'BeMade',
|
||||
'website': 'https://www.bemade.org',
|
||||
'depends': ['mail', 'bemade_user_password_bundle'],
|
||||
'data': [
|
||||
'security/ir.model.access.csv',
|
||||
'views/res_config_settings_views.xml',
|
||||
'views/mailcow_mailbox_views.xml',
|
||||
'views/mailcow_alias_views.xml',
|
||||
'views/mailcow_blacklist_views.xml',
|
||||
'views/res_users_views.xml',
|
||||
|
||||
],
|
||||
'demo': [],
|
||||
'installable': True,
|
||||
'application': False,
|
||||
'auto_install': False,
|
||||
}
|
||||
30
bemade_mailcow_blacklist/demo/demo.xml
Normal file
30
bemade_mailcow_blacklist/demo/demo.xml
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<odoo>
|
||||
<data>
|
||||
<!--
|
||||
<record id="object0" model="bemade_mailcow_blacklist.bemade_mailcow_blacklist">
|
||||
<field name="name">Object 0</field>
|
||||
<field name="value">0</field>
|
||||
</record>
|
||||
|
||||
<record id="object1" model="bemade_mailcow_blacklist.bemade_mailcow_blacklist">
|
||||
<field name="name">Object 1</field>
|
||||
<field name="value">10</field>
|
||||
</record>
|
||||
|
||||
<record id="object2" model="bemade_mailcow_blacklist.bemade_mailcow_blacklist">
|
||||
<field name="name">Object 2</field>
|
||||
<field name="value">20</field>
|
||||
</record>
|
||||
|
||||
<record id="object3" model="bemade_mailcow_blacklist.bemade_mailcow_blacklist">
|
||||
<field name="name">Object 3</field>
|
||||
<field name="value">30</field>
|
||||
</record>
|
||||
|
||||
<record id="object4" model="bemade_mailcow_blacklist.bemade_mailcow_blacklist">
|
||||
<field name="name">Object 4</field>
|
||||
<field name="value">40</field>
|
||||
</record>
|
||||
-->
|
||||
</data>
|
||||
</odoo>
|
||||
9
bemade_mailcow_blacklist/models/__init__.py
Normal file
9
bemade_mailcow_blacklist/models/__init__.py
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import mail_alias
|
||||
from . import mailcow
|
||||
from . import mailcow_alias
|
||||
from . import mailcow_blacklist
|
||||
from . import mailcow_mailbox
|
||||
from . import res_config_settings
|
||||
from . import res_users
|
||||
20
bemade_mailcow_blacklist/models/mail_alias.py
Normal file
20
bemade_mailcow_blacklist/models/mail_alias.py
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
from odoo import models, fields, api, _
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
class MailAlias(models.Model):
|
||||
_inherit = 'mail.alias'
|
||||
|
||||
mailcow_id = fields.One2many('mail.mailcow.alias', 'alias_id')
|
||||
|
||||
def create(self, vals):
|
||||
alias = super(MailAlias, self).create(vals)
|
||||
mailcow_alias = self.env['mail.mailcow.alias'].search([('address', '=', alias.alias_name + '@' + alias.alias_domain)])
|
||||
if mailcow_alias:
|
||||
mailcow_alias.write({'active': True})
|
||||
else:
|
||||
self.env['mail.mailcow.alias'].create({
|
||||
'address': alias.alias_name + '@' + alias.alias_domain,
|
||||
'goto': alias.alias_defaults.get('email_from', False),
|
||||
'alias_id': alias.id,
|
||||
})
|
||||
return alias
|
||||
48
bemade_mailcow_blacklist/models/mailcow.py
Normal file
48
bemade_mailcow_blacklist/models/mailcow.py
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from odoo import models, fields, api, exceptions
|
||||
import requests
|
||||
import logging
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
class MailMailcow(models.AbstractModel):
|
||||
_name = 'mail.mailcow'
|
||||
_description = 'Mailcow API'
|
||||
|
||||
def get_credentials(self):
|
||||
params = self.env['ir.config_parameter'].sudo()
|
||||
return {
|
||||
'base_url': params.get_param('mailcow.base_url'),
|
||||
'api_key': params.get_param('mailcow.api_key'),
|
||||
}
|
||||
|
||||
def api_request(self, endpoint, method='GET', data=None):
|
||||
creds = self.get_credentials()
|
||||
url = creds['base_url'] + endpoint
|
||||
headers = {
|
||||
'accept': 'application/json',
|
||||
'X-API-Key': creds['api_key'],
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
|
||||
try:
|
||||
if method == 'GET':
|
||||
response = requests.get(url, headers=headers)
|
||||
elif method == 'POST':
|
||||
response = requests.post(url, headers=headers, json=data)
|
||||
elif method == 'DELETE':
|
||||
response = requests.delete(url, headers=headers)
|
||||
elif method == 'PUT':
|
||||
response = requests.put(url, headers=headers, json=data)
|
||||
|
||||
response.raise_for_status()
|
||||
|
||||
except requests.exceptions.HTTPError as error:
|
||||
_logger.error('HTTP error occurred: %s', error)
|
||||
return False
|
||||
except Exception as error:
|
||||
_logger.error('An error occurred: %s', error)
|
||||
return False
|
||||
|
||||
return response.json()
|
||||
97
bemade_mailcow_blacklist/models/mailcow_alias.py
Normal file
97
bemade_mailcow_blacklist/models/mailcow_alias.py
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
from odoo import models, fields, api, _
|
||||
from odoo.exceptions import ValidationError
|
||||
import logging
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class MailcowAlias(models.Model):
|
||||
_name = 'mail.mailcow.alias'
|
||||
_description = 'Mailcow Alias'
|
||||
_inherit = ['mail.thread', 'mail.activity.mixin']
|
||||
_rec_name = 'address'
|
||||
|
||||
address = fields.Char(string='Alias Address', required=True, tracking=True)
|
||||
goto = fields.Char(string='Alias Destination', required=True, tracking=True)
|
||||
active = fields.Boolean(string='Active', default=True, tracking=True)
|
||||
catchall = fields.Boolean(string='Catchall', default=False, tracking=True)
|
||||
alias_id = fields.Many2one(comodel_name='mail.alias', string='Alias')
|
||||
|
||||
_sql_constraints = [
|
||||
('address_unique', 'UNIQUE(address)', 'The alias address must be unique!'),
|
||||
]
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
alias = super(MailcowAlias, self).create(vals)
|
||||
|
||||
if 'mc_id' not in vals:
|
||||
data = {
|
||||
"active": str(int(alias.active)),
|
||||
"address": alias.address,
|
||||
"goto": alias.goto,
|
||||
"private_comment": f"Created by {self.env.user.name} on {fields.Datetime.now()}",
|
||||
"public_comment": "Alias created in Odoo"
|
||||
}
|
||||
result = self.env['mail.mailcow'].api_request('api/v1/add/alias', 'POST', data)
|
||||
if not result:
|
||||
raise ValidationError(_("Failed to create alias on Mailcow server."))
|
||||
|
||||
return alias
|
||||
|
||||
def unlink(self):
|
||||
for record in self:
|
||||
endpoint = f"api/v1/delete/alias/{record.mc_id}"
|
||||
result = self.env['mail.mailcow'].api_request(endpoint, 'POST')
|
||||
if not result:
|
||||
raise ValidationError(_("Failed to delete alias on Mailcow server."))
|
||||
return super(MailcowAlias, self).unlink()
|
||||
|
||||
def write(self, vals):
|
||||
for record in self:
|
||||
data = {
|
||||
"attr": {
|
||||
"active": str(int(vals.get('active', record.active))),
|
||||
"address": vals.get('address', record.address),
|
||||
"goto": vals.get('goto', record.goto),
|
||||
"private_comment": f"Modified by {self.env.user.name} on {fields.Datetime.now()}",
|
||||
"public_comment": f"Alias modified in Odoo. Changes: {vals}",
|
||||
},
|
||||
"items": [record.mc_id]
|
||||
}
|
||||
result = self.env['mail.mailcow'].api_request('api/v1/edit/alias', 'POST', data)
|
||||
if not result:
|
||||
raise ValidationError(_("Failed to update alias on Mailcow server."))
|
||||
|
||||
return super(MailcowAlias, self).write(vals)
|
||||
|
||||
@api.model
|
||||
def sync_aliases(self):
|
||||
"""
|
||||
Synchronize the list of aliases from Mailcow server with Odoo.
|
||||
For each alias fetched from Mailcow server, it tries to find a matching record
|
||||
in Odoo. If it doesn't exist, it creates a new record.
|
||||
"""
|
||||
endpoint = 'api/v1/get/alias/all'
|
||||
mailcow_aliases = self.api_request(endpoint)
|
||||
|
||||
if not mailcow_aliases:
|
||||
return
|
||||
|
||||
for mc_alias in mailcow_aliases:
|
||||
domain = mc_alias['domain']
|
||||
alias_domain = self.env['ir.config_parameter'].sudo().get_param('mail.catchall.domain')
|
||||
if domain == alias_domain:
|
||||
alias = self.search([('address', '=', mc_alias['address'])], limit=1)
|
||||
if not alias:
|
||||
self.create({
|
||||
'address': mc_alias['address'],
|
||||
'active': mc_alias['active'] == '1',
|
||||
'goto': mc_alias['goto'],
|
||||
'domain': mc_alias['domain']
|
||||
})
|
||||
else:
|
||||
alias.write({
|
||||
'active': mc_alias['active'] == '1',
|
||||
'goto': mc_alias['goto']
|
||||
})
|
||||
69
bemade_mailcow_blacklist/models/mailcow_blacklist.py
Normal file
69
bemade_mailcow_blacklist/models/mailcow_blacklist.py
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from odoo import models, fields, api
|
||||
import logging
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
class MailcowBlacklist(models.Model):
|
||||
_name = 'mail.mailcow.blacklist'
|
||||
_description = 'Mailcow Blacklist'
|
||||
_inherit = ['mail.mailcow', 'mail.thread', 'mail.activity.mixin']
|
||||
|
||||
email = fields.Char(string='Email', required=True, track_visibility='onchange')
|
||||
prefid = fields.Integer(string='Mailcow ID', required=True, track_visibility='onchange')
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
"""
|
||||
Overridden create method to add the new blacklist entry to the Mailcow server.
|
||||
"""
|
||||
res = super().create(vals)
|
||||
domain = self.env['res.config.settings'].get_values()['mail.catchall.domain']
|
||||
|
||||
endpoint_add = 'api/v1/add/domain-policy'
|
||||
endpoint_get_bl = f"api/v1/get/policy_bl_domain/{domain}"
|
||||
data = {
|
||||
'domain': domain,
|
||||
'object_from': res.email,
|
||||
'object_list': 'bl'
|
||||
}
|
||||
res.api_request(endpoint_add, 'POST', data)
|
||||
_logger.info(f'Added {vals["email"]} to Mailcow blacklist')
|
||||
|
||||
res.api_request(endpoint_get_bl, 'GET', None)
|
||||
|
||||
return res
|
||||
|
||||
def write(self, vals):
|
||||
"""
|
||||
Overridden write method to update the blacklist entry on the Mailcow server.
|
||||
"""
|
||||
old_email = self.email
|
||||
res = super().write(vals)
|
||||
if 'email' in vals:
|
||||
delete_endpoint = 'api/v1/delete/domain-policy'
|
||||
add_endpoint = 'api/v1/add/domain-policy'
|
||||
delete_data = {
|
||||
'items': [old_email]
|
||||
}
|
||||
add_data = {
|
||||
'items': [vals['email']]
|
||||
}
|
||||
self.api_request(delete_endpoint, 'POST', delete_data)
|
||||
self.api_request(add_endpoint, 'POST', add_data)
|
||||
_logger.info(f'Updated {old_email} to {vals["email"]} in Mailcow blacklist')
|
||||
return res
|
||||
|
||||
def unlink(self):
|
||||
"""
|
||||
Overridden unlink method to remove the blacklist entry from the Mailcow server.
|
||||
"""
|
||||
for record in self:
|
||||
endpoint = 'api/v1/delete/blacklist'
|
||||
data = {
|
||||
'items': [record.email]
|
||||
}
|
||||
record.api_request(endpoint, 'POST', data)
|
||||
_logger.info(f'Removed {record.email} from Mailcow blacklist')
|
||||
return super().unlink()
|
||||
134
bemade_mailcow_blacklist/models/mailcow_mailbox.py
Normal file
134
bemade_mailcow_blacklist/models/mailcow_mailbox.py
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
from odoo import models, fields, api, _
|
||||
from odoo.exceptions import ValidationError
|
||||
import logging
|
||||
import secrets
|
||||
import string
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class MailcowMailbox(models.Model):
|
||||
_name = 'mail.mailcow.mailbox'
|
||||
_inherit = ['mail.mailcow', 'mail.thread', 'mail.activity.mixin']
|
||||
_description = 'Mailcow Mailbox'
|
||||
|
||||
name = fields.Char(track_visibility='onchange')
|
||||
address = fields.Char(compute='_compute_address', store=True, readonly=True, track_visibility='onchange')
|
||||
local_part = fields.Char(required=True, track_visibility='onchange')
|
||||
domain = fields.Char(required=True, track_visibility='onchange')
|
||||
active = fields.Boolean(default=True, track_visibility='onchange')
|
||||
user_id = fields.Many2one('res.users', ondelete='cascade', track_visibility='onchange')
|
||||
password = fields.Char(readonly=True, track_visibility='onchange')
|
||||
|
||||
@api.depends('local_part', 'domain')
|
||||
def _compute_address(self):
|
||||
for record in self:
|
||||
record.address = f"{record.local_part}@{record.domain}"
|
||||
|
||||
def sync_mailboxes(self):
|
||||
"""
|
||||
Synchronize Mailcow mailboxes with Odoo
|
||||
"""
|
||||
endpoint = 'api/v1/get/mailbox/all'
|
||||
data = self.api_request(endpoint)
|
||||
if data:
|
||||
for item in data:
|
||||
domain = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
|
||||
if item['domain'] == domain:
|
||||
self.create({
|
||||
'name': item['name'],
|
||||
'local_part': item['local_part'],
|
||||
'domain': item['domain'],
|
||||
'active': item['active'],
|
||||
'password': item['password'],
|
||||
})
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
"""
|
||||
Override the create function to create a Mailcow mailbox whenever a user is created in Odoo.
|
||||
"""
|
||||
password = secrets.token_hex(16)
|
||||
vals['password'] = password
|
||||
|
||||
# Check if email exists on Mailcow
|
||||
endpoint = f"api/v1/get/mailbox/{vals['address']}"
|
||||
response = self.api_request(endpoint)
|
||||
|
||||
if not response:
|
||||
# If email does not exist on Mailcow, create it
|
||||
endpoint = 'api/v1/add/mailbox'
|
||||
data = {
|
||||
'local_part': vals['local_part'],
|
||||
'domain': vals['domain'],
|
||||
'name': vals['name'],
|
||||
'password': password,
|
||||
'password2': password,
|
||||
'quota': "3072",
|
||||
'active': "1",
|
||||
'force_pw_update': "0",
|
||||
'tls_enforce_in': "0",
|
||||
'tls_enforce_out': "0",
|
||||
}
|
||||
self.api_request(endpoint, method='POST', data=data)
|
||||
_logger.info(f'Mailbox {vals["address"]} has been created on Mailcow server')
|
||||
|
||||
return super().create(vals)
|
||||
|
||||
def write(self, vals):
|
||||
"""
|
||||
Override the write function to update a Mailcow mailbox whenever a user is updated in Odoo.
|
||||
"""
|
||||
if 'active' in vals or 'local_part' in vals or 'domain' in vals:
|
||||
endpoint = f'api/v1/edit/mailbox/{self.address}'
|
||||
data = {
|
||||
'items': [self.address],
|
||||
'attr': {
|
||||
'active': '1' if vals.get('active', self.active) else '0',
|
||||
'local_part': vals.get('local_part', self.local_part),
|
||||
'domain': vals.get('domain', self.domain),
|
||||
}
|
||||
}
|
||||
self.api_request(endpoint, method='POST', data=data)
|
||||
_logger.info(f'Mailbox {self.address} has been updated on Mailcow server')
|
||||
|
||||
return super().write(vals)
|
||||
|
||||
def unlink(self):
|
||||
"""
|
||||
Override the unlink function to delete a Mailcow mailbox whenever a user is deleted in Odoo.
|
||||
"""
|
||||
endpoint = f'api/v1/delete/mailbox/{self.address}'
|
||||
self.api_request(endpoint, method='POST')
|
||||
_logger.info(f'Mailbox {self.address} has been deleted on Mailcow server')
|
||||
|
||||
return super().unlink()
|
||||
|
||||
|
||||
def create_mailbox_for_user(self, user):
|
||||
"""
|
||||
Function to create a Mailcow mailbox for a new Odoo user.
|
||||
|
||||
Parameters:
|
||||
user (res.users): The newly created Odoo user
|
||||
|
||||
Returns:
|
||||
mail.mailcow.mailbox: The newly created Mailcow mailbox
|
||||
"""
|
||||
data = {
|
||||
'local_part': user.login.split('@')[0],
|
||||
'domain': user.login.split('@')[1],
|
||||
'name': user.name,
|
||||
'password': user.password,
|
||||
}
|
||||
endpoint = 'api/v1/add/mailbox'
|
||||
self.api_request(endpoint, method='POST', data=data)
|
||||
_logger.info(f'Mailbox for user {user.login} has been created on Mailcow server')
|
||||
|
||||
pw_bundle = seld.env['password.bundle'].search([('name', '=', user.name)])
|
||||
self.env['password.key'].create_mailbox_for_user(res)
|
||||
|
||||
return self.create({
|
||||
'address': user.login,
|
||||
'user_id': user.id,
|
||||
})
|
||||
15
bemade_mailcow_blacklist/models/res_config_settings.py
Normal file
15
bemade_mailcow_blacklist/models/res_config_settings.py
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
from odoo import fields, models
|
||||
|
||||
class ResConfigSettings(models.TransientModel):
|
||||
_inherit = 'res.config.settings'
|
||||
|
||||
mailcow_base_url = fields.Char(
|
||||
string="Mailcow Base URL",
|
||||
help="URL for the Mailcow server API",
|
||||
config_parameter='mailcow.base_url',
|
||||
)
|
||||
mailcow_api_key = fields.Char(
|
||||
string="Mailcow API Key",
|
||||
help="API key for the Mailcow server",
|
||||
config_parameter='mailcow.api_key',
|
||||
)
|
||||
14
bemade_mailcow_blacklist/models/res_users.py
Normal file
14
bemade_mailcow_blacklist/models/res_users.py
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
from odoo import models, fields, api
|
||||
|
||||
class ResUsers(models.Model):
|
||||
_inherit = 'res.users'
|
||||
|
||||
mailcow_mailbox = fields.Boolean(string='Mailcow Mailbox', default=False)
|
||||
|
||||
def create(self, vals):
|
||||
res = super(ResUsers, self).create(vals)
|
||||
|
||||
if vals.get('mailcow_mailbox'):
|
||||
self.env['mail.mailcow.mailbox'].create_mailbox_for_user(res)
|
||||
|
||||
return res
|
||||
7
bemade_mailcow_blacklist/security/ir.model.access.csv
Normal file
7
bemade_mailcow_blacklist/security/ir.model.access.csv
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_mail_mailcow_alias_all,access_mail_mailcow_alias,model_mail_mailcow_alias,base.group_user,1,0,0,0
|
||||
access_mail_mailcow_alias_admin,access_mail_mailcow_alias,model_mail_mailcow_alias,base.group_system,1,1,1,1
|
||||
access_mail_mailcow_mailbox_all,access_mail_mailcow_mailbox,model_mail_mailcow_mailbox,base.group_user,1,0,0,0
|
||||
access_mail_mailcow_mailbox_admin,access_mail_mailcow_mailbox,model_mail_mailcow_mailbox,base.group_system,1,1,1,1
|
||||
access_mail_mailcow_blacklist_all,access_mail_mailcow_blacklist,model_mail_mailcow_blacklist,base.group_user,1,0,0,0
|
||||
access_mail_mailcow_blacklist_admin,access_mail_mailcow_blacklist,model_mail_mailcow_blacklist,base.group_system,1,1,1,1
|
||||
|
58
bemade_mailcow_blacklist/views/mailcow_alias_views.xml
Normal file
58
bemade_mailcow_blacklist/views/mailcow_alias_views.xml
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="mailcow_alias_view_tree" model="ir.ui.view">
|
||||
<field name="name">mailcow.alias.view.tree</field>
|
||||
<field name="model">mail.mailcow.alias</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Alias" decoration-info="active == False">
|
||||
<field name="active"/>
|
||||
<field name="address"/>
|
||||
<field name="goto"/>
|
||||
<field name="alias_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="mailcow_alias_view_form" model="ir.ui.view">
|
||||
<field name="name">mailcow.alias.view.form</field>
|
||||
<field name="model">mail.mailcow.alias</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Alias">
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="active"/>
|
||||
<field name="address"/>
|
||||
<field name="goto"/>
|
||||
<field name="alias_id"/>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Messages" name="messages">
|
||||
<field name="message_ids" widget="mail_thread"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="mailcow_alias_action" model="ir.actions.act_window">
|
||||
<field name="name">Aliases</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">mail.mailcow.alias</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Create a new Alias
|
||||
</p>
|
||||
<p>
|
||||
Add the details of the new Alias.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="mailcow_menu_alias"
|
||||
name="Aliases"
|
||||
parent="mailcow_menu"
|
||||
action="mailcow_alias_action"
|
||||
sequence="20"/>
|
||||
</odoo>
|
||||
52
bemade_mailcow_blacklist/views/mailcow_blacklist_views.xml
Normal file
52
bemade_mailcow_blacklist/views/mailcow_blacklist_views.xml
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="mailcow_blacklist_view_tree" model="ir.ui.view">
|
||||
<field name="name">mailcow.blacklist.view.tree</field>
|
||||
<field name="model">mail.mailcow.blacklist</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Blacklist">
|
||||
<field name="email"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="mailcow_blacklist_view_form" model="ir.ui.view">
|
||||
<field name="name">mailcow.blacklist.view.form</field>
|
||||
<field name="model">mail.mailcow.blacklist</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Blacklist">
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="email"/>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Messages" name="messages">
|
||||
<field name="message_ids" widget="mail_thread"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="mailcow_blacklist_action" model="ir.actions.act_window">
|
||||
<field name="name">Blacklist</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">mail.mailcow.blacklist</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Create a new Blacklist Entry
|
||||
</p>
|
||||
<p>
|
||||
Add the details of the new Blacklist Entry.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="mailcow_menu_blacklist"
|
||||
name="Blacklist"
|
||||
parent="mailcow_menu"
|
||||
action="mailcow_blacklist_action"
|
||||
sequence="30"/>
|
||||
</odoo>
|
||||
67
bemade_mailcow_blacklist/views/mailcow_mailbox_views.xml
Normal file
67
bemade_mailcow_blacklist/views/mailcow_mailbox_views.xml
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="mailcow_mailbox_view_tree" model="ir.ui.view">
|
||||
<field name="name">mailcow.mailbox.view.tree</field>
|
||||
<field name="model">mail.mailcow.mailbox</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Mailbox" decoration-info="active == False">
|
||||
<field name="active"/>
|
||||
<field name="name"/>
|
||||
<field name="local_part"/>
|
||||
<field name="domain"/>
|
||||
<field name="address"/>
|
||||
<field name="user_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="mailcow_mailbox_view_form" model="ir.ui.view">
|
||||
<field name="name">mailcow.mailbox.view.form</field>
|
||||
<field name="model">mail.mailcow.mailbox</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Mailbox">
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="active"/>
|
||||
<field name="name"/>
|
||||
<field name="local_part"/>
|
||||
<field name="domain"/>
|
||||
<field name="address"/>
|
||||
<field name="user_id"/>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Messages" name="messages">
|
||||
<field name="message_ids" widget="mail_thread"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="mailcow_mailbox_action" model="ir.actions.act_window">
|
||||
<field name="name">Mailboxes</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">mail.mailcow.mailbox</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Create a new Mailbox
|
||||
</p>
|
||||
<p>
|
||||
Add the details of the new Mailbox.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="mailcow_menu"
|
||||
name="Mailcow"
|
||||
sequence="10"
|
||||
web_icon="mail_mailcow,static/description/icon.png"/>
|
||||
|
||||
<menuitem id="mailcow_menu_mailbox"
|
||||
name="Mailboxes"
|
||||
parent="mailcow_menu"
|
||||
action="mailcow_mailbox_action"
|
||||
sequence="10"/>
|
||||
</odoo>
|
||||
39
bemade_mailcow_blacklist/views/res_config_settings_views.xml
Normal file
39
bemade_mailcow_blacklist/views/res_config_settings_views.xml
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="view_res_config_settings_form_inherit_mailcow" model="ir.ui.view">
|
||||
<field name="name">res.config.settings.form.inherit.mailcow</field>
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="inherit_id" ref="base_setup.res_config_settings_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[hasclass('settings')]" position="inside">
|
||||
<div class="app_settings_block" data-string="Mailcow" string="Mailcow" data-key="mailcow" groups="base.group_system">
|
||||
<h2>Mailcow Settings</h2>
|
||||
<div class="row mt16 o_settings_container">
|
||||
<div class="col-12 col-lg-6 o_setting_box">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="mailcow_api_key"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="mailcow_api_key"/>
|
||||
<div class="text-muted">
|
||||
API key for Mailcow server
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="mailcow_base_url"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="mailcow_base_url"/>
|
||||
<div class="text-muted">
|
||||
Base URL for Mailcow server
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
20
bemade_mailcow_blacklist/views/res_users_views.xml
Normal file
20
bemade_mailcow_blacklist/views/res_users_views.xml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="view_users_form_mailcow" model="ir.ui.view">
|
||||
<field name="name">res.users.mailcow.form</field>
|
||||
<field name="model">res.users</field>
|
||||
<field name="inherit_id" ref="base.view_users_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<data>
|
||||
<xpath expr="//notebook" position="inside">
|
||||
<page string="Mailcow" name="mailcow">
|
||||
<group>
|
||||
<field name="mailcow_mailbox"/>
|
||||
<field name="mailcow_mailbox_password"/>
|
||||
</group>
|
||||
</page>
|
||||
</xpath>
|
||||
</data>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
24
bemade_mailcow_blacklist/views/templates.xml
Normal file
24
bemade_mailcow_blacklist/views/templates.xml
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<odoo>
|
||||
<data>
|
||||
<!--
|
||||
<template id="listing">
|
||||
<ul>
|
||||
<li t-foreach="objects" t-as="object">
|
||||
<a t-attf-href="#{ root }/objects/#{ object.id }">
|
||||
<t t-esc="object.display_name"/>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
<template id="object">
|
||||
<h1><t t-esc="object.display_name"/></h1>
|
||||
<dl>
|
||||
<t t-foreach="object._fields" t-as="field">
|
||||
<dt><t t-esc="field"/></dt>
|
||||
<dd><t t-esc="object[field]"/></dd>
|
||||
</t>
|
||||
</dl>
|
||||
</template>
|
||||
-->
|
||||
</data>
|
||||
</odoo>
|
||||
60
bemade_mailcow_blacklist/views/views.xml
Normal file
60
bemade_mailcow_blacklist/views/views.xml
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
<odoo>
|
||||
<data>
|
||||
<!-- explicit list view definition -->
|
||||
<!--
|
||||
<record model="ir.ui.view" id="bemade_mailcow_blacklist.list">
|
||||
<field name="name">bemade_mailcow_blacklist list</field>
|
||||
<field name="model">bemade_mailcow_blacklist.bemade_mailcow_blacklist</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree>
|
||||
<field name="name"/>
|
||||
<field name="value"/>
|
||||
<field name="value2"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
-->
|
||||
|
||||
<!-- actions opening views on models -->
|
||||
<!--
|
||||
<record model="ir.actions.act_window" id="bemade_mailcow_blacklist.action_window">
|
||||
<field name="name">bemade_mailcow_blacklist window</field>
|
||||
<field name="res_model">bemade_mailcow_blacklist.bemade_mailcow_blacklist</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
-->
|
||||
|
||||
<!-- server action to the one above -->
|
||||
<!--
|
||||
<record model="ir.actions.server" id="bemade_mailcow_blacklist.action_server">
|
||||
<field name="name">bemade_mailcow_blacklist server</field>
|
||||
<field name="model_id" ref="model_bemade_mailcow_blacklist_bemade_mailcow_blacklist"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">
|
||||
action = {
|
||||
"type": "ir.actions.act_window",
|
||||
"view_mode": "tree,form",
|
||||
"res_model": model._name,
|
||||
}
|
||||
</field>
|
||||
</record>
|
||||
-->
|
||||
|
||||
<!-- Top menu item -->
|
||||
<!--
|
||||
<menuitem name="bemade_mailcow_blacklist" id="bemade_mailcow_blacklist.menu_root"/>
|
||||
-->
|
||||
<!-- menu categories -->
|
||||
<!--
|
||||
<menuitem name="Menu 1" id="bemade_mailcow_blacklist.menu_1" parent="bemade_mailcow_blacklist.menu_root"/>
|
||||
<menuitem name="Menu 2" id="bemade_mailcow_blacklist.menu_2" parent="bemade_mailcow_blacklist.menu_root"/>
|
||||
-->
|
||||
<!-- actions -->
|
||||
<!--
|
||||
<menuitem name="List" id="bemade_mailcow_blacklist.menu_1_list" parent="bemade_mailcow_blacklist.menu_1"
|
||||
action="bemade_mailcow_blacklist.action_window"/>
|
||||
<menuitem name="Server to list" id="bemade_mailcow_blacklist" parent="bemade_mailcow_blacklist.menu_2"
|
||||
action="bemade_mailcow_blacklist.action_server"/>
|
||||
-->
|
||||
</data>
|
||||
</odoo>
|
||||
Loading…
Reference in a new issue