diff --git a/crm/api/session.py b/crm/api/session.py index c5fb5c4e..368a272c 100644 --- a/crm/api/session.py +++ b/crm/api/session.py @@ -30,4 +30,18 @@ def get_contacts(): distinct=True, ).run(as_dict=1) - return contacts \ No newline at end of file + return contacts + +@frappe.whitelist() +def get_organizations(): + if frappe.session.user == "Guest": + frappe.throw("Authentication failed", exc=frappe.AuthenticationError) + + organizations = frappe.qb.get_query( + "CRM Organization", + fields=['name', 'organization_logo', 'website'], + order_by="name asc", + distinct=True, + ).run(as_dict=1) + + return organizations diff --git a/crm/fcrm/doctype/crm_organization/__init__.py b/crm/fcrm/doctype/crm_organization/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/crm/fcrm/doctype/crm_organization/crm_organization.js b/crm/fcrm/doctype/crm_organization/crm_organization.js new file mode 100644 index 00000000..763952d1 --- /dev/null +++ b/crm/fcrm/doctype/crm_organization/crm_organization.js @@ -0,0 +1,8 @@ +// Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +// frappe.ui.form.on("CRM Organization", { +// refresh(frm) { + +// }, +// }); diff --git a/crm/fcrm/doctype/crm_organization/crm_organization.json b/crm/fcrm/doctype/crm_organization/crm_organization.json new file mode 100644 index 00000000..d58e76aa --- /dev/null +++ b/crm/fcrm/doctype/crm_organization/crm_organization.json @@ -0,0 +1,57 @@ +{ + "actions": [], + "allow_rename": 1, + "autoname": "field:organization_name", + "creation": "2023-11-03 16:23:59.341751", + "doctype": "DocType", + "engine": "InnoDB", + "field_order": [ + "organization_name", + "website", + "organization_logo" + ], + "fields": [ + { + "fieldname": "organization_name", + "fieldtype": "Data", + "label": "Organization Name", + "unique": 1 + }, + { + "fieldname": "website", + "fieldtype": "Data", + "label": "Website" + }, + { + "fieldname": "organization_logo", + "fieldtype": "Attach Image", + "label": "Organization Logo" + } + ], + "image_field": "organization_logo", + "index_web_pages_for_search": 1, + "links": [], + "modified": "2023-11-03 16:25:25.366741", + "modified_by": "Administrator", + "module": "FCRM", + "name": "CRM Organization", + "naming_rule": "By fieldname", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + } + ], + "sort_field": "modified", + "sort_order": "DESC", + "states": [] +} \ No newline at end of file diff --git a/crm/fcrm/doctype/crm_organization/crm_organization.py b/crm/fcrm/doctype/crm_organization/crm_organization.py new file mode 100644 index 00000000..5933eabf --- /dev/null +++ b/crm/fcrm/doctype/crm_organization/crm_organization.py @@ -0,0 +1,9 @@ +# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + + +class CRMOrganization(Document): + pass diff --git a/crm/fcrm/doctype/crm_organization/test_crm_organization.py b/crm/fcrm/doctype/crm_organization/test_crm_organization.py new file mode 100644 index 00000000..e11be575 --- /dev/null +++ b/crm/fcrm/doctype/crm_organization/test_crm_organization.py @@ -0,0 +1,9 @@ +# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt + +# import frappe +from frappe.tests.utils import FrappeTestCase + + +class TestCRMOrganization(FrappeTestCase): + pass diff --git a/crm/fcrm/doctype/twilio_settings/twilio_settings.json b/crm/fcrm/doctype/twilio_settings/twilio_settings.json index ed3aa43f..8aef9749 100644 --- a/crm/fcrm/doctype/twilio_settings/twilio_settings.json +++ b/crm/fcrm/doctype/twilio_settings/twilio_settings.json @@ -7,6 +7,7 @@ "editable_grid": 1, "engine": "InnoDB", "field_order": [ + "section_break_malx", "account_sid", "api_key", "api_secret", @@ -14,8 +15,9 @@ "auth_token", "twiml_sid", "section_break_ssqj", - "record_calls", - "column_break_avmt" + "enabled", + "column_break_avmt", + "record_calls" ], "fields": [ { @@ -23,7 +25,7 @@ "fieldtype": "Data", "in_list_view": 1, "label": "Account SID", - "reqd": 1 + "mandatory_depends_on": "eval: doc.enabled" }, { "fieldname": "api_key", @@ -46,7 +48,7 @@ "fieldtype": "Password", "in_list_view": 1, "label": "Auth Token", - "reqd": 1 + "mandatory_depends_on": "eval: doc.enabled" }, { "fieldname": "twiml_sid", @@ -67,12 +69,22 @@ { "fieldname": "column_break_avmt", "fieldtype": "Column Break" + }, + { + "fieldname": "section_break_malx", + "fieldtype": "Section Break" + }, + { + "default": "0", + "fieldname": "enabled", + "fieldtype": "Check", + "label": "Enabled" } ], "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2023-09-20 16:42:17.025651", + "modified": "2023-11-03 15:13:09.155818", "modified_by": "Administrator", "module": "FCRM", "name": "Twilio Settings", diff --git a/crm/twilio/api.py b/crm/twilio/api.py index 536b62ae..4297e5a7 100644 --- a/crm/twilio/api.py +++ b/crm/twilio/api.py @@ -5,6 +5,10 @@ import frappe from frappe import _ from .twilio_handler import Twilio, IncomingCall, TwilioCallDetails +@frappe.whitelist() +def is_enabled(): + return frappe.db.get_single_value("Twilio Settings", "enabled") + @frappe.whitelist() def generate_access_token(): """Returns access token that is required to authenticate Twilio Client SDK. diff --git a/crm/twilio/twilio_handler.py b/crm/twilio/twilio_handler.py index 61e527dd..71a64461 100644 --- a/crm/twilio/twilio_handler.py +++ b/crm/twilio/twilio_handler.py @@ -27,8 +27,8 @@ class Twilio: """Make a twilio connection. """ settings = frappe.get_doc("Twilio Settings") - # if not (settings and settings.enabled): - # return + if not (settings and settings.enabled): + return return Twilio(settings=settings) def get_phone_numbers(self): @@ -115,6 +115,8 @@ class Twilio: @classmethod def get_twilio_client(self): twilio_settings = frappe.get_doc("Twilio Settings") + if not twilio_settings.enabled: + frappe.throw(_("Please enable twilio settings before making a call.")) auth_token = get_decrypted_password("Twilio Settings", "Twilio Settings", 'auth_token') client = TwilioClient(twilio_settings.account_sid, auth_token) diff --git a/frappe-ui b/frappe-ui index 89e3e41b..e0859c61 160000 --- a/frappe-ui +++ b/frappe-ui @@ -1 +1 @@ -Subproject commit 89e3e41b9d1aa378c15591b4d9365102befc8b8c +Subproject commit e0859c6165a5d54a999f94e7c1cf9647ecd2bf72 diff --git a/frontend/package.json b/frontend/package.json index 5bb2a96f..b70de79c 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -9,21 +9,23 @@ "serve": "vite preview" }, "dependencies": { - "@tiptap/vue-3": "^2.0.4", "@twilio/voice-sdk": "^2.7.1", - "@vitejs/plugin-vue": "^4.2.3", "@vueuse/core": "^10.3.0", "@vueuse/integrations": "^10.3.0", - "autoprefixer": "^10.4.14", "feather-icons": "^4.28.0", - "frappe-ui": "^0.1.13", + "frappe-ui": "^0.1.14", "pinia": "^2.0.33", - "postcss": "^8.4.5", "socket.io-client": "^4.7.2", "sortablejs": "^1.15.0", "tailwindcss": "^3.3.3", "vite": "^4.4.9", "vue": "^3.3.4", "vue-router": "^4.2.2" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^4.2.3", + "autoprefixer": "^10.4.14", + "postcss": "^8.4.5", + "vite": "^4.4.9" } } diff --git a/frontend/src/components/Activities.vue b/frontend/src/components/Activities.vue index bca4adb0..ab059e89 100644 --- a/frontend/src/components/Activities.vue +++ b/frontend/src/components/Activities.vue @@ -619,8 +619,8 @@ import EmailAtIcon from '@/components/Icons/EmailAtIcon.vue' import InboundCallIcon from '@/components/Icons/InboundCallIcon.vue' import OutboundCallIcon from '@/components/Icons/OutboundCallIcon.vue' import CommunicationArea from '@/components/CommunicationArea.vue' -import NoteModal from '@/components/NoteModal.vue' -import TaskModal from '@/components/TaskModal.vue' +import NoteModal from '@/components/Modals/NoteModal.vue' +import TaskModal from '@/components/Modals/TaskModal.vue' import { timeAgo, dateFormat, diff --git a/frontend/src/components/AppSidebar.vue b/frontend/src/components/AppSidebar.vue index 8d3fde2b..f56d4ead 100644 --- a/frontend/src/components/AppSidebar.vue +++ b/frontend/src/components/AppSidebar.vue @@ -39,6 +39,7 @@ import UserDropdown from '@/components/UserDropdown.vue' import LeadsIcon from '@/components/Icons/LeadsIcon.vue' import DealsIcon from '@/components/Icons/DealsIcon.vue' import ContactsIcon from '@/components/Icons/ContactsIcon.vue' +import OrganizationsIcon from '@/components/Icons/OrganizationsIcon.vue' import NoteIcon from '@/components/Icons/NoteIcon.vue' import PhoneIcon from '@/components/Icons/PhoneIcon.vue' import CollapseSidebar from '@/components/Icons/CollapseSidebar.vue' @@ -61,6 +62,11 @@ const links = [ icon: ContactsIcon, to: 'Contacts', }, + { + label: 'Organizations', + icon: OrganizationsIcon, + to: 'Organizations', + }, { label: 'Notes', icon: NoteIcon, diff --git a/frontend/src/components/CallUI.vue b/frontend/src/components/CallUI.vue index 92f4ae87..2de01dff 100644 --- a/frontend/src/components/CallUI.vue +++ b/frontend/src/components/CallUI.vue @@ -2,17 +2,17 @@