Skip to content

Commit

Permalink
Move mail_activity_not_deleted and mail_recipient_unchecked from mail…
Browse files Browse the repository at this point in the history
…-addons (#9)

* Move mail_activity_not_deleted and mail_recipient_unchecked from mail-addons
  • Loading branch information
ddufresne authored Mar 1, 2019
1 parent 22146e2 commit 0cc82e3
Show file tree
Hide file tree
Showing 17 changed files with 313 additions and 2 deletions.
2 changes: 2 additions & 0 deletions .docker_files/main/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
'depends': [
'ir_attachment_access_token_portal',
'ir_attachment_name_autocomplete',
'mail_activity_not_deleted',
'mail_recipient_unchecked',
],
'installable': True,
}
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
FROM quay.io/numigi/odoo-public:11.0
MAINTAINER numigi <[email protected]>

USER odoo

COPY ir_attachment_access_token_portal /mnt/extra-addons/ir_attachment_access_token_portal
COPY ir_attachment_name_autocomplete /mnt/extra-addons/ir_attachment_name_autocomplete
COPY mail_activity_not_deleted /mnt/extra-addons/mail_activity_not_deleted
COPY mail_recipient_unchecked /mnt/extra-addons/mail_recipient_unchecked

COPY .docker_files/main /mnt/extra-addons/main
COPY .docker_files/odoo.conf /etc/odoo
18 changes: 18 additions & 0 deletions mail_activity_not_deleted/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Mail Activity Not Deleted
=========================
Since version 11.0, Odoo adds the concept of activities.
One issue with this feature is that when an activity is completed, the activity record is deleted from the database.

This module deactivates terminated activities instead of deleting them from the mail_activity table.

New State
---------
The state Done is added to activities. Any completed activity is automatically set to Done.

New Field
---------
The field Date Done is added to activities. When completing the activity, this field is filled with the current time.

