Parcourir la source

Moved feed from Communication to Activity Log (#4435)

* Removed comment_type 'updated'

* New doctype activity log

* Moved feed.py to activity_log

* Updated feed gets stored in activity_log

* Activity page fetches feed from activity_log

* feed match condition change

* modified

* modified hooks.py

* modified sessions.py

* patch added

* naming in patch

* moved login, logout feed to activity_log

* changes in auth.py, hooks.py

* deleted doctype authentication_log and added test cases

* added utils.py in core

* moved some methods from communication.py to utils.py
version-14
Shreya Shah il y a 7 ans
committed by Rushabh Mehta
Parent
révision
acdbb97ba5
23 fichiers modifiés avec 945 ajouts et 455 suppressions
  1. +1
    -1
      frappe/auth.py
  2. +0
    -0
      frappe/core/doctype/activity_log/__init__.py
  3. +8
    -0
      frappe/core/doctype/activity_log/activity_log.js
  4. +717
    -0
      frappe/core/doctype/activity_log/activity_log.json
  5. +49
    -0
      frappe/core/doctype/activity_log/activity_log.py
  6. +1
    -1
      frappe/core/doctype/activity_log/activity_log_list.js
  7. +9
    -16
      frappe/core/doctype/activity_log/feed.py
  8. +4
    -6
      frappe/core/doctype/activity_log/test_activity_log.py
  9. +0
    -8
      frappe/core/doctype/authentication_log/authentication_log.js
  10. +0
    -341
      frappe/core/doctype/authentication_log/authentication_log.json
  11. +0
    -27
      frappe/core/doctype/authentication_log/authentication_log.py
  12. +5
    -5
      frappe/core/doctype/communication/communication.json
  13. +30
    -30
      frappe/core/doctype/communication/communication.py
  14. +5
    -3
      frappe/core/doctype/communication/email.py
  15. +23
    -0
      frappe/core/doctype/communication/test_communication.js
  16. +34
    -0
      frappe/core/utils.py
  17. +13
    -9
      frappe/desk/page/activity/activity.py
  18. +3
    -3
      frappe/hooks.py
  19. +14
    -2
      frappe/model/delete_doc.py
  20. +2
    -1
      frappe/patches.txt
  21. +25
    -0
      frappe/patches/v9_1/move_feed_to_activity_log.py
  22. +1
    -1
      frappe/sessions.py
  23. +1
    -1
      frappe/tests/ui/tests.txt

+ 1
- 1
frappe/auth.py Voir le fichier

@@ -15,7 +15,7 @@ from frappe.sessions import Session, clear_sessions, delete_session
from frappe.modules.patch_handler import check_session_stopped from frappe.modules.patch_handler import check_session_stopped
from frappe.translate import get_lang_code from frappe.translate import get_lang_code
from frappe.utils.password import check_password from frappe.utils.password import check_password
from frappe.core.doctype.authentication_log.authentication_log import add_authentication_log
from frappe.core.doctype.activity_log.activity_log import add_authentication_log
from frappe.utils.background_jobs import enqueue from frappe.utils.background_jobs import enqueue
from frappe.twofactor import (should_run_2fa, authenticate_for_2factor, from frappe.twofactor import (should_run_2fa, authenticate_for_2factor,
confirm_otp_token, get_cached_user_pass) confirm_otp_token, get_cached_user_pass)


frappe/core/doctype/authentication_log/__init__.py → frappe/core/doctype/activity_log/__init__.py Voir le fichier


+ 8
- 0
frappe/core/doctype/activity_log/activity_log.js Voir le fichier

@@ -0,0 +1,8 @@
// Copyright (c) 2017, Frappe Technologies and contributors
// For license information, please see license.txt

frappe.ui.form.on('Activity Log', {
refresh: function() {

}
});

+ 717
- 0
frappe/core/doctype/activity_log/activity_log.json Voir le fichier

@@ -0,0 +1,717 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 0,
"autoname": "",
"beta": 0,
"creation": "2017-10-05 11:10:38.780133",
"custom": 0,
"description": "Keep track of all update feeds",
"docstatus": 0,
"doctype": "DocType",
"document_type": "Setup",
"editable_grid": 0,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "subject",
"fieldtype": "Small Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 1,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Subject",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_8",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "content",
"fieldtype": "Text Editor",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Message",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0,
"width": "400"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_5",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
"columns": 0,
"fieldname": "additional_info",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "More Information",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "Now",
"fieldname": "communication_date",
"fieldtype": "Datetime",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Date",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_7",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "operation",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Operation",
"length": 0,
"no_copy": 0,
"options": "\nLogin\nLogout",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "status",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Status",
"length": 0,
"no_copy": 0,
"options": "\nSuccess\nFailed\nLinked\nClosed",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
"columns": 0,
"fieldname": "reference_section",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Reference",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "reference_doctype",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Reference DocType",
"length": 0,
"no_copy": 0,
"options": "DocType",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "reference_name",
"fieldtype": "Dynamic Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Reference Name",
"length": 0,
"no_copy": 0,
"options": "reference_doctype",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "reference_owner",
"fieldtype": "Read Only",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Reference Owner",
"length": 0,
"no_copy": 0,
"options": "reference_name.owner",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_14",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "timeline_doctype",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Timeline DocType",
"length": 0,
"no_copy": 0,
"options": "DocType",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "timeline_name",
"fieldtype": "Dynamic Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Timeline Name",
"length": 0,
"no_copy": 0,
"options": "timeline_doctype",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "link_doctype",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Link DocType",
"length": 0,
"no_copy": 0,
"options": "DocType",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "link_name",
"fieldtype": "Dynamic Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Link Name",
"length": 0,
"no_copy": 0,
"options": "link_doctype",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "__user",
"fieldname": "user",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 1,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "User",
"length": 0,
"no_copy": 0,
"options": "User",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "full_name",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Full Name",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "fa fa-comment",
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-11-21 12:39:23.659308",
"modified_by": "Administrator",
"module": "Core",
"name": "Activity Log",
"name_case": "",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 0,
"read": 1,
"report": 1,
"role": "System Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 0
},
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 0
},
{
"amend": 0,
"apply_user_permissions": 1,
"cancel": 0,
"create": 0,
"delete": 1,
"email": 1,
"export": 0,
"if_owner": 1,
"import": 0,
"permlevel": 0,
"print": 0,
"read": 1,
"report": 0,
"role": "All",
"set_user_permissions": 0,
"share": 0,
"submit": 0,
"user_permission_doctypes": "[\"Email Account\"]",
"write": 0
}
],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"search_fields": "subject",
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "subject",
"track_changes": 1,
"track_seen": 1
}

