Skip to content

Commit

Permalink
[ADD][mail_activity_board] Add new module that insert activities boar…
Browse files Browse the repository at this point in the history
…d in boards. (OCA#283)

* [ADD] Module that insert activities board.

* [FIX] Author error in __manifest__ file and style changes.

* [FIX] Fix replace in view, rename files and style changes.

* [FIX] Enumerated list ends without a blank line; unexpected unindent.

* [FIX] Name fail.

* [FIX] Bug in view.

* [FIX]  Add button Activities in mail.thread and readme folder. Others improvements in style of code.

* [FIX] Type 'tree' not found in registry: problem solved.

* [FIX] Dependence change: 'mail' for 'calendar'.

* [FIX] Eliminated unnecessary imports.

* [FIX] Bugs about js and if/else.

* [FIX] Improvements following guide lines and eliminating unnecessary attributes in views.

* [ADD] Added counter in the 'Activities List' button.

* [FIX] Bugs in javascript with 'Activities' button.

* [ADD] Tests folder.

* [FIX] Deleted references to modules not installed.

* [FIX] Formatting javascript.

* [FIX] Bug: added a soft line before a class.

* [FIX] Bug: OCA#283 (comment)

* [FIX] Escaping 'lt' in xml file. Bug: OCA#283 (comment)

* [FIX] The meeting attendees are shown in kanban mode on the meeting board.

* [FIX] Hide in form view of the activity board the assistant field if the activity is not a meeting type or if there are no assistants.

* [FIX] Change to default kanban view for partners.
  • Loading branch information
dajuayen authored and pegonzalezspesol committed Oct 23, 2019
1 parent 6823fd6 commit eb274b0
Show file tree
Hide file tree
Showing 15 changed files with 540 additions and 0 deletions.
21 changes: 21 additions & 0 deletions mail_activity_board/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
**This file is going to be generated by oca-gen-addon-readme.**

*Manual changes will be overwritten.*

Please provide content in the ``readme`` directory:

* **DESCRIPTION.rst** (required)
* INSTALL.rst (optional)
* CONFIGURE.rst (optional)
* **USAGE.rst** (optional, highly recommended)
* DEVELOP.rst (optional)
* ROADMAP.rst (optional)
* HISTORY.rst (optional, recommended)
* **CONTRIBUTORS.rst** (optional, highly recommended)
* CREDITS.rst (optional)

Content of this README will also be drawn from the addon manifest,
from keys such as name, authors, maintainers, development_status,
and license.

A good, one sentence summary in the manifest is also highly recommended.
1 change: 1 addition & 0 deletions mail_activity_board/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
24 changes: 24 additions & 0 deletions mail_activity_board/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Copyright 2018 David Juaneda - <djuaneda@sdi.es>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{
'name': 'Activities board',
'summary': 'Add Activity Boards',
'version': '11.0.1.0.0',
'development_status': 'Beta',
'category': 'Social Network',
'website': 'https://github.com/OCA/social',
'author': 'SDi, David Juaneda, Odoo Community Association (OCA)',
'license': 'AGPL-3',
'installable': True,
'depends': [
'calendar',
'board',
],
'data': [
'views/templates.xml',
'views/mail_activity_view.xml',
],
'qweb': [
'static/src/xml/inherit_chatter.xml',
]
}
2 changes: 2 additions & 0 deletions mail_activity_board/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import mail_activity
from . import mail_activity_mixin
45 changes: 45 additions & 0 deletions mail_activity_board/models/mail_activity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Copyright 2018 David Juaneda - <djuaneda@sdi.es>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import api, models, fields


class MailActivity(models.Model):
_inherit = "mail.activity"

res_model_id_name = fields.Char(
related='res_model_id.name', string="Origin",
readonly=True)
duration = fields.Float(
related='calendar_event_id.duration', readonly=True)
calendar_event_id_start = fields.Datetime(
related='calendar_event_id.start', readonly=True)
calendar_event_id_partner_ids = fields.Many2many(
related='calendar_event_id.partner_ids',
readonly=True)

@api.multi
def open_origin(self):
self.ensure_one()
vid = self.env[self.res_model].browse(self.res_id).get_formview_id()
response = {
'type': 'ir.actions.act_window',
'res_model': self.res_model,
'view_mode': 'form',
'res_id': self.res_id,
'target': 'current',
'flags': {
'form': {
'action_buttons': False
}
},
'views': [
(vid, "form")
]
}
return response

@api.model
def action_activities_board(self):
action = self.env.ref(
'mail_activity_board.open_boards_activities').read()[0]
return action
32 changes: 32 additions & 0 deletions mail_activity_board/models/mail_activity_mixin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Copyright 2018 David Juaneda - <djuaneda@sdi.es>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models


class MailActivityMixin(models.AbstractModel):
_inherit = 'mail.activity.mixin'

def redirect_to_activities(self, **kwargs):
"""Redirects to the list of activities of the object shown.
Redirects to the activity board and configures the domain so that
only those activities that are related to the object shown are
displayed.
Add to the title of the view the name the class of the object from
which the activities will be displayed.
:param kwargs: contains the id of the object and the model it's about.
:return: action.
"""
id = kwargs.get("id")
action = self.env['mail.activity'].action_activities_board()
views = []
for v in action['views']:
if v[1] == 'tree':
v = (v[0], 'list')
views.append(v)
action['views'] = views
action['domain'] = [('res_id', '=', id)]
return action
3 changes: 3 additions & 0 deletions mail_activity_board/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
* `SDI <https://www.sdi.es>`_:

* David Juaneda
2 changes: 2 additions & 0 deletions mail_activity_board/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
This module adds an activity board with form, tree, kanban, calendar, pivot, graph and search views.

9 changes: 9 additions & 0 deletions mail_activity_board/readme/USAGE.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
To use this module, you need to:

#. Access to the views from menu Boards.

A smartButton of activities is added in the mail thread from form view.
From this smartButton is linked to the activity board, to the view tree,
which shows the activities related to the opportunity.

From the form view of the activity you can navigate to the origin of the activity.
33 changes: 33 additions & 0 deletions mail_activity_board/static/src/js/override_chatter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/* Copyright 2018 David Juaneda
* License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). */
odoo.define('mail.Chatter.activity', function (require) {
"use strict";

var chatter = require('mail.Chatter');

chatter.include({

events: _.extend({}, chatter.prototype.events, {
'click .o_chatter_button_list_activity': '_onListActivity',
}),

/**
* Performs the action to redirect to the activities of the object.
*
* @private
*/
_onListActivity: function () {
this._rpc({
model: this.record.model,
method: 'redirect_to_activities',
args: [[]],
kwargs: {
'id':this.record.res_id,
'model':this.record.model,
},
context: this.record.getContext(),
}).then($.proxy(this, "do_action"));
},

});
});
13 changes: 13 additions & 0 deletions mail_activity_board/static/src/xml/inherit_chatter.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">

<t t-extend="mail.Chatter.Buttons">
<t t-jquery="button.o_chatter_button_schedule_activity" t-operation="after">
<button t-if="schedule_activity_btn" class="btn btn-sm btn-link o_chatter_button_list_activity"
title="See activities list" type="button">
<i class="fa fa-list"/> Activities
</button>
</t>
</t>

</templates>
1 change: 1 addition & 0 deletions mail_activity_board/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import test_mail_activity_board
136 changes: 136 additions & 0 deletions mail_activity_board/tests/test_mail_activity_board.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# Copyright 2018 David Juaneda - <djuaneda@sdi.es>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo.tests.common import TransactionCase


class TestMailActivityBoardMethods(TransactionCase):

def setUp(self):
super(TestMailActivityBoardMethods, self).setUp()
# Set up activities

# Create a user as 'Crm Salesman' and added few groups
self.employee = self.env['res.users'].create({
'company_id': self.env.ref("base.main_company").id,
'name': "Employee",
'login': "csu",
'email': "crmuser@yourcompany.com",
'groups_id': [(6, 0, [self.env.ref('base.group_user').id])]
})

# lead_model_id = self.env['ir.model']._get('crm.lead').id
partner_model_id = self.env['ir.model']._get('res.partner').id

ActivityType = self.env['mail.activity.type']
self.activity1 = ActivityType.create({
'name': 'Initial Contact',
'days': 5,
'summary': 'ACT 1 : Presentation, barbecue, ... ',
'res_model_id': partner_model_id,
})
self.activity2 = ActivityType.create({
'name': 'Call for Demo',
'days': 6,
'summary': 'ACT 2 : I want to show you my ERP !',
'res_model_id': partner_model_id,
})
self.activity3 = ActivityType.create({
'name': 'Celebrate the sale',
'days': 3,
'summary': 'ACT 3 : '
'Beers for everyone because I am a good salesman !',
'res_model_id': partner_model_id,
})

# I create an opportunity, as employee
self.partner_client = self.env.ref("base.res_partner_1")

self.act1 = self.env['mail.activity'].sudo().create({
'activity_type_id': self.activity3.id,
'note': 'Partner activity 1.',
'res_id': self.partner_client.id,
'res_model_id': partner_model_id,
'user_id': self.employee.id
})
self.act2 = self.env['mail.activity'].sudo().create({
'activity_type_id': self.activity2.id,
'note': 'Partner activity 2.',
'res_id': self.partner_client.id,
'res_model_id': partner_model_id,
'user_id': self.employee.id
})
self.act3 = self.env['mail.activity'].sudo().create({
'activity_type_id': self.activity3.id,
'note': 'Partner activity 3.',
'res_id': self.partner_client.id,
'res_model_id': partner_model_id,
'user_id': self.employee.id
})

def get_view(self, activity):
action = activity.open_origin()
result = self.env[action.get('res_model')]\
.load_views(action.get('views'))
return result.get('fields_views').get(action.get('view_mode'))

def test_open_origin_res_partner(self):
""" This test case checks
- If the method redirects to the form view of the correct one
of an object of the 'res.partner' class to which the activity
belongs.
"""
# Id of the form view for the class 'crm.lead', type 'lead'
form_view_partner_id = self.env.ref('base.view_partner_form').id

# Id of the form view return open_origin()
view = self.get_view(self.act1)

# Check the next view is correct
self.assertEqual(form_view_partner_id, view.get('view_id'))

# Id of the form view return open_origin()
view = self.get_view(self.act2)

# Check the next view is correct
self.assertEqual(form_view_partner_id, view.get('view_id'))

# Id of the form view return open_origin()
view = self.get_view(self.act3)

# Check the next view is correct
self.assertEqual(form_view_partner_id, view.get('view_id'))

def test_redirect_to_activities(self):
""" This test case checks
- if the method returns the correct action,
- if the correct activities are shown.
"""
action_id = self.env.ref(
'mail_activity_board.open_boards_activities').id
action = self.partner_client\
.redirect_to_activities(**{'id': self.partner_client.id})
self.assertEqual(action.get('id'), action_id)

kwargs = {
'groupby': [
"activity_type_id"
]
}
kwargs['domain'] = action.get('domain')

result = self.env[action.get('res_model')]\
.load_views(action.get('views'))
fields = result.get('fields_views').get('kanban').get('fields')
kwargs['fields'] = list(fields.keys())

result = self.env['mail.activity'].read_group(**kwargs)

acts = []
for group in result:
records = self.env['mail.activity'].search_read(
domain=group.get('__domain'), fields=kwargs['fields']
)
acts += [id.get('id') for id in records]

for act in acts:
self.assertIn(act, self.partner_client.activity_ids.ids)
Loading

0 comments on commit eb274b0

Please sign in to comment.