Contributors
------------
* Numigi (tm) and all its contributors (https://bit.ly/numigiens)
4 changes: 4 additions & 0 deletions mail_activity_not_deleted/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# © 2018 Numigi (tm) and all its contributors (https://bit.ly/numigiens)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).

from . import models
14 changes: 14 additions & 0 deletions mail_activity_not_deleted/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# © 2018 Numigi (tm) and all its contributors (https://bit.ly/numigiens)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).

{
'name': 'Mail Activity Not Deleted',
'version': '1.0.0',
'author': 'Numigi',
'maintainer': 'Numigi',
'license': 'LGPL-3',
'category': 'Other',
'summary': 'Deactivate terminated activities instead of deleting.',
'depends': ['mail'],
'installable': True,
}
33 changes: 33 additions & 0 deletions mail_activity_not_deleted/i18n/fr.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * mail_activity_not_deleted
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 11.0+e\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-05-29 15:13-0400\n"
"PO-Revision-Date: 2018-05-29 19:13+0000\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.8.7.1\n"

#. module: mail_activity_not_deleted
#: model:ir.model.fields,field_description:mail_activity_not_deleted.field_mail_activity_active
msgid "Active"
msgstr "Actif"

#. module: mail_activity_not_deleted
#: model:ir.model,name:mail_activity_not_deleted.model_mail_activity
msgid "Activity"
msgstr "Activité"

#. module: mail_activity_not_deleted
#: model:ir.model.fields,field_description:mail_activity_not_deleted.field_mail_activity_date_done
msgid "Date Done"
msgstr "Terminé le"
4 changes: 4 additions & 0 deletions mail_activity_not_deleted/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# © 2018 Numigi (tm) and all its contributors (https://bit.ly/numigiens)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).

from . import mail_activity, user
80 changes: 80 additions & 0 deletions mail_activity_not_deleted/models/mail_activity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# © 2018 Numigi (tm) and all its contributors (https://bit.ly/numigiens)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).

from datetime import datetime

from odoo import api, fields, models


class MailActivityInactivatedInsteadOfDeleted(models.Model):

_inherit = 'mail.activity'

active = fields.Boolean(default=True)
date_done = fields.Datetime()

def action_feedback(self, feedback=False):
self = self.with_context(mail_activity_no_delete=True)
return super(MailActivityInactivatedInsteadOfDeleted, self).action_feedback(False)

@api.multi
def unlink(self):
"""Deactivate instead of deleting the activity when it is completed."""
if self._context.get('mail_activity_no_delete'):
self._send_signal_done()
self.write({
'active': False,
'date_done': datetime.now(),
})
for activity in self:
activity._update_record_date_deadline()
else:
return super().unlink()

def _send_signal_done(self):
"""Send the signal to the chatter that the activity has been completed.
The code in this method was extracted odoo/addons/mail/models/mail_activity.py.
"""
for activity in self:
if activity.date_deadline <= fields.Date.today():
self.env['bus.bus'].sendone(
(self._cr.dbname, 'res.partner', activity.user_id.partner_id.id),
{'type': 'activity_updated', 'activity_deleted': True})

def _update_record_date_deadline(self):
"""Update the stored fields that depend on activity_ids on the related record."""
record = self.env[self.res_model].browse(self.res_id)
record.modified(['activity_ids'])
record.recompute()


class MailActivityWithStateDone(models.Model):
"""Add the state done to mail activities."""

_inherit = 'mail.activity'

state = fields.Selection(selection_add=[('done', 'Done')])

@api.depends('date_deadline')
def _compute_state(self):
super()._compute_state()

done_activities = self.filtered(lambda a: a.date_done)
for activity in done_activities:
activity.state = 'done'


class MailActivityMixinWithActivityNotDeletedWhenRecordDeactivated(models.AbstractModel):
"""When deactivating a record, deactivate activities instead of deleting them."""

_inherit = 'mail.activity.mixin'

# auto_join prevents the active filter from being automatically applied.
activity_ids = fields.One2many(auto_join=False)

@api.multi
def write(self, vals):
if 'active' in vals and vals['active'] is False:
self = self.with_context(mail_activity_no_delete=True)
return super(MailActivityMixinWithActivityNotDeletedWhenRecordDeactivated, self).write(vals)
55 changes: 55 additions & 0 deletions mail_activity_not_deleted/models/user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# © 2018 Numigi (tm) and all its contributors (https://bit.ly/numigiens)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).

from odoo import api, fields, models, modules


class User(models.Model):

_inherit = 'res.users'

@api.model
def activity_user_count(self):
"""Prevent inactive activities from appearing in the main Odoo navbar.
This method is a copy from the method defined at:
odoo/addons/mail/models/res_users.py
Only the active filter was added in the sql query.
"""
query = """SELECT m.id, count(*), act.res_model as model,
CASE
WHEN %(today)s::date - act.date_deadline::date = 0 Then 'today'
WHEN %(today)s::date - act.date_deadline::date > 0 Then 'overdue'
WHEN %(today)s::date - act.date_deadline::date < 0 Then 'planned'
END AS states
FROM mail_activity AS act
JOIN ir_model AS m ON act.res_model_id = m.id
WHERE user_id = %(user_id)s
AND act.active
GROUP BY m.id, states, act.res_model;
"""
self.env.cr.execute(query, {
'today': fields.Date.context_today(self),
'user_id': self.env.uid,
})
activity_data = self.env.cr.dictfetchall()
model_ids = [a['id'] for a in activity_data]
model_names = {n[0]:n[1] for n in self.env['ir.model'].browse(model_ids).name_get()}

user_activities = {}
for activity in activity_data:
if not user_activities.get(activity['model']):
user_activities[activity['model']] = {
'name': model_names[activity['id']],
'model': activity['model'],
'icon': modules.module.get_module_icon(self.env[activity['model']]._original_module),
'total_count': 0, 'today_count': 0, 'overdue_count': 0, 'planned_count': 0,
}
user_activities[activity['model']]['%s_count' % activity['states']] += activity['count']
if activity['states'] in ('today','overdue'):
user_activities[activity['model']]['total_count'] += activity['count']

return list(user_activities.values())
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file.
65 changes: 65 additions & 0 deletions mail_activity_not_deleted/tests/test_mail_activity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# © 2018 Numigi (tm) and all its contributors (https://bit.ly/numigiens)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).

from datetime import datetime

from odoo import fields
from odoo.tests import common


class TestMailActivity(common.SavepointCase):

@classmethod
def setUpClass(cls):
super().setUpClass()
cls.partner = cls.env['res.partner'].create({'name': 'Test'})
cls.partner.write({
'activity_ids': [(0, 0, {
'res_id': cls.partner.id,
'res_model_id': cls.env.ref('base.model_res_partner').id,
'date_deadline': datetime.now().date(),
'user_id': cls.env.user.id,
})]
})
cls.activity = cls.partner.activity_ids

def test_when_activity_is_completed_then_it_is_inactive_instead_of_deleted(self):
self.assertTrue(self.activity.active)

self.activity.action_done()
self.assertTrue(self.activity.exists())
self.assertFalse(self.activity.active)

def test_when_record_is_deactivated_then_the_activity_is_inactive_instead_of_deleted(self):
self.assertTrue(self.activity.active)

self.partner.active = False
self.activity.refresh()
self.assertTrue(self.activity.exists())
self.assertFalse(self.activity.active)

def test_the_date_done_is_computed_when_the_activity_is_completed(self):
self.assertFalse(self.activity.date_done)

time_before = fields.Datetime.to_string(datetime.now())
self.activity.action_done()
time_after = fields.Datetime.to_string(datetime.now())

self.assertLessEqual(time_before, self.activity.date_done)
self.assertLessEqual(self.activity.date_done, time_after)

def test_the_state_is_done_after_the_activity_is_completed(self):
self.assertNotEqual(self.activity.state, 'done')
self.activity.action_done()
self.activity.refresh()
self.assertEqual(self.activity.state, 'done')

def test_when_the_activity_is_archived_then_it_is_not_due_today(self):
self.assertEqual(self.partner.activity_state, 'today')
self.activity.action_done()
self.assertFalse(self.partner.activity_state)

def test_when_the_activity_is_archived_then_partner_has_no_activity_deadline(self):
self.assertTrue(self.partner.activity_date_deadline)
self.activity.action_done()
self.assertFalse(self.partner.activity_date_deadline)
7 changes: 7 additions & 0 deletions mail_recipient_unchecked/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Mail Recipient Unchecked
========================
This module unchecks the recipients of the chatter.

Contributors
------------
* Numigi (tm) and all its contributors (https://bit.ly/numigiens)
3 changes: 3 additions & 0 deletions mail_recipient_unchecked/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
# © 2018 Numigi (tm) and all its contributors (https://bit.ly/numigiens)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
18 changes: 18 additions & 0 deletions mail_recipient_unchecked/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
# © 2018 Numigi (tm) and all its contributors (https://bit.ly/numigiens)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).

{
'name': 'Mail Recipient Unchecked',
'version': '1.0.0',
'author': 'Numigi',
'maintainer': 'Numigi',
'license': 'LGPL-3',
'category': 'Other',
'summary': 'Uncheck the recipients of chatter message by default.',
'depends': [
'mail',
],
'qweb': ['templates/chatter.xml'],
'installable': True,
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions mail_recipient_unchecked/templates/chatter.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates>
<t t-name="mail.chatter.ChatComposer" t-extend="mail.chatter.ChatComposer">
<t t-jquery="input[type='checkbox'][t-att-data-fullname='recipient.full_name']" t-operation="attributes">
<attribute name="t-att-checked">undefined</attribute>
</t>
</t>
</templates>

0 comments on commit 0cc82e3

Please sign in to comment.