Merge PR #835 into 15.0

Signed-off-by etobella
This commit is contained in:
OCA-git-bot 2022-01-21 10:51:09 +00:00
commit 027b5c3a54
20 changed files with 1266 additions and 0 deletions

View File

@ -0,0 +1,79 @@
==================
Mail Activity Done
==================
.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! 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-LGPL--3-blue.png
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html
:alt: License: LGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsocial-lightgray.png?logo=github
:target: https://github.com/OCA/social/tree/14.0/mail_activity_done
:alt: OCA/social
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/social-14-0/social-14-0-mail_activity_done
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
:target: https://runbot.odoo-community.org/runbot/205/14.0
:alt: Try me on Runbot
|badge1| |badge2| |badge3| |badge4| |badge5|
This module implements the capability to keep activities that have been
completed, for future reporting, by setting them with the boolean 'Done'.
The activities that have been completed will not appear in the chatter.
**Table of contents**
.. contents::
:local:
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/social/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/social/issues/new?body=module:%20mail_activity_done%0Aversion:%2014.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
~~~~~~~
* ForgeFlow
Contributors
~~~~~~~~~~~~
* Jordi Ballester <jordi.ballester@forgeflow.com> (www.forgeflow.com)
* Eduardo Magdalena <emagdalena@c2i.es> (C2i Change 2 improve http://www.c2i.es)
* Radovan Skolnik <radovan@skolnik.info> (https://www.kema.sk)
* Manuel Regidor <manuel.regidor@sygel.es> (https://www.sygel.es)
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/social <https://github.com/OCA/social/tree/14.0/mail_activity_done>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View File

@ -0,0 +1,2 @@
from . import models
from .hooks import post_load_hook, pre_init_hook, uninstall_hook

View File

@ -0,0 +1,20 @@
# Copyright 2018-22 ForgeFlow <http://www.forgeflow.com>
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
{
"name": "Mail Activity Done",
"version": "15.0.1.0.0",
"author": "ForgeFlow, Odoo Community Association (OCA)",
"license": "LGPL-3",
"category": "Discuss",
"website": "https://github.com/OCA/social",
"depends": ["mail"],
"data": ["views/mail_activity_views.xml"],
"assets": {
"web.assets_backend": [
"mail_activity_done/static/src/js/mail_activity.esm.js",
],
},
"pre_init_hook": "pre_init_hook",
"post_load": "post_load_hook",
"uninstall_hook": "uninstall_hook",
}

View File

@ -0,0 +1,94 @@
# Copyright 2018-22 ForgeFlow <http://www.forgeflow.com>
# Copyright 2018 Odoo, S.A.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
from odoo import Command, fields
from odoo.addons.mail.models.mail_activity import MailActivity
def pre_init_hook(cr):
"""The objective of this hook is to default to false all values of field
'done' of mail.activity
"""
cr.execute(
"""SELECT column_name
FROM information_schema.columns
WHERE table_name='mail_activity' AND
column_name='done'"""
)
if not cr.fetchone():
cr.execute(
"""
ALTER TABLE mail_activity ADD COLUMN done boolean;
"""
)
cr.execute(
"""
UPDATE mail_activity
SET done = False
"""
)
def post_load_hook():
def _new_action_done(self, feedback=False, attachment_ids=None):
"""Overwritten method"""
if "done" not in self._fields:
return self._action_done_original(
feedback=feedback, attachment_ids=attachment_ids
)
# marking as 'done'
messages = self.env["mail.message"]
next_activities_values = []
for activity in self:
# extract value to generate next activities
if activity.chaining_type == "trigger":
vals = activity.with_context(
activity_previous_deadline=activity.date_deadline
)._prepare_next_activity_values()
next_activities_values.append(vals)
# post message on activity, before deleting it
record = self.env[activity.res_model].browse(activity.res_id)
activity.done = True
activity.active = False
activity.date_done = fields.Date.today()
record.message_post_with_view(
"mail.message_activity_done",
values={
"activity": activity,
"feedback": feedback,
"display_assignee": activity.user_id != self.env.user,
},
subtype_id=self.env["ir.model.data"]._xmlid_to_res_id(
"mail.mt_activities"
),
mail_activity_type_id=activity.activity_type_id.id,
attachment_ids=[
Command.link(attachment_id) for attachment_id in attachment_ids
]
if attachment_ids
else [],
)
messages |= record.message_ids[0]
next_activities = self.env["mail.activity"].create(next_activities_values)
return messages, next_activities
if not hasattr(MailActivity, "_action_done_original"):
MailActivity._action_done_original = MailActivity._action_done
MailActivity._action_done = _new_action_done
def uninstall_hook(cr, registry):
"""The objective of this hook is to remove all activities that are done
upon module uninstall
"""
cr.execute(
"""
DELETE FROM mail_activity
WHERE done=True
"""
)

View File

@ -0,0 +1,109 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * mail_activity_done
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 13.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2021-04-16 14:36+0000\n"
"Last-Translator: Tamás Dombos <tdombos@gmail.com>\n"
"Language-Team: none\n"
"Language: hu\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.3.2\n"
#. module: mail_activity_done
#. openerp-web
#: code:addons/mail_activity_done/static/src/js/mail_activity.js:0
#, python-format
msgid "%d days overdue"
msgstr "%d nap késésben"
#. module: mail_activity_done
#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity__active
msgid "Active"
msgstr "Aktív"
#. module: mail_activity_done
#: model:ir.model.fields,field_description:mail_activity_done.field_event_event__activity_ids
#: model:ir.model.fields,field_description:mail_activity_done.field_event_registration__activity_ids
#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity_mixin__activity_ids
#: model:ir.model.fields,field_description:mail_activity_done.field_mailing_mailing__activity_ids
#: model:ir.model.fields,field_description:mail_activity_done.field_res_partner__activity_ids
#: model:ir.model.fields,field_description:mail_activity_done.field_res_users__activity_ids
msgid "Activities"
msgstr "Tevékenységek"
#. module: mail_activity_done
#: model:ir.model,name:mail_activity_done.model_mail_activity
msgid "Activity"
msgstr "Tevékenység"
#. module: mail_activity_done
#: model:ir.model,name:mail_activity_done.model_mail_activity_mixin
msgid "Activity Mixin"
msgstr "Tevékenység mixin"
#. module: mail_activity_done
#: model_terms:ir.ui.view,arch_db:mail_activity_done.mail_activity_view_search
#: model_terms:ir.ui.view,arch_db:mail_activity_done.res_partner_view_search_inherit_mail
msgid "Completed Activities"
msgstr "Elkészült tevékenységek"
#. module: mail_activity_done
#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity__date_done
msgid "Completed Date"
msgstr "Elkészülés dátuma"
#. module: mail_activity_done
#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity__done
#: model:ir.model.fields.selection,name:mail_activity_done.selection__mail_activity__state__done
msgid "Done"
msgstr "Kész"
#. module: mail_activity_done
#. openerp-web
#: code:addons/mail_activity_done/static/src/js/mail_activity.js:0
#, python-format
msgid "Due in %d days"
msgstr "%d napon belül esedékes"
#. module: mail_activity_done
#: model_terms:ir.ui.view,arch_db:mail_activity_done.res_partner_view_search_inherit_mail
msgid "Open Activities"
msgstr "Nyitott tevékenységek"
#. module: mail_activity_done
#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity__state
msgid "State"
msgstr "Állapot"
#. module: mail_activity_done
#. openerp-web
#: code:addons/mail_activity_done/static/src/js/mail_activity.js:0
#, python-format
msgid "Today"
msgstr "Ma"
#. module: mail_activity_done
#. openerp-web
#: code:addons/mail_activity_done/static/src/js/mail_activity.js:0
#, python-format
msgid "Tomorrow"
msgstr "Holnap"
#. module: mail_activity_done
#: model:ir.model,name:mail_activity_done.model_res_users
msgid "Users"
msgstr "Felhasználók"
#. module: mail_activity_done
#. openerp-web
#: code:addons/mail_activity_done/static/src/js/mail_activity.js:0
#, python-format
msgid "Yesterday"
msgstr "Tegnap"

View File

@ -0,0 +1,133 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * mail_activity_done
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 14.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: mail_activity_done
#. openerp-web
#: code:addons/mail_activity_done/static/src/js/mail_activity.js:0
#, python-format
msgid "%d days overdue"
msgstr ""
#. module: mail_activity_done
#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity__active
msgid "Active"
msgstr ""
#. module: mail_activity_done
#: model:ir.model.fields,field_description:mail_activity_done.field_account_bank_statement_line__activity_ids
#: model:ir.model.fields,field_description:mail_activity_done.field_account_journal__activity_ids
#: model:ir.model.fields,field_description:mail_activity_done.field_account_move__activity_ids
#: model:ir.model.fields,field_description:mail_activity_done.field_account_payment__activity_ids
#: model:ir.model.fields,field_description:mail_activity_done.field_event_event__activity_ids
#: model:ir.model.fields,field_description:mail_activity_done.field_event_registration__activity_ids
#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity_mixin__activity_ids
#: model:ir.model.fields,field_description:mail_activity_done.field_mailing_mailing__activity_ids
#: model:ir.model.fields,field_description:mail_activity_done.field_product_product__activity_ids
#: model:ir.model.fields,field_description:mail_activity_done.field_product_template__activity_ids
#: model:ir.model.fields,field_description:mail_activity_done.field_res_partner__activity_ids
#: model:ir.model.fields,field_description:mail_activity_done.field_res_users__activity_ids
msgid "Activities"
msgstr ""
#. module: mail_activity_done
#: model:ir.model,name:mail_activity_done.model_mail_activity
msgid "Activity"
msgstr ""
#. module: mail_activity_done
#: model:ir.model,name:mail_activity_done.model_mail_activity_mixin
msgid "Activity Mixin"
msgstr ""
#. module: mail_activity_done
#: model_terms:ir.ui.view,arch_db:mail_activity_done.mail_activity_view_search
#: model_terms:ir.ui.view,arch_db:mail_activity_done.res_partner_view_search_inherit_mail
msgid "Completed Activities"
msgstr ""
#. module: mail_activity_done
#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity__date_done
msgid "Completed Date"
msgstr ""
#. module: mail_activity_done
#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity__display_name
#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity_mixin__display_name
#: model:ir.model.fields,field_description:mail_activity_done.field_res_users__display_name
msgid "Display Name"
msgstr ""
#. module: mail_activity_done
#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity__done
#: model:ir.model.fields.selection,name:mail_activity_done.selection__mail_activity__state__done
msgid "Done"
msgstr ""
#. module: mail_activity_done
#. openerp-web
#: code:addons/mail_activity_done/static/src/js/mail_activity.js:0
#, python-format
msgid "Due in %d days"
msgstr ""
#. module: mail_activity_done
#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity__id
#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity_mixin__id
#: model:ir.model.fields,field_description:mail_activity_done.field_res_users__id
msgid "ID"
msgstr ""
#. module: mail_activity_done
#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity____last_update
#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity_mixin____last_update
#: model:ir.model.fields,field_description:mail_activity_done.field_res_users____last_update
msgid "Last Modified on"
msgstr ""
#. module: mail_activity_done
#: model_terms:ir.ui.view,arch_db:mail_activity_done.res_partner_view_search_inherit_mail
msgid "Open Activities"
msgstr ""
#. module: mail_activity_done
#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity__state
msgid "State"
msgstr ""
#. module: mail_activity_done
#. openerp-web
#: code:addons/mail_activity_done/static/src/js/mail_activity.js:0
#, python-format
msgid "Today"
msgstr ""
#. module: mail_activity_done
#. openerp-web
#: code:addons/mail_activity_done/static/src/js/mail_activity.js:0
#, python-format
msgid "Tomorrow"
msgstr ""
#. module: mail_activity_done
#: model:ir.model,name:mail_activity_done.model_res_users
msgid "Users"
msgstr ""
#. module: mail_activity_done
#. openerp-web
#: code:addons/mail_activity_done/static/src/js/mail_activity.js:0
#, python-format
msgid "Yesterday"
msgstr ""

View File

@ -0,0 +1,2 @@
from . import mail_activity
from . import res_users

View File

@ -0,0 +1,70 @@
# Copyright 2018-22 ForgeFlow <http://www.forgeflow.com>
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
from odoo import api, fields, models
class MailActivity(models.Model):
_inherit = "mail.activity"
active = fields.Boolean(default=True)
done = fields.Boolean(default=False)
state = fields.Selection(
selection_add=[("done", "Done")],
compute="_compute_state",
search="_search_state",
)
date_done = fields.Date("Completed Date", index=True, readonly=True)
@api.depends("date_deadline", "done")
def _compute_state(self):
res = super()._compute_state()
for record in self.filtered(lambda activity: activity.done):
record.state = "done"
return res
def _search_state(self, operator, operand):
if not operand:
# checking for is (not) set
if operator == "=":
# is not set - never happens actually so we create impossible domain
return [("id", "=", False)]
else:
# is set - always - return empty domain
return []
else:
# checking for value
if operand == "done":
if operator == "=":
return ["&", ("done", operator, True), ("active", "=", False)]
else:
return ["&", ("done", operator, False), ("active", "=", True)]
else:
if operator == "=":
return [
"&",
(
"date_deadline",
{"today": "=", "overdue": "<", "planned": ">"}[operand],
fields.Date.today(),
),
("done", "=", False),
]
else:
return [
"|",
(
"date_deadline",
{"today": "!=", "overdue": ">=", "planned": "<="}[operand],
fields.Date.today(),
),
("done", "=", True),
]
class MailActivityMixin(models.AbstractModel):
_inherit = "mail.activity.mixin"
activity_ids = fields.One2many(
domain=lambda self: [("res_model", "=", self._name), ("active", "=", True)]
)

View File

@ -0,0 +1,58 @@
# Copyright 2018-22 ForgeFlow <http://www.forgeflow.com>
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
from odoo import api, fields, models, modules
class ResUsers(models.Model):
_inherit = "res.users"
@api.model
def systray_get_activities(self):
# Here we totally override the method. Not very nice, but
# we should perhaps ask Odoo to add a hook here.
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.done = False
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"].sudo().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,
"type": "activity",
}
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())

View File

@ -0,0 +1,5 @@
* Jordi Ballester <jordi.ballester@forgeflow.com> (www.forgeflow.com)
* Eduardo Magdalena <emagdalena@c2i.es> (C2i Change 2 improve http://www.c2i.es)
* Radovan Skolnik <radovan@skolnik.info> (https://www.kema.sk)
* Manuel Regidor <manuel.regidor@sygel.es> (https://www.sygel.es)
* Bernat Puig <bernat.puig@forgeflow.com> (www.forgeflow.com)

View File

@ -0,0 +1,2 @@
This module implements the capability to keep activities that have been
completed, for future reporting, by setting them with the boolean 'Done'.

View File

@ -0,0 +1,9 @@
To use this module, you need to:
#. Access to an activity from the systray activities menu.
#. Once finished, open the activity and mark it as Done.
To check activities:
#. Go to Settings -> Technical -> Activities
#. To see finished activities filter by Completed Activities

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@ -0,0 +1,424 @@
<?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.15.1: http://docutils.sourceforge.net/" />
<title>Mail Activity Done</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-activity-done">
<h1 class="title">Mail Activity Done</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/lgpl-3.0-standalone.html"><img alt="License: LGPL-3" src="https://img.shields.io/badge/licence-LGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/social/tree/14.0/mail_activity_done"><img alt="OCA/social" src="https://img.shields.io/badge/github-OCA%2Fsocial-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/social-14-0/social-14-0-mail_activity_done"><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/205/14.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p>
<p>This module implements the capability to keep activities that have been
completed, for future reporting, by setting them with the boolean Done.</p>
<p>The activities that have been completed will not appear in the chatter.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#bug-tracker" id="id1">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="id2">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="id3">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="id4">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="id5">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#id1">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/social/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/social/issues/new?body=module:%20mail_activity_done%0Aversion:%2014.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="#id2">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#id3">Authors</a></h2>
<ul class="simple">
<li>ForgeFlow</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#id4">Contributors</a></h2>
<ul class="simple">
<li>Jordi Ballester &lt;<a class="reference external" href="mailto:jordi.ballester&#64;forgeflow.com">jordi.ballester&#64;forgeflow.com</a>&gt; (www.forgeflow.com)</li>
<li>Eduardo Magdalena &lt;<a class="reference external" href="mailto:emagdalena&#64;c2i.es">emagdalena&#64;c2i.es</a>&gt; (C2i Change 2 improve <a class="reference external" href="http://www.c2i.es">http://www.c2i.es</a>)</li>
<li>Radovan Skolnik &lt;<a class="reference external" href="mailto:radovan&#64;skolnik.info">radovan&#64;skolnik.info</a>&gt; (<a class="reference external" href="https://www.kema.sk">https://www.kema.sk</a>)</li>
<li>Manuel Regidor &lt;<a class="reference external" href="mailto:manuel.regidor&#64;sygel.es">manuel.regidor&#64;sygel.es</a>&gt; (<a class="reference external" href="https://www.sygel.es">https://www.sygel.es</a>)</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#id5">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/social/tree/14.0/mail_activity_done">OCA/social</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>

View File

@ -0,0 +1,84 @@
/** @odoo-module **/
// Copyright 2018-22 ForgeFlow <http://www.forgeflow.com>
// License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
import {qweb as QWeb, _t} from "web.core";
import mailUtils from "@mail/js/utils";
import mail_activity from "mail.activity";
import time from "web.time";
// We are forced here to override the method, as there is no possibility
// to inherit it.
var setDelayLabel = function (activities) {
var today = moment().startOf("day");
_.each(activities, function (activity) {
var to_display = "";
var deadline = moment(activity.date_deadline).startOf("day");
// On next line, true means no rounding
var diff = deadline.diff(today, "days", true);
if (diff === 0) {
to_display = _t("Today");
} else if (diff < 0) {
// This block is for overdue
// eslint-disable-line no-lonely-if
if (diff === -1) {
to_display = _t("Yesterday");
} else {
to_display = _.str.sprintf(_t("%d days overdue"), Math.abs(diff));
}
// This block is for due
} else if (diff === 1) {
// eslint-disable-line no-lonely-if
to_display = _t("Tomorrow");
} else {
to_display = _.str.sprintf(_t("Due in %d days"), Math.abs(diff));
}
activity.label_delay = to_display;
});
// We do not want to show the activities that have been completed.
var open_activities = _.filter(activities, function (activity) {
return activity.done !== true;
});
return open_activities;
};
mail_activity.include({
/**
* @override
* @private
*/
_render: function () {
_.each(this._activities, function (activity) {
var note = mailUtils.parseAndTransform(
activity.note || "",
mailUtils.inline
);
var is_blank = /^\s*$/.test(note);
if (is_blank) {
activity.note = "";
} else {
activity.note = mailUtils.parseAndTransform(
activity.note,
mailUtils.addLink
);
}
});
var activities = setDelayLabel(this._activities);
if (activities.length) {
var nbActivities = _.countBy(activities, "state");
this.$el.html(
QWeb.render("mail.activity_items", {
activities: activities,
nbPlannedActivities: nbActivities.planned,
nbTodayActivities: nbActivities.today,
nbOverdueActivities: nbActivities.overdue,
dateFormat: time.getLangDateFormat(),
datetimeFormat: time.getLangDatetimeFormat(),
})
);
} else {
this.$el.empty();
}
},
});

View File

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

View File

@ -0,0 +1,41 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from datetime import date
from odoo.tests.common import TransactionCase
class TestMailActivityDoneMethods(TransactionCase):
def setUp(self):
super(TestMailActivityDoneMethods, self).setUp()
self.employee = self.env["res.users"].create(
{
"company_id": self.env.ref("base.main_company").id,
"name": "Test User",
"login": "testuser",
"groups_id": [(6, 0, [self.env.ref("base.group_user").id])],
}
)
activity_type = self.env["mail.activity.type"].search(
[("name", "=", "Meeting")], limit=1
)
self.act1 = self.env["mail.activity"].create(
{
"activity_type_id": activity_type.id,
"res_id": self.env.ref("base.res_partner_1").id,
"res_model_id": self.env["ir.model"]._get("res.partner").id,
"user_id": self.employee.id,
"date_deadline": date.today(),
}
)
def test_mail_activity_done(self):
self.act1.done = True
self.assertEqual(self.act1.state, "done")
def test_systray_get_activities(self):
act_count = self.employee.with_user(self.employee).systray_get_activities()
self.assertEqual(
len(act_count), 1, "Number of activities should be equal to one"
)

View File

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<!--
Copyright 2018-20 ForgeFlow <http://www.forgeflow.com>
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
-->
<record id="mail_activity_view_form_popup" model="ir.ui.view">
<field name="name">mail.activity.view.form.popup</field>
<field name="model">mail.activity</field>
<field name="inherit_id" ref="mail.mail_activity_view_form_popup" />
<field name="priority">20</field>
<field name="arch" type="xml">
<field name="activity_type_id" position="after">
<field name="state" />
<field name="date_done" />
</field>
<button name="action_done" position="attributes">
<attribute
name="attrs"
>{'invisible':[('state', '=', 'done')]}</attribute>
</button>
</field>
</record>
<record id="mail_activity_view_search" model="ir.ui.view">
<field name="name">mail.activity.view.search</field>
<field name="model">mail.activity</field>
<field name="inherit_id" ref="mail.mail_activity_view_search" />
<field name="arch" type="xml">
<field name="res_model" position="after">
<field name="done" />
<field name="active" />
<filter
string="Completed Activities"
name="activities_completed"
domain="[('active', '=', False), ('state', '=', 'done')]"
/>
</field>
<filter name="activities_overdue" position="attributes">
<attribute
name="domain"
>[('date_deadline', '&lt;', context_today().strftime('%Y-%m-%d'))]</attribute>
</filter>
<filter name="activities_today" position="attributes">
<attribute
name="domain"
>[('date_deadline', '=', context_today().strftime('%Y-%m-%d'))]</attribute>
</filter>
<filter name="activities_upcoming_all" position="attributes">
<attribute
name="domain"
>[('date_deadline', '&gt;', context_today().strftime('%Y-%m-%d'))]</attribute>
</filter>
</field>
</record>
<record id="res_partner_view_search_inherit_mail" model="ir.ui.view">
<field name="name">res.partner.view.search.inherit.mail</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="mail.res_partner_view_search_inherit_mail" />
<field name="arch" type="xml">
<filter name="activities_overdue" position="before">
<filter
string="Open Activities"
name="activities_open"
domain="[('activity_ids.active', '=', True)]"
/>
<filter
string="Completed Activities"
name="activities_completed"
domain="[('activity_ids.active', '=', False), ('activity_ids.state', '=', 'done')]"
/>
</filter>
<filter name="activities_overdue" position="attributes">
<attribute
name="domain"
>[('activity_ids.date_deadline', '&lt;', context_today().strftime('%Y-%m-%d'))]</attribute>
</filter>
<filter name="activities_today" position="attributes">
<attribute
name="domain"
>[('activity_ids.date_deadline', '=', context_today().strftime('%Y-%m-%d'))]</attribute>
</filter>
<filter name="activities_upcoming_all" position="attributes">
<attribute
name="domain"
>[('activity_ids.date_deadline', '&gt;', context_today().strftime('%Y-%m-%d'))]</attribute>
</filter>
</field>
</record>
<record id="mail_activity_view_tree" model="ir.ui.view">
<field name="name">mail.activity.view.tree</field>
<field name="model">mail.activity</field>
<field name="inherit_id" ref="mail.mail_activity_view_tree" />
<field name="arch" type="xml">
<field name="date_deadline" position="after">
<field name="state" />
<field name="date_done" />
</field>
<tree position="attributes">
<attribute name="decoration-muted">state == 'done'</attribute>
<attribute
name="decoration-danger"
>date_deadline &lt; current_date and state != 'done'</attribute>
<attribute
name="decoration-success"
>date_deadline == current_date and state != 'done'</attribute>
</tree>
</field>
</record>
<record id="mail_activity_view_calendar" model="ir.ui.view">
<field name="name">mail.activity.view.calendar</field>
<field name="model">mail.activity</field>
<field name="inherit_id" ref="mail.mail_activity_view_calendar" />
<field name="priority" eval="2" />
<field name="arch" type="xml">
<field name="summary" position="after">
<field name="state" />
<field name="date_done" />
</field>
</field>
</record>
</odoo>

View File

@ -0,0 +1 @@
../../../../mail_activity_done

View File

@ -0,0 +1,6 @@
import setuptools
setuptools.setup(
setup_requires=['setuptools-odoo'],
odoo_addon=True,
)