diff --git a/crm/api/__init__.py b/crm/api/__init__.py index cb56e3bd..cc2fda67 100644 --- a/crm/api/__init__.py +++ b/crm/api/__init__.py @@ -123,6 +123,12 @@ 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) + return { + "existing_members": existing_members, + "existing_invites": existing_invites, + "to_invite": to_invite, + } + @frappe.whitelist() def get_file_uploader_defaults(doctype: str): diff --git a/crm/fcrm/doctype/crm_form_script/crm_form_script.json b/crm/fcrm/doctype/crm_form_script/crm_form_script.json index 9246913a..f261f564 100644 --- a/crm/fcrm/doctype/crm_form_script/crm_form_script.json +++ b/crm/fcrm/doctype/crm_form_script/crm_form_script.json @@ -65,7 +65,7 @@ ], "index_web_pages_for_search": 1, "links": [], - "modified": "2024-09-16 19:40:19.340948", + "modified": "2025-05-19 17:57:24.610295", "modified_by": "Administrator", "module": "FCRM", "name": "CRM Form Script", @@ -83,9 +83,19 @@ "role": "Sales Manager", "share": 1, "write": 1 + }, + { + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "All", + "share": 1 } ], + "row_format": "Dynamic", "sort_field": "modified", "sort_order": "DESC", "states": [] -} \ No newline at end of file +} diff --git a/crm/fcrm/doctype/crm_invitation/crm_invitation.py b/crm/fcrm/doctype/crm_invitation/crm_invitation.py index f4c9a8f9..625cd882 100644 --- a/crm/fcrm/doctype/crm_invitation/crm_invitation.py +++ b/crm/fcrm/doctype/crm_invitation/crm_invitation.py @@ -21,7 +21,7 @@ class CRMInvitation(Document): if frappe.local.dev_server: print(f"Invite link for {self.email}: {invite_link}") - title = f"Frappe CRM" + title = "Frappe CRM" template = "crm_invitation" frappe.sendmail( @@ -44,12 +44,24 @@ class CRMInvitation(Document): user = self.create_user_if_not_exists() user.append_roles(self.role) + if self.role == "Sales User": + self.update_module_in_user(user, "FCRM") user.save(ignore_permissions=True) self.status = "Accepted" self.accepted_at = frappe.utils.now() self.save(ignore_permissions=True) + def update_module_in_user(self, user, module): + block_modules = frappe.get_all( + "Module Def", + fields=["name as module"], + filters={"name": ["!=", module]}, + ) + + if block_modules: + user.set("block_modules", block_modules) + def create_user_if_not_exists(self): if not frappe.db.exists("User", self.email): first_name = self.email.split("@")[0].title() diff --git a/crm/fcrm/doctype/erpnext_crm_settings/erpnext_crm_settings.py b/crm/fcrm/doctype/erpnext_crm_settings/erpnext_crm_settings.py index f530a65d..7a004387 100644 --- a/crm/fcrm/doctype/erpnext_crm_settings/erpnext_crm_settings.py +++ b/crm/fcrm/doctype/erpnext_crm_settings/erpnext_crm_settings.py @@ -264,7 +264,7 @@ def create_customer_in_remote_site(customer, erpnext_crm_settings): @frappe.whitelist() def get_crm_form_script(): return """ -async function setupForm({ doc, call, $dialog, updateField, createToast }) { +async function setupForm({ doc, call, $dialog, updateField, toast }) { let actions = []; let is_erpnext_integration_enabled = await call("frappe.client.get_single_value", {doctype: "ERPNext CRM Settings", field: "enabled"}); if (!["Lost", "Won"].includes(doc?.status) && is_erpnext_integration_enabled) { diff --git a/frappe-ui b/frappe-ui index 29307e4f..8b615c0e 160000 --- a/frappe-ui +++ b/frappe-ui @@ -1 +1 @@ -Subproject commit 29307e4fffaacdbb3d9c5d95c5270b2f245a5607 +Subproject commit 8b615c0e899d75b99c7d36ec6df97b5d0386b2ca diff --git a/frontend/components.d.ts b/frontend/components.d.ts index bfacdcf1..29a6ae9c 100644 --- a/frontend/components.d.ts +++ b/frontend/components.d.ts @@ -150,6 +150,8 @@ declare module 'vue' { ListIcon: typeof import('./src/components/Icons/ListIcon.vue')['default'] ListRows: typeof import('./src/components/ListViews/ListRows.vue')['default'] LoadingIndicator: typeof import('./src/components/Icons/LoadingIndicator.vue')['default'] + LucideCalendar: typeof import('~icons/lucide/calendar')['default'] + LucidePlus: typeof import('~icons/lucide/plus')['default'] MarkAsDoneIcon: typeof import('./src/components/Icons/MarkAsDoneIcon.vue')['default'] MaximizeIcon: typeof import('./src/components/Icons/MaximizeIcon.vue')['default'] MenuIcon: typeof import('./src/components/Icons/MenuIcon.vue')['default'] @@ -173,6 +175,7 @@ declare module 'vue' { OrganizationsIcon: typeof import('./src/components/Icons/OrganizationsIcon.vue')['default'] OrganizationsListView: typeof import('./src/components/ListViews/OrganizationsListView.vue')['default'] OutboundCallIcon: typeof import('./src/components/Icons/OutboundCallIcon.vue')['default'] + Password: typeof import('./src/components/Controls/Password.vue')['default'] PauseIcon: typeof import('./src/components/Icons/PauseIcon.vue')['default'] PhoneIcon: typeof import('./src/components/Icons/PhoneIcon.vue')['default'] PinIcon: typeof import('./src/components/Icons/PinIcon.vue')['default'] @@ -207,6 +210,7 @@ declare module 'vue' { SmileIcon: typeof import('./src/components/Icons/SmileIcon.vue')['default'] SortBy: typeof import('./src/components/SortBy.vue')['default'] SortIcon: typeof import('./src/components/Icons/SortIcon.vue')['default'] + SquareAsterisk: typeof import('./src/components/Icons/SquareAsterisk.vue')['default'] StepsIcon: typeof import('./src/components/Icons/StepsIcon.vue')['default'] SuccessIcon: typeof import('./src/components/Icons/SuccessIcon.vue')['default'] TableMultiselectInput: typeof import('./src/components/Controls/TableMultiselectInput.vue')['default'] diff --git a/frontend/src/components/Controls/Grid.vue b/frontend/src/components/Controls/Grid.vue index e08cdd7d..54bc29dc 100644 --- a/frontend/src/components/Controls/Grid.vue +++ b/frontend/src/components/Controls/Grid.vue @@ -216,6 +216,13 @@ :options="field.options" @change="(e) => fieldChange(e.target.value, field, row)" /> + diff --git a/frontend/src/components/FieldLayout/Field.vue b/frontend/src/components/FieldLayout/Field.vue index 92ce15f8..a190817f 100644 --- a/frontend/src/components/FieldLayout/Field.vue +++ b/frontend/src/components/FieldLayout/Field.vue @@ -136,7 +136,6 @@ - +