diff --git a/crm/api/__init__.py b/crm/api/__init__.py index 141da446..58739de0 100644 --- a/crm/api/__init__.py +++ b/crm/api/__init__.py @@ -3,6 +3,7 @@ import frappe from frappe.translate import get_all_translations from frappe.utils import validate_email_address, split_emails, cstr from frappe.utils.telemetry import POSTHOG_HOST_FIELD, POSTHOG_PROJECT_FIELD +from frappe.core.api.file import get_max_file_size @frappe.whitelist(allow_guest=True) @@ -107,3 +108,20 @@ def invite_by_email(emails: str, role: str): for email in to_invite: frappe.get_doc(doctype="CRM Invitation", email=email, role=role).insert(ignore_permissions=True) + + +@frappe.whitelist() +def get_file_uploader_defaults(doctype: str): + max_number_of_files = None + make_attachments_public = False + if doctype: + meta = frappe.get_meta(doctype) + max_number_of_files = meta.get("max_attachments") + make_attachments_public = meta.get("make_attachments_public") + + return { + 'allowed_file_types': frappe.get_system_settings("allowed_file_extensions"), + 'max_file_size': get_max_file_size(), + 'max_number_of_files': max_number_of_files, + 'make_attachments_public': bool(make_attachments_public), + } \ No newline at end of file diff --git a/crm/api/activities.py b/crm/api/activities.py index 31d74580..8cc714eb 100644 --- a/crm/api/activities.py +++ b/crm/api/activities.py @@ -1,5 +1,6 @@ import json +from bs4 import BeautifulSoup import frappe from frappe import _ from frappe.utils.caching import redis_cache @@ -35,10 +36,11 @@ def get_deal_activities(name): calls = [] notes = [] tasks = [] + attachments = [] creation_text = "created this deal" if lead: - activities, calls, notes, tasks = get_lead_activities(lead) + activities, calls, notes, tasks, attachments = get_lead_activities(lead) creation_text = "converted the lead to this deal" activities.append({ @@ -131,14 +133,26 @@ def get_deal_activities(name): } activities.append(activity) + for attachment_log in docinfo.attachment_logs: + activity = { + "name": attachment_log.name, + "activity_type": "attachment_log", + "creation": attachment_log.creation, + "owner": attachment_log.owner, + "data": parse_attachment_log(attachment_log.content, attachment_log.comment_type), + "is_lead": False, + } + activities.append(activity) + calls = calls + get_linked_calls(name) notes = notes + get_linked_notes(name) tasks = tasks + get_linked_tasks(name) + attachments = attachments + get_attachments('CRM Deal', name) activities.sort(key=lambda x: x["creation"], reverse=True) activities = handle_multiple_versions(activities) - return activities, calls, notes, tasks + return activities, calls, notes, tasks, attachments def get_lead_activities(name): get_docinfo('', "CRM Lead", name) @@ -245,22 +259,34 @@ def get_lead_activities(name): } activities.append(activity) + for attachment_log in docinfo.attachment_logs: + activity = { + "name": attachment_log.name, + "activity_type": "attachment_log", + "creation": attachment_log.creation, + "owner": attachment_log.owner, + "data": parse_attachment_log(attachment_log.content, attachment_log.comment_type), + "is_lead": True, + } + activities.append(activity) + calls = get_linked_calls(name) notes = get_linked_notes(name) tasks = get_linked_tasks(name) + attachments = get_attachments('CRM Lead', name) activities.sort(key=lambda x: x["creation"], reverse=True) activities = handle_multiple_versions(activities) - return activities, calls, notes, tasks + return activities, calls, notes, tasks, attachments + -@redis_cache() def get_attachments(doctype, name): return frappe.db.get_all( "File", filters={"attached_to_doctype": doctype, "attached_to_name": name}, - fields=["name", "file_name", "file_url", "file_size", "is_private"], - ) + fields=["name", "file_name", "file_type", "file_url", "file_size", "is_private", "creation", "owner"], + ) or [] def handle_multiple_versions(versions): activities = [] @@ -342,3 +368,26 @@ def get_linked_tasks(name): ], ) return tasks or [] + +def parse_attachment_log(html, type): + soup = BeautifulSoup(html, "html.parser") + a_tag = soup.find("a") + type = "added" if type == "Attachment" else "removed" + if not a_tag: + return { + "type": type, + "file_name": html.replace("Removed ", ""), + "file_url": "", + "is_private": False, + } + + is_private = False + if "private/files" in a_tag["href"]: + is_private = True + + return { + "type": type, + "file_name": a_tag.text, + "file_url": a_tag["href"], + "is_private": is_private, + } \ No newline at end of file diff --git a/crm/api/whatsapp.py b/crm/api/whatsapp.py index 1a0f52fd..a38c1194 100644 --- a/crm/api/whatsapp.py +++ b/crm/api/whatsapp.py @@ -103,7 +103,41 @@ def is_whatsapp_installed(): def get_whatsapp_messages(reference_doctype, reference_name): if not frappe.db.exists("DocType", "WhatsApp Message"): return [] - messages = frappe.get_all( + messages = [] + + if reference_doctype == 'CRM Deal': + lead = frappe.db.get_value(reference_doctype, reference_name, 'lead') + if lead: + messages = frappe.get_all( + "WhatsApp Message", + filters={ + "reference_doctype": "CRM Lead", + "reference_name": lead, + }, + fields=[ + "name", + "type", + "to", + "from", + "content_type", + "message_type", + "attach", + "template", + "use_template", + "message_id", + "is_reply", + "reply_to_message_id", + "creation", + "message", + "status", + "reference_doctype", + "reference_name", + "template_parameters", + "template_header_parameters", + ], + ) + + messages += frappe.get_all( "WhatsApp Message", filters={ "reference_doctype": reference_doctype, diff --git a/crm/fcrm/doctype/crm_call_log/test_crm_call_log.py b/crm/fcrm/doctype/crm_call_log/test_crm_call_log.py index 9c8198a4..34fe2bae 100644 --- a/crm/fcrm/doctype/crm_call_log/test_crm_call_log.py +++ b/crm/fcrm/doctype/crm_call_log/test_crm_call_log.py @@ -2,8 +2,8 @@ # See license.txt # import frappe -from frappe.tests.utils import FrappeTestCase +from frappe.tests import UnitTestCase -class TestCRMCallLog(FrappeTestCase): +class TestCRMCallLog(UnitTestCase): pass diff --git a/crm/fcrm/doctype/crm_communication_status/test_crm_communication_status.py b/crm/fcrm/doctype/crm_communication_status/test_crm_communication_status.py index 85f289cc..bf5b69e2 100644 --- a/crm/fcrm/doctype/crm_communication_status/test_crm_communication_status.py +++ b/crm/fcrm/doctype/crm_communication_status/test_crm_communication_status.py @@ -2,8 +2,8 @@ # See license.txt # import frappe -from frappe.tests.utils import FrappeTestCase +from frappe.tests import UnitTestCase -class TestCRMCommunicationStatus(FrappeTestCase): +class TestCRMCommunicationStatus(UnitTestCase): pass diff --git a/crm/fcrm/doctype/crm_deal/test_crm_deal.py b/crm/fcrm/doctype/crm_deal/test_crm_deal.py index b9ecc378..85ef9331 100644 --- a/crm/fcrm/doctype/crm_deal/test_crm_deal.py +++ b/crm/fcrm/doctype/crm_deal/test_crm_deal.py @@ -2,8 +2,8 @@ # See license.txt # import frappe -from frappe.tests.utils import FrappeTestCase +from frappe.tests import UnitTestCase -class TestCRMDeal(FrappeTestCase): +class TestCRMDeal(UnitTestCase): pass diff --git a/crm/fcrm/doctype/crm_deal_status/test_crm_deal_status.py b/crm/fcrm/doctype/crm_deal_status/test_crm_deal_status.py index b5463dc1..4e60b78d 100644 --- a/crm/fcrm/doctype/crm_deal_status/test_crm_deal_status.py +++ b/crm/fcrm/doctype/crm_deal_status/test_crm_deal_status.py @@ -2,8 +2,8 @@ # See license.txt # import frappe -from frappe.tests.utils import FrappeTestCase +from frappe.tests import UnitTestCase -class TestCRMDealStatus(FrappeTestCase): +class TestCRMDealStatus(UnitTestCase): pass diff --git a/crm/fcrm/doctype/crm_fields_layout/test_crm_fields_layout.py b/crm/fcrm/doctype/crm_fields_layout/test_crm_fields_layout.py index bdc71c0a..6ea73d02 100644 --- a/crm/fcrm/doctype/crm_fields_layout/test_crm_fields_layout.py +++ b/crm/fcrm/doctype/crm_fields_layout/test_crm_fields_layout.py @@ -2,8 +2,8 @@ # See license.txt # import frappe -from frappe.tests.utils import FrappeTestCase +from frappe.tests import UnitTestCase -class TestCRMFieldsLayout(FrappeTestCase): +class TestCRMFieldsLayout(UnitTestCase): pass diff --git a/crm/fcrm/doctype/crm_form_script/test_crm_form_script.py b/crm/fcrm/doctype/crm_form_script/test_crm_form_script.py index ae222e72..f5e8d982 100644 --- a/crm/fcrm/doctype/crm_form_script/test_crm_form_script.py +++ b/crm/fcrm/doctype/crm_form_script/test_crm_form_script.py @@ -2,8 +2,8 @@ # See license.txt # import frappe -from frappe.tests.utils import FrappeTestCase +from frappe.tests import UnitTestCase -class TestCRMFormScript(FrappeTestCase): +class TestCRMFormScript(UnitTestCase): pass diff --git a/crm/fcrm/doctype/crm_holiday_list/test_crm_holiday_list.py b/crm/fcrm/doctype/crm_holiday_list/test_crm_holiday_list.py index 87754859..ee90dc8a 100644 --- a/crm/fcrm/doctype/crm_holiday_list/test_crm_holiday_list.py +++ b/crm/fcrm/doctype/crm_holiday_list/test_crm_holiday_list.py @@ -2,8 +2,8 @@ # See license.txt # import frappe -from frappe.tests.utils import FrappeTestCase +from frappe.tests import UnitTestCase -class TestCRMHolidayList(FrappeTestCase): +class TestCRMHolidayList(UnitTestCase): pass diff --git a/crm/fcrm/doctype/crm_industry/test_crm_industry.py b/crm/fcrm/doctype/crm_industry/test_crm_industry.py index 8d23632d..16d87b13 100644 --- a/crm/fcrm/doctype/crm_industry/test_crm_industry.py +++ b/crm/fcrm/doctype/crm_industry/test_crm_industry.py @@ -2,8 +2,8 @@ # See license.txt # import frappe -from frappe.tests.utils import FrappeTestCase +from frappe.tests import UnitTestCase -class TestCRMIndustry(FrappeTestCase): +class TestCRMIndustry(UnitTestCase): pass diff --git a/crm/fcrm/doctype/crm_invitation/test_crm_invitation.py b/crm/fcrm/doctype/crm_invitation/test_crm_invitation.py index e2b3dc24..ddee0e24 100644 --- a/crm/fcrm/doctype/crm_invitation/test_crm_invitation.py +++ b/crm/fcrm/doctype/crm_invitation/test_crm_invitation.py @@ -2,8 +2,8 @@ # See license.txt # import frappe -from frappe.tests.utils import FrappeTestCase +from frappe.tests import UnitTestCase -class TestCRMInvitation(FrappeTestCase): +class TestCRMInvitation(UnitTestCase): pass diff --git a/crm/fcrm/doctype/crm_lead/test_crm_lead.py b/crm/fcrm/doctype/crm_lead/test_crm_lead.py index 73a71202..e730792e 100644 --- a/crm/fcrm/doctype/crm_lead/test_crm_lead.py +++ b/crm/fcrm/doctype/crm_lead/test_crm_lead.py @@ -2,8 +2,8 @@ # See license.txt # import frappe -from frappe.tests.utils import FrappeTestCase +from frappe.tests import UnitTestCase -class TestCRMLead(FrappeTestCase): +class TestCRMLead(UnitTestCase): pass diff --git a/crm/fcrm/doctype/crm_lead_source/test_crm_lead_source.py b/crm/fcrm/doctype/crm_lead_source/test_crm_lead_source.py index eb9f2c6a..31d37917 100644 --- a/crm/fcrm/doctype/crm_lead_source/test_crm_lead_source.py +++ b/crm/fcrm/doctype/crm_lead_source/test_crm_lead_source.py @@ -2,8 +2,8 @@ # See license.txt # import frappe -from frappe.tests.utils import FrappeTestCase +from frappe.tests import UnitTestCase -class TestCRMLeadSource(FrappeTestCase): +class TestCRMLeadSource(UnitTestCase): pass diff --git a/crm/fcrm/doctype/crm_lead_status/test_crm_lead_status.py b/crm/fcrm/doctype/crm_lead_status/test_crm_lead_status.py index 9cb24fd4..d542056a 100644 --- a/crm/fcrm/doctype/crm_lead_status/test_crm_lead_status.py +++ b/crm/fcrm/doctype/crm_lead_status/test_crm_lead_status.py @@ -2,8 +2,8 @@ # See license.txt # import frappe -from frappe.tests.utils import FrappeTestCase +from frappe.tests import UnitTestCase -class TestCRMLeadStatus(FrappeTestCase): +class TestCRMLeadStatus(UnitTestCase): pass diff --git a/crm/fcrm/doctype/crm_notification/test_crm_notification.py b/crm/fcrm/doctype/crm_notification/test_crm_notification.py index e643a91d..466bad4d 100644 --- a/crm/fcrm/doctype/crm_notification/test_crm_notification.py +++ b/crm/fcrm/doctype/crm_notification/test_crm_notification.py @@ -2,8 +2,8 @@ # See license.txt # import frappe -from frappe.tests.utils import FrappeTestCase +from frappe.tests import UnitTestCase -class TestCRMNotification(FrappeTestCase): +class TestCRMNotification(UnitTestCase): pass diff --git a/crm/fcrm/doctype/crm_organization/test_crm_organization.py b/crm/fcrm/doctype/crm_organization/test_crm_organization.py index e11be575..e8066754 100644 --- a/crm/fcrm/doctype/crm_organization/test_crm_organization.py +++ b/crm/fcrm/doctype/crm_organization/test_crm_organization.py @@ -2,8 +2,8 @@ # See license.txt # import frappe -from frappe.tests.utils import FrappeTestCase +from frappe.tests import UnitTestCase -class TestCRMOrganization(FrappeTestCase): +class TestCRMOrganization(UnitTestCase): pass diff --git a/crm/fcrm/doctype/crm_service_level_agreement/test_crm_service_level_agreement.py b/crm/fcrm/doctype/crm_service_level_agreement/test_crm_service_level_agreement.py index 40e2555e..bf6ae587 100644 --- a/crm/fcrm/doctype/crm_service_level_agreement/test_crm_service_level_agreement.py +++ b/crm/fcrm/doctype/crm_service_level_agreement/test_crm_service_level_agreement.py @@ -2,8 +2,8 @@ # See license.txt # import frappe -from frappe.tests.utils import FrappeTestCase +from frappe.tests import UnitTestCase -class TestCRMServiceLevelAgreement(FrappeTestCase): +class TestCRMServiceLevelAgreement(UnitTestCase): pass diff --git a/crm/fcrm/doctype/crm_service_level_priority/test_crm_service_level_priority.py b/crm/fcrm/doctype/crm_service_level_priority/test_crm_service_level_priority.py index f1f5448b..89f9c4e3 100644 --- a/crm/fcrm/doctype/crm_service_level_priority/test_crm_service_level_priority.py +++ b/crm/fcrm/doctype/crm_service_level_priority/test_crm_service_level_priority.py @@ -2,8 +2,8 @@ # See license.txt # import frappe -from frappe.tests.utils import FrappeTestCase +from frappe.tests import UnitTestCase -class TestCRMServiceLevelPriority(FrappeTestCase): +class TestCRMServiceLevelPriority(UnitTestCase): pass diff --git a/crm/fcrm/doctype/crm_task/test_crm_task.py b/crm/fcrm/doctype/crm_task/test_crm_task.py index f8316336..d632cebe 100644 --- a/crm/fcrm/doctype/crm_task/test_crm_task.py +++ b/crm/fcrm/doctype/crm_task/test_crm_task.py @@ -2,8 +2,8 @@ # See license.txt # import frappe -from frappe.tests.utils import FrappeTestCase +from frappe.tests import UnitTestCase -class TestCRMTask(FrappeTestCase): +class TestCRMTask(UnitTestCase): pass diff --git a/crm/fcrm/doctype/crm_territory/test_crm_territory.py b/crm/fcrm/doctype/crm_territory/test_crm_territory.py index 475707fd..c1315d94 100644 --- a/crm/fcrm/doctype/crm_territory/test_crm_territory.py +++ b/crm/fcrm/doctype/crm_territory/test_crm_territory.py @@ -2,8 +2,8 @@ # See license.txt # import frappe -from frappe.tests.utils import FrappeTestCase +from frappe.tests import UnitTestCase -class TestCRMTerritory(FrappeTestCase): +class TestCRMTerritory(UnitTestCase): pass diff --git a/crm/fcrm/doctype/crm_view_settings/test_crm_view_settings.py b/crm/fcrm/doctype/crm_view_settings/test_crm_view_settings.py index cd6df2d7..1d002a30 100644 --- a/crm/fcrm/doctype/crm_view_settings/test_crm_view_settings.py +++ b/crm/fcrm/doctype/crm_view_settings/test_crm_view_settings.py @@ -2,8 +2,8 @@ # See license.txt # import frappe -from frappe.tests.utils import FrappeTestCase +from frappe.tests import UnitTestCase -class TestCRMViewSettings(FrappeTestCase): +class TestCRMViewSettings(UnitTestCase): pass diff --git a/crm/fcrm/doctype/erpnext_crm_settings/test_erpnext_crm_settings.py b/crm/fcrm/doctype/erpnext_crm_settings/test_erpnext_crm_settings.py index 17ae0284..937b9ef7 100644 --- a/crm/fcrm/doctype/erpnext_crm_settings/test_erpnext_crm_settings.py +++ b/crm/fcrm/doctype/erpnext_crm_settings/test_erpnext_crm_settings.py @@ -2,8 +2,8 @@ # See license.txt # import frappe -from frappe.tests.utils import FrappeTestCase +from frappe.tests import UnitTestCase -class TestERPNextCRMSettings(FrappeTestCase): +class TestERPNextCRMSettings(UnitTestCase): pass diff --git a/crm/fcrm/doctype/fcrm_note/test_fcrm_note.py b/crm/fcrm/doctype/fcrm_note/test_fcrm_note.py index 86635b28..6a98a6ff 100644 --- a/crm/fcrm/doctype/fcrm_note/test_fcrm_note.py +++ b/crm/fcrm/doctype/fcrm_note/test_fcrm_note.py @@ -2,8 +2,8 @@ # See license.txt # import frappe -from frappe.tests.utils import FrappeTestCase +from frappe.tests import UnitTestCase -class TestFCRMNote(FrappeTestCase): +class TestFCRMNote(UnitTestCase): pass diff --git a/crm/fcrm/doctype/fcrm_settings/__init__.py b/crm/fcrm/doctype/fcrm_settings/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/crm/fcrm/doctype/fcrm_settings/fcrm_settings.js b/crm/fcrm/doctype/fcrm_settings/fcrm_settings.js new file mode 100644 index 00000000..4264130f --- /dev/null +++ b/crm/fcrm/doctype/fcrm_settings/fcrm_settings.js @@ -0,0 +1,42 @@ +// Copyright (c) 2024, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on("FCRM Settings", { + // refresh(frm) { + + // }, + restore_defaults: function (frm) { + let message = __( + "This will restore (if not exist) all the default statuses, custom fields and layouts. Delete & Restore will delete default layouts and then restore them." + ); + let d = new frappe.ui.Dialog({ + title: __("Restore Defaults"), + primary_action_label: __("Restore"), + primary_action: () => { + frm.call("restore_defaults", { force: false }, () => { + frappe.show_alert({ + message: __( + "Default statuses, custom fields and layouts restored successfully." + ), + indicator: "green", + }); + }); + d.hide(); + }, + secondary_action_label: __("Delete & Restore"), + secondary_action: () => { + frm.call("restore_defaults", { force: true }, () => { + frappe.show_alert({ + message: __( + "Default statuses, custom fields and layouts restored successfully." + ), + indicator: "green", + }); + }); + d.hide(); + }, + }); + d.show(); + d.set_message(message); + }, +}); diff --git a/crm/fcrm/doctype/fcrm_settings/fcrm_settings.json b/crm/fcrm/doctype/fcrm_settings/fcrm_settings.json new file mode 100644 index 00000000..c76784ae --- /dev/null +++ b/crm/fcrm/doctype/fcrm_settings/fcrm_settings.json @@ -0,0 +1,40 @@ +{ + "actions": [], + "allow_rename": 1, + "creation": "2024-09-29 13:48:02.715924", + "doctype": "DocType", + "engine": "InnoDB", + "field_order": [ + "restore_defaults" + ], + "fields": [ + { + "fieldname": "restore_defaults", + "fieldtype": "Button", + "label": "Restore Defaults" + } + ], + "index_web_pages_for_search": 1, + "issingle": 1, + "links": [], + "modified": "2024-09-29 13:49:07.835379", + "modified_by": "Administrator", + "module": "FCRM", + "name": "FCRM Settings", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "print": 1, + "read": 1, + "role": "System Manager", + "share": 1, + "write": 1 + } + ], + "sort_field": "creation", + "sort_order": "DESC", + "states": [] +} \ No newline at end of file diff --git a/crm/fcrm/doctype/fcrm_settings/fcrm_settings.py b/crm/fcrm/doctype/fcrm_settings/fcrm_settings.py new file mode 100644 index 00000000..65e6d6f3 --- /dev/null +++ b/crm/fcrm/doctype/fcrm_settings/fcrm_settings.py @@ -0,0 +1,12 @@ +# Copyright (c) 2024, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +import frappe +from frappe.model.document import Document +from crm.install import after_install + + +class FCRMSettings(Document): + @frappe.whitelist() + def restore_defaults(self, force=False): + after_install(force) diff --git a/crm/fcrm/doctype/fcrm_settings/test_fcrm_settings.py b/crm/fcrm/doctype/fcrm_settings/test_fcrm_settings.py new file mode 100644 index 00000000..8e626f3e --- /dev/null +++ b/crm/fcrm/doctype/fcrm_settings/test_fcrm_settings.py @@ -0,0 +1,9 @@ +# Copyright (c) 2024, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt + +# import frappe +from frappe.tests import UnitTestCase + + +class TestFCRMSettings(UnitTestCase): + pass diff --git a/crm/fcrm/doctype/twilio_agents/test_twilio_agents.py b/crm/fcrm/doctype/twilio_agents/test_twilio_agents.py index 72cdd5cc..29ecc305 100644 --- a/crm/fcrm/doctype/twilio_agents/test_twilio_agents.py +++ b/crm/fcrm/doctype/twilio_agents/test_twilio_agents.py @@ -2,8 +2,8 @@ # See license.txt # import frappe -from frappe.tests.utils import FrappeTestCase +from frappe.tests import UnitTestCase -class TestTwilioAgents(FrappeTestCase): +class TestTwilioAgents(UnitTestCase): pass diff --git a/crm/fcrm/doctype/twilio_settings/test_twilio_settings.py b/crm/fcrm/doctype/twilio_settings/test_twilio_settings.py index 095e747e..21b03841 100644 --- a/crm/fcrm/doctype/twilio_settings/test_twilio_settings.py +++ b/crm/fcrm/doctype/twilio_settings/test_twilio_settings.py @@ -2,8 +2,8 @@ # See license.txt # import frappe -from frappe.tests.utils import FrappeTestCase +from frappe.tests import UnitTestCase -class TestTwilioSettings(FrappeTestCase): +class TestTwilioSettings(UnitTestCase): pass diff --git a/crm/install.py b/crm/install.py index ec196f8b..da660f78 100644 --- a/crm/install.py +++ b/crm/install.py @@ -9,11 +9,11 @@ from frappe.custom.doctype.custom_field.custom_field import create_custom_fields def before_install(): pass -def after_install(): +def after_install(force=False): add_default_lead_statuses() add_default_deal_statuses() add_default_communication_statuses() - add_default_fields_layout() + add_default_fields_layout(force) add_property_setter() add_email_template_custom_fields() add_default_industries() @@ -111,7 +111,7 @@ def add_default_communication_statuses(): doc.status = status doc.insert() -def add_default_fields_layout(): +def add_default_fields_layout(force=False): quick_entry_layouts = { "CRM Lead-Quick Entry": { "doctype": "CRM Lead", @@ -148,7 +148,10 @@ def add_default_fields_layout(): for layout in quick_entry_layouts: if frappe.db.exists("CRM Fields Layout", layout): - continue + if force: + frappe.delete_doc("CRM Fields Layout", layout) + else: + continue doc = frappe.new_doc("CRM Fields Layout") doc.type = "Quick Entry" @@ -158,7 +161,10 @@ def add_default_fields_layout(): for layout in sidebar_fields_layouts: if frappe.db.exists("CRM Fields Layout", layout): - continue + if force: + frappe.delete_doc("CRM Fields Layout", layout) + else: + continue doc = frappe.new_doc("CRM Fields Layout") doc.type = "Side Panel" @@ -217,7 +223,6 @@ def add_default_industries(): def add_default_lead_sources(): - lead_sources = ["Existing Customer", "Reference", "Advertisement", "Cold Calling", "Exhibition", "Supplier Reference", "Mass Mailing", "Customer's Vendor", "Campaign", "Walk In"] for source in lead_sources: diff --git a/crm/www/crm.py b/crm/www/crm.py index 44347cf3..22b2ed58 100644 --- a/crm/www/crm.py +++ b/crm/www/crm.py @@ -9,11 +9,9 @@ no_cache = 1 def get_context(): - csrf_token = frappe.sessions.get_csrf_token() frappe.db.commit() context = frappe._dict() context.boot = get_boot() - context.boot.csrf_token = csrf_token if frappe.session.user != "Guest": capture("active_site", "crm") return context @@ -33,6 +31,7 @@ def get_boot(): "default_route": get_default_route(), "site_name": frappe.local.site, "read_only_mode": frappe.flags.read_only, + "csrf_token": frappe.sessions.get_csrf_token(), } ) diff --git a/frappe-ui b/frappe-ui index 427b7618..b2dbd419 160000 --- a/frappe-ui +++ b/frappe-ui @@ -1 +1 @@ -Subproject commit 427b76188fe8b20e683bccf9bb4003821253259f +Subproject commit b2dbd41936905aa46b18d3c22e5d09a7b08a9b98 diff --git a/frontend/package.json b/frontend/package.json index 18861947..56683963 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -14,7 +14,7 @@ "@vueuse/core": "^10.3.0", "@vueuse/integrations": "^10.3.0", "feather-icons": "^4.28.0", - "frappe-ui": "^0.1.70", + "frappe-ui": "^0.1.71", "gemoji": "^8.1.0", "lodash": "^4.17.21", "mime": "^4.0.1", diff --git a/frontend/src/components/Activities/Activities.vue b/frontend/src/components/Activities/Activities.vue index 55e6fae5..f4613998 100644 --- a/frontend/src/components/Activities/Activities.vue +++ b/frontend/src/components/Activities/Activities.vue @@ -2,6 +2,7 @@ -
- +
+
@@ -103,6 +95,15 @@
+
+ +
+
+
+
+ {{ activity.owner_name }} + {{ __(activity.data.type) }} + + {{ activity.data.file_name }} + + {{ activity.data.file_name }} + +
+
+ +
+ {{ __(timeAgo(activity.creation)) }} +
+
+
+
+
+
@@ -395,6 +435,18 @@ :doctype="doctype" :doc="doc" /> + diff --git a/frontend/src/components/Activities/ActivityHeader.vue b/frontend/src/components/Activities/ActivityHeader.vue index 60a70898..9f734d4e 100644 --- a/frontend/src/components/Activities/ActivityHeader.vue +++ b/frontend/src/components/Activities/ActivityHeader.vue @@ -55,6 +55,16 @@ {{ __('New Task') }} +