+ 49
- 0
frappe/core/doctype/activity_log/activity_log.py Voir le fichier

@@ -0,0 +1,49 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, Frappe Technologies and contributors
# For license information, please see license.txt

from __future__ import unicode_literals
from frappe import _
from frappe.utils import get_fullname, now
from frappe.model.document import Document
from frappe.core.utils import get_parent_doc, set_timeline_doc
import frappe

class ActivityLog(Document):
def before_insert(self):
self.full_name = get_fullname(self.user)
self.date = now()

def validate(self):
self.set_status()
set_timeline_doc(self)

def set_status(self):
if not self.is_new():
return

if self.reference_doctype and self.reference_name:
self.status = "Linked"

def on_trash(self): # pylint: disable=no-self-use
frappe.throw(_("Sorry! You cannot delete auto-generated comments"))

def on_doctype_update():
"""Add indexes in `tabActivity Log`"""
frappe.db.add_index("Activity Log", ["reference_doctype", "reference_name"])
frappe.db.add_index("Activity Log", ["timeline_doctype", "timeline_name"])
frappe.db.add_index("Activity Log", ["link_doctype", "link_name"])

def add_authentication_log(subject, user, operation="Login", status="Success"):
frappe.get_doc({
"doctype": "Activity Log",
"user": user,
"status": status,
"subject": subject,
"operation": operation,
}).insert(ignore_permissions=True)

def clear_authentication_logs():
"""clear 100 day old authentication logs"""
frappe.db.sql("""delete from `tabActivity Log` where \
creation<DATE_SUB(NOW(), INTERVAL 100 DAY)""")

frappe/core/doctype/authentication_log/authentication_log_list.js → frappe/core/doctype/activity_log/activity_log_list.js Voir le fichier

@@ -1,4 +1,4 @@
frappe.listview_settings['Authentication Log'] = {
frappe.listview_settings['Activity Log'] = {
get_indicator: function(doc) { get_indicator: function(doc) {
if(doc.operation == "Login" && doc.status == "Success") if(doc.operation == "Login" && doc.status == "Success")
return [__(doc.status), "green"]; return [__(doc.status), "green"];

frappe/core/doctype/communication/feed.py → frappe/core/doctype/activity_log/feed.py Voir le fichier

@@ -4,22 +4,19 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import frappe import frappe
import frappe.permissions import frappe.permissions
from frappe.model.document import Document
from frappe.utils import get_fullname from frappe.utils import get_fullname
from frappe import _ from frappe import _
from frappe.core.doctype.communication.comment import add_info_comment
from frappe.core.doctype.authentication_log.authentication_log import add_authentication_log
from frappe.core.doctype.activity_log.activity_log import add_authentication_log
from six import string_types from six import string_types


def update_feed(doc, method=None): def update_feed(doc, method=None):
"adds a new communication with comment_type='Updated'"
if frappe.flags.in_patch or frappe.flags.in_install or frappe.flags.in_import: if frappe.flags.in_patch or frappe.flags.in_install or frappe.flags.in_import:
return return


if doc._action!="save" or doc.flags.ignore_feed: if doc._action!="save" or doc.flags.ignore_feed:
return return


if doc.doctype == "Communication" or doc.meta.issingle:
if doc.doctype == "Activity Log" or doc.meta.issingle:
return return


if hasattr(doc, "get_feed"): if hasattr(doc, "get_feed"):
@@ -34,16 +31,12 @@ def update_feed(doc, method=None):
name = feed.name or doc.name name = feed.name or doc.name


# delete earlier feed # delete earlier feed
frappe.db.sql("""delete from `tabCommunication`
frappe.db.sql("""delete from `tabActivity Log`
where where
reference_doctype=%s and reference_name=%s reference_doctype=%s and reference_name=%s
and communication_type='Comment'
and comment_type='Updated'""", (doctype, name))

and link_doctype=%s""", (doctype, name,feed.link_doctype))
frappe.get_doc({ frappe.get_doc({
"doctype": "Communication",
"communication_type": "Comment",
"comment_type": "Updated",
"doctype": "Activity Log",
"reference_doctype": doctype, "reference_doctype": doctype,
"reference_name": name, "reference_name": name,
"subject": feed.subject, "subject": feed.subject,
@@ -75,9 +68,9 @@ def get_feed_match_conditions(user=None, force=True):
list(set(can_read) - set(user_permissions.keys()))] list(set(can_read) - set(user_permissions.keys()))]


if can_read_doctypes: if can_read_doctypes:
conditions += ["""(tabCommunication.reference_doctype is null
or tabCommunication.reference_doctype = ''
or tabCommunication.reference_doctype in ({}))""".format(", ".join(can_read_doctypes))]
conditions += ["""(`tabCommunication`.reference_doctype is null
or `tabCommunication`.reference_doctype = ''
or `tabCommunication`.reference_doctype in ({}))""".format(", ".join(can_read_doctypes))]


if user_permissions: if user_permissions:
can_read_docs = [] can_read_docs = []
@@ -86,7 +79,7 @@ def get_feed_match_conditions(user=None, force=True):
can_read_docs.append('"{}|{}"'.format(doctype, frappe.db.escape(n))) can_read_docs.append('"{}|{}"'.format(doctype, frappe.db.escape(n)))


if can_read_docs: if can_read_docs:
conditions.append("concat_ws('|', tabCommunication.reference_doctype, tabCommunication.reference_name) in ({})".format(
conditions.append("concat_ws('|', `tabCommunication`.reference_doctype, `tabCommunication`.reference_name) in ({})".format(
", ".join(can_read_docs))) ", ".join(can_read_docs)))


return "(" + " or ".join(conditions) + ")" return "(" + " or ".join(conditions) + ")"

frappe/core/doctype/authentication_log/test_authentication_log.py → frappe/core/doctype/activity_log/test_activity_log.py Voir le fichier

@@ -6,10 +6,8 @@ from __future__ import unicode_literals
import frappe import frappe
import unittest import unittest


# test_records = frappe.get_test_records('Authentication Log')

class TestAuthenticationLog(unittest.TestCase):
def test_authentication_log(self):
class TestActivityLog(unittest.TestCase):
def test_activity_log(self):
from frappe.auth import LoginManager, CookieManager from frappe.auth import LoginManager, CookieManager


# test user login log # test user login log
@@ -40,10 +38,10 @@ class TestAuthenticationLog(unittest.TestCase):
frappe.local.form_dict = frappe._dict() frappe.local.form_dict = frappe._dict()


def get_auth_log(self, operation='Login'): def get_auth_log(self, operation='Login'):
names = frappe.db.sql_list("""select name from `tabAuthentication Log`
names = frappe.db.sql_list("""select name from `tabActivity Log`
where user='Administrator' and operation='{operation}' order by where user='Administrator' and operation='{operation}' order by
creation desc""".format(operation=operation)) creation desc""".format(operation=operation))


name = names[0] name = names[0]
auth_log = frappe.get_doc('Authentication Log', name)
auth_log = frappe.get_doc('Activity Log', name)
return auth_log return auth_log

+ 0
- 8
frappe/core/doctype/authentication_log/authentication_log.js Voir le fichier

@@ -1,8 +0,0 @@
// Copyright (c) 2016, Frappe Technologies and contributors
// For license information, please see license.txt

frappe.ui.form.on('Authentication Log', {
refresh: function(frm) {

}
});

+ 0
- 341
frappe/core/doctype/authentication_log/authentication_log.json Voir le fichier

@@ -1,341 +0,0 @@
{
"allow_copy": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"creation": "2017-01-23 16:56:25.875531",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "Setup",
"editable_grid": 1,
"engine": "InnoDB",
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "user_details",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "User Details",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "user",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "User",
"length": 0,
"no_copy": 0,
"options": "",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "full_name",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Full Name",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_8",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "date",
"fieldtype": "Datetime",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Date",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_6",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "subject",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Subject",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_2",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "operation",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Operation",
"length": 0,
"no_copy": 0,
"options": "\nLogin\nLogout",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "status",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Status",
"length": 0,
"no_copy": 0,
"options": "\nSuccess\nFailed",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}
],
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 1,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-01-24 14:51:13.726113",
"modified_by": "Administrator",
"module": "Core",
"name": "Authentication Log",
"name_case": "",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "All",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 0
}
],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "subject",
"track_seen": 0
}

+ 0
- 27
frappe/core/doctype/authentication_log/authentication_log.py Voir le fichier

@@ -1,27 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt

from __future__ import unicode_literals
import frappe
from frappe.utils import get_fullname, now
from frappe.model.document import Document

class AuthenticationLog(Document):
def before_insert(self):
self.full_name = get_fullname(self.user)
self.date = now()

def add_authentication_log(subject, user, operation="Login", status="Success"):
frappe.get_doc({
"doctype": "Authentication Log",
"user": user,
"status": status,
"subject": subject,
"operation": operation,
}).insert(ignore_permissions=True)

def clear_authentication_logs():
"""clear 100 day old authentication logs"""
frappe.db.sql("""delete from `tabAuthentication Log` where
creation<DATE_SUB(NOW(), INTERVAL 100 DAY)""")

+ 5
- 5
frappe/core/doctype/communication/communication.json Voir le fichier

@@ -267,7 +267,7 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"depends_on": "eval:in_list([\"Phone\", \"SMS\"], doc.communication_medium)",
"depends_on": "eval:in_list([\"Phone\",\"SMS\"],doc.communication_medium)",
"fieldname": "phone_no", "fieldname": "phone_no",
"fieldtype": "Data", "fieldtype": "Data",
"hidden": 0, "hidden": 0,
@@ -487,12 +487,12 @@
"ignore_xss_filter": 0, "ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_global_search": 0, "in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Comment Type", "label": "Comment Type",
"length": 0, "length": 0,
"no_copy": 0, "no_copy": 0,
"options": "\nComment\nLike\nInfo\nLabel\nWorkflow\nCreated\nUpdated\nSubmitted\nCancelled\nDeleted\nAssigned\nAssignment Completed\nAttachment\nAttachment Removed\nShared\nUnshared\nBot\nRelinked",
"options": "\nComment\nLike\nInfo\nLabel\nWorkflow\nCreated\nSubmitted\nCancelled\nUpdated\nDeleted\nAssigned\nAssignment Completed\nAttachment\nAttachment Removed\nShared\nUnshared\nBot\nRelinked",
"permlevel": 0, "permlevel": 0,
"precision": "", "precision": "",
"print_hide": 0, "print_hide": 0,
@@ -1490,7 +1490,7 @@
"issingle": 0, "issingle": 0,
"istable": 0, "istable": 0,
"max_attachments": 0, "max_attachments": 0,
"modified": "2017-10-25 12:53:49.547620",
"modified": "2017-11-13 12:00:44.238575",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Core", "module": "Core",
"name": "Communication", "name": "Communication",


+ 30
- 30
frappe/core/doctype/communication/communication.py Voir le fichier

@@ -64,7 +64,7 @@ class Communication(Document):
self.set_status() self.set_status()
self.set_sender_full_name() self.set_sender_full_name()
validate_email(self) validate_email(self)
self.set_timeline_doc()
set_timeline_doc(self)


def after_insert(self): def after_insert(self):
if not (self.reference_doctype and self.reference_name): if not (self.reference_doctype and self.reference_name):
@@ -149,35 +149,6 @@ class Communication(Document):
self.sender = sender_email self.sender = sender_email
self.sender_full_name = sender_name or get_fullname(frappe.session.user) if frappe.session.user!='Administrator' else None self.sender_full_name = sender_name or get_fullname(frappe.session.user) if frappe.session.user!='Administrator' else None


def get_parent_doc(self):
"""Returns document of `reference_doctype`, `reference_doctype`"""
if not hasattr(self, "parent_doc"):
if self.reference_doctype and self.reference_name:
self.parent_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
else:
self.parent_doc = None
return self.parent_doc

def set_timeline_doc(self):
"""Set timeline_doctype and timeline_name"""
parent_doc = self.get_parent_doc()
if (self.timeline_doctype and self.timeline_name) or not parent_doc:
return

timeline_field = parent_doc.meta.timeline_field
if not timeline_field:
return

doctype = parent_doc.meta.get_link_doctype(timeline_field)
name = parent_doc.get(timeline_field)

if doctype and name:
self.timeline_doctype = doctype
self.timeline_name = name

else:
return

def send(self, print_html=None, print_format=None, attachments=None, def send(self, print_html=None, print_format=None, attachments=None,
send_me_a_copy=False, recipients=None): send_me_a_copy=False, recipients=None):
"""Send communication via Email. """Send communication via Email.
@@ -253,6 +224,35 @@ class Communication(Document):
if commit: if commit:
frappe.db.commit() frappe.db.commit()


def get_parent_doc(doc):
"""Returns document of `reference_doctype`, `reference_doctype`"""
if not hasattr(doc, "parent_doc"):
if doc.reference_doctype and doc.reference_name:
doc.parent_doc = frappe.get_doc(doc.reference_doctype, doc.reference_name)
else:
doc.parent_doc = None
return doc.parent_doc

def set_timeline_doc(doc):
"""Set timeline_doctype and timeline_name"""
parent_doc = get_parent_doc(doc)
if (doc.timeline_doctype and doc.timeline_name) or not parent_doc:
return

timeline_field = parent_doc.meta.timeline_field
if not timeline_field:
return

doctype = parent_doc.meta.get_link_doctype(timeline_field)
name = parent_doc.get(timeline_field)

if doctype and name:
doc.timeline_doctype = doctype
doc.timeline_name = name

else:
return

def on_doctype_update(): def on_doctype_update():
"""Add indexes in `tabCommunication`""" """Add indexes in `tabCommunication`"""
frappe.db.add_index("Communication", ["reference_doctype", "reference_name"]) frappe.db.add_index("Communication", ["reference_doctype", "reference_name"])


+ 5
- 3
frappe/core/doctype/communication/email.py Voir le fichier

@@ -7,6 +7,7 @@ from six import string_types
import frappe import frappe
import json import json
from email.utils import formataddr from email.utils import formataddr
from frappe.core.utils import get_parent_doc
from frappe.utils import (get_url, get_formatted_email, cint, from frappe.utils import (get_url, get_formatted_email, cint,
validate_email_add, split_emails, time_diff_in_seconds, parse_addr) validate_email_add, split_emails, time_diff_in_seconds, parse_addr)
from frappe.utils.file_manager import get_file from frappe.utils.file_manager import get_file
@@ -175,7 +176,8 @@ def _notify(doc, print_html=None, print_format=None, attachments=None,


def update_parent_mins_to_first_response(doc): def update_parent_mins_to_first_response(doc):
"""Update mins_to_first_communication of parent document based on who is replying.""" """Update mins_to_first_communication of parent document based on who is replying."""
parent = doc.get_parent_doc()

parent = get_parent_doc(doc)
if not parent: if not parent:
return return


@@ -444,7 +446,7 @@ def filter_email_list(doc, email_list, exclude, is_cc=False, is_bcc=False):
return filtered return filtered


def get_owner_email(doc): def get_owner_email(doc):
owner = doc.get_parent_doc().owner
owner = get_parent_doc(doc).owner
return get_formatted_email(owner) or owner return get_formatted_email(owner) or owner


def get_assignees(doc): def get_assignees(doc):
@@ -463,7 +465,7 @@ def get_attach_link(doc, print_format):
"doctype": doc.reference_doctype, "doctype": doc.reference_doctype,
"name": doc.reference_name, "name": doc.reference_name,
"print_format": print_format, "print_format": print_format,
"key": doc.get_parent_doc().get_signature()
"key": get_parent_doc(doc).get_signature()
}) })


def sendmail(communication_name, print_html=None, print_format=None, attachments=None, def sendmail(communication_name, print_html=None, print_format=None, attachments=None,


+ 23
- 0
frappe/core/doctype/communication/test_communication.js Voir le fichier

@@ -0,0 +1,23 @@
/* eslint-disable */
// rename this file from _test_[name] to test_[name] to activate
// and remove above this line

QUnit.test("test: Communication", function (assert) {
let done = assert.async();

// number of asserts
assert.expect(1);

frappe.run_serially([
// insert a new Communication
() => frappe.tests.make('Communication', [
// values to be set
{key: 'value'}
]),
() => {
assert.equal(cur_frm.doc.key, 'value');
},
() => done()
]);

});

+ 34
- 0
frappe/core/utils.py Voir le fichier

@@ -0,0 +1,34 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt

import frappe
from frappe import _

def get_parent_doc(doc):
"""Returns document of `reference_doctype`, `reference_doctype`"""
if not hasattr(doc, "parent_doc"):
if doc.reference_doctype and doc.reference_name:
doc.parent_doc = frappe.get_doc(doc.reference_doctype, doc.reference_name)
else:
doc.parent_doc = None
return doc.parent_doc

def set_timeline_doc(doc):
"""Set timeline_doctype and timeline_name"""
parent_doc = get_parent_doc(doc)
if (doc.timeline_doctype and doc.timeline_name) or not parent_doc:
return

timeline_field = parent_doc.meta.timeline_field
if not timeline_field:
return

doctype = parent_doc.meta.get_link_doctype(timeline_field)
name = parent_doc.get(timeline_field)

if doctype and name:
doc.timeline_doctype = doctype
doc.timeline_name = name

else:
return

+ 13
- 9
frappe/desk/page/activity/activity.py Voir le fichier

@@ -4,25 +4,31 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import frappe import frappe
from frappe.utils import cint from frappe.utils import cint
from frappe.core.doctype.communication.feed import get_feed_match_conditions
from frappe.core.doctype.activity_log.feed import get_feed_match_conditions


@frappe.whitelist() @frappe.whitelist()
def get_feed(start, page_length, show_likes=False): def get_feed(start, page_length, show_likes=False):
"""get feed""" """get feed"""
match_conditions = get_feed_match_conditions(frappe.session.user) match_conditions = get_feed_match_conditions(frappe.session.user)


result = frappe.db.sql("""select name, owner, modified, creation, seen, comment_type,
result = frappe.db.sql("""select X.*
from (select name, owner, modified, creation, seen, comment_type,
reference_doctype, reference_name, link_doctype, link_name, subject, reference_doctype, reference_name, link_doctype, link_name, subject,
communication_type, communication_medium, content communication_type, communication_medium, content
from `tabCommunication`
where
from `tabCommunication`
where
communication_type in ("Communication", "Comment") communication_type in ("Communication", "Comment")
and communication_medium != "Email" and communication_medium != "Email"
and (comment_type is null or comment_type != "Like" and (comment_type is null or comment_type != "Like"
or (comment_type="Like" and (owner=%(user)s or reference_owner=%(user)s))) or (comment_type="Like" and (owner=%(user)s or reference_owner=%(user)s)))
{match_conditions} {match_conditions}
{show_likes} {show_likes}
order by creation desc
union
select name, owner, modified, creation, '0', 'Updated',
reference_doctype, reference_name, link_doctype, link_name, subject,
'Comment', '', content
from `tabActivity Log`) X
order by X.creation DESC
limit %(start)s, %(page_length)s""" limit %(start)s, %(page_length)s"""
.format(match_conditions="and {0}".format(match_conditions) if match_conditions else "", .format(match_conditions="and {0}".format(match_conditions) if match_conditions else "",
show_likes="and comment_type='Like'" if show_likes else ""), show_likes="and comment_type='Like'" if show_likes else ""),
@@ -43,10 +49,8 @@ def get_feed(start, page_length, show_likes=False):
@frappe.whitelist() @frappe.whitelist()
def get_heatmap_data(): def get_heatmap_data():
return dict(frappe.db.sql("""select unix_timestamp(date(creation)), count(name) return dict(frappe.db.sql("""select unix_timestamp(date(creation)), count(name)
from `tabCommunication`
from `tabActivity Log`
where where
communication_type in ("Communication", "Comment")
and communication_medium != "Email"
and date(creation) > subdate(curdate(), interval 1 year)
date(creation) > subdate(curdate(), interval 1 year)
group by date(creation) group by date(creation)
order by creation asc""")) order by creation asc"""))

+ 3
- 3
frappe/hooks.py Voir le fichier

@@ -68,7 +68,7 @@ calendars = ["Event"]
# login # login


on_session_creation = [ on_session_creation = [
"frappe.core.doctype.communication.feed.login_feed",
"frappe.core.doctype.activity_log.feed.login_feed",
"frappe.core.doctype.user.user.notify_admin_access_to_system_manager", "frappe.core.doctype.user.user.notify_admin_access_to_system_manager",
"frappe.limits.check_if_expired", "frappe.limits.check_if_expired",
"frappe.utils.scheduler.reset_enabled_scheduler_events", "frappe.utils.scheduler.reset_enabled_scheduler_events",
@@ -110,7 +110,7 @@ doc_events = {
"*": { "*": {
"on_update": [ "on_update": [
"frappe.desk.notifications.clear_doctype_notifications", "frappe.desk.notifications.clear_doctype_notifications",
"frappe.core.doctype.communication.feed.update_feed"
"frappe.core.doctype.activity_log.feed.update_feed"
], ],
"after_rename": "frappe.desk.notifications.clear_doctype_notifications", "after_rename": "frappe.desk.notifications.clear_doctype_notifications",
"on_cancel": [ "on_cancel": [
@@ -153,7 +153,7 @@ scheduler_events = {
"frappe.utils.scheduler.restrict_scheduler_events_if_dormant", "frappe.utils.scheduler.restrict_scheduler_events_if_dormant",
"frappe.email.doctype.auto_email_report.auto_email_report.send_daily", "frappe.email.doctype.auto_email_report.auto_email_report.send_daily",
"frappe.core.doctype.feedback_request.feedback_request.delete_feedback_request", "frappe.core.doctype.feedback_request.feedback_request.delete_feedback_request",
"frappe.core.doctype.authentication_log.authentication_log.clear_authentication_logs"
"frappe.core.doctype.activity_log.activity_log.clear_authentication_logs"
], ],
"daily_long": [ "daily_long": [
"frappe.integrations.doctype.dropbox_settings.dropbox_settings.take_backups_daily", "frappe.integrations.doctype.dropbox_settings.dropbox_settings.take_backups_daily",


+ 14
- 2
frappe/model/delete_doc.py Voir le fichier

@@ -188,7 +188,7 @@ def check_if_doc_is_linked(doc, method="Delete"):
for item in frappe.db.get_values(link_dt, {link_field:doc.name}, for item in frappe.db.get_values(link_dt, {link_field:doc.name},
["name", "parent", "parenttype", "docstatus"], as_dict=True): ["name", "parent", "parenttype", "docstatus"], as_dict=True):
linked_doctype = item.parenttype if item.parent else link_dt linked_doctype = item.parenttype if item.parent else link_dt
if linked_doctype in ("Communication", "ToDo", "DocShare", "Email Unsubscribe", 'File', 'Version'):
if linked_doctype in ("Communication", "ToDo", "DocShare", "Email Unsubscribe", 'File', 'Version', "Activity Log"):
# don't check for communication and todo! # don't check for communication and todo!
continue continue


@@ -204,7 +204,7 @@ def check_if_doc_is_linked(doc, method="Delete"):
def check_if_doc_is_dynamically_linked(doc, method="Delete"): def check_if_doc_is_dynamically_linked(doc, method="Delete"):
'''Raise `frappe.LinkExistsError` if the document is dynamically linked''' '''Raise `frappe.LinkExistsError` if the document is dynamically linked'''
for df in get_dynamic_link_map().get(doc.doctype, []): for df in get_dynamic_link_map().get(doc.doctype, []):
if df.parent in ("Communication", "ToDo", "DocShare", "Email Unsubscribe", 'File', 'Version'):
if df.parent in ("Communication", "ToDo", "DocShare", "Email Unsubscribe", "Activity Log", 'File', 'Version'):
# don't check for communication and todo! # don't check for communication and todo!
continue continue


@@ -276,6 +276,18 @@ def delete_dynamic_links(doctype, name):
set timeline_doctype=null, timeline_name=null set timeline_doctype=null, timeline_name=null
where timeline_doctype=%s and timeline_name=%s""", (doctype, name)) where timeline_doctype=%s and timeline_name=%s""", (doctype, name))


# unlink activity_log reference_doctype
frappe.db.sql("""update `tabActivity Log`
set reference_doctype=null, reference_name=null
where
reference_doctype=%s
and reference_name=%s""", (doctype, name))

# unlink activity_log timeline_doctype
frappe.db.sql("""update `tabActivity Log`
set timeline_doctype=null, timeline_name=null
where timeline_doctype=%s and timeline_name=%s""", (doctype, name))

def insert_feed(doc): def insert_feed(doc):
from frappe.utils import get_fullname from frappe.utils import get_fullname




+ 2
- 1
frappe/patches.txt Voir le fichier

@@ -197,4 +197,5 @@ frappe.patches.v8_10.delete_static_web_page_from_global_search
frappe.patches.v8_x.add_bgn_xaf_xof_currencies frappe.patches.v8_x.add_bgn_xaf_xof_currencies
frappe.patches.v9_1.add_sms_sender_name_as_parameters frappe.patches.v9_1.add_sms_sender_name_as_parameters
frappe.patches.v9_1.resave_domain_settings frappe.patches.v9_1.resave_domain_settings
frappe.patches.v9_1.revert_domain_settings
frappe.patches.v9_1.revert_domain_settings
frappe.patches.v9_1.move_feed_to_activity_log

+ 25
- 0
frappe/patches/v9_1/move_feed_to_activity_log.py Voir le fichier

@@ -0,0 +1,25 @@
import frappe

def execute():
frappe.reload_doc("core", "doctype", "communication")
frappe.reload_doc("core", "doctype", "activity_log")

communication_data = frappe.get_all('Communication', filters= {'comment_type': 'Updated'})
activity_log_fields = frappe.get_meta('Activity Log').fields

for d in communication_data:
communication_doc = frappe.get_doc('Communication', d)

activity_data = {'doctype': 'Activity Log'}
for field in activity_log_fields:
if communication_doc.get(field.fieldname):
activity_data[field.fieldname] = communication_doc.get_value(field.fieldname)

activity_doc = frappe.get_doc(activity_data)
activity_doc.insert()

frappe.db.sql("""update `tabActivity Log` set creation = %s,\
modified = %s where name = %s""", (communication_doc.creation,communication_doc.modified,activity_doc.name))

frappe.db.sql("""delete from `tabCommunication` where name='{0}'""".format(communication_doc.name))
frappe.delete_doc("DocType", "Authentication Log")

+ 1
- 1
frappe/sessions.py Voir le fichier

@@ -101,7 +101,7 @@ def get_sessions_to_clear(user=None, keep_current=False, device=None):
(user, device)) (user, device))


def delete_session(sid=None, user=None, reason="Session Expired"): def delete_session(sid=None, user=None, reason="Session Expired"):
from frappe.core.doctype.communication.feed import logout_feed
from frappe.core.doctype.activity_log.feed import logout_feed


frappe.cache().hdel("session", sid) frappe.cache().hdel("session", sid)
frappe.cache().hdel("last_db_session_update", sid) frappe.cache().hdel("last_db_session_update", sid)


+ 1
- 1
frappe/tests/ui/tests.txt Voir le fichier

@@ -17,4 +17,4 @@ frappe/core/doctype/role_profile/test_role_profile.js
frappe/core/doctype/user/test_user_with_role_profile.js frappe/core/doctype/user/test_user_with_role_profile.js
frappe/tests/ui/test_list_count.js frappe/tests/ui/test_list_count.js
frappe/workflow/doctype/workflow/tests/test_workflow_create.js frappe/workflow/doctype/workflow/tests/test_workflow_create.js
frappe/workflow/doctype/workflow/tests/test_workflow_test.js
frappe/workflow/doctype/workflow/tests/test_workflow_test.js

Chargement…
Annuler
Enregistrer