From d408d066c76f7101ee18e455e64b7214894b54e7 Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Mon, 13 Nov 2023 12:21:50 +0530 Subject: [PATCH] feat: set contact as primary from UI --- crm/fcrm/doctype/crm_deal/api.py | 2 +- crm/fcrm/doctype/crm_deal/crm_deal.py | 10 ++ frontend/src/components/Icons/SuccessIcon.vue | 16 +++ frontend/src/pages/Deal.vue | 123 ++++++++++-------- 4 files changed, 99 insertions(+), 52 deletions(-) create mode 100644 frontend/src/components/Icons/SuccessIcon.vue diff --git a/crm/fcrm/doctype/crm_deal/api.py b/crm/fcrm/doctype/crm_deal/api.py index 6da46106..a995e65a 100644 --- a/crm/fcrm/doctype/crm_deal/api.py +++ b/crm/fcrm/doctype/crm_deal/api.py @@ -22,7 +22,7 @@ def get_deal(name): deal["contacts"] = frappe.get_all( "CRM Contacts", filters={"parenttype": "CRM Deal", "parent": deal.name}, - fields=["contact"], + fields=["contact", "is_primary"], ) return deal diff --git a/crm/fcrm/doctype/crm_deal/crm_deal.py b/crm/fcrm/doctype/crm_deal/crm_deal.py index 927c8baa..c1f34b28 100644 --- a/crm/fcrm/doctype/crm_deal/crm_deal.py +++ b/crm/fcrm/doctype/crm_deal/crm_deal.py @@ -75,4 +75,14 @@ def remove_contact(deal, contact): deal = frappe.get_cached_doc("CRM Deal", deal) deal.contacts = [d for d in deal.contacts if d.contact != contact] deal.save() + return True + +@frappe.whitelist() +def set_primary_contact(deal, contact): + if not frappe.has_permission("CRM Deal", "write", deal): + frappe.throw(_("Not allowed to set primary contact for Deal"), frappe.PermissionError) + + deal = frappe.get_cached_doc("CRM Deal", deal) + deal.set_primary_contact(contact) + deal.save() return True \ No newline at end of file diff --git a/frontend/src/components/Icons/SuccessIcon.vue b/frontend/src/components/Icons/SuccessIcon.vue new file mode 100644 index 00000000..831786e6 --- /dev/null +++ b/frontend/src/components/Icons/SuccessIcon.vue @@ -0,0 +1,16 @@ + diff --git a/frontend/src/pages/Deal.vue b/frontend/src/pages/Deal.vue index 9d309b5a..6202c46f 100644 --- a/frontend/src/pages/Deal.vue +++ b/frontend/src/pages/Deal.vue @@ -209,37 +209,6 @@ - - - {{ getContactByName(contact.name).full_name }} - -
- - +
+ + + + +
{ contacts: deal.data.contacts.map((contact) => { return { name: contact.contact, + is_primary: contact.is_primary, opened: false, } }), @@ -598,10 +583,30 @@ const detailSections = computed(() => { const showContactModal = ref(false) const _contact = ref({}) -async function addContact(value) { +function contactOptions(contact) { + let options = [ + { + label: 'Delete', + icon: 'trash-2', + onClick: () => removeContact(contact.name), + }, + ] + + if (!contact.is_primary) { + options.push({ + label: 'Set as primary contact', + icon: h(SuccessIcon, { class: 'h-4 w-4' }), + onClick: () => setPrimaryContact(contact.name), + }) + } + + return options +} + +async function addContact(contact) { let d = await call('crm.fcrm.doctype.crm_deal.crm_deal.add_contact', { deal: props.dealId, - contact: value, + contact, }) if (d) { await contacts.reload() @@ -614,10 +619,10 @@ async function addContact(value) { } } -async function removeContact(value) { +async function removeContact(contact) { let d = await call('crm.fcrm.doctype.crm_deal.crm_deal.remove_contact', { deal: props.dealId, - contact: value, + contact, }) if (d) { deal.reload() @@ -630,6 +635,22 @@ async function removeContact(value) { } } +async function setPrimaryContact(contact) { + let d = await call('crm.fcrm.doctype.crm_deal.crm_deal.set_primary_contact', { + deal: props.dealId, + contact, + }) + if (d) { + await contacts.reload() + deal.reload() + createToast({ + title: 'Primary contact set', + icon: 'check', + iconClasses: 'text-green-600', + }) + } +} + const organization = computed(() => { return getOrganization(deal.data.organization